2020-01-13 Jason Merrill <jason@redhat.com>
+ PR c++/92582 - ICE with member template as requirement.
+ * pt.c (struct find_template_parameter_info): Add ctx_parms.
+ (any_template_parm_r): Handle TEMPLATE_DECL.
+ (find_template_parameters): Take parms instead of their depth.
+ * constraint.cc (build_parameter_mapping): Pass them.
+
PR c++/33799 - destroy return value if local cleanup throws.
* cp-tree.h (current_retval_sentinel): New macro.
* decl.c (start_preparsed_function): Set up cleanup for retval.
static tree
build_parameter_mapping (tree expr, tree args, tree decl)
{
- int depth = 0;
+ tree ctx_parms = NULL_TREE;
if (decl)
{
gcc_assert (TREE_CODE (decl) == TEMPLATE_DECL);
- tree parms = DECL_TEMPLATE_PARMS (decl);
- depth = TREE_INT_CST_LOW (TREE_PURPOSE (parms));
+ ctx_parms = DECL_TEMPLATE_PARMS (decl);
}
else if (current_template_parms)
{
point of declaration of concepts is currently set after the
initializer, the template parameter lists are not available
when normalizing concept definitions, hence the case above. */
- depth = TMPL_PARMS_DEPTH (current_template_parms);
+ ctx_parms = current_template_parms;
}
- tree parms = find_template_parameters (expr, depth);
+ tree parms = find_template_parameters (expr, ctx_parms);
tree map = map_arguments (parms, args);
return map;
}
extern void clear_satisfaction_cache ();
extern bool* lookup_subsumption_result (tree, tree);
extern bool save_subsumption_result (tree, tree, bool);
-extern tree find_template_parameters (tree, int);
+extern tree find_template_parameters (tree, tree);
extern bool equivalent_constraints (tree, tree);
extern bool equivalently_constrained (tree, tree);
extern bool subsumes_constraints (tree, tree);
struct find_template_parameter_info
{
- explicit find_template_parameter_info (int d)
- : max_depth (d)
+ explicit find_template_parameter_info (tree ctx_parms)
+ : ctx_parms (ctx_parms),
+ max_depth (TMPL_PARMS_DEPTH (ctx_parms))
{}
hash_set<tree> visited;
hash_set<tree> parms;
+ tree ctx_parms;
int max_depth;
};
WALK_SUBTREE (TREE_TYPE (t));
break;
+ case TEMPLATE_DECL:
+ {
+ /* If T is a member template that shares template parameters with
+ ctx_parms, we need to mark all those parameters for mapping. */
+ tree dparms = DECL_TEMPLATE_PARMS (t);
+ tree cparms = ftpi->ctx_parms;
+ while (TMPL_PARMS_DEPTH (dparms) > ftpi->max_depth)
+ dparms = TREE_CHAIN (dparms);
+ while (dparms
+ && (TREE_TYPE (TREE_VALUE (dparms))
+ != TREE_TYPE (TREE_VALUE (cparms))))
+ dparms = TREE_CHAIN (dparms),
+ cparms = TREE_CHAIN (cparms);
+ if (dparms)
+ {
+ int ddepth = TMPL_PARMS_DEPTH (dparms);
+ tree dargs = TI_ARGS (get_template_info (DECL_TEMPLATE_RESULT (t)));
+ for (int i = 0; i < ddepth; ++i)
+ WALK_SUBTREE (TMPL_ARGS_LEVEL (dargs, i+1));
+ }
+ }
+ break;
+
default:
break;
}
return 0;
}
-/* Returns a list of unique template parameters found within T. */
+/* Returns a list of unique template parameters found within T, where CTX_PARMS
+ are the template parameters in scope. */
tree
-find_template_parameters (tree t, int depth)
+find_template_parameters (tree t, tree ctx_parms)
{
- find_template_parameter_info ftpi (depth);
+ if (!ctx_parms)
+ return NULL_TREE;
+
+ find_template_parameter_info ftpi (ctx_parms);
for_each_template_parm (t, keep_template_parm, &ftpi, &ftpi.visited,
/*include_nondeduced*/true, any_template_parm_r);
tree list = NULL_TREE;
--- /dev/null
+// PR c++/92582
+// { dg-do compile { target concepts } }
+
+template <class a, class> concept b = true;
+template <typename> struct A {
+ template <typename c> static constexpr bool d = b<c, int>;
+ template <typename c> static void f(c) requires d<c>;
+};
+int main()
+{
+ A<void>::f(0);
+}