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.

I think this is pretty simple since we get the proper constructor as out 
`InitExpr` anyway.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D135025

Files:
  clang/lib/AST/Interp/ByteCodeExprGen.cpp
  clang/lib/AST/Interp/ByteCodeStmtGen.cpp
  clang/test/AST/Interp/records.cpp


Index: clang/test/AST/Interp/records.cpp
===================================================================
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -157,3 +157,17 @@
 static_assert(LT2.v[0].second == false, "");
 static_assert(LT2.v[2].first == true, "");
 static_assert(LT2.v[2].second == false, "");
+
+class Base {
+public:
+  int i;
+  constexpr Base() : i(10) {}
+  constexpr Base(int i) : i(i) {}
+};
+
+class A : public Base {
+public:
+  constexpr A() : Base(100) {}
+};
+constexpr A a{};
+static_assert(a.i == 100, "");
Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -100,28 +100,39 @@
     const Record *R = this->getRecord(RD);
 
     for (const auto *Init : Ctor->inits()) {
-      const FieldDecl *Member = Init->getMember();
       const Expr *InitExpr = Init->getInit();
-      const Record::Field *F = R->getField(Member);
+      if (const FieldDecl *Member = Init->getMember()) {
+        const Record::Field *F = R->getField(Member);
 
-      if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
-        if (!this->emitThis(InitExpr))
-          return false;
+        if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
+          if (!this->emitThis(InitExpr))
+            return false;
 
-        if (!this->visit(InitExpr))
-          return false;
+          if (!this->visit(InitExpr))
+            return false;
 
-        if (!this->emitInitField(*T, F->Offset, InitExpr))
-          return false;
+          if (!this->emitInitField(*T, F->Offset, InitExpr))
+            return false;
+        } else {
+          // Non-primitive case. Get a pointer to the field-to-initialize
+          // on the stack and call visitInitialzer() for it.
+          if (!this->emitThis(InitExpr))
+            return false;
+
+          if (!this->emitGetPtrField(F->Offset, InitExpr))
+            return false;
+
+          if (!this->visitInitializer(InitExpr))
+            return false;
+
+          if (!this->emitPopPtr(InitExpr))
+            return false;
+        }
       } else {
-        // Non-primitive case. Get a pointer to the field-to-initialize
-        // on the stack and call visitInitialzer() for it.
+        // Base class constructor.
         if (!this->emitThis(InitExpr))
           return false;
 
-        if (!this->emitGetPtrField(F->Offset, InitExpr))
-          return false;
-
         if (!this->visitInitializer(InitExpr))
           return false;
 
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -115,6 +115,7 @@
   case CK_NoOp:
   case CK_UserDefinedConversion:
   case CK_NullToPointer:
+  case CK_UncheckedDerivedToBase:
     return this->Visit(SubExpr);
 
   case CK_IntegralToBoolean:


Index: clang/test/AST/Interp/records.cpp
===================================================================
--- clang/test/AST/Interp/records.cpp
+++ clang/test/AST/Interp/records.cpp
@@ -157,3 +157,17 @@
 static_assert(LT2.v[0].second == false, "");
 static_assert(LT2.v[2].first == true, "");
 static_assert(LT2.v[2].second == false, "");
+
+class Base {
+public:
+  int i;
+  constexpr Base() : i(10) {}
+  constexpr Base(int i) : i(i) {}
+};
+
+class A : public Base {
+public:
+  constexpr A() : Base(100) {}
+};
+constexpr A a{};
+static_assert(a.i == 100, "");
Index: clang/lib/AST/Interp/ByteCodeStmtGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeStmtGen.cpp
+++ clang/lib/AST/Interp/ByteCodeStmtGen.cpp
@@ -100,28 +100,39 @@
     const Record *R = this->getRecord(RD);
 
     for (const auto *Init : Ctor->inits()) {
-      const FieldDecl *Member = Init->getMember();
       const Expr *InitExpr = Init->getInit();
-      const Record::Field *F = R->getField(Member);
+      if (const FieldDecl *Member = Init->getMember()) {
+        const Record::Field *F = R->getField(Member);
 
-      if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
-        if (!this->emitThis(InitExpr))
-          return false;
+        if (Optional<PrimType> T = this->classify(InitExpr->getType())) {
+          if (!this->emitThis(InitExpr))
+            return false;
 
-        if (!this->visit(InitExpr))
-          return false;
+          if (!this->visit(InitExpr))
+            return false;
 
-        if (!this->emitInitField(*T, F->Offset, InitExpr))
-          return false;
+          if (!this->emitInitField(*T, F->Offset, InitExpr))
+            return false;
+        } else {
+          // Non-primitive case. Get a pointer to the field-to-initialize
+          // on the stack and call visitInitialzer() for it.
+          if (!this->emitThis(InitExpr))
+            return false;
+
+          if (!this->emitGetPtrField(F->Offset, InitExpr))
+            return false;
+
+          if (!this->visitInitializer(InitExpr))
+            return false;
+
+          if (!this->emitPopPtr(InitExpr))
+            return false;
+        }
       } else {
-        // Non-primitive case. Get a pointer to the field-to-initialize
-        // on the stack and call visitInitialzer() for it.
+        // Base class constructor.
         if (!this->emitThis(InitExpr))
           return false;
 
-        if (!this->emitGetPtrField(F->Offset, InitExpr))
-          return false;
-
         if (!this->visitInitializer(InitExpr))
           return false;
 
Index: clang/lib/AST/Interp/ByteCodeExprGen.cpp
===================================================================
--- clang/lib/AST/Interp/ByteCodeExprGen.cpp
+++ clang/lib/AST/Interp/ByteCodeExprGen.cpp
@@ -115,6 +115,7 @@
   case CK_NoOp:
   case CK_UserDefinedConversion:
   case CK_NullToPointer:
+  case CK_UncheckedDerivedToBase:
     return this->Visit(SubExpr);
 
   case CK_IntegralToBoolean:
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to