From ac308262f344153d472b16c85cc1c3036ce43308 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Mon, 14 Oct 2019 16:13:49 -0400 Subject: [PATCH] PR c++/91930 - ICE with constrained inherited default ctor. The testcase was crashing because lazily_declare_fn was failing to add a defaulted constructor, because the implicit declaration was less constrained than the inherited default constructor. But when we have an inherited constructor, we shouldn't be trying to declare a default constructor in the first place, because it counts as "a user-declared constructor". With that fixed I needed to adjust a couple of inherited constructor testcases that previously had been diagnosing the default constructor as deleted rather than not declared. * name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR for inherited constructor. From-SVN: r276968 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/name-lookup.c | 1 + gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C | 4 ++-- gcc/testsuite/g++.dg/cpp1z/inh-ctor22.C | 4 ++-- gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor6.C | 12 ++++++++++++ 5 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 28641071757..7245b3ed270 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2019-10-14 Jason Merrill + + PR c++/91930 - ICE with constrained inherited default ctor. + * name-lookup.c (do_class_using_decl): Set TYPE_HAS_USER_CONSTRUCTOR + for inherited constructor. + 2019-10-14 Paolo Carlini * decl.c (check_tag_decl): Use DECL_SOURCE_LOCATION. diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index 57ab129c9ec..9352ce5da0b 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -4613,6 +4613,7 @@ do_class_using_decl (tree scope, tree name) maybe_warn_cpp0x (CPP0X_INHERITING_CTORS); name = ctor_identifier; CLASSTYPE_NON_AGGREGATE (current_class_type) = true; + TYPE_HAS_USER_CONSTRUCTOR (current_class_type) = true; } /* Cannot introduce a constructor name. */ diff --git a/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C b/gcc/testsuite/g++.dg/cpp0x/inh-ctor5.C index d0038c16a14..673b6380504 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 { // { dg-error "no match" } +struct D1 : B1 { using B1::B1; // implicitly declares D1(int) int x; }; void test() { D1 d(6); // OK: d.x is not initialized - D1 e; // { dg-error "deleted" } D1 has no default constructor + D1 e; // { dg-error "no match" } 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 02ec58a3e8e..98336a158c1 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 { // { dg-message "B1::B1" } +struct D1 : 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 a deleted default constructor + D1 e; // { dg-error "" } D1 has no default constructor } struct D2 : B2 { diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor6.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor6.C new file mode 100644 index 00000000000..c92d6ac774c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor6.C @@ -0,0 +1,12 @@ +// PR c++/91930 +// { dg-do compile { target c++2a } } + +template struct basic_mixin { + basic_mixin() requires true; +}; + +struct mixin : basic_mixin { + using basic_mixin::basic_mixin; +}; + +mixin m; -- 2.30.2