[clang] [analyzer] Fix getElementRegion to retain address space information (PR #151249)

via cfe-commits cfe-commits at lists.llvm.org
Tue Jul 29 16:00:20 PDT 2025


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-static-analyzer-1

Author: None (vabridgers)

<details>
<summary>Changes</summary>

This change modifies getElementRegion to retain address space information when removing all QualType qualifiers. Always removing address space qualifiers can expose cases where QualTypes for different pointer types may be different depending on how the QualTypes are obtained.

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.

 #<!-- -->0 <addr> llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (clang-21)
 ...
 #<!-- -->7 <addr> (anonymous namespace)::SimpleSValBuilder::evalBinOpLL(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>,
  clang::BinaryOperatorKind, clang::ento::Loc, clang::ento::Loc, clang::QualType) SimpleSValBuilder.cpp:0:0
 #<!-- -->8 <addr> clang::ento::SValBuilder::evalBinOp(llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>,
  clang::BinaryOperatorKind, clang::ento::SVal, clang::ento::SVal, clang::QualType) (clang-21)
 #<!-- -->9 <addr> clang::ento::ExprEngine::VisitBinaryOperator(clang::BinaryOperator const*, clang::ento::ExplodedNode*,
  clang::ento::ExplodedNodeSet&) (clang-21)

---
Full diff: https://github.com/llvm/llvm-project/pull/151249.diff


3 Files Affected:

- (modified) clang/include/clang/AST/Type.h (+10) 
- (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+1-1) 
- (added) clang/test/Analysis/element-region-addr-space.c (+18) 


``````````diff
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 98810fbea726e..a56fbbe1fac56 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1188,6 +1188,7 @@ class QualType {
   void removeLocalConst();
   void removeLocalVolatile();
   void removeLocalRestrict();
+  QualType removeNonAddressSpaceQualifiers();
 
   void removeLocalFastQualifiers() { Value.setInt(0); }
   void removeLocalFastQualifiers(unsigned Mask) {
@@ -8274,6 +8275,15 @@ inline void QualType::removeLocalVolatile() {
   removeLocalFastQualifiers(Qualifiers::Volatile);
 }
 
+inline QualType QualType::removeNonAddressSpaceQualifiers() {
+  if (getQualifiers().hasTargetSpecificAddressSpace()) {
+    removeLocalFastQualifiers();
+  } else {
+    return getCanonicalType().getUnqualifiedType();
+  }
+  return *this;
+}
+
 /// Check if this type has any address space qualifier.
 inline bool QualType::hasAddressSpace() const {
   return getQualifiers().hasAddressSpace();
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 3e68373028b10..895f2ab43dc35 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -1217,7 +1217,7 @@ const ElementRegion *
 MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx,
                                    const SubRegion *superRegion,
                                    const ASTContext &Ctx) {
-  QualType T = Ctx.getCanonicalType(elementType).getUnqualifiedType();
+  QualType T = elementType.removeNonAddressSpaceQualifiers();
 
   llvm::FoldingSetNodeID ID;
   ElementRegion::ProfileRegion(ID, T, Idx, superRegion);
diff --git a/clang/test/Analysis/element-region-addr-space.c b/clang/test/Analysis/element-region-addr-space.c
new file mode 100644
index 0000000000000..f8a1185fd1ecf
--- /dev/null
+++ b/clang/test/Analysis/element-region-addr-space.c
@@ -0,0 +1,18 @@
+// RUN: %clang_analyze_cc1 -triple amdgcn-unknown-unknown \
+// RUN: -analyzer-checker=core,unix.Malloc,debug.ExprInspection -verify \
+// RUN: -Wno-incompatible-pointer-types -Wno-unused-comparison %s
+
+// expected-no-diagnostics
+//
+// By default, pointers are 64-bits.
+#define ADDRESS_SPACE_32BITS __attribute__((address_space(3)))
+ADDRESS_SPACE_32BITS void *b();
+ADDRESS_SPACE_32BITS int *c();
+typedef struct {
+  ADDRESS_SPACE_32BITS int *e;
+} f;
+void g() {
+  ADDRESS_SPACE_32BITS void *h = b();
+  ADDRESS_SPACE_32BITS f *j = c();
+  j->e == h;
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/151249


More information about the cfe-commits mailing list