-
Notifications
You must be signed in to change notification settings - Fork 14.6k
[analyzer] Retain address space information in getElementRegion #151370
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
The factory method `MemRegionManager::getElementRegion()` is the main way of constructing `ElementRegion` objects, which are widespread in the analysis and may represent array elements (as lvalues), pointer arithmetics and type conversions. This factory method used to strip all qualifiers from the type associated with the element (after canonicalizing it), but the address space qualifier can affect the size of a pointer type, so stripping it caused an assertion failure (in `evalBinOpLL`): clang: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:785: void assertEqualBitWidths(clang::ento::ProgramStateRef, clang::ento::Loc, clang::ento::Loc): Assertion `RhsBitwidth == LhsBitwidth && "RhsLoc and LhsLoc bitwidth must be same!"' failed. Co-authored-by: Vince Bridgers <vince.a.bridgers@ericsson.com>
@llvm/pr-subscribers-clang-static-analyzer-1 @llvm/pr-subscribers-clang Author: Donát Nagy (NagyDonat) ChangesThe factory method This factory method used to strip all qualifiers from the type associated with the element (after canonicalizing it), but the address space qualifier can affect the size of a pointer type, so stripping it caused an assertion failure (in clang: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:785: void assertEqualBitWidths(clang::ento::ProgramStateRef, clang::ento::Loc, clang::ento::Loc): Assertion `RhsBitwidth == LhsBitwidth && "RhsLoc and LhsLoc bitwidth must be same!"' failed. Full diff: https://github.com/llvm/llvm-project/pull/151370.diff 2 Files Affected:
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 3e68373028b10..0058a0ddfb0df 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1219,6 +1219,16 @@ MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
const ASTContext &Ctx) {
QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
+ // The address space must be preserved because some target-specific address
+ // spaces influence the size of the pointer value which is represented by the
+ // element region.
+ LangAS AS = elementType.getAddressSpace();
+ if (AS != LangAS::Default) {
+ Qualifiers Quals;
+ Quals.setAddressSpace(AS);
+ T = Ctx.getQualifiedType(T, Quals);
+ }
+
llvm::FoldingSetNodeID ID;
ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
diff --git a/clang/test/Analysis/element-region-address-space.c b/clang/test/Analysis/element-region-address-space.c
new file mode 100644
index 0000000000000..fddc1bb840231
--- /dev/null
+++ b/clang/test/Analysis/element-region-address-space.c
@@ -0,0 +1,11 @@
+// RUN: %clang_analyze_cc1 -triple amdgcn-unknown-unknown \
+// RUN: -analyzer-checker=core,unix.Malloc -verify %s
+
+// expected-no-diagnostics
+//
+// By default, pointers are 64-bits.
+#define ADDRESS_SPACE_32BITS __attribute__((address_space(3)))
+
+int test(ADDRESS_SPACE_32BITS int *p, ADDRESS_SPACE_32BITS void *q) {
+ return p == q;
+}
|
LGTM, thanks for coming up with a good solution for this problem. |
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.
LGTM, thanks for PR!
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.
I find this solution a lot more robust.
I'll think about this before casting my vote.
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.
LGTM modulo suggestions.
Thanks both of you.
Co-authored-by: Balazs Benics <benicsbalazs@gmail.com>
The factory method
MemRegionManager::getElementRegion()
is the main way of constructingElementRegion
objects, which are widespread in the analysis and may represent array elements (as lvalues), pointer arithmetics and type conversions.This factory method used to strip all qualifiers from the type associated with the element (after canonicalizing it), but the address space qualifier can affect the size of a pointer type, so stripping it caused an assertion failure (in
evalBinOpLL
):clang: clang/lib/StaticAnalyzer/Core/SimpleSValBuilder.cpp:785: void assertEqualBitWidths(clang::ento::ProgramStateRef, clang::ento::Loc, clang::ento::Loc): Assertion `RhsBitwidth == LhsBitwidth && "RhsLoc and LhsLoc bitwidth must be same!"' failed.