Author: Aleksandr Nogikh
Date: 2026-02-26T10:57:49-08:00
New Revision: b8618ff61e719c9328f5198bbb9c5734223d5a37

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

LOG: [AllocToken] [Clang] Fix type inference for atomic types (#183571)

When evaluating whether an allocated type contains a pointer to generate
the `alloc_token` metadata, `typeContainsPointer` incorrectly stopped
recursion upon encountering an `AtomicType`. This resulted in types like
`_Atomic(int *)` (or `std::atomic<int *>` under libc++) being
incorrectly evaluated as not containing a pointer.

Add support for `AtomicType` in `typeContainsPointer` by recursively
checking the contained type.

Add tests for structs containing `_Atomic(int *)` and `_Atomic(int)`.

Added: 
    

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 e439ed4dbb386..5ceb6f4a85e7f 100644
--- a/clang/lib/AST/InferAlloc.cpp
+++ b/clang/lib/AST/InferAlloc.cpp
@@ -44,6 +44,11 @@ typeContainsPointer(QualType T,
   // The type is an array; check the element type.
   if (const ArrayType *AT = dyn_cast<ArrayType>(CanonicalType))
     return typeContainsPointer(AT->getElementType(), VisitedRD, 
IncompleteType);
+
+  // The type is an atomic type.
+  if (const AtomicType *AT = dyn_cast<AtomicType>(CanonicalType))
+    return typeContainsPointer(AT->getValueType(), VisitedRD, IncompleteType);
+
   // The type is a struct, class, or union.
   if (const RecordDecl *RD = CanonicalType->getAsRecordDecl()) {
     if (!RD->isCompleteDefinition()) {

diff  --git a/clang/test/CodeGenCXX/alloc-token-pointer.cpp 
b/clang/test/CodeGenCXX/alloc-token-pointer.cpp
index f12ee7a40a6b8..d352880711435 100644
--- a/clang/test/CodeGenCXX/alloc-token-pointer.cpp
+++ b/clang/test/CodeGenCXX/alloc-token-pointer.cpp
@@ -187,6 +187,26 @@ uptr *test_uintptr_isptr2() {
   return new uptr;
 }
 
+struct StructWithAtomic {
+  _Atomic(int *) val;
+};
+
+// CHECK-LABEL: define dso_local noundef ptr @_Z23test_struct_with_atomicv(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 8){{.*}} 
!alloc_token [[META_STRUCTWITHATOMIC:![0-9]+]]
+StructWithAtomic *test_struct_with_atomic() {
+  return new StructWithAtomic;
+}
+
+struct StructWithAtomicNonPtr {
+  _Atomic(int) val;
+};
+
+// CHECK-LABEL: define dso_local noundef ptr 
@_Z30test_struct_with_atomic_nonptrv(
+// CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4){{.*}} 
!alloc_token [[META_STRUCTWITHATOMICNONPTR:![0-9]+]]
+StructWithAtomicNonPtr *test_struct_with_atomic_nonptr() {
+  return new StructWithAtomicNonPtr;
+}
+
 // CHECK: [[META_INT]] = !{!"int", i1 false}
 // CHECK: [[META_INTPTR]] = !{!"int *", i1 true}
 // CHECK: [[META_ULONG]] = !{!"unsigned long", i1 false}
@@ -195,3 +215,5 @@ uptr *test_uintptr_isptr2() {
 // CHECK: [[META_VIRTUALTESTCLASS]] = !{!"VirtualTestClass", i1 true}
 // CHECK: [[META_MYSTRUCTUINTPTR]] = !{!"MyStructUintptr", i1 true}
 // CHECK: [[META_UINTPTR]] = !{!"unsigned long", i1 true}
+// CHECK: [[META_STRUCTWITHATOMIC]] = !{!"StructWithAtomic", i1 true}
+// CHECK: [[META_STRUCTWITHATOMICNONPTR]] = !{!"StructWithAtomicNonPtr", i1 
false}


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

Reply via email to