aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-14 13:59:54 -0500
committerJason Merrill <jason@redhat.com>2020-01-14 15:20:12 -0500
commit08c8c973c082457a7d6192673e87475f1fdfdbef (patch)
treeb04556341be3025f2077cdc3fe0e0c9fa9122bcf
parenta5a3c2dcf73aa245b0eb6f6cf56c4d03ab6056da (diff)
downloadgcc-08c8c973c082457a7d6192673e87475f1fdfdbef.zip
gcc-08c8c973c082457a7d6192673e87475f1fdfdbef.tar.gz
gcc-08c8c973c082457a7d6192673e87475f1fdfdbef.tar.bz2
PR c++/92590 - wrong handling of inherited default ctor.
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. * 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.
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/class.c5
-rw-r--r--gcc/cp/method.c7
-rw-r--r--gcc/cp/name-lookup.c1
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/testsuite/g++.dg/concepts/inherit-ctor3.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor35.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C4
-rw-r--r--gcc/testsuite/g++.dg/template/crash7.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/error2.C2
12 files changed, 44 insertions, 20 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 3cc7c48..c137539 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -14,6 +14,20 @@
2020-01-14 Jason Merrill <jason@redhat.com>
+ PR c++/92590 - wrong handling of inherited default ctor.
+ * class.c (add_method): A constrained inherited ctor doesn't hide an
+ implicit derived ctor.
+ Revert:
+ PR c++/92552 - ICE with inherited constrained default ctor.
+ * pt.c (instantiate_class_template_1): Copy
+ TYPE_HAS_USER_CONSTRUCTOR.
+ 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++/92594 - ICE with inherited trivial default ctor.
+ * method.c (trivial_fn_p): Treat an inherited default constructor
+ like a normal default 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.
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index 07abe52..719c3ec 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 e20a88f..fef19e1 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 3c2c50d..cd7a581 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 4fdc74f..7e675ce 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11578,7 +11578,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 dda202f..abfe96e 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 0000000..0ec4393
--- /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 673b638..d0038c1 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 98336a1..02ec58a 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 82d1474..aa244bc 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 00d387c..691628e 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 666aea0..2e65718 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" }
}