On Sat, Jul 23, 2016 at 10:55 PM, Jason Merrill <ja...@redhat.com> wrote:
> Using build_value_init in a base initialization is wrong, because it
> calls the complete object constructor and misses protected access.  So
> let's handle list-value-initialization in expand_aggr_init_1.
>
> Tested x86_64-pc-linux-gnu, applying to trunk.
commit db083599cde3a758e04c151b7fd86346ae598a4b
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Jul 22 00:48:45 2016 -0400

        PR c++/55922 - list-value-initialization of base
    
        PR c++/63151
        * init.c (expand_aggr_init_1): Handle list-initialization from {}.

diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 6047639..6362263 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
index 0000000..68ccad9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-base2.C
@@ -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
index 0000000..9febac3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/initlist-base3.C
@@ -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{}
+    {}  
+};

Reply via email to