-
Notifications
You must be signed in to change notification settings - Fork 12k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[analyzer] Fix crash in BasicValueFactory.cpp with __int128_t integers #67212
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-static-analyzer-1 ChangesThis change avoids a crash in BasicValueFactory by checking the bit width of an APSInt to avoid calling getZExtValue if greater than 64-bits. This was caught by our internal, randomized test generator. Clang invocation <src-root>/llvm/include/llvm/ADT/APInt.h:1488: #9 <address> llvm::APInt::getZExtValue() const Full diff: https://github.com/llvm/llvm-project/pull/67212.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
index 5924f6a671c2ac1..351735cdf42dc8f 100644
--- a/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp
@@ -275,6 +275,9 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
if (V2.isSigned() && V2.isNegative())
return nullptr;
+ if (V2.getBitWidth() > 64)
+ return nullptr;
+
uint64_t Amt = V2.getZExtValue();
if (Amt >= V1.getBitWidth())
@@ -298,6 +301,9 @@ BasicValueFactory::evalAPSInt(BinaryOperator::Opcode Op,
if (V2.isSigned() && V2.isNegative())
return nullptr;
+ if (V2.getBitWidth() > 64)
+ return nullptr;
+
uint64_t Amt = V2.getZExtValue();
if (Amt >= V1.getBitWidth())
diff --git a/clang/test/Analysis/int128-nocrash.c b/clang/test/Analysis/int128-nocrash.c
new file mode 100644
index 000000000000000..0e9d2322080b8b8
--- /dev/null
+++ b/clang/test/Analysis/int128-nocrash.c
@@ -0,0 +1,10 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=optin.portability.UnixAPI \
+// RUN: -triple x86_64-pc-linux-gnu -x c %s
+
+// Don't crash!
+// expected-no-diagnostics
+const __int128_t a = ( ((__int128_t)1) << 64 | 1);
+
+void b() {
+ 2 >> a;
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good commit! I was suspicious at first because getBitWidth()
tends to be problematic, but I couldn't find any concrete case where the new code behaves incorrectly.
I'll resolve the comments in an update. Thanks for the comments! |
I support changes like this. However, I think we should prefer reusing existing test files to creating more and more new ones. That has one benefit to me, one can see multiple cases of the topic on one screen without jumping around to open multiple. |
Thanks @steakhal, I'll look at including this test into an existing case. Best |
48eab23
to
137b82a
Compare
@steakhal, I looked at the existing test cases, but cannot find an existing test where this case would easily fit. I'm happy to follow a specific suggestion about where or how to reformat or rename this test. For now, I'll assume this current approach is ok until I see some concrete suggestions. Thanks |
Hey guys, is it ok to merge this fix? Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's simple and clean, let's just merge it :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please be sure to add a release note about the fix, too!
137b82a
to
ccf6554
Compare
I'll wait for an ok from @AaronBallman before merging. Thank you! |
This change avoids a crash in BasicValueFactory by checking the bit width of an APSInt to avoid calling getZExtValue if greater than 64-bits. Clang invocation clang -cc1 -analyzer-checker=optin.portability.UnixAPI case.c <src-root>/llvm/include/llvm/ADT/APInt.h:1488: uint64_t llvm::APInt::getZExtValue() const: Assertion `getActiveBits() <= 64 && "Too many bits for uint64_t"' failed. ... llvm#9 <address> llvm::APInt::getZExtValue() const <src-root>/llvm/include/llvm/ADT/APInt.h:1488:5 clang::BinaryOperatorKind, llvm::APSInt const&, llvm::APSInt const&) <src-root>/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp:307:37 llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::BinaryOperatorKind, clang::ento::NonLoc, clang::ento::NonLoc, clang::QualType) <src-root>/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:531:31 llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>, clang::BinaryOperatorKind, clang::ento::SVal, clang::ento::SVal, clang::QualType) <src-root>/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp:532:26 ...
ccf6554
to
2467ec4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assuming precommit CI comes back green, the changes LGTM, thank you!
This change avoids a crash in BasicValueFactory by checking the bit width of an APSInt to avoid calling getZExtValue if greater than 64-bits. This was caught by our internal, randomized test generator.
Clang invocation
clang -cc1 -analyzer-checker=optin.portability.UnixAPI case.c
/llvm/include/llvm/ADT/APInt.h:1488:
uint64_t llvm::APInt::getZExtValue() const: Assertion `getActiveBits() <= 64
&& "Too many bits for uint64_t"' failed.
...
#9
llvm::APInt::getZExtValue() const/llvm/include/llvm/ADT/APInt.h:1488:5
clang::BinaryOperatorKind, llvm::APSInt const&, llvm::APSInt const&)
/clang/lib/StaticAnalyzer/Core/BasicValueFactory.cpp:307:37
llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>,
clang::BinaryOperatorKind, clang::ento::NonLoc, clang::ento::NonLoc,
clang::QualType)
/clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:531:31
llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>,
clang::BinaryOperatorKind, clang::ento::SVal, clang::ento::SVal,
clang::QualType)
/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp:532:26
...