[C++ PATCH] PR c++/92590 - wrong handling of inherited default ctor.

Jason Merrill jason@redhat.com
Tue Jan 14 20:47:00 GMT 2020


I thought my earlier fix for 91930 was an obvious bug fix, but apparently an
inherited constructor does not count as user-declared.  So this patch
reverts that change and the other follow-on patches, and fixes 91930
differently, by not letting the inherited default constructor hide the
implicitly-declared default constructor.

Tested x86_64-pc-linux-gnu, applying to trunk.

	* class.c (add_method): A constrained inherited ctor doesn't hide an
	implicit derived ctor.

	Revert:
	PR c++/91930 - ICE with constrained inherited default ctor.
	* name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR
	for inherited constructor.
	PR c++/92552 - ICE with inherited constrained default ctor.
	* pt.c (instantiate_class_template_1): Copy
	TYPE_HAS_USER_CONSTRUCTOR.
	PR c++/92594 - ICE with inherited trivial default ctor.
	* method.c (trivial_fn_p): Treat an inherited default constructor
	like a normal default constructor.
---
 gcc/cp/class.c                                     |  5 +++--
 gcc/cp/method.c                                    |  7 +------
 gcc/cp/name-lookup.c                               |  1 -
 gcc/cp/pt.c                                        |  1 -
 gcc/testsuite/g++.dg/concepts/inherit-ctor3.C      |  4 ++--
 gcc/testsuite/g++.dg/cpp0x/inh-ctor35.C            | 14 ++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C             |  4 ++--
 gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C            |  4 ++--
 .../g++.dg/cpp2a/concepts-inherit-ctor2.C          |  4 ++--
 gcc/testsuite/g++.dg/template/crash7.C             |  4 +++-
 gcc/testsuite/g++.old-deja/g++.pt/error2.C         |  2 +-
 11 files changed, 30 insertions(+), 20 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/inh-ctor35.C

diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 07abe5298d1..719c3ece6e1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -1079,9 +1079,10 @@ add_method (tree type, tree method, bool via_using)
 	    {
 	      special_function_kind sfk = special_memfn_p (method);
 
-	      if (sfk == sfk_none)
+	      if (sfk == sfk_none || DECL_INHERITED_CTOR (fn))
 		/* Non-special member functions coexist if they are not
-		   equivalently constrained.  */
+		   equivalently constrained.  A member function is not hidden
+		   by an inherited constructor.  */
 		continue;
 
 	      /* P0848: For special member functions, deleted, unsatisfied, or
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index e20a88febdc..fef19e18196 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -458,12 +458,7 @@ trivial_fn_p (tree fn)
   /* If fn is a clone, get the primary variant.  */
   if (tree prim = DECL_CLONED_FUNCTION (fn))
     fn = prim;
-  special_function_kind sfk = special_function_p (fn);
-  /* An inherited default constructor is equivalent to a non-inherited default
-     constructor, so let it be trivial.  */
-  if (sfk == sfk_inheriting_constructor && default_ctor_p (fn))
-    sfk = sfk_constructor;
-  return type_has_trivial_fn (DECL_CONTEXT (fn), sfk);
+  return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn));
 }
 
 /* PARM is a PARM_DECL for a function which we want to forward to another
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 3c2c50d13a4..cd7a5816e46 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -4634,7 +4634,6 @@ lookup_using_decl (tree scope, name_lookup &lookup)
 	  maybe_warn_cpp0x (CPP0X_INHERITING_CTORS);
 	  lookup.name = ctor_identifier;
 	  CLASSTYPE_NON_AGGREGATE (current) = true;
-	  TYPE_HAS_USER_CONSTRUCTOR (current) = true;
     	}
 
       /* Cannot introduce a constructor name.  */
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index fa82ecad233..3793b33ce4d 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11573,7 +11573,6 @@ instantiate_class_template_1 (tree type)
   SET_TYPE_ALIGN (type, TYPE_ALIGN (pattern));
   TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern);
   CLASSTYPE_NON_AGGREGATE (type) = CLASSTYPE_NON_AGGREGATE (pattern);
-  TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern);
   if (ANON_AGGR_TYPE_P (pattern))
     SET_ANON_AGGR_TYPE_P (type);
   if (CLASSTYPE_VISIBILITY_SPECIFIED (pattern))
diff --git a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
index dda202f4c24..abfe96e8240 100644
--- a/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
+++ b/gcc/testsuite/g++.dg/concepts/inherit-ctor3.C
@@ -11,7 +11,7 @@ template<typename T>
   };
 
 template<typename T>
-  struct S2 : S1<T> {
+  struct S2 : S1<T> { // { dg-error "no matching function" }
     using S1<T>::S1; // { dg-error "no matching function" }
   };
 
@@ -19,5 +19,5 @@ struct X { } x;
 
 int main() {
   S2<X> s1(0); // { dg-error "use of deleted function" }
-  S2<X> s2; // { dg-error "no matching function" }
+  S2<X> s2; // { dg-error "use of deleted function" }
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor35.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor35.C
new file mode 100644
index 00000000000..0ec43938848
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor35.C
@@ -0,0 +1,14 @@
+// PR c++/92590
+// { dg-do compile { target c++11 } }
+
+class Base {
+  protected:
+    Base();
+};
+
+class Derived : public Base {
+  public:
+    using Base::Base;
+};
+
+Derived d;
diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
index 673b6380504..d0038c16a14 100644
--- a/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
+++ b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C
@@ -6,13 +6,13 @@ struct B1 {
 struct B2 {
   B2(double) { }
 };
-struct D1 : B1 {
+struct D1 : B1 {    // { dg-error "no match" }
   using B1::B1;	    // implicitly declares D1(int)
   int x;
 };
 void test() {
   D1 d(6);	    // OK: d.x is not initialized
-  D1 e;		    // { dg-error "no match" } D1 has no default constructor
+  D1 e;		    // { dg-error "deleted" } D1 has no default constructor
 }
 struct D2 : B2 {
   using B2::B2;	    // { dg-error "B1::B1" }
diff --git a/gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C b/gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C
index 98336a158c1..02ec58a3e8e 100644
--- a/gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C
+++ b/gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C
@@ -12,7 +12,7 @@ struct B2 {
 
 int get();
 
-struct D1 : B1 {
+struct D1 : B1 {		// { dg-message "B1::B1" }
   using B1::B1;  // inherits B1(int, ...)
   int x;
   int y = get();
@@ -22,7 +22,7 @@ void test() {
   D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
   // then d.x is default-initialized (no initialization is performed),
   // then d.y is initialized by calling get()
-  D1 e;          // { dg-error "" } D1 has no default constructor
+  D1 e;          // { dg-error "" } D1 has a deleted default constructor
 }
 
 struct D2 : B2 {
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C
index 82d14746df2..aa244bc04c1 100644
--- a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C
@@ -9,10 +9,10 @@ template<typename T>
   };
 
 template<typename T>
-  struct S2 : S1<T> {
+  struct S2 : S1<T> { // { dg-error "matching" }
     using S1<T>::S1;
   };
 
 int main() {
-  S2<int> s; // { dg-error "no matching function" }
+  S2<int> s; // { dg-error "deleted function" }
 }
diff --git a/gcc/testsuite/g++.dg/template/crash7.C b/gcc/testsuite/g++.dg/template/crash7.C
index 00d387c1197..691628e7878 100644
--- a/gcc/testsuite/g++.dg/template/crash7.C
+++ b/gcc/testsuite/g++.dg/template/crash7.C
@@ -10,4 +10,6 @@ template <typename> struct A
     template <typename> A(typename A::X) {} // { dg-error "incomplete" }
 };
 
-A<void> a;			// { dg-message "no match" }
+// We currently don't give the "no match" error because we don't add the
+// invalid constructor template to TYPE_METHODS.
+A<void> a;			// { dg-message "required" }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/error2.C b/gcc/testsuite/g++.old-deja/g++.pt/error2.C
index 666aea0a1ef..2e65718b679 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/error2.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/error2.C
@@ -9,7 +9,7 @@ public:
 
 void f ()
 {
-  Test<void> c; // { dg-error "no match" }
+  Test<void> c; // { dg-message "required" }
 }
 
 

base-commit: 8982b5535c2762f566fd15e5862acf4702a78690
-- 
2.18.1



More information about the Gcc-patches mailing list