-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[clang][analyzer] execute evalCast for all kinds of Region which has a binding in RegionStore
#139095
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
Conversation
…s a binding in RegionStore
|
@llvm/pr-subscribers-clang Author: None (flovent) ChangesThis PR aims to fix crash caused by The crash caused by Unlike other casts, such as Its corresponding AST node is:
This change only affects the testcase for llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp Lines 997 to 1003 in 55517f5
UnknownVal is reasonable and it is consistent with reinterpret_cast.
Full diff: https://github.com/llvm/llvm-project/pull/139095.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 1cc9cb84cbfa4..84331804edc9e 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1650,7 +1650,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
// Check if the region has a binding.
if (V)
- return *V;
+ return svalBuilder.evalCast(*V, T, QualType{});
// The location does not have a bound value. This means that it has
// the value it had upon its creation and/or entry to the analyzed
diff --git a/clang/test/Analysis/builtin_bitcast.cpp b/clang/test/Analysis/builtin_bitcast.cpp
index 5a0d9e7189b8e..2cd1b96bf4550 100644
--- a/clang/test/Analysis/builtin_bitcast.cpp
+++ b/clang/test/Analysis/builtin_bitcast.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \
// RUN: -analyzer-checker=core,debug.ExprInspection
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify -std=c++20 %s \
+// RUN: -analyzer-checker=core,debug.ExprInspection
template <typename T> void clang_analyzer_dump(T);
using size_t = decltype(sizeof(int));
@@ -39,7 +41,7 @@ struct A {
}
};
void gh_69922(size_t p) {
- // expected-warning-re@+1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
+ // expected-warning@+1 {{Unknown}}
clang_analyzer_dump(__builtin_bit_cast(A*, p & 1));
__builtin_bit_cast(A*, p & 1)->set(2); // no-crash
@@ -49,5 +51,31 @@ void gh_69922(size_t p) {
// store to the member variable `n`.
clang_analyzer_dump(__builtin_bit_cast(A*, p & 1)->n); // Ideally, this should print "2".
- // expected-warning-re@-1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
+ // expected-warning@-1 {{Unknown}}
+}
+
+static void issue_71174() {
+ auto res = __builtin_bit_cast(unsigned long long, &issue_71174) | 1; // no-crash
+}
+
+#if __cplusplus >= 202002L
+#include "Inputs/system-header-simulator-cxx.h"
+using intptr_t = decltype(sizeof(int*));
+
+namespace std {
+template< class To, class From >
+constexpr To bit_cast( const From& from ) noexcept {
+ #if __has_builtin(__builtin_bit_cast)
+ return __builtin_bit_cast(To, from);
+#else
+ To to;
+ std::memcpy(&to, &from, sizeof(To));
+ return to;
+#endif
+}
+}
+
+bool issue_137417(std::string* x) {
+ return x == std::bit_cast<std::string*>(static_cast<intptr_t>(-1)); // no-crash
}
+#endif
\ No newline at end of file
|
|
@llvm/pr-subscribers-clang-static-analyzer-1 Author: None (flovent) ChangesThis PR aims to fix crash caused by The crash caused by Unlike other casts, such as Its corresponding AST node is:
This change only affects the testcase for llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp Lines 997 to 1003 in 55517f5
UnknownVal is reasonable and it is consistent with reinterpret_cast.
Full diff: https://github.com/llvm/llvm-project/pull/139095.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 1cc9cb84cbfa4..84331804edc9e 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -1650,7 +1650,7 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T)
// Check if the region has a binding.
if (V)
- return *V;
+ return svalBuilder.evalCast(*V, T, QualType{});
// The location does not have a bound value. This means that it has
// the value it had upon its creation and/or entry to the analyzed
diff --git a/clang/test/Analysis/builtin_bitcast.cpp b/clang/test/Analysis/builtin_bitcast.cpp
index 5a0d9e7189b8e..2cd1b96bf4550 100644
--- a/clang/test/Analysis/builtin_bitcast.cpp
+++ b/clang/test/Analysis/builtin_bitcast.cpp
@@ -1,5 +1,7 @@
// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify %s \
// RUN: -analyzer-checker=core,debug.ExprInspection
+// RUN: %clang_analyze_cc1 -triple x86_64-unknown-unknown -verify -std=c++20 %s \
+// RUN: -analyzer-checker=core,debug.ExprInspection
template <typename T> void clang_analyzer_dump(T);
using size_t = decltype(sizeof(int));
@@ -39,7 +41,7 @@ struct A {
}
};
void gh_69922(size_t p) {
- // expected-warning-re@+1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
+ // expected-warning@+1 {{Unknown}}
clang_analyzer_dump(__builtin_bit_cast(A*, p & 1));
__builtin_bit_cast(A*, p & 1)->set(2); // no-crash
@@ -49,5 +51,31 @@ void gh_69922(size_t p) {
// store to the member variable `n`.
clang_analyzer_dump(__builtin_bit_cast(A*, p & 1)->n); // Ideally, this should print "2".
- // expected-warning-re@-1 {{(reg_${{[0-9]+}}<size_t p>) & 1U}}
+ // expected-warning@-1 {{Unknown}}
+}
+
+static void issue_71174() {
+ auto res = __builtin_bit_cast(unsigned long long, &issue_71174) | 1; // no-crash
+}
+
+#if __cplusplus >= 202002L
+#include "Inputs/system-header-simulator-cxx.h"
+using intptr_t = decltype(sizeof(int*));
+
+namespace std {
+template< class To, class From >
+constexpr To bit_cast( const From& from ) noexcept {
+ #if __has_builtin(__builtin_bit_cast)
+ return __builtin_bit_cast(To, from);
+#else
+ To to;
+ std::memcpy(&to, &from, sizeof(To));
+ return to;
+#endif
+}
+}
+
+bool issue_137417(std::string* x) {
+ return x == std::bit_cast<std::string*>(static_cast<intptr_t>(-1)); // no-crash
}
+#endif
\ No newline at end of file
|
This PR aims to fix crash caused by
std::bit_cast(#137417) and__builtin_bit_cast(#71174).The crash caused by
std::bit_castis actually due to the__builtin_bit_castused in its implementation (see the code added intest/Analysis/builtin_bitcast.cpp), so both issues share the same root cause.Unlike other casts, such as
reinterpret_cast,__builtin_bit_castdoes not have an explicit cast kind (e.g.,CK_IntegralToPointer) in its AST node. For example, consider the following code:Its corresponding AST node is:
ExprEnginewill callevalLoadforLValueToRValueBitCast, which eventually leads to theRegionStore::getBindingAPI. Before this PR's change, it will return originalSValwith it's orignal type. For the example code above, whole expression'sSValwill be evaluated to-1'sSVal(NonLoc), if we compare it with aLoc(e.g., a pointer), assert fails and then crash happens.This change only affects the testcase for
__builtin_bit_castitself, ingh_69922it should be evaluated toLoc, but since orignal region is aSymbolReigon, and it can't casted toLocnow,llvm-project/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
Lines 997 to 1003 in 55517f5
UnknownValis reasonable and it is consistent withreinterpret_cast.