royjacobson created this revision. Herald added a project: All. royjacobson requested review of this revision. Herald added a project: clang. Herald added a subscriber: cfe-commits.
As pointed out in https://github.com/llvm/llvm-project/issues/61336, objects with unnamed bitfields aren't be uniquely representable. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D145852 Files: clang/docs/ReleaseNotes.rst clang/lib/AST/ASTContext.cpp clang/test/SemaCXX/type-traits.cpp Index: clang/test/SemaCXX/type-traits.cpp =================================================================== --- clang/test/SemaCXX/type-traits.cpp +++ clang/test/SemaCXX/type-traits.cpp @@ -2878,9 +2878,15 @@ char d : 2; }; +struct UnnamedBitfield { + int named : 8; + int : 24; +}; + 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"); struct BoolBitfield { bool b : 8; Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -2831,13 +2831,17 @@ return structHasUniqueObjectRepresentations(Context, RD); } -template <typename RangeT> +template <bool CheckUnnamedBitFields, typename RangeT> static std::optional<int64_t> structSubobjectsHaveUniqueObjectRepresentations( const RangeT &Subobjects, int64_t CurOffsetInBits, const ASTContext &Context, const clang::ASTRecordLayout &Layout) { for (const auto *Subobject : Subobjects) { std::optional<int64_t> SizeInBits = getSubobjectSizeInBits(Subobject, Context); + if constexpr (CheckUnnamedBitFields) { + if (Subobject->isUnnamedBitfield()) + return std::nullopt; + } if (!SizeInBits) return std::nullopt; if (*SizeInBits != 0) { @@ -2873,15 +2877,15 @@ }); std::optional<int64_t> OffsetAfterBases = - structSubobjectsHaveUniqueObjectRepresentations(Bases, CurOffsetInBits, - Context, Layout); + structSubobjectsHaveUniqueObjectRepresentations<false>( + Bases, CurOffsetInBits, Context, Layout); if (!OffsetAfterBases) return std::nullopt; CurOffsetInBits = *OffsetAfterBases; } std::optional<int64_t> OffsetAfterFields = - structSubobjectsHaveUniqueObjectRepresentations( + structSubobjectsHaveUniqueObjectRepresentations<true>( RD->fields(), CurOffsetInBits, Context, Layout); if (!OffsetAfterFields) return std::nullopt; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -202,6 +202,9 @@ - Fix crash when evaluating consteval constructor of derived class whose base has more than one field. (`#60166 <https://github.com/llvm/llvm-project/issues/60166>`_) +- 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 ^^^^^^^^^^^^^^^^^^^^^^^^^
Index: clang/test/SemaCXX/type-traits.cpp =================================================================== --- clang/test/SemaCXX/type-traits.cpp +++ clang/test/SemaCXX/type-traits.cpp @@ -2878,9 +2878,15 @@ char d : 2; }; +struct UnnamedBitfield { + int named : 8; + int : 24; +}; + 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"); struct BoolBitfield { bool b : 8; Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -2831,13 +2831,17 @@ return structHasUniqueObjectRepresentations(Context, RD); } -template <typename RangeT> +template <bool CheckUnnamedBitFields, typename RangeT> static std::optional<int64_t> structSubobjectsHaveUniqueObjectRepresentations( const RangeT &Subobjects, int64_t CurOffsetInBits, const ASTContext &Context, const clang::ASTRecordLayout &Layout) { for (const auto *Subobject : Subobjects) { std::optional<int64_t> SizeInBits = getSubobjectSizeInBits(Subobject, Context); + if constexpr (CheckUnnamedBitFields) { + if (Subobject->isUnnamedBitfield()) + return std::nullopt; + } if (!SizeInBits) return std::nullopt; if (*SizeInBits != 0) { @@ -2873,15 +2877,15 @@ }); std::optional<int64_t> OffsetAfterBases = - structSubobjectsHaveUniqueObjectRepresentations(Bases, CurOffsetInBits, - Context, Layout); + structSubobjectsHaveUniqueObjectRepresentations<false>( + Bases, CurOffsetInBits, Context, Layout); if (!OffsetAfterBases) return std::nullopt; CurOffsetInBits = *OffsetAfterBases; } std::optional<int64_t> OffsetAfterFields = - structSubobjectsHaveUniqueObjectRepresentations( + structSubobjectsHaveUniqueObjectRepresentations<true>( RD->fields(), CurOffsetInBits, Context, Layout); if (!OffsetAfterFields) return std::nullopt; Index: clang/docs/ReleaseNotes.rst =================================================================== --- clang/docs/ReleaseNotes.rst +++ clang/docs/ReleaseNotes.rst @@ -202,6 +202,9 @@ - Fix crash when evaluating consteval constructor of derived class whose base has more than one field. (`#60166 <https://github.com/llvm/llvm-project/issues/60166>`_) +- 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 ^^^^^^^^^^^^^^^^^^^^^^^^^
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits