[clang] bc5e47f - [clang][bytecode] Check pointer types in ::toRValue() (#206712)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 30 05:45:05 PDT 2026
Author: Timm Baeder
Date: 2026-06-30T14:45:01+02:00
New Revision: bc5e47fb75c383ed6b27aa082a0114934d6bfbbe
URL: https://github.com/llvm/llvm-project/commit/bc5e47fb75c383ed6b27aa082a0114934d6bfbbe
DIFF: https://github.com/llvm/llvm-project/commit/bc5e47fb75c383ed6b27aa082a0114934d6bfbbe.diff
LOG: [clang][bytecode] Check pointer types in ::toRValue() (#206712)
Now that we let more reinterpret_casts through, we need to check we have
the proper type here, too. We already did that for some of the types but
not for records and arrays.
Added:
Modified:
clang/lib/AST/ByteCode/Pointer.cpp
clang/test/AST/ByteCode/codegen.cpp
Removed:
################################################################################
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 37659eb79e1df..4eb6df2f0d6a1 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -915,8 +915,12 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Primitives should never end up here.
assert(!Ctx.canClassify(Ty));
+ const Descriptor *FieldDesc = Ptr.getFieldDesc();
+ assert(FieldDesc);
if (const auto *RT = Ty->getAsCanonical<RecordType>()) {
+ if (!FieldDesc->isRecord())
+ return false;
const auto *Record = Ptr.getRecord();
assert(Record && "Missing record descriptor");
@@ -986,6 +990,8 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
}
if (const auto *AT = Ty->getAsArrayTypeUnsafe()) {
+ if (!FieldDesc->isArray())
+ return false;
const size_t NumElems = Ptr.getNumElems();
QualType ElemTy = AT->getElementType();
R = APValue(APValue::UninitArray{}, NumElems, NumElems);
@@ -1005,14 +1011,12 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Complex types.
if (Ty->isAnyComplexType()) {
- const Descriptor *Desc = Ptr.getFieldDesc();
// Can happen via C casts.
- if (!Desc->getType()->isAnyComplexType())
+ if (!FieldDesc->getType()->isAnyComplexType())
return false;
- PrimType ElemT = Desc->getPrimType();
+ PrimType ElemT = FieldDesc->getPrimType();
if (isIntegerOrBoolType(ElemT)) {
- PrimType ElemT = Desc->getPrimType();
INT_TYPE_SWITCH(ElemT, {
auto V1 = Ptr.elem<T>(0);
auto V2 = Ptr.elem<T>(1);
@@ -1029,10 +1033,10 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Vector types.
if (const auto *VT = Ty->getAs<VectorType>()) {
- const Descriptor *Desc = Ptr.getFieldDesc();
- assert(Ptr.getFieldDesc()->isPrimitiveArray());
- PrimType ElemT = Desc->getPrimType();
+ if (!FieldDesc->isPrimitiveArray())
+ return false;
+ PrimType ElemT = FieldDesc->getPrimType();
SmallVector<APValue> Values;
Values.reserve(VT->getNumElements());
for (unsigned I = 0; I != VT->getNumElements(); ++I) {
@@ -1047,9 +1051,9 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
// Constant Matrix types.
if (const auto *MT = Ty->getAs<ConstantMatrixType>()) {
- assert(Ptr.getFieldDesc()->isPrimitiveArray());
- const Descriptor *Desc = Ptr.getFieldDesc();
- PrimType ElemT = Desc->getPrimType();
+ if (!FieldDesc->isPrimitiveArray())
+ return false;
+ PrimType ElemT = FieldDesc->getPrimType();
unsigned NumElems = MT->getNumElementsFlattened();
SmallVector<APValue> Values;
diff --git a/clang/test/AST/ByteCode/codegen.cpp b/clang/test/AST/ByteCode/codegen.cpp
index 53698f13a17a2..385b9a1338d91 100644
--- a/clang/test/AST/ByteCode/codegen.cpp
+++ b/clang/test/AST/ByteCode/codegen.cpp
@@ -151,3 +151,12 @@ X test24() {
/// Used to crash in codegen because the cast worked.
auto MemcpySemantics = *(_Complex double *)&(float[2]){};
+
+namespace InvalidReinterpretCast {
+ struct X {};
+ const X &_S_ti() {
+ constexpr char __tag{};
+ // CHECK: ret ptr %__tag
+ return reinterpret_cast<const X &>(__tag);
+ }
+}
More information about the cfe-commits
mailing list