[clang] [clang][bytecode] Diagnose invalid virtual base casts (PR #204518)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 17 23:38:57 PDT 2026
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/204518
None
>From 2dc4a1a64e81e6a6f09f7ff6a8215e1d7a9e8f6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 18 Jun 2026 08:38:18 +0200
Subject: [PATCH] [clang][bytecode] Diagnose invalid virtual base casts
---
clang/lib/AST/ByteCode/Interp.h | 2 ++
clang/lib/AST/ByteCode/Pointer.cpp | 1 +
clang/lib/AST/ByteCode/Record.cpp | 3 ++-
clang/test/AST/ByteCode/invalid.cpp | 9 +++++++++
4 files changed, 14 insertions(+), 1 deletion(-)
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}}
+}
More information about the cfe-commits
mailing list