https://github.com/a-nogikh created 
https://github.com/llvm/llvm-project/pull/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)`.


>From 298059bb529993fe660316d0a65a860426f39d3c Mon Sep 17 00:00:00 2001
From: Aleksandr Nogikh <[email protected]>
Date: Thu, 26 Feb 2026 16:44:59 +0000
Subject: [PATCH] [AllocToken] [Clang] Fix type inference for atomic types

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)`.
---
 clang/lib/AST/InferAlloc.cpp                  |  5 +++++
 clang/test/CodeGenCXX/alloc-token-pointer.cpp | 22 +++++++++++++++++++
 2 files changed, 27 insertions(+)

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