aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constraint.cc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-01-24 14:58:56 -0500
committerJason Merrill <jason@redhat.com>2020-01-25 01:07:51 -0500
commit9c1179c339e050e2ce7c545f648b684d38dec69d (patch)
treefef82e21680ee056351348a5cc251447eb17b822 /gcc/cp/constraint.cc
parent8b91e848130e45b427599ad30e99f96e447ea9aa (diff)
downloadgcc-9c1179c339e050e2ce7c545f648b684d38dec69d.zip
gcc-9c1179c339e050e2ce7c545f648b684d38dec69d.tar.gz
gcc-9c1179c339e050e2ce7c545f648b684d38dec69d.tar.bz2
c++: Fix ICE with constrained friend (PR93400).
Here, the problem was that tsubst_friend_function was modifying the CONSTRAINT_INFO for the friend template to have the constraints for one instantiation, which fell down when we went to adjust it for another instantiation. Fixed by deferring substitution of trailing requirements until we try to check declaration matching. PR c++/93400 - ICE with constrained friend. * constraint.cc (maybe_substitute_reqs_for): New. * decl.c (function_requirements_equivalent_p): Call it. * pt.c (tsubst_friend_function): Only substitute TEMPLATE_PARMS_CONSTRAINTS. (tsubst_template_parms): Copy constraints.
Diffstat (limited to 'gcc/cp/constraint.cc')
-rw-r--r--gcc/cp/constraint.cc23
1 files changed, 23 insertions, 0 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index 823604a..cda644e 100644
--- a/gcc/cp/constraint.cc
+++ b/gcc/cp/constraint.cc
@@ -1189,6 +1189,29 @@ remove_constraints (tree t)
decl_constraints->remove (t);
}
+/* If DECL is a friend, substitute into REQS to produce requirements suitable
+ for declaration matching. */
+
+tree
+maybe_substitute_reqs_for (tree reqs, const_tree decl_)
+{
+ if (reqs == NULL_TREE)
+ return NULL_TREE;
+ tree decl = CONST_CAST_TREE (decl_);
+ tree result = STRIP_TEMPLATE (decl);
+ if (DECL_FRIEND_P (result))
+ {
+ tree tmpl = decl == result ? DECL_TI_TEMPLATE (result) : decl;
+ tree gargs = generic_targs_for (tmpl);
+ processing_template_decl_sentinel s;
+ if (uses_template_parms (gargs))
+ ++processing_template_decl;
+ reqs = tsubst_constraint (reqs, gargs,
+ tf_warning_or_error, NULL_TREE);
+ }
+ return reqs;
+}
+
/* Returns the template-head requires clause for the template
declaration T or NULL_TREE if none. */