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

Reply via email to