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 &amp;&amp;
 "RhsLoc and LhsLoc bitwidth must be same!"' failed.

 #<!-- -->0 &lt;addr&gt; llvm::sys::PrintStackTrace(llvm::raw_ostream&amp;, 
int) (clang-21)
 ...
 #<!-- -->7 &lt;addr&gt; (anonymous 
namespace)::SimpleSValBuilder::evalBinOpLL(llvm::IntrusiveRefCntPtr&lt;clang::ento::ProgramState
 const&gt;,
  clang::BinaryOperatorKind, clang::ento::Loc, clang::ento::Loc, 
clang::QualType) SimpleSValBuilder.cpp:0:0
 #<!-- -->8 &lt;addr&gt; 
clang::ento::SValBuilder::evalBinOp(llvm::IntrusiveRefCntPtr&lt;clang::ento::ProgramState
 const&gt;,
  clang::BinaryOperatorKind, clang::ento::SVal, clang::ento::SVal, 
clang::QualType) (clang-21)
 #<!-- -->9 &lt;addr&gt; 
clang::ento::ExprEngine::VisitBinaryOperator(clang::BinaryOperator const*, 
clang::ento::ExplodedNode*,
  clang::ento::ExplodedNodeSet&amp;) (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
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to