Author: Timm Baeder
Date: 2026-06-18T09:56:30+02:00
New Revision: e727e5b51fbecdd0cac1619686b16758cdf8a426

URL: 
https://github.com/llvm/llvm-project/commit/e727e5b51fbecdd0cac1619686b16758cdf8a426
DIFF: 
https://github.com/llvm/llvm-project/commit/e727e5b51fbecdd0cac1619686b16758cdf8a426.diff

LOG: [clang][bytecode] Diagnose invalid virtual base casts (#204518)

Added: 
    

Modified: 
    clang/lib/AST/ByteCode/Interp.h
    clang/lib/AST/ByteCode/Pointer.cpp
    clang/lib/AST/ByteCode/Record.cpp
    clang/test/AST/ByteCode/invalid.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 0f9e585e19769..f80617361f768 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -2169,6 +2169,8 @@ inline bool VirtBaseHelper(InterpState &S, CodePtr OpPC, 
const RecordDecl *Decl,
     return false;
   Pointer Base = Ptr.stripBaseCasts();
   const Record::Base *VirtBase = Base.getRecord()->getVirtualBase(Decl);
+  if (!VirtBase)
+    return false;
   S.Stk.push<Pointer>(Base.atField(VirtBase->Offset));
   return true;
 }

diff  --git a/clang/lib/AST/ByteCode/Pointer.cpp 
b/clang/lib/AST/ByteCode/Pointer.cpp
index 96cd8bb9e11c2..de2b3421f404b 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -872,6 +872,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
 
         for (unsigned I = 0; I != NV; ++I) {
           const Record::Base *VD = Record->getVirtualBase(I);
+          assert(VD);
           QualType VirtBaseTy =
               Ctx.getASTContext().getCanonicalTagType(VD->Decl);
           PtrView VP = Ptr.atField(VD->Offset);

diff  --git a/clang/lib/AST/ByteCode/Record.cpp 
b/clang/lib/AST/ByteCode/Record.cpp
index 13a5ffb85787c..cc8b64d522484 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -63,6 +63,7 @@ const Record::Base *Record::getBase(QualType T) const {
 
 const Record::Base *Record::getVirtualBase(const RecordDecl *FD) const {
   auto It = VirtualBaseMap.find(FD);
-  assert(It != VirtualBaseMap.end() && "Missing virtual base");
+  if (It == VirtualBaseMap.end())
+    return nullptr;
   return It->second;
 }

diff  --git a/clang/test/AST/ByteCode/invalid.cpp 
b/clang/test/AST/ByteCode/invalid.cpp
index fb209d353c4a1..e79b698a32719 100644
--- a/clang/test/AST/ByteCode/invalid.cpp
+++ b/clang/test/AST/ByteCode/invalid.cpp
@@ -209,3 +209,12 @@ namespace IncNonDereferencable {
       ;
   }
 }
+
+namespace InvalidVirtualCast {
+  struct X {};
+  struct Y : virtual X {};
+  struct Z {
+  } z;
+  static_assert((X *)(Y *)&z, ""); // both-error {{not an integral constant 
expression}} \
+                                   // both-note {{cast that performs the 
conversions of a reinterpret_cast is not allowed in a constant expression}}
+}


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to