Skip to content

Commit b54e02a

Browse files
authored
[clang][bytecode] Check pointer data type for bitcast eligibility (#146552)
So we get the proper type for a heap-allocated value.
1 parent 8dbfe83 commit b54e02a

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

clang/lib/AST/ByteCode/InterpBuiltinBitCast.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,8 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
335335

336336
BitcastBuffer Buffer(FullBitWidth);
337337
size_t BuffSize = FullBitWidth.roundToBytes();
338-
if (!CheckBitcastType(S, OpPC, Ptr.getType(), /*IsToType=*/false))
338+
QualType DataType = Ptr.getFieldDesc()->getDataType(S.getASTContext());
339+
if (!CheckBitcastType(S, OpPC, DataType, /*IsToType=*/false))
339340
return false;
340341

341342
bool Success = readPointerToBuffer(S.getContext(), Ptr, Buffer,
@@ -370,8 +371,8 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
370371
assert(FromPtr.isBlockPointer());
371372
assert(ToPtr.isBlockPointer());
372373

373-
QualType FromType = FromPtr.getType();
374-
QualType ToType = ToPtr.getType();
374+
QualType FromType = FromPtr.getFieldDesc()->getDataType(S.getASTContext());
375+
QualType ToType = ToPtr.getFieldDesc()->getDataType(S.getASTContext());
375376

376377
if (!CheckBitcastType(S, OpPC, ToType, /*IsToType=*/true))
377378
return false;

clang/test/AST/ByteCode/placement-new.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fexperimental-new-constant-interpreter -verify=expected,both %s -DBYTECODE
22
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify=ref,both %s
33

4+
typedef __INT64_TYPE__ int64_t;
45
namespace std {
56
using size_t = decltype(sizeof(0));
67
template<typename T> struct allocator {
@@ -465,3 +466,23 @@ namespace ArrayRoot {
465466

466467
static_assert(foo() == 0);
467468
}
469+
470+
namespace bitcast {
471+
template <typename F, typename T>
472+
constexpr T bit_cast(const F &f) {
473+
return __builtin_bit_cast(T, f);
474+
}
475+
constexpr int foo() {
476+
double *d = std::allocator<double>{}.allocate(2);
477+
std::construct_at<double>(d, 0);
478+
479+
double &dd = *d;
480+
481+
int64_t i = bit_cast<double, int64_t>(*d);
482+
483+
484+
std::allocator<double>{}.deallocate(d);
485+
return i;
486+
}
487+
static_assert(foo() == 0);
488+
}

0 commit comments

Comments
 (0)