MitalAshok updated this revision to Diff 432699.
MitalAshok added a comment.

Rebase release notes


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D125802/new/

https://reviews.llvm.org/D125802

Files:
  clang/docs/ReleaseNotes.rst
  clang/lib/AST/ASTContext.cpp
  clang/test/SemaCXX/has_unique_object_reps_bitint.cpp

Index: clang/test/SemaCXX/has_unique_object_reps_bitint.cpp
===================================================================
--- /dev/null
+++ clang/test/SemaCXX/has_unique_object_reps_bitint.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fsyntax-only -verify -std=c++17 -Wno-bitfield-width %s
+//  expected-no-diagnostics
+
+static_assert(__has_unique_object_representations(_BitInt(8)));
+static_assert(__has_unique_object_representations(unsigned _BitInt(8)));
+static_assert(__has_unique_object_representations(_BitInt(sizeof(int) * 8u)));
+// sizeof(_BitInt(24)) may be 4 to align it to the next greater integer type, in which case it would have 8 padding bits.
+static_assert(__has_unique_object_representations(_BitInt(24)) == (sizeof(_BitInt(24)) == 3));
+
+static_assert(!__has_unique_object_representations(_BitInt(7)));
+static_assert(!__has_unique_object_representations(unsigned _BitInt(7)));
+static_assert(!__has_unique_object_representations(_BitInt(2)));
+static_assert(!__has_unique_object_representations(unsigned _BitInt(1)));
+
+template <unsigned N>
+constexpr bool check() {
+  if constexpr (N <= __BITINT_MAXWIDTH__) {
+    static_assert(__has_unique_object_representations(_BitInt(N)) == (sizeof(_BitInt(N)) * 8u == N));
+    static_assert(__has_unique_object_representations(unsigned _BitInt(N)) == (sizeof(unsigned _BitInt(N)) * 8u == N));
+  }
+  return true;
+}
+
+template <unsigned... N>
+constexpr bool do_check = (check<N>() && ...);
+
+static_assert(do_check<2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18>);
+static_assert(do_check<15, 16, 17, 23, 24, 25, 31, 32, 33>);
+static_assert(do_check<39, 40, 41, 47, 48, 49>);
+static_assert(do_check<127, 128, 129, 255, 256, 257, 383, 384, 385>);
+
+template <unsigned N>
+struct in_struct {
+  _BitInt(N) x;
+  static constexpr bool check() {
+    return __has_unique_object_representations(in_struct<N>) == __has_unique_object_representations(_BitInt(N));
+  }
+};
+
+static_assert(in_struct<8>::check());
+static_assert(in_struct<7>::check());
+
+struct bit_fields_1 {
+  _BitInt(7) x : 7;
+  unsigned _BitInt(1) y : 1;
+};
+
+static_assert(__has_unique_object_representations(bit_fields_1) == (sizeof(bit_fields_1) == 1));
+
+struct bit_fields_2 {
+  _BitInt(8) x : 7;
+};
+
+static_assert(!__has_unique_object_representations(bit_fields_2));
+
+struct bit_fields_3 {
+  _BitInt(15) x : 8;
+};
+
+static_assert(__has_unique_object_representations(bit_fields_3) == (sizeof(bit_fields_3) == 1));
+
+#if __BITINT_MAXWIDTH__ >= 129
+struct bit_fields_4 {
+  _BitInt(129) x : 128;
+};
+
+static_assert(__has_unique_object_representations(bit_fields_4) == (sizeof(bit_fields_4) == 128 / 8));
+#endif
+
+struct bit_fields_5 {
+  _BitInt(2) x : 8;
+};
+
+static_assert(!__has_unique_object_representations(bit_fields_5));
+
+template <unsigned N>
+struct ref_member {
+  _BitInt(N) & x;
+};
+
+struct int_ref_member {
+  int &x;
+};
+
+static_assert(__has_unique_object_representations(ref_member<7>) == __has_unique_object_representations(ref_member<8>));
+static_assert(__has_unique_object_representations(ref_member<8>) == __has_unique_object_representations(int_ref_member));
Index: clang/lib/AST/ASTContext.cpp
===================================================================
--- clang/lib/AST/ASTContext.cpp
+++ clang/lib/AST/ASTContext.cpp
@@ -2684,7 +2684,11 @@
     if (!RD->isUnion())
       return structHasUniqueObjectRepresentations(Context, RD);
   }
-  if (!Field->getType()->isReferenceType() &&
+
+  // A _BitInt type may not be unique if it has padding bits
+  // but if it is a bitfield the padding bits are not used.
+  bool IsBitIntType = Field->getType()->isBitIntType();
+  if (!Field->getType()->isReferenceType() && !IsBitIntType &&
       !Context.hasUniqueObjectRepresentations(Field->getType()))
     return llvm::None;
 
@@ -2692,9 +2696,17 @@
       Context.toBits(Context.getTypeSizeInChars(Field->getType()));
   if (Field->isBitField()) {
     int64_t BitfieldSize = Field->getBitWidthValue(Context);
-    if (BitfieldSize > FieldSizeInBits)
+    if (IsBitIntType) {
+      if ((unsigned)BitfieldSize >
+          cast<BitIntType>(Field->getType())->getNumBits())
+        return llvm::None;
+    } else if (BitfieldSize > FieldSizeInBits) {
       return llvm::None;
+    }
     FieldSizeInBits = BitfieldSize;
+  } else if (IsBitIntType &&
+             !Context.hasUniqueObjectRepresentations(Field->getType())) {
+    return llvm::None;
   }
   return FieldSizeInBits;
 }
@@ -2792,8 +2804,13 @@
     return false;
 
   // All integrals and enums are unique.
-  if (Ty->isIntegralOrEnumerationType())
+  if (Ty->isIntegralOrEnumerationType()) {
+    // Except _BitInt types that have padding bits.
+    if (const auto *BIT = dyn_cast<BitIntType>(Ty))
+      return getTypeSize(BIT) == BIT->getNumBits();
+
     return true;
+  }
 
   // All other pointers are unique.
   if (Ty->isPointerType())
Index: clang/docs/ReleaseNotes.rst
===================================================================
--- clang/docs/ReleaseNotes.rst
+++ clang/docs/ReleaseNotes.rst
@@ -158,6 +158,8 @@
 - Implement `CWG 2394 <https://wg21.link/cwg2394>`_: Const class members
   may be initialized with a defaulted default constructor under the same
   conditions it would be allowed for a const object elsewhere.
+- ``__has_unique_object_representations`` no longer reports that ``_BitInt`` types
+  have unique object representations if they have padding bits.
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to