[clang][bytecode] Check pointer data type for bitcast eligibility (#146552)
So we get the proper type for a heap-allocated value.
This commit is contained in:
@@ -335,7 +335,8 @@ bool clang::interp::DoBitCast(InterpState &S, CodePtr OpPC, const Pointer &Ptr,
|
|||||||
|
|
||||||
BitcastBuffer Buffer(FullBitWidth);
|
BitcastBuffer Buffer(FullBitWidth);
|
||||||
size_t BuffSize = FullBitWidth.roundToBytes();
|
size_t BuffSize = FullBitWidth.roundToBytes();
|
||||||
if (!CheckBitcastType(S, OpPC, Ptr.getType(), /*IsToType=*/false))
|
QualType DataType = Ptr.getFieldDesc()->getDataType(S.getASTContext());
|
||||||
|
if (!CheckBitcastType(S, OpPC, DataType, /*IsToType=*/false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool Success = readPointerToBuffer(S.getContext(), Ptr, Buffer,
|
bool Success = readPointerToBuffer(S.getContext(), Ptr, Buffer,
|
||||||
@@ -370,8 +371,8 @@ bool clang::interp::DoBitCastPtr(InterpState &S, CodePtr OpPC,
|
|||||||
assert(FromPtr.isBlockPointer());
|
assert(FromPtr.isBlockPointer());
|
||||||
assert(ToPtr.isBlockPointer());
|
assert(ToPtr.isBlockPointer());
|
||||||
|
|
||||||
QualType FromType = FromPtr.getType();
|
QualType FromType = FromPtr.getFieldDesc()->getDataType(S.getASTContext());
|
||||||
QualType ToType = ToPtr.getType();
|
QualType ToType = ToPtr.getFieldDesc()->getDataType(S.getASTContext());
|
||||||
|
|
||||||
if (!CheckBitcastType(S, OpPC, ToType, /*IsToType=*/true))
|
if (!CheckBitcastType(S, OpPC, ToType, /*IsToType=*/true))
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fexperimental-new-constant-interpreter -verify=expected,both %s -DBYTECODE
|
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -fexperimental-new-constant-interpreter -verify=expected,both %s -DBYTECODE
|
||||||
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify=ref,both %s
|
// RUN: %clang_cc1 -std=c++2c -fcxx-exceptions -verify=ref,both %s
|
||||||
|
|
||||||
|
typedef __INT64_TYPE__ int64_t;
|
||||||
namespace std {
|
namespace std {
|
||||||
using size_t = decltype(sizeof(0));
|
using size_t = decltype(sizeof(0));
|
||||||
template<typename T> struct allocator {
|
template<typename T> struct allocator {
|
||||||
@@ -465,3 +466,23 @@ namespace ArrayRoot {
|
|||||||
|
|
||||||
static_assert(foo() == 0);
|
static_assert(foo() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace bitcast {
|
||||||
|
template <typename F, typename T>
|
||||||
|
constexpr T bit_cast(const F &f) {
|
||||||
|
return __builtin_bit_cast(T, f);
|
||||||
|
}
|
||||||
|
constexpr int foo() {
|
||||||
|
double *d = std::allocator<double>{}.allocate(2);
|
||||||
|
std::construct_at<double>(d, 0);
|
||||||
|
|
||||||
|
double &dd = *d;
|
||||||
|
|
||||||
|
int64_t i = bit_cast<double, int64_t>(*d);
|
||||||
|
|
||||||
|
|
||||||
|
std::allocator<double>{}.deallocate(d);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
static_assert(foo() == 0);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user