[clang] [clang][bytecode] Refuse to contruct objects with virtual bases (PR #110142)
Timm Baeder via cfe-commits
cfe-commits at lists.llvm.org
Thu Sep 26 09:20:08 PDT 2024
https://github.com/tbaederr created https://github.com/llvm/llvm-project/pull/110142
None
>From cfbd9ae7f7d8c671ae7248cf24138d058d9143e6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbaeder at redhat.com>
Date: Thu, 26 Sep 2024 18:19:09 +0200
Subject: [PATCH] [clang][bytecode] Refuse to contruct objects with virtual
bases
---
clang/lib/AST/ByteCode/Interp.cpp | 22 ++++++++++++++++++++++
clang/test/AST/ByteCode/cxx23.cpp | 15 +++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 2f4a05a85753c0..c43f64901909ce 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1043,6 +1043,25 @@ bool CheckLiteralType(InterpState &S, CodePtr OpPC, const Type *T) {
return false;
}
+static bool checkConstructor(InterpState &S, CodePtr OpPC, const Function *Func,
+ const Pointer &ThisPtr) {
+ assert(Func->isConstructor());
+
+ const Descriptor *D = ThisPtr.getFieldDesc();
+
+ // FIXME: I think this case is not 100% correct. E.g. a pointer into a
+ // subobject of a composite array.
+ if (!D->ElemRecord)
+ return true;
+
+ if (D->ElemRecord->getNumVirtualBases() == 0)
+ return true;
+
+ S.FFDiag(S.Current->getLocation(OpPC), diag::note_constexpr_virtual_base)
+ << Func->getParentDecl();
+ return false;
+}
+
bool CallVar(InterpState &S, CodePtr OpPC, const Function *Func,
uint32_t VarArgSize) {
if (Func->hasThisPointer()) {
@@ -1117,6 +1136,9 @@ bool Call(InterpState &S, CodePtr OpPC, const Function *Func,
if (!CheckInvoke(S, OpPC, ThisPtr))
return cleanup();
}
+
+ if (Func->isConstructor() && !checkConstructor(S, OpPC, Func, ThisPtr))
+ return false;
}
if (!CheckCallable(S, OpPC, Func))
diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp
index 9d7e9d753e6d2f..b51f761ce0caf6 100644
--- a/clang/test/AST/ByteCode/cxx23.cpp
+++ b/clang/test/AST/ByteCode/cxx23.cpp
@@ -158,6 +158,21 @@ namespace VirtualBases {
/// Calls the constructor of D.
D d;
}
+
+#if __cplusplus >= 202302L
+ struct VBase {};
+ struct HasVBase : virtual VBase {}; // all23-note 1{{virtual base class declared here}}
+ struct Derived : HasVBase {
+ constexpr Derived() {} // all23-error {{constexpr constructor not allowed in struct with virtual base class}}
+ };
+ template<typename T> struct DerivedFromVBase : T {
+ constexpr DerivedFromVBase();
+ };
+ constexpr int f(DerivedFromVBase<HasVBase>) {}
+ template<typename T> constexpr DerivedFromVBase<T>::DerivedFromVBase() : T() {}
+ constexpr int nVBase = (DerivedFromVBase<HasVBase>(), 0); // all23-error {{constant expression}} \
+ // all23-note {{cannot construct object of type 'DerivedFromVBase<VirtualBases::HasVBase>' with virtual base class in a constant expression}}
+#endif
}
namespace LabelGoto {
More information about the cfe-commits
mailing list