This revision was landed with ongoing or failed builds.
This revision was automatically updated to reflect the committed changes.
Closed by commit rG569222e172e5: [clang][Interp] Only check constructors for 
global variables (authored by tbaeder).

Changed prior to commit:
  https://reviews.llvm.org/D140723?vs=485480&id=501770#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D140723/new/

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
@@ -85,10 +85,11 @@
                                           // ref-note {{in call to}}
 
 
-struct Int { int a; }; // expected-note {{subobject declared here}}
+struct Int { int a; };
 constexpr int initializedLocal3() {
-  Int i; // expected-note {{subobject of type 'int' is not initialized}}
-  return i.a; // ref-note {{read of uninitialized object is not allowed in a constant expression}}
+  Int i;
+  return i.a; // ref-note {{read of uninitialized object is not allowed in a constant expression}} \
+              // expected-note {{read of object outside its lifetime}}
 }
 static_assert(initializedLocal3() == 20); // expected-error {{not an integral constant expression}} \
                                           // expected-note {{in call to}} \
@@ -157,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
@@ -328,6 +328,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
@@ -1455,6 +1455,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;
@@ -1480,11 +1485,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
@@ -431,6 +431,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
@@ -162,6 +162,9 @@
     if (!visitInitializer(Init))
       return false;
 
+    if (Init->getType()->isRecordType() && !this->emitCheckGlobalCtor(Init))
+      return false;
+
     return this->emitPopPtr(Init);
   }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to