On Wed, Feb 08, 2017 at 04:51:54PM -0500, Jason Merrill wrote:
> On Tue, Feb 7, 2017 at 4:30 PM, Jakub Jelinek <ja...@redhat.com> wrote:
> > P0017R1 added in [dcl.init.aggr]/1 that classes with inherited constructors
> > are not aggregate.  CLASSTYPE_NON_AGGREGATE is set slightly before
> > add_implicitly_declared_members is called and so we don't know about the
> > inherited ctors yet.
> 
> Hmm, why doesn't my patch for 78124 to set CLASSTYPE_NON_AGGREGATE in
> do_class_using_decl cover this testcase?

It does set CLASSTYPE_NON_AGGREGATE on a different RECORD_TYPE,
do_class_using_decl sees the template, while what is tested and what
check_bases_and_members is called on is the implicit instantiation thereof.

The following completely untested patch also fixes it.  Or is there some
even better place where to copy over that bit from the template to the
instantiation?

2017-02-08  Jakub Jelinek  <ja...@redhat.com>

        PR c++/79143
        * pt.c (lookup_template_class_1): Copy CLASSTYPE_NON_AGGREGATE
        from template_type to t.

        * g++.dg/cpp1z/pr79143.C: New test.

--- gcc/cp/pt.c.jj      2017-02-06 21:02:40.000000000 +0100
+++ gcc/cp/pt.c 2017-02-08 23:18:20.461836658 +0100
@@ -8770,6 +8770,8 @@ lookup_template_class_1 (tree d1, tree a
          t = make_class_type (TREE_CODE (template_type));
          CLASSTYPE_DECLARED_CLASS (t)
            = CLASSTYPE_DECLARED_CLASS (template_type);
+         CLASSTYPE_NON_AGGREGATE (t)
+           = CLASSTYPE_NON_AGGREGATE (template_type);
          SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t);
 
          /* A local class.  Make sure the decl gets registered properly.  */
--- gcc/testsuite/g++.dg/cpp1z/pr79143.C.jj     2017-02-07 17:55:19.091028200 
+0100
+++ gcc/testsuite/g++.dg/cpp1z/pr79143.C        2017-02-07 17:54:48.000000000 
+0100
@@ -0,0 +1,28 @@
+// PR c++/79143
+// { dg-do compile }
+// { dg-options "-std=c++1z" }
+
+struct base {
+  base (int, int) {}
+};
+
+template<class>
+struct derived : base {
+  using base::base;
+};
+
+template<class>
+struct derived2 : base {
+  derived2 (int x, int y) : base (x, y) {}
+};
+
+int
+main ()
+{
+  base (13, 42);
+  derived<int> (13, 42);
+  derived2<int> (13, 42);
+  base{13, 42};
+  derived<int>{13, 42}; // { dg-bogus "too many initializers" }
+  derived2<int>{13, 42};
+}


        Jakub

Reply via email to