diff options
-rw-r--r-- | gcc/cp/decl.cc | 4 | ||||
-rw-r--r-- | gcc/cp/pt.cc | 19 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/concepts/explicit-spec1a.C | 11 |
3 files changed, 20 insertions, 14 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 544efdc..238e72f 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -956,9 +956,7 @@ static bool function_requirements_equivalent_p (tree newfn, tree oldfn) { /* In the concepts TS, the combined constraints are compared. */ - if (cxx_dialect < cxx20 - && (DECL_TEMPLATE_SPECIALIZATION (newfn) - <= DECL_TEMPLATE_SPECIALIZATION (oldfn))) + if (cxx_dialect < cxx20) { tree ci1 = get_constraints (oldfn); tree ci2 = get_constraints (newfn); diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index fbf498a..2d8e4fd 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -2482,17 +2482,14 @@ determine_specialization (tree template_id, } /* It was a specialization of a template. */ - targs = DECL_TI_ARGS (DECL_TEMPLATE_RESULT (TREE_VALUE (templates))); - if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (targs)) - { - *targs_out = copy_node (targs); - SET_TMPL_ARGS_LEVEL (*targs_out, - TMPL_ARGS_DEPTH (*targs_out), - TREE_PURPOSE (templates)); - } - else - *targs_out = TREE_PURPOSE (templates); - return TREE_VALUE (templates); + tree tmpl = TREE_VALUE (templates); + *targs_out = add_outermost_template_args (tmpl, TREE_PURPOSE (templates)); + + /* Propagate the template's constraints to the declaration. */ + if (tsk != tsk_template) + set_constraints (decl, get_constraints (tmpl)); + + return tmpl; } /* Returns a chain of parameter types, exactly like the SPEC_TYPES, diff --git a/gcc/testsuite/g++.dg/concepts/explicit-spec1a.C b/gcc/testsuite/g++.dg/concepts/explicit-spec1a.C new file mode 100644 index 0000000..ec67874 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/explicit-spec1a.C @@ -0,0 +1,11 @@ +// A version of explicit-spec1.C where the template g has trailing instead of +// template requirements. +// PR c++/107864 +// { dg-do compile { target concepts } } + +template<typename T> concept C = __is_class(T); +struct Y { int n; } y; +template<class T> void g(T) requires C<T> { } +int called; +template<> void g(Y) { called = 3; } +int main() { g(y); } |