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");
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;
}
--- /dev/null
+// PR c++/96830
+// { dg-do compile { target c++20 } }
+
+template<class T> requires true
+struct A {
+ template<class U> friend struct A; // { dg-error "different constraints" }
+ template<class U> requires (!!true) friend struct A; // { dg-error "different constraints" }
+};
+
+template<class T>
+struct B {
+ template<class U> requires true friend struct A;
+ template<class U> requires true friend struct B; // { dg-error "different constraints" }
+};
+
+template<class T> concept C = true;
+
+template<C T>
+struct D {
+ template<class U> friend struct D; // { dg-error "different constraints" }
+ template<C U> friend struct D;
+};
+
+template struct A<int>;
+template struct B<int>;
+template struct D<int>;