From ec62dc95c4f8776c9f4eff2a9a06f9aef6a2d98a Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Tue, 14 Mar 2023 19:12:08 -0400 Subject: [PATCH] c++: constrained template friend class matching [PR96830] When instantiating a constrained template friend naming an already declared class template, tsubst_friend_class erroneously passes to redeclare_class_template the existing template's constraints instead of those of the friend declaration, which causes the constraint comparison check therein to trivially succeed and we fail to diagnose legitimate constraint mismatches. PR c++/96830 gcc/cp/ChangeLog: * pt.cc (redeclare_class_template): Add missing "of" in constraint mismatch diagnostic. (tsubst_friend_class): For an already declared class template, substitute and pass the friend declaration's constraints to redeclare_class_template instead of passing the existing template's constraints. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/concepts-friend14.C: New test. --- gcc/cp/pt.cc | 8 ++++++-- gcc/testsuite/g++.dg/cpp2a/concepts-friend14.C | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-friend14.C diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index c53d8e2..eb153ad 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -6377,7 +6377,7 @@ redeclare_class_template (tree type, tree parms, tree cons) if (!cp_tree_equal (req1, req2)) { auto_diagnostic_group d; - error_at (input_location, "redeclaration %q#D with different " + error_at (input_location, "redeclaration of %q#D with different " "constraints", tmpl); inform (DECL_SOURCE_LOCATION (tmpl), "original declaration appeared here"); @@ -11564,7 +11564,11 @@ tsubst_friend_class (tree friend_tmpl, tree args) tf_warning_or_error); location_t saved_input_location = input_location; input_location = DECL_SOURCE_LOCATION (friend_tmpl); - tree cons = get_constraints (tmpl); + tree cons = get_constraints (friend_tmpl); + ++processing_template_decl; + cons = tsubst_constraint_info (cons, args, tf_warning_or_error, + DECL_FRIEND_CONTEXT (friend_tmpl)); + --processing_template_decl; redeclare_class_template (TREE_TYPE (tmpl), parms, cons); input_location = saved_input_location; } diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-friend14.C b/gcc/testsuite/g++.dg/cpp2a/concepts-friend14.C new file mode 100644 index 0000000..f46c7e4 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/concepts-friend14.C @@ -0,0 +1,26 @@ +// PR c++/96830 +// { dg-do compile { target c++20 } } + +template requires true +struct A { + template friend struct A; // { dg-error "different constraints" } + template requires (!!true) friend struct A; // { dg-error "different constraints" } +}; + +template +struct B { + template requires true friend struct A; + template requires true friend struct B; // { dg-error "different constraints" } +}; + +template concept C = true; + +template +struct D { + template friend struct D; // { dg-error "different constraints" } + template friend struct D; +}; + +template struct A; +template struct B; +template struct D; -- 2.7.4