tmpl = most_general_template (tmpl);
}
+ d = tmpl ? tmpl : decl;
+
/* If we're not diagnosing errors, use cached constraints, if any. */
if (!diag)
- if (tree *p = hash_map_safe_get (normalized_map, tmpl))
+ if (tree *p = hash_map_safe_get (normalized_map, d))
return *p;
tree norm = NULL_TREE;
- if (tree ci = get_constraints (decl))
+ if (tree ci = get_constraints (d))
{
push_access_scope_guard pas (decl);
norm = get_normalized_constraints_from_info (ci, tmpl, diag);
}
if (!diag)
- hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);
+ hash_map_safe_put<hm_ggc> (normalized_map, d, norm);
return norm;
}
if (declspecs->gnu_thread_keyword_p)
SET_DECL_GNU_TLS_P (decl);
}
+
+ /* Set the constraints on the declaration. */
+ bool memtmpl = (processing_template_decl
+ > template_class_depth (current_class_type));
+ if (memtmpl)
+ {
+ tree tmpl_reqs
+ = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
+ tree ci = build_constraints (tmpl_reqs, NULL_TREE);
+ set_constraints (decl, ci);
+ }
}
else
{
targs = coerce_template_parms (parms, explicit_targs, fns,
tf_warning_or_error,
/*req_all*/true, /*use_defarg*/true);
- if (targs != error_mark_node)
+ if (targs != error_mark_node
+ && constraints_satisfied_p (fns, targs))
templates = tree_cons (targs, fns, templates);
}
else for (lkp_iterator iter (fns); iter; ++iter)
--- /dev/null
+// PR c++/98486
+// { dg-do compile { target c++20 } }
+
+template<class T, class U> concept C = __is_same(T, U);
+
+template<C<int>> int v;
+
+template<> int v<int>;
+template<> int v<char>; // { dg-error "match" }
--- /dev/null
+// PR c++/98486
+// { dg-do compile { target c++20 } }
+
+template<class T, class U> concept C = __is_same(T, U);
+
+struct A {
+ template<C<int>> static int v;
+};
+
+template<> int A::v<int>;
+template<> int A::v<char>; // { dg-error "match" }
+
+int x = A::v<int>;
+int y = A::v<char>; // { dg-error "invalid" }
--- /dev/null
+// PR c++/98486
+// { dg-do compile { target c++20 } }
+
+template<class T, class U> concept C = __is_same(T, U);
+
+template<class T>
+struct A {
+ template<C<T>> static int v;
+};
+
+template<> template<> int A<int>::v<int>;
+template<> template<> int A<int>::v<char>; // { dg-error "match" }
+
+int x = A<int>::v<int>;
+int y = A<int>::v<char>; // { dg-error "invalid" }