Skip to content

Commit 192be3c

Browse files
authored
fix: constexpr bit_cast with empty base classes (llvm#82383)
Prior to this commit, clang would fail to produce a constant value for `b` in: ```c++ struct base { }; struct s : base { int z; }; constexpr auto b = std::bit_cast<s>(0x12); ``` e.g. https://godbolt.org/z/srrbTMPq4
1 parent d39ac3a commit 192be3c

File tree

3 files changed

+7
-4
lines changed

3 files changed

+7
-4
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,8 @@ Bug Fixes to C++ Support
392392
Fixes (#GH84368).
393393
- Fixed a crash while checking constraints of a trailing requires-expression of a lambda, that the
394394
expression references to an entity declared outside of the lambda. (#GH64808)
395+
- Clang's __builtin_bit_cast will now produce a constant value for records with empty bases. See:
396+
(#GH82383)
395397

396398
Bug Fixes to AST Handling
397399
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/ExprConstant.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7347,9 +7347,6 @@ class BufferToAPValueConverter {
73477347
for (size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
73487348
const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
73497349
CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
7350-
if (BaseDecl->isEmpty() ||
7351-
Info.Ctx.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero())
7352-
continue;
73537350

73547351
std::optional<APValue> SubObj = visitType(
73557352
BS.getType(), Layout.getBaseClassOffset(BaseDecl) + Offset);

clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,8 @@ void test_record() {
9090
struct tuple4 {
9191
unsigned x, y, z, doublez;
9292

93-
constexpr bool operator==(tuple4 const &other) const {
93+
bool operator==(tuple4 const &other) const = default;
94+
constexpr bool operator==(bases const &other) const {
9495
return x == other.x && y == other.y &&
9596
z == other.z && doublez == other.doublez;
9697
}
@@ -99,6 +100,9 @@ void test_record() {
99100
constexpr tuple4 t4 = bit_cast<tuple4>(b);
100101
static_assert(t4 == tuple4{1, 2, 3, 4});
101102
static_assert(round_trip<tuple4>(b));
103+
104+
constexpr auto b2 = bit_cast<bases>(t4);
105+
static_assert(t4 == b2);
102106
}
103107

104108
void test_partially_initialized() {

0 commit comments

Comments
 (0)