[clang] fix: constexpr bit_cast with empty base classes (PR #82383)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Feb 20 08:58:00 PST 2024
https://github.com/sethp created https://github.com/llvm/llvm-project/pull/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
>From ed6a576ba0c9492f8aa4c995ea7316263a979fae Mon Sep 17 00:00:00 2001
From: sethp <seth.pellegrino at gmail.com>
Date: Tue, 20 Feb 2024 08:57:13 -0800
Subject: [PATCH] fix: constexpr bit_cast with empty base classes
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
---
clang/lib/AST/ExprConstant.cpp | 3 ---
clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp | 6 +++++-
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index fcf8f6591a7923..e1863cbf6c317c 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -7312,9 +7312,6 @@ class BufferToAPValueConverter {
for (size_t I = 0, E = CXXRD->getNumBases(); I != E; ++I) {
const CXXBaseSpecifier &BS = CXXRD->bases_begin()[I];
CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
- if (BaseDecl->isEmpty() ||
- Info.Ctx.getASTRecordLayout(BaseDecl).getNonVirtualSize().isZero())
- continue;
std::optional<APValue> SubObj = visitType(
BS.getType(), Layout.getBaseClassOffset(BaseDecl) + Offset);
diff --git a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
index c5b8032f40b131..7520b43a194aba 100644
--- a/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
+++ b/clang/test/SemaCXX/constexpr-builtin-bit-cast.cpp
@@ -90,7 +90,8 @@ void test_record() {
struct tuple4 {
unsigned x, y, z, doublez;
- constexpr bool operator==(tuple4 const &other) const {
+ bool operator==(tuple4 const &other) const = default;
+ constexpr bool operator==(bases const &other) const {
return x == other.x && y == other.y &&
z == other.z && doublez == other.doublez;
}
@@ -99,6 +100,9 @@ void test_record() {
constexpr tuple4 t4 = bit_cast<tuple4>(b);
static_assert(t4 == tuple4{1, 2, 3, 4});
static_assert(round_trip<tuple4>(b));
+
+ constexpr auto b2 = bit_cast<bases>(t4);
+ static_assert(t4 == b2);
}
void test_partially_initialized() {
More information about the cfe-commits
mailing list