From 1d4d21e2e0950f6c451198e380371ee3142ce2fb Mon Sep 17 00:00:00 2001 From: Roy Jacobson Date: Sat, 11 Mar 2023 18:39:33 +0200 Subject: [PATCH] [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 --- clang/docs/ReleaseNotes.rst | 3 +++ clang/lib/AST/ASTContext.cpp | 5 +++++ clang/test/SemaCXX/type-traits.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 4640ecc..cd9aae9 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -291,6 +291,9 @@ Bug Fixes to C++ Support template parameters with different 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 `_) Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 612fcd4..bd4f2ff 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 7d425ac..e3fc657 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::value, "Alignm static_assert(!has_unique_object_representations::value, "Alignment causes padding"); static_assert(!has_unique_object_representations::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::value, "Packed structs have no padding"); +static_assert(has_unique_object_representations::value, "Packed structs have no padding"); + static_assert(!has_unique_object_representations::value, "Functions are not unique"); static_assert(!has_unique_object_representations::value, "Functions are not unique"); static_assert(!has_unique_object_representations::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::value, "Bitfield padding"); static_assert(has_unique_object_representations::value, "Bitfield padding"); static_assert(!has_unique_object_representations::value, "Bitfield padding"); +static_assert(!has_unique_object_representations::value, "Bitfield padding"); +static_assert(!has_unique_object_representations::value, "Bitfield padding"); +static_assert(has_unique_object_representations::value, "Bitfield padding"); +static_assert(sizeof(UnnamedEmptyBitfieldSplit) != (sizeof(short) * 2), "Wrong size"); +static_assert(!has_unique_object_representations::value, "Bitfield padding"); struct BoolBitfield { bool b : 8; -- 2.7.4