Author: Marco Elver
Date: 2026-07-23T08:52:35+02:00
New Revision: bc3d3c9e3af37fab009d3fa10349f56b150e69d4

URL: 
https://github.com/llvm/llvm-project/commit/bc3d3c9e3af37fab009d3fa10349f56b150e69d4
DIFF: 
https://github.com/llvm/llvm-project/commit/bc3d3c9e3af37fab009d3fa10349f56b150e69d4.diff

LOG: [AllocToken] Fix typeContainsPointer for references, PMFs, blocks, ObjC 
pointers (#211349)

When evaluating whether an allocated type contains a pointer to generate
the alloc_token metadata, typeContainsPointer() previously only checked
for PointerType.

Expand typeContainsPointer() to check isAnyPointerType(),
isReferenceType(), isMemberFunctionPointerType(), and
isBlockPointerType().

Added: 
    clang/test/CodeGenObjCXX/alloc-token-pointer.mm

Modified: 
    clang/lib/AST/InferAlloc.cpp
    clang/test/CodeGenCXX/alloc-token-pointer.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/InferAlloc.cpp b/clang/lib/AST/InferAlloc.cpp
index 5ceb6f4a85e7f..6c99a81d739f1 100644
--- a/clang/lib/AST/InferAlloc.cpp
+++ b/clang/lib/AST/InferAlloc.cpp
@@ -27,7 +27,9 @@ typeContainsPointer(QualType T,
                     llvm::SmallPtrSet<const RecordDecl *, 4> &VisitedRD,
                     bool &IncompleteType) {
   QualType CanonicalType = T.getCanonicalType();
-  if (CanonicalType->isPointerType())
+  if (CanonicalType->isAnyPointerType() || CanonicalType->isReferenceType() ||
+      CanonicalType->isMemberFunctionPointerType() ||
+      CanonicalType->isBlockPointerType())
     return true; // base case
 
   // Look through typedef chain to check for special types.

diff  --git a/clang/test/CodeGenCXX/alloc-token-pointer.cpp 
b/clang/test/CodeGenCXX/alloc-token-pointer.cpp
index d352880711435..40f4c8001dc5e 100644
--- a/clang/test/CodeGenCXX/alloc-token-pointer.cpp
+++ b/clang/test/CodeGenCXX/alloc-token-pointer.cpp
@@ -207,6 +207,38 @@ StructWithAtomicNonPtr *test_struct_with_atomic_nonptr() {
   return new StructWithAtomicNonPtr;
 }
 
+struct Dummy { void foo(); int data; };
+
+struct StructWithRef {
+  int &r;
+};
+
+// CHECK-LABEL: define dso_local noundef ptr @_Z20test_struct_with_refPi(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 8){{.*}} 
!alloc_token [[META_STRUCTWITHREF:![0-9]+]]
+StructWithRef *test_struct_with_ref(int *p) {
+  return new StructWithRef{*p};
+}
+
+struct StructWithPMF {
+  void (Dummy::*pmf)();
+};
+
+// CHECK-LABEL: define dso_local noundef ptr @_Z20test_struct_with_pmfv(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 16){{.*}} 
!alloc_token [[META_STRUCTWITHPMF:![0-9]+]]
+StructWithPMF *test_struct_with_pmf() {
+  return new StructWithPMF;
+}
+
+struct StructWithPMD {
+  int Dummy::*pmd;
+};
+
+// CHECK-LABEL: define dso_local noundef ptr @_Z20test_struct_with_pmdv(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 8){{.*}} 
!alloc_token [[META_STRUCTWITHPMD:![0-9]+]]
+StructWithPMD *test_struct_with_pmd() {
+  return new StructWithPMD;
+}
+
 // CHECK: [[META_INT]] = !{!"int", i1 false}
 // CHECK: [[META_INTPTR]] = !{!"int *", i1 true}
 // CHECK: [[META_ULONG]] = !{!"unsigned long", i1 false}
@@ -217,3 +249,6 @@ StructWithAtomicNonPtr *test_struct_with_atomic_nonptr() {
 // CHECK: [[META_UINTPTR]] = !{!"unsigned long", i1 true}
 // CHECK: [[META_STRUCTWITHATOMIC]] = !{!"StructWithAtomic", i1 true}
 // CHECK: [[META_STRUCTWITHATOMICNONPTR]] = !{!"StructWithAtomicNonPtr", i1 
false}
+// CHECK: [[META_STRUCTWITHREF]] = !{!"StructWithRef", i1 true}
+// CHECK: [[META_STRUCTWITHPMF]] = !{!"StructWithPMF", i1 true}
+// CHECK: [[META_STRUCTWITHPMD]] = !{!"StructWithPMD", i1 false}

diff  --git a/clang/test/CodeGenObjCXX/alloc-token-pointer.mm 
b/clang/test/CodeGenObjCXX/alloc-token-pointer.mm
new file mode 100644
index 0000000000000..08671fb79821b
--- /dev/null
+++ b/clang/test/CodeGenObjCXX/alloc-token-pointer.mm
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsanitize=alloc-token -triple x86_64-apple-macosx10.15.0 
-std=c++20 -fblocks -fobjc-arc -emit-llvm -disable-llvm-passes %s -o - | 
FileCheck %s
+
+@class ObjCClass;
+
+struct StructWithBlock {
+  void (^b)(void);
+};
+
+// CHECK-LABEL: define {{.*}}ptr @_Z22test_struct_with_blockv(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 8){{.*}} 
!alloc_token [[META_STRUCTWITHBLOCK:![0-9]+]]
+StructWithBlock *test_struct_with_block() {
+  return new StructWithBlock;
+}
+
+struct StructWithObjCPtr {
+  id obj;
+  Class cls;
+  ObjCClass *ptr;
+};
+
+// CHECK-LABEL: define {{.*}}ptr @_Z25test_struct_with_objc_ptrv(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 24){{.*}} 
!alloc_token [[META_STRUCTWITHOBJCPTR:![0-9]+]]
+StructWithObjCPtr *test_struct_with_objc_ptr() {
+  return new StructWithObjCPtr;
+}
+
+// CHECK: [[META_STRUCTWITHBLOCK]] = !{!"StructWithBlock", i1 true}
+// CHECK: [[META_STRUCTWITHOBJCPTR]] = !{!"StructWithObjCPtr", i1 true}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to