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

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)

>From 846b3c4ffb1b45d637cf8a651fb866d25dfef955 Mon Sep 17 00:00:00 2001
From: Vince Bridgers <vince.a.bridg...@ericsson.com>
Date: Tue, 29 Jul 2025 22:24:58 +0200
Subject: [PATCH] [analyzer] Fix getElementRegion to retain address space
 information

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)
---
 clang/include/clang/AST/Type.h                 | 10 ++++++++++
 clang/lib/StaticAnalyzer/Core/MemRegion.cpp    |  2 +-
 .../test/Analysis/element-region-addr-space.c  | 18 ++++++++++++++++++
 3 files changed, 29 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/Analysis/element-region-addr-space.c

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;
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to