[PATCH] D135025: [clang][Interp] Support base class constructors

Timm Bäder via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Sun Oct 2 00:18:38 PDT 2022


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:


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D135025.464539.patch
Type: text/x-patch
Size: 3036 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20221002/164cdef4/attachment.bin>


More information about the cfe-commits mailing list