https://github.com/flash1729 updated https://github.com/llvm/llvm-project/pull/212768
>From 8cebfe1aa29d466308528cccd539c38080a5029f Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Wed, 29 Jul 2026 17:20:06 +0530 Subject: [PATCH 1/2] [clang] Handle _Atomic types in hasUniqueObjectRepresentations Atomic types aren't scalar, so the predicate rejected them before layout was checked and fell through to false. _Atomic(T) shares T's representation when sizes match; padding from size rounding makes it non-unique. Fixes the FIXME in bugprone-suspicious-memory-comparison (D89651). --- .../checkers/bugprone/suspicious-memory-comparison.c | 4 +--- clang/docs/ReleaseNotes.md | 6 ++++++ clang/lib/AST/ASTContext.cpp | 9 ++++++++- clang/test/SemaCXX/type-traits.cpp | 10 ++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-memory-comparison.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-memory-comparison.c index d3ecffec9a7816..1f8bd7bd9f1ad6 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-memory-comparison.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/suspicious-memory-comparison.c @@ -286,9 +286,7 @@ struct AtomicMember { }; void Test_AtomicMember(void) { - // FIXME: this is a false positive as the list of objects with unique object - // representations is incomplete. + // _Atomic(int) has the same object representation as int: no warning. struct AtomicMember a, b; memcmp(&a, &b, sizeof(struct AtomicMember)); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: comparing object representation of type 'struct AtomicMember' which does not have a unique object representation; consider comparing the members of the object manually } diff --git a/clang/docs/ReleaseNotes.md b/clang/docs/ReleaseNotes.md index 80e770a40838ad..20b37f466b84fc 100644 --- a/clang/docs/ReleaseNotes.md +++ b/clang/docs/ReleaseNotes.md @@ -327,6 +327,12 @@ features cannot lower the translation-unit ABI level; - Fixed a crash when classifying a call to a builtin with dependent arguments, such as when the call is used as an `auto` non-type template argument. +- `__has_unique_object_representations` now returns `true` for `_Atomic` types + whose object representation is identical to that of their value type, such + as `_Atomic(int)`. Atomic types whose size is rounded up to a power of two + (adding padding bits) continue to report `false`. This also fixes a false + positive in the `bugprone-suspicious-memory-comparison` clang-tidy check. + #### Bug Fixes to Attribute Support - The `counted_by`/`counted_by_or_null` diagnostic that rejects a pointer whose diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2228811546c0fd..6aea6cfcf25ca1 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3062,6 +3062,14 @@ bool ASTContext::hasUniqueObjectRepresentations( "hasUniqueObjectRepresentations should not be called with an " "incomplete type"); + // _Atomic(T) shares T's object representation unless its size was rounded + // up to a power of two, in which case the extra bytes are padding. Atomic + // types are never trivially copyable, so (9.1) is judged on the value type. + if (const auto *AT = Ty->getAs<AtomicType>()) + return getTypeSize(AT) == getTypeSize(AT->getValueType()) && + hasUniqueObjectRepresentations(AT->getValueType(), + CheckIfTriviallyCopyable); + // (9.1) - T is trivially copyable... if (CheckIfTriviallyCopyable && !Ty.isTriviallyCopyableType(*this)) return false; @@ -3102,7 +3110,6 @@ bool ASTContext::hasUniqueObjectRepresentations( // FIXME: More cases to handle here (list by rsmith): // vectors (careful about, eg, vector of 3 foo) // _Complex int and friends - // _Atomic T // Obj-C block pointers // Obj-C object pointers // and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t, diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index ff74461308fb15..246da619fe0469 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -3504,6 +3504,16 @@ static_assert(__has_unique_object_representations(const int *), "as are pointers static_assert(__has_unique_object_representations(volatile int *), "as are pointers"); static_assert(__has_unique_object_representations(const volatile int *), "as are pointers"); +static_assert(__has_unique_object_representations(_Atomic(int)), "layout-identical atomics are"); +static_assert(!__has_unique_object_representations(_Atomic(float)), "value type is not unique"); +struct AtomicReprThreeChars { char a, b, c; }; +static_assert(!__has_unique_object_representations(_Atomic(AtomicReprThreeChars)), + "atomic size rounded up to a power of two adds padding"); +struct AtomicReprMember { _Atomic(int) x; }; +static_assert(__has_unique_object_representations(AtomicReprMember), "atomic member, no padding"); +struct AtomicReprPadded { char c; _Atomic(int) x; }; +static_assert(!__has_unique_object_representations(AtomicReprPadded), "padding before atomic member"); + class C {}; using FP = int (*)(int); using PMF = int (C::*)(int); >From 1806d1b6abb09fe1e9caef8d9461466d7bb59ea4 Mon Sep 17 00:00:00 2001 From: flash1729 <[email protected]> Date: Wed, 14 Oct 2026 17:03:54 +0530 Subject: [PATCH 2/2] Add _Atomic _BitInt wrapper tests --- clang/test/SemaCXX/type-traits.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp index 246da619fe0469..9afa52348894e7 100644 --- a/clang/test/SemaCXX/type-traits.cpp +++ b/clang/test/SemaCXX/type-traits.cpp @@ -3506,6 +3506,14 @@ static_assert(__has_unique_object_representations(const volatile int *), "as are static_assert(__has_unique_object_representations(_Atomic(int)), "layout-identical atomics are"); static_assert(!__has_unique_object_representations(_Atomic(float)), "value type is not unique"); +// Sema rejects _Atomic directly on a _BitInt (Sema::BuildAtomicType), so go +// through a trivially copyable wrapper to reach the _BitInt padding-bit check. +struct AtomicReprBitIntPadded { _BitInt(12) x; }; +static_assert(!__has_unique_object_representations(_Atomic(AtomicReprBitIntPadded)), + "_BitInt(12) has padding bits"); +struct AtomicReprBitIntExact { _BitInt(32) x; }; +static_assert(__has_unique_object_representations(_Atomic(AtomicReprBitIntExact)), + "_BitInt(32) has no padding bits"); struct AtomicReprThreeChars { char a, b, c; }; static_assert(!__has_unique_object_representations(_Atomic(AtomicReprThreeChars)), "atomic size rounded up to a power of two adds padding"); _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
