diff mbox

[C++] For -std=c++1z treat class types with inherited ctors as non-aggregate (PR c++/79143)

Message ID 20170208222437.GF1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 8, 2017, 10:24 p.m. UTC
On Wed, Feb 08, 2017 at 04:51:54PM -0500, Jason Merrill wrote:
> On Tue, Feb 7, 2017 at 4:30 PM, Jakub Jelinek <jakub@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  <jakub@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.



	Jakub

Comments

Jason Merrill Feb. 8, 2017, 11:47 p.m. UTC | #1
On Wed, Feb 8, 2017 at 5:24 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Wed, Feb 08, 2017 at 04:51:54PM -0500, Jason Merrill wrote:
>> On Tue, Feb 7, 2017 at 4:30 PM, Jakub Jelinek <jakub@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?

Better I think in instantiate_class_template_1, about where we copy TYPE_PACKED.

Jason
diff mbox

Patch

--- 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};
+}