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
