diff mbox

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

Message ID 20170207213036.GX1849@tucnak
State New
Headers show

Commit Message

Jakub Jelinek Feb. 7, 2017, 9:30 p.m. UTC
Hi!

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.

Not 100% sure if we want to do this even for -std=c++1z
-fno-new-inheriting-ctors (i.e. if the below block shouldn't be guarded with
&& flag_new_inheriting_ctors too), because e.g. for
-fno-new-inheriting-ctors we actually don't set TYPE_HAS_USER_CONSTRUCTOR.

Bootstrapped/regtested on x86_64-linux and i686-linux and additionally
tested with make check-c++-all on both.

2017-02-07  Jakub Jelinek  <jakub@redhat.com>

	PR c++/79143
	* class.c (add_implicitly_declared_members): Set
	CLASSTYPE_NON_AGGREGATE and CLASSTYPE_NON_LAYOUT_POD_P on types
	with inherited constructors for C++17.

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


	Jakub

Comments

Jason Merrill Feb. 8, 2017, 9:51 p.m. UTC | #1
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?

Jason
diff mbox

Patch

--- gcc/cp/class.c.jj	2017-02-04 08:43:15.000000000 +0100
+++ gcc/cp/class.c	2017-02-07 18:00:24.479093367 +0100
@@ -3453,8 +3453,19 @@  add_implicitly_declared_members (tree t,
 	  location_t loc = input_location;
 	  input_location = DECL_SOURCE_LOCATION (using_decl);
 	  if (ctor_list)
-	    for (; ctor_list; ctor_list = OVL_NEXT (ctor_list))
-	      one_inherited_ctor (OVL_CURRENT (ctor_list), t, using_decl);
+	    {
+	      if (cxx_dialect >= cxx1z)
+		{
+		  /* [dcl.init.aggr]/1: An aggregate is an array or a class
+		     with
+		     - no user-provided, explicit or inherited
+		       constructors.  */
+		  CLASSTYPE_NON_AGGREGATE (t) = 1;
+		  CLASSTYPE_NON_LAYOUT_POD_P (t) = 1;
+		}
+	      for (; ctor_list; ctor_list = OVL_NEXT (ctor_list))
+		one_inherited_ctor (OVL_CURRENT (ctor_list), t, using_decl);
+	    }
 	  *access_decls = TREE_CHAIN (*access_decls);
 	  input_location = loc;
 	}
--- 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};
+}