[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