PR c++/55922 - list-value-initialization of base
authorJason Merrill <jason@redhat.com>
Sun, 24 Jul 2016 02:56:22 +0000 (22:56 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sun, 24 Jul 2016 02:56:22 +0000 (22:56 -0400)
PR c++/63151
* init.c (expand_aggr_init_1): Handle list-initialization from {}.

From-SVN: r238688

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/g++.dg/cpp0x/initlist-base2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/cpp0x/initlist-base3.C [new file with mode: 0644]

index f4585a3..d60846b 100644 (file)
@@ -1,5 +1,9 @@
 2016-07-23  Jason Merrill  <jason@redhat.com>
 
+       PR c++/55922
+       PR c++/63151
+       * init.c (expand_aggr_init_1): Handle list-initialization from {}.
+
        PR c++/70709
        * class.c (walk_subobject_offsets): Handle 0-length array.
 
index 6047639..6362263 100644 (file)
@@ -1817,6 +1817,19 @@ expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
       return;
     }
 
+  /* List-initialization from {} becomes value-initialization for non-aggregate
+     classes with default constructors.  Handle this here so protected access
+     works.  */
+  if (init && TREE_CODE (init) == TREE_LIST)
+    {
+      tree elt = TREE_VALUE (init);
+      if (DIRECT_LIST_INIT_P (elt)
+         && CONSTRUCTOR_ELTS (elt) == 0
+         && CLASSTYPE_NON_AGGREGATE (type)
+         && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
+       init = void_type_node;
+    }
+
   /* If an explicit -- but empty -- initializer list was present,
      that's value-initialization.  */
   if (init == void_type_node)
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-base2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-base2.C
new file mode 100644 (file)
index 0000000..68ccad9
--- /dev/null
@@ -0,0 +1,21 @@
+// PR c++/55922
+// { dg-do run { target c++11 } }
+
+bool called = false;
+
+struct Base {
+  Base() { if (called) throw 1; called = true; }
+};
+
+struct B1 : virtual Base {
+  B1() { }
+};
+
+struct C : B1, virtual Base {
+  C() : B1{}
+  { }
+};
+
+int main() {
+  C c;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-base3.C b/gcc/testsuite/g++.dg/cpp0x/initlist-base3.C
new file mode 100644 (file)
index 0000000..9febac3
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/71774
+// { dg-do compile { target c++11 } }
+
+class Meow
+{
+  protected:
+    Meow() =default;        
+    virtual void f() {}
+};
+
+class Purr : public Meow
+{
+  public:
+    Purr()
+      : Meow{}
+    {}  
+};