GCC with patches for OS216
Revision | 08c8c973c082457a7d6192673e87475f1fdfdbef (tree) |
---|---|
Zeit | 2020-01-15 05:20:12 |
Autor | Jason Merrill <jason@redh...> |
Commiter | Jason Merrill |
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.
@@ -14,6 +14,20 @@ | ||
14 | 14 | |
15 | 15 | 2020-01-14 Jason Merrill <jason@redhat.com> |
16 | 16 | |
17 | + PR c++/92590 - wrong handling of inherited default ctor. | |
18 | + * class.c (add_method): A constrained inherited ctor doesn't hide an | |
19 | + implicit derived ctor. | |
20 | + Revert: | |
21 | + PR c++/92552 - ICE with inherited constrained default ctor. | |
22 | + * pt.c (instantiate_class_template_1): Copy | |
23 | + TYPE_HAS_USER_CONSTRUCTOR. | |
24 | + PR c++/91930 - ICE with constrained inherited default ctor. | |
25 | + * name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR | |
26 | + for inherited constructor. | |
27 | + PR c++/92594 - ICE with inherited trivial default ctor. | |
28 | + * method.c (trivial_fn_p): Treat an inherited default constructor | |
29 | + like a normal default constructor. | |
30 | + | |
17 | 31 | PR c++/92594 - ICE with inherited trivial default ctor. |
18 | 32 | * method.c (trivial_fn_p): Treat an inherited default constructor |
19 | 33 | like a normal default constructor. |
@@ -1079,9 +1079,10 @@ add_method (tree type, tree method, bool via_using) | ||
1079 | 1079 | { |
1080 | 1080 | special_function_kind sfk = special_memfn_p (method); |
1081 | 1081 | |
1082 | - if (sfk == sfk_none) | |
1082 | + if (sfk == sfk_none || DECL_INHERITED_CTOR (fn)) | |
1083 | 1083 | /* Non-special member functions coexist if they are not |
1084 | - equivalently constrained. */ | |
1084 | + equivalently constrained. A member function is not hidden | |
1085 | + by an inherited constructor. */ | |
1085 | 1086 | continue; |
1086 | 1087 | |
1087 | 1088 | /* P0848: For special member functions, deleted, unsatisfied, or |
@@ -458,12 +458,7 @@ trivial_fn_p (tree fn) | ||
458 | 458 | /* If fn is a clone, get the primary variant. */ |
459 | 459 | if (tree prim = DECL_CLONED_FUNCTION (fn)) |
460 | 460 | fn = prim; |
461 | - special_function_kind sfk = special_function_p (fn); | |
462 | - /* An inherited default constructor is equivalent to a non-inherited default | |
463 | - constructor, so let it be trivial. */ | |
464 | - if (sfk == sfk_inheriting_constructor && default_ctor_p (fn)) | |
465 | - sfk = sfk_constructor; | |
466 | - return type_has_trivial_fn (DECL_CONTEXT (fn), sfk); | |
461 | + return type_has_trivial_fn (DECL_CONTEXT (fn), special_function_p (fn)); | |
467 | 462 | } |
468 | 463 | |
469 | 464 | /* PARM is a PARM_DECL for a function which we want to forward to another |
@@ -4634,7 +4634,6 @@ lookup_using_decl (tree scope, name_lookup &lookup) | ||
4634 | 4634 | maybe_warn_cpp0x (CPP0X_INHERITING_CTORS); |
4635 | 4635 | lookup.name = ctor_identifier; |
4636 | 4636 | CLASSTYPE_NON_AGGREGATE (current) = true; |
4637 | - TYPE_HAS_USER_CONSTRUCTOR (current) = true; | |
4638 | 4637 | } |
4639 | 4638 | |
4640 | 4639 | /* Cannot introduce a constructor name. */ |
@@ -11578,7 +11578,6 @@ instantiate_class_template_1 (tree type) | ||
11578 | 11578 | SET_TYPE_ALIGN (type, TYPE_ALIGN (pattern)); |
11579 | 11579 | TYPE_USER_ALIGN (type) = TYPE_USER_ALIGN (pattern); |
11580 | 11580 | CLASSTYPE_NON_AGGREGATE (type) = CLASSTYPE_NON_AGGREGATE (pattern); |
11581 | - TYPE_HAS_USER_CONSTRUCTOR (type) = TYPE_HAS_USER_CONSTRUCTOR (pattern); | |
11582 | 11581 | if (ANON_AGGR_TYPE_P (pattern)) |
11583 | 11582 | SET_ANON_AGGR_TYPE_P (type); |
11584 | 11583 | if (CLASSTYPE_VISIBILITY_SPECIFIED (pattern)) |
@@ -11,7 +11,7 @@ template<typename T> | ||
11 | 11 | }; |
12 | 12 | |
13 | 13 | template<typename T> |
14 | - struct S2 : S1<T> { | |
14 | + struct S2 : S1<T> { // { dg-error "no matching function" } | |
15 | 15 | using S1<T>::S1; // { dg-error "no matching function" } |
16 | 16 | }; |
17 | 17 |
@@ -19,5 +19,5 @@ struct X { } x; | ||
19 | 19 | |
20 | 20 | int main() { |
21 | 21 | S2<X> s1(0); // { dg-error "use of deleted function" } |
22 | - S2<X> s2; // { dg-error "no matching function" } | |
22 | + S2<X> s2; // { dg-error "use of deleted function" } | |
23 | 23 | } |
@@ -0,0 +1,14 @@ | ||
1 | +// PR c++/92590 | |
2 | +// { dg-do compile { target c++11 } } | |
3 | + | |
4 | +class Base { | |
5 | + protected: | |
6 | + Base(); | |
7 | +}; | |
8 | + | |
9 | +class Derived : public Base { | |
10 | + public: | |
11 | + using Base::Base; | |
12 | +}; | |
13 | + | |
14 | +Derived d; |
@@ -6,13 +6,13 @@ struct B1 { | ||
6 | 6 | struct B2 { |
7 | 7 | B2(double) { } |
8 | 8 | }; |
9 | -struct D1 : B1 { | |
9 | +struct D1 : B1 { // { dg-error "no match" } | |
10 | 10 | using B1::B1; // implicitly declares D1(int) |
11 | 11 | int x; |
12 | 12 | }; |
13 | 13 | void test() { |
14 | 14 | D1 d(6); // OK: d.x is not initialized |
15 | - D1 e; // { dg-error "no match" } D1 has no default constructor | |
15 | + D1 e; // { dg-error "deleted" } D1 has no default constructor | |
16 | 16 | } |
17 | 17 | struct D2 : B2 { |
18 | 18 | using B2::B2; // { dg-error "B1::B1" } |
@@ -12,7 +12,7 @@ struct B2 { | ||
12 | 12 | |
13 | 13 | int get(); |
14 | 14 | |
15 | -struct D1 : B1 { | |
15 | +struct D1 : B1 { // { dg-message "B1::B1" } | |
16 | 16 | using B1::B1; // inherits B1(int, ...) |
17 | 17 | int x; |
18 | 18 | int y = get(); |
@@ -22,7 +22,7 @@ void test() { | ||
22 | 22 | D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4), |
23 | 23 | // then d.x is default-initialized (no initialization is performed), |
24 | 24 | // then d.y is initialized by calling get() |
25 | - D1 e; // { dg-error "" } D1 has no default constructor | |
25 | + D1 e; // { dg-error "" } D1 has a deleted default constructor | |
26 | 26 | } |
27 | 27 | |
28 | 28 | struct D2 : B2 { |
@@ -9,10 +9,10 @@ template<typename T> | ||
9 | 9 | }; |
10 | 10 | |
11 | 11 | template<typename T> |
12 | - struct S2 : S1<T> { | |
12 | + struct S2 : S1<T> { // { dg-error "matching" } | |
13 | 13 | using S1<T>::S1; |
14 | 14 | }; |
15 | 15 | |
16 | 16 | int main() { |
17 | - S2<int> s; // { dg-error "no matching function" } | |
17 | + S2<int> s; // { dg-error "deleted function" } | |
18 | 18 | } |
@@ -10,4 +10,6 @@ template <typename> struct A | ||
10 | 10 | template <typename> A(typename A::X) {} // { dg-error "incomplete" } |
11 | 11 | }; |
12 | 12 | |
13 | -A<void> a; // { dg-message "no match" } | |
13 | +// We currently don't give the "no match" error because we don't add the | |
14 | +// invalid constructor template to TYPE_METHODS. | |
15 | +A<void> a; // { dg-message "required" } |
@@ -9,7 +9,7 @@ public: | ||
9 | 9 | |
10 | 10 | void f () |
11 | 11 | { |
12 | - Test<void> c; // { dg-error "no match" } | |
12 | + Test<void> c; // { dg-message "required" } | |
13 | 13 | } |
14 | 14 | |
15 | 15 |