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); + } +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
