tbaeder created this revision.
tbaeder added reviewers: aaron.ballman, erichkeane, tahonermann, shafik.
Herald added a project: All.
tbaeder requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
This is a follow-up to https://reviews.llvm.org/D136694. I can also merge the
two patches.
I couldn't come up with a better way of doing this than adding a new opcode
which is //only// emitted from `visitGlobalInitializer()`.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D140723
Files:
clang/lib/AST/Interp/ByteCodeExprGen.h
clang/lib/AST/Interp/Interp.cpp
clang/lib/AST/Interp/Interp.h
clang/lib/AST/Interp/Opcodes.td
clang/test/AST/Interp/cxx20.cpp
Index: clang/test/AST/Interp/cxx20.cpp
===================================================================
--- clang/test/AST/Interp/cxx20.cpp
+++ clang/test/AST/Interp/cxx20.cpp
@@ -158,21 +158,19 @@
class Derived : public Base {
public:
- constexpr Derived() : Base() {} // expected-note {{subobject of type 'int' is not initialized}}
- };
+ constexpr Derived() : Base() {} };
-constexpr Derived D; // expected-error {{must be initialized by a constant expression}} \\
- // expected-note {{in call to 'Derived()'}} \
- // ref-error {{must be initialized by a constant expression}} \
- // ref-note {{subobject of type 'int' is not initialized}}
+ constexpr Derived D; // expected-error {{must be initialized by a constant expression}} \
+ // expected-note {{subobject of type 'int' is not initialized}} \
+ // ref-error {{must be initialized by a constant expression}} \
+ // ref-note {{subobject of type 'int' is not initialized}}
class C2 {
public:
A a;
- constexpr C2() {} // expected-note {{subobject of type 'int' is not initialized}}
- };
+ constexpr C2() {} };
constexpr C2 c2; // expected-error {{must be initialized by a constant expression}} \
- // expected-note {{in call to 'C2()'}} \
+ // expected-note {{subobject of type 'int' is not initialized}} \
// ref-error {{must be initialized by a constant expression}} \
// ref-note {{subobject of type 'int' is not initialized}}
Index: clang/lib/AST/Interp/Opcodes.td
===================================================================
--- clang/lib/AST/Interp/Opcodes.td
+++ clang/lib/AST/Interp/Opcodes.td
@@ -322,6 +322,8 @@
// [] -> [Pointer]
def SetLocal : AccessOpcode { let HasCustomEval = 1; }
+def CheckGlobalCtor : Opcode {}
+
// [] -> [Value]
def GetGlobal : AccessOpcode;
// [Value] -> []
Index: clang/lib/AST/Interp/Interp.h
===================================================================
--- clang/lib/AST/Interp/Interp.h
+++ clang/lib/AST/Interp/Interp.h
@@ -1365,6 +1365,11 @@
return true;
}
+inline bool CheckGlobalCtor(InterpState &S, CodePtr &PC) {
+ const Pointer &Obj = S.Stk.peek<Pointer>();
+ return CheckCtorCall(S, PC, Obj);
+}
+
inline bool Call(InterpState &S, CodePtr &PC, const Function *Func) {
auto NewFrame = std::make_unique<InterpFrame>(S, Func, PC);
Pointer ThisPtr;
@@ -1388,11 +1393,6 @@
if (Interpret(S, CallResult)) {
NewFrame.release(); // Frame was delete'd already.
assert(S.Current == FrameBefore);
-
- // For constructors, check that all fields have been initialized.
- if (Func->isConstructor() && !CheckCtorCall(S, PC, ThisPtr))
- return false;
-
return true;
}
Index: clang/lib/AST/Interp/Interp.cpp
===================================================================
--- clang/lib/AST/Interp/Interp.cpp
+++ clang/lib/AST/Interp/Interp.cpp
@@ -512,6 +512,15 @@
Result = false;
}
}
+
+ // Check Fields in all bases
+ for (const Record::Base &B : R->bases()) {
+ Pointer P = Pointer(BasePtr.block(), B.Offset);
+ Result &= CheckFieldsInitialized(S, OpPC, P, B.R);
+ }
+
+ // TODO: Virtual bases
+
return Result;
}
Index: clang/lib/AST/Interp/ByteCodeExprGen.h
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.h
+++ clang/lib/AST/Interp/ByteCodeExprGen.h
@@ -177,6 +177,9 @@
if (!visitInitializer(Init))
return false;
+ if (Init->getType()->isRecordType() && !this->emitCheckGlobalCtor(Init))
+ return false;
+
return this->emitPopPtr(Init);
}
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits