[clang] 1d4d21e - [Clang][AST] Fix __has_unique_object_representations computation for unnamed bitfields.
Roy Jacobson via cfe-commits
cfe-commits at lists.llvm.org
Sat Apr 1 14:54:52 PDT 2023
Author: Roy Jacobson
Date: 2023-04-02T00:54:45+03:00
New Revision: 1d4d21e2e0950f6c451198e380371ee3142ce2fb
URL: https://github.com/llvm/llvm-project/commit/1d4d21e2e0950f6c451198e380371ee3142ce2fb
DIFF: https://github.com/llvm/llvm-project/commit/1d4d21e2e0950f6c451198e380371ee3142ce2fb.diff
LOG: [Clang][AST] Fix __has_unique_object_representations computation for unnamed bitfields.
As pointed out in https://github.com/llvm/llvm-project/issues/61336, objects with
unnamed bitfields aren't be uniquely representable.
Reviewed By: shafik, Endill
Differential Revision: https://reviews.llvm.org/D145852
Added:
Modified:
clang/docs/ReleaseNotes.rst
clang/lib/AST/ASTContext.cpp
clang/test/SemaCXX/type-traits.cpp
Removed:
################################################################################
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 4640ecccb9ad4..cd9aae998a503 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -291,6 +291,9 @@ Bug Fixes to C++ Support
template parameters with
diff erent nested constraints.
- Fix type equivalence comparison between auto types to take constraints into
account.
+- Fix bug in the computation of the ``__has_unique_object_representations``
+ builtin for types with unnamed bitfields.
+ (`#61336 <https://github.com/llvm/llvm-project/issues/61336>`_)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 612fcd4897c8f..bd4f2ff024949 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -2716,6 +2716,11 @@ getSubobjectSizeInBits(const FieldDecl *Field, const ASTContext &Context) {
int64_t FieldSizeInBits =
Context.toBits(Context.getTypeSizeInChars(Field->getType()));
if (Field->isBitField()) {
+ // If we have explicit padding bits, they don't contribute bits
+ // to the actual object representation, so return 0.
+ if (Field->isUnnamedBitfield())
+ return 0;
+
int64_t BitfieldSize = Field->getBitWidthValue(Context);
if (IsBitIntType) {
if ((unsigned)BitfieldSize >
diff --git a/clang/test/SemaCXX/type-traits.cpp b/clang/test/SemaCXX/type-traits.cpp
index 7d425acb56813..e3fc65713cedf 100644
--- a/clang/test/SemaCXX/type-traits.cpp
+++ b/clang/test/SemaCXX/type-traits.cpp
@@ -2828,6 +2828,17 @@ static_assert(!has_unique_object_representations<WeirdAlignment>::value, "Alignm
static_assert(!has_unique_object_representations<WeirdAlignmentUnion>::value, "Alignment causes padding");
static_assert(!has_unique_object_representations<WeirdAlignment[42]>::value, "Also no arrays that have padding");
+struct __attribute__((packed)) PackedNoPadding1 {
+ short i;
+ int j;
+};
+struct __attribute__((packed)) PackedNoPadding2 {
+ int j;
+ short i;
+};
+static_assert(has_unique_object_representations<PackedNoPadding1>::value, "Packed structs have no padding");
+static_assert(has_unique_object_representations<PackedNoPadding2>::value, "Packed structs have no padding");
+
static_assert(!has_unique_object_representations<int(int)>::value, "Functions are not unique");
static_assert(!has_unique_object_representations<int(int) const>::value, "Functions are not unique");
static_assert(!has_unique_object_representations<int(int) volatile>::value, "Functions are not unique");
@@ -2878,9 +2889,35 @@ struct AlignedPaddedBitfield {
char d : 2;
};
+struct UnnamedBitfield {
+ int named : 8;
+ int : 24;
+};
+
+struct __attribute__((packed)) UnnamedBitfieldPacked {
+ int named : 8;
+ int : 24;
+};
+
+struct UnnamedEmptyBitfield {
+ int named;
+ int : 0;
+};
+
+struct UnnamedEmptyBitfieldSplit {
+ short named;
+ int : 0;
+ short also_named;
+};
+
static_assert(!has_unique_object_representations<PaddedBitfield>::value, "Bitfield padding");
static_assert(has_unique_object_representations<UnPaddedBitfield>::value, "Bitfield padding");
static_assert(!has_unique_object_representations<AlignedPaddedBitfield>::value, "Bitfield padding");
+static_assert(!has_unique_object_representations<UnnamedBitfield>::value, "Bitfield padding");
+static_assert(!has_unique_object_representations<UnnamedBitfieldPacked>::value, "Bitfield padding");
+static_assert(has_unique_object_representations<UnnamedEmptyBitfield>::value, "Bitfield padding");
+static_assert(sizeof(UnnamedEmptyBitfieldSplit) != (sizeof(short) * 2), "Wrong size");
+static_assert(!has_unique_object_representations<UnnamedEmptyBitfieldSplit>::value, "Bitfield padding");
struct BoolBitfield {
bool b : 8;
More information about the cfe-commits
mailing list