We set TYPE_HAS_USER_CONSTRUCTOR on the template type in lookup_using_decl, but we didn't copy it to the instantiation. Setting it in one_inherited_ctor is too late, as that gets called after we decide whether to set CLASSTYPE_LAZY_DEFAULT_CTOR. This change affects other testcases as well; the changes are fixes for the other inherited constructor tests as well.
Tested x86_64-pc-linux-gnu, applying to trunk. * pt.c (instantiate_class_template_1): Copy TYPE_HAS_USER_CONSTRUCTOR. * class.c (one_inherited_ctor): Don't set it here. --- gcc/cp/class.c | 1 - gcc/cp/pt.c | 1 + gcc/testsuite/g++.dg/concepts/inherit-ctor3.C | 4 ++-- .../g++.dg/cpp2a/concepts-inherit-ctor2.C | 4 ++-- .../g++.dg/cpp2a/concepts-inherit-ctor7.C | 14 ++++++++++++++ gcc/testsuite/g++.dg/template/crash7.C | 4 +--- gcc/testsuite/g++.old-deja/g++.pt/error2.C | 2 +- 7 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor7.C diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4da08812702..07abe5298d1 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -3141,7 +3141,6 @@ one_inherited_ctor (tree ctor, tree t, tree using_decl) ctor = implicitly_declare_fn (sfk_inheriting_constructor, t, /*const*/false, ctor, parms); add_method (t, ctor, using_decl != NULL_TREE); - TYPE_HAS_USER_CONSTRUCTOR (t) = true; return; } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index bc23e9e0354..cd48f533d5d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -11544,6 +11544,7 @@ 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 abfe96e8240..dda202f4c24 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> { // { dg-error "no matching function" } + struct S2 : S1<T> { 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 "use of deleted function" } + S2<X> s2; // { dg-error "no matching function" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor2.C index aa244bc04c1..82d14746df2 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> { // { dg-error "matching" } + struct S2 : S1<T> { using S1<T>::S1; }; int main() { - S2<int> s; // { dg-error "deleted function" } + S2<int> s; // { dg-error "no matching function" } } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor7.C b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor7.C new file mode 100644 index 00000000000..2592b529356 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-inherit-ctor7.C @@ -0,0 +1,14 @@ +// PR c++/92552 +// { dg-do compile { target concepts } } + +template <typename T> struct basic_mixin { + basic_mixin() requires true; +}; +template <typename Cur> +struct mixin : basic_mixin<Cur> { + using basic_mixin<Cur>::basic_mixin; +}; +int main() { + (void)__is_constructible(mixin<int>); + // noexcept(mixin<int>()); also triggers ICE +} diff --git a/gcc/testsuite/g++.dg/template/crash7.C b/gcc/testsuite/g++.dg/template/crash7.C index 691628e7878..00d387c1197 100644 --- a/gcc/testsuite/g++.dg/template/crash7.C +++ b/gcc/testsuite/g++.dg/template/crash7.C @@ -10,6 +10,4 @@ template <typename> struct A template <typename> A(typename A::X) {} // { dg-error "incomplete" } }; -// 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" } +A<void> a; // { dg-message "no match" } diff --git a/gcc/testsuite/g++.old-deja/g++.pt/error2.C b/gcc/testsuite/g++.old-deja/g++.pt/error2.C index 2e65718b679..666aea0a1ef 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-message "required" } + Test<void> c; // { dg-error "no match" } } base-commit: b0f2d29e5944b0f3f09f217edd4375201ba6a164 -- 2.18.1