Hi rsmith,

This patch ensures that when an object of a class type with a trivial default
constructor is default-initialized in a constant expression, any (empty) bases
are also initialized.

http://llvm-reviews.chandlerc.com/D2909

Files:
  lib/AST/ExprConstant.cpp
  test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp

Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -5117,16 +5117,9 @@
     if (!Result.isUninit())
       return true;
 
-    if (ZeroInit)
-      return ZeroInitialization(E);
-
-    const CXXRecordDecl *RD = FD->getParent();
-    if (RD->isUnion())
-      Result = APValue((FieldDecl*)0);
-    else
-      Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
-                       std::distance(RD->field_begin(), RD->field_end()));
-    return true;
+    // We zero-initialize even if E does not require zero-initialization
+    // because this a simple way to ensure that empty bases are initialized.
+    return ZeroInitialization(E);
   }
 
   const FunctionDecl *Definition = 0;
@@ -5606,19 +5599,10 @@
     if (HadZeroInit)
       return true;
 
-    if (ZeroInit) {
-      ImplicitValueInitExpr VIE(Type);
-      return EvaluateInPlace(*Value, Info, Subobject, &VIE);
-    }
-
-    const CXXRecordDecl *RD = FD->getParent();
-    if (RD->isUnion())
-      *Value = APValue((FieldDecl*)0);
-    else
-      *Value =
-          APValue(APValue::UninitStruct(), RD->getNumBases(),
-                  std::distance(RD->field_begin(), RD->field_end()));
-    return true;
+    // We zero-initialize even if E does not require zero-initialization
+    // because this a simple way to ensure that empty bases are initialized.
+    ImplicitValueInitExpr VIE(Type);
+    return EvaluateInPlace(*Value, Info, Subobject, &VIE);
   }
 
   const FunctionDecl *Definition = 0;
Index: test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
===================================================================
--- test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -334,3 +334,18 @@
 
   constexpr int k = V<int>().x; // FIXME: ok?
 }
+
+namespace PR19010 {
+  struct Empty {};
+
+  struct Empty2 : Empty {};
+
+  struct Test : Empty2 {
+    constexpr Test() {}
+    Empty2 array[2];
+  };
+
+  void test() {
+    constexpr Test t;
+  }
+}
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -5117,16 +5117,9 @@
     if (!Result.isUninit())
       return true;
 
-    if (ZeroInit)
-      return ZeroInitialization(E);
-
-    const CXXRecordDecl *RD = FD->getParent();
-    if (RD->isUnion())
-      Result = APValue((FieldDecl*)0);
-    else
-      Result = APValue(APValue::UninitStruct(), RD->getNumBases(),
-                       std::distance(RD->field_begin(), RD->field_end()));
-    return true;
+    // We zero-initialize even if E does not require zero-initialization
+    // because this a simple way to ensure that empty bases are initialized.
+    return ZeroInitialization(E);
   }
 
   const FunctionDecl *Definition = 0;
@@ -5606,19 +5599,10 @@
     if (HadZeroInit)
       return true;
 
-    if (ZeroInit) {
-      ImplicitValueInitExpr VIE(Type);
-      return EvaluateInPlace(*Value, Info, Subobject, &VIE);
-    }
-
-    const CXXRecordDecl *RD = FD->getParent();
-    if (RD->isUnion())
-      *Value = APValue((FieldDecl*)0);
-    else
-      *Value =
-          APValue(APValue::UninitStruct(), RD->getNumBases(),
-                  std::distance(RD->field_begin(), RD->field_end()));
-    return true;
+    // We zero-initialize even if E does not require zero-initialization
+    // because this a simple way to ensure that empty bases are initialized.
+    ImplicitValueInitExpr VIE(Type);
+    return EvaluateInPlace(*Value, Info, Subobject, &VIE);
   }
 
   const FunctionDecl *Definition = 0;
Index: test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
===================================================================
--- test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
+++ test/CXX/dcl.dcl/dcl.spec/dcl.constexpr/p4.cpp
@@ -334,3 +334,18 @@
 
   constexpr int k = V<int>().x; // FIXME: ok?
 }
+
+namespace PR19010 {
+  struct Empty {};
+
+  struct Empty2 : Empty {};
+
+  struct Test : Empty2 {
+    constexpr Test() {}
+    Empty2 array[2];
+  };
+
+  void test() {
+    constexpr Test t;
+  }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to