1 /* Processing rules for constraints.
2 Copyright (C) 2013-2021 Free Software Foundation, Inc.
3 Contributed by Andrew Sutton (andrew.n.sutton@gmail.com)
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
20
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "tm.h"
25 #include "timevar.h"
26 #include "hash-set.h"
27 #include "machmode.h"
28 #include "vec.h"
29 #include "double-int.h"
30 #include "input.h"
31 #include "alias.h"
32 #include "symtab.h"
33 #include "wide-int.h"
34 #include "inchash.h"
35 #include "tree.h"
36 #include "stringpool.h"
37 #include "attribs.h"
38 #include "intl.h"
39 #include "flags.h"
40 #include "cp-tree.h"
41 #include "c-family/c-common.h"
42 #include "c-family/c-objc.h"
43 #include "cp-objcp-common.h"
44 #include "tree-inline.h"
45 #include "decl.h"
46 #include "toplev.h"
47 #include "type-utils.h"
48
49 static tree satisfaction_value (tree t);
50
51 /* When we're parsing or substuting a constraint expression, we have slightly
52 different expression semantics. In particular, we don't want to reduce a
53 concept-id to a satisfaction value. */
54
55 processing_constraint_expression_sentinel::
processing_constraint_expression_sentinel()56 processing_constraint_expression_sentinel ()
57 {
58 ++scope_chain->x_processing_constraint;
59 }
60
61 processing_constraint_expression_sentinel::
~processing_constraint_expression_sentinel()62 ~processing_constraint_expression_sentinel ()
63 {
64 --scope_chain->x_processing_constraint;
65 }
66
67 bool
processing_constraint_expression_p()68 processing_constraint_expression_p ()
69 {
70 return scope_chain->x_processing_constraint != 0;
71 }
72
73 /*---------------------------------------------------------------------------
74 Constraint expressions
75 ---------------------------------------------------------------------------*/
76
77 /* Information provided to substitution. */
78
79 struct subst_info
80 {
subst_infosubst_info81 subst_info (tsubst_flags_t cmp, tree in)
82 : complain (cmp), in_decl (in)
83 { }
84
85 /* True if we should not diagnose errors. */
quietsubst_info86 bool quiet() const
87 {
88 return complain == tf_none;
89 }
90
91 /* True if we should diagnose errors. */
noisysubst_info92 bool noisy() const
93 {
94 return !quiet ();
95 }
96
97 tsubst_flags_t complain;
98 tree in_decl;
99 };
100
101 /* Provides additional context for satisfaction.
102
103 During satisfaction:
104 - The flag noisy() controls whether to diagnose ill-formed satisfaction,
105 such as the satisfaction value of an atom being non-bool or non-constant.
106 - The flag diagnose_unsatisfaction_p() controls whether to additionally
107 explain why a constraint is not satisfied.
108 - We enter satisfaction with noisy+unsat from diagnose_constraints.
109 - We enter satisfaction with noisy-unsat from the replay inside
110 constraint_satisfaction_value.
111 - We enter satisfaction quietly (both flags cleared) from
112 constraints_satisfied_p.
113
114 During evaluation of a requires-expression:
115 - The flag noisy() controls whether to diagnose ill-formed types and
116 expressions inside its requirements.
117 - The flag diagnose_unsatisfaction_p() controls whether to additionally
118 explain why the requires-expression evaluates to false.
119 - We enter tsubst_requires_expr with noisy+unsat from
120 diagnose_atomic_constraint and potentially from
121 satisfy_nondeclaration_constraints.
122 - We enter tsubst_requires_expr with noisy-unsat from
123 cp_parser_requires_expression when processing a requires-expression that
124 appears outside a template.
125 - We enter tsubst_requires_expr quietly (both flags cleared) when
126 substituting through a requires-expression as part of template
127 instantiation. */
128
129 struct sat_info : subst_info
130 {
sat_infosat_info131 sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false)
132 : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat)
133 {
134 if (diagnose_unsatisfaction_p ())
135 gcc_checking_assert (noisy ());
136 }
137
138 /* True if we should diagnose the cause of satisfaction failure.
139 Implies noisy(). */
140 bool
diagnose_unsatisfaction_psat_info141 diagnose_unsatisfaction_p () const
142 {
143 return diagnose_unsatisfaction;
144 }
145
146 bool diagnose_unsatisfaction;
147 };
148
149 static tree constraint_satisfaction_value (tree, tree, sat_info);
150
151 /* True if T is known to be some type other than bool. Note that this
152 is false for dependent types and errors. */
153
154 static inline bool
known_non_bool_p(tree t)155 known_non_bool_p (tree t)
156 {
157 return (t && !WILDCARD_TYPE_P (t) && TREE_CODE (t) != BOOLEAN_TYPE);
158 }
159
160 static bool
check_constraint_atom(cp_expr expr)161 check_constraint_atom (cp_expr expr)
162 {
163 if (known_non_bool_p (TREE_TYPE (expr)))
164 {
165 error_at (expr.get_location (),
166 "constraint expression does not have type %<bool%>");
167 return false;
168 }
169
170 /* Check that we're using function concepts correctly. */
171 if (concept_check_p (expr))
172 {
173 tree id = unpack_concept_check (expr);
174 tree tmpl = TREE_OPERAND (id, 0);
175 if (OVL_P (tmpl) && TREE_CODE (expr) == TEMPLATE_ID_EXPR)
176 {
177 error_at (EXPR_LOC_OR_LOC (expr, input_location),
178 "function concept must be called");
179 return false;
180 }
181 }
182
183 return true;
184 }
185
186 static bool
check_constraint_operands(location_t,cp_expr lhs,cp_expr rhs)187 check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
188 {
189 return check_constraint_atom (lhs) && check_constraint_atom (rhs);
190 }
191
192 /* Validate the semantic properties of the constraint expression. */
193
194 static cp_expr
finish_constraint_binary_op(location_t loc,tree_code code,cp_expr lhs,cp_expr rhs)195 finish_constraint_binary_op (location_t loc,
196 tree_code code,
197 cp_expr lhs,
198 cp_expr rhs)
199 {
200 gcc_assert (processing_constraint_expression_p ());
201 if (lhs == error_mark_node || rhs == error_mark_node)
202 return error_mark_node;
203 if (!check_constraint_operands (loc, lhs, rhs))
204 return error_mark_node;
205 tree overload;
206 cp_expr expr = build_x_binary_op (loc, code,
207 lhs, TREE_CODE (lhs),
208 rhs, TREE_CODE (rhs),
209 &overload, tf_none);
210 /* When either operand is dependent, the overload set may be non-empty. */
211 if (expr == error_mark_node)
212 return error_mark_node;
213 expr.set_location (loc);
214 expr.set_range (lhs.get_start (), rhs.get_finish ());
215 return expr;
216 }
217
218 cp_expr
finish_constraint_or_expr(location_t loc,cp_expr lhs,cp_expr rhs)219 finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
220 {
221 return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
222 }
223
224 cp_expr
finish_constraint_and_expr(location_t loc,cp_expr lhs,cp_expr rhs)225 finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
226 {
227 return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
228 }
229
230 cp_expr
finish_constraint_primary_expr(cp_expr expr)231 finish_constraint_primary_expr (cp_expr expr)
232 {
233 if (expr == error_mark_node)
234 return error_mark_node;
235 if (!check_constraint_atom (expr))
236 return cp_expr (error_mark_node, expr.get_location ());
237 return expr;
238 }
239
240 /* Combine two constraint-expressions with a logical-and. */
241
242 tree
combine_constraint_expressions(tree lhs,tree rhs)243 combine_constraint_expressions (tree lhs, tree rhs)
244 {
245 processing_constraint_expression_sentinel pce;
246 if (!lhs)
247 return rhs;
248 if (!rhs)
249 return lhs;
250 return finish_constraint_and_expr (input_location, lhs, rhs);
251 }
252
253 /* Extract the template-id from a concept check. For standard and variable
254 checks, this is simply T. For function concept checks, this is the
255 called function. */
256
257 tree
unpack_concept_check(tree t)258 unpack_concept_check (tree t)
259 {
260 gcc_assert (concept_check_p (t));
261
262 if (TREE_CODE (t) == CALL_EXPR)
263 t = CALL_EXPR_FN (t);
264
265 gcc_assert (TREE_CODE (t) == TEMPLATE_ID_EXPR);
266 return t;
267 }
268
269 /* Extract the TEMPLATE_DECL from a concept check. */
270
271 tree
get_concept_check_template(tree t)272 get_concept_check_template (tree t)
273 {
274 tree id = unpack_concept_check (t);
275 tree tmpl = TREE_OPERAND (id, 0);
276 if (OVL_P (tmpl))
277 tmpl = OVL_FIRST (tmpl);
278 return tmpl;
279 }
280
281 /* Returns true if any of the arguments in the template argument list is
282 a wildcard or wildcard pack. */
283
284 bool
contains_wildcard_p(tree args)285 contains_wildcard_p (tree args)
286 {
287 for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
288 {
289 tree arg = TREE_VEC_ELT (args, i);
290 if (TREE_CODE (arg) == WILDCARD_DECL)
291 return true;
292 }
293 return false;
294 }
295
296 /*---------------------------------------------------------------------------
297 Resolution of qualified concept names
298 ---------------------------------------------------------------------------*/
299
300 /* This facility is used to resolve constraint checks from requirement
301 expressions. A constraint check is a call to a function template declared
302 with the keyword 'concept'.
303
304 The result of resolution is a pair (a TREE_LIST) whose value is the
305 matched declaration, and whose purpose contains the coerced template
306 arguments that can be substituted into the call. */
307
308 /* Given an overload set OVL, try to find a unique definition that can be
309 instantiated by the template arguments ARGS.
310
311 This function is not called for arbitrary call expressions. In particular,
312 the call expression must be written with explicit template arguments
313 and no function arguments. For example:
314
315 f<T, U>()
316
317 If a single match is found, this returns a TREE_LIST whose VALUE
318 is the constraint function (not the template), and its PURPOSE is
319 the complete set of arguments substituted into the parameter list. */
320
321 static tree
resolve_function_concept_overload(tree ovl,tree args)322 resolve_function_concept_overload (tree ovl, tree args)
323 {
324 int nerrs = 0;
325 tree cands = NULL_TREE;
326 for (lkp_iterator iter (ovl); iter; ++iter)
327 {
328 tree tmpl = *iter;
329 if (TREE_CODE (tmpl) != TEMPLATE_DECL)
330 continue;
331
332 /* Don't try to deduce checks for non-concepts. We often end up trying
333 to resolve constraints in functional casts as part of a
334 postfix-expression. We can save time and headaches by not
335 instantiating those declarations.
336
337 NOTE: This masks a potential error, caused by instantiating
338 non-deduced contexts using placeholder arguments. */
339 tree fn = DECL_TEMPLATE_RESULT (tmpl);
340 if (DECL_ARGUMENTS (fn))
341 continue;
342 if (!DECL_DECLARED_CONCEPT_P (fn))
343 continue;
344
345 /* Remember the candidate if we can deduce a substitution. */
346 ++processing_template_decl;
347 tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
348 if (tree subst = coerce_template_parms (parms, args, tmpl))
349 {
350 if (subst == error_mark_node)
351 ++nerrs;
352 else
353 cands = tree_cons (subst, fn, cands);
354 }
355 --processing_template_decl;
356 }
357
358 if (!cands)
359 /* We either had no candidates or failed deductions. */
360 return nerrs ? error_mark_node : NULL_TREE;
361 else if (TREE_CHAIN (cands))
362 /* There are multiple candidates. */
363 return error_mark_node;
364
365 return cands;
366 }
367
368 /* Determine if the call expression CALL is a constraint check, and
369 return the concept declaration and arguments being checked. If CALL
370 does not denote a constraint check, return NULL. */
371
372 tree
resolve_function_concept_check(tree call)373 resolve_function_concept_check (tree call)
374 {
375 gcc_assert (TREE_CODE (call) == CALL_EXPR);
376
377 /* A constraint check must be only a template-id expression.
378 If it's a call to a base-link, its function(s) should be a
379 template-id expression. If this is not a template-id, then
380 it cannot be a concept-check. */
381 tree target = CALL_EXPR_FN (call);
382 if (BASELINK_P (target))
383 target = BASELINK_FUNCTIONS (target);
384 if (TREE_CODE (target) != TEMPLATE_ID_EXPR)
385 return NULL_TREE;
386
387 /* Get the overload set and template arguments and try to
388 resolve the target. */
389 tree ovl = TREE_OPERAND (target, 0);
390
391 /* This is a function call of a variable concept... ill-formed. */
392 if (TREE_CODE (ovl) == TEMPLATE_DECL)
393 {
394 error_at (location_of (call),
395 "function call of variable concept %qE", call);
396 return error_mark_node;
397 }
398
399 tree args = TREE_OPERAND (target, 1);
400 return resolve_function_concept_overload (ovl, args);
401 }
402
403 /* Returns a pair containing the checked concept and its associated
404 prototype parameter. The result is a TREE_LIST whose TREE_VALUE
405 is the concept (non-template) and whose TREE_PURPOSE contains
406 the converted template arguments, including the deduced prototype
407 parameter (in position 0). */
408
409 tree
resolve_concept_check(tree check)410 resolve_concept_check (tree check)
411 {
412 gcc_assert (concept_check_p (check));
413 tree id = unpack_concept_check (check);
414 tree tmpl = TREE_OPERAND (id, 0);
415
416 /* If this is an overloaded function concept, perform overload
417 resolution (this only happens when deducing prototype parameters
418 and template introductions). */
419 if (TREE_CODE (tmpl) == OVERLOAD)
420 {
421 if (OVL_CHAIN (tmpl))
422 return resolve_function_concept_check (check);
423 tmpl = OVL_FIRST (tmpl);
424 }
425
426 tree args = TREE_OPERAND (id, 1);
427 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
428 ++processing_template_decl;
429 tree result = coerce_template_parms (parms, args, tmpl);
430 --processing_template_decl;
431 if (result == error_mark_node)
432 return error_mark_node;
433 return build_tree_list (result, DECL_TEMPLATE_RESULT (tmpl));
434 }
435
436 /* Given a call expression or template-id expression to a concept EXPR
437 possibly including a wildcard, deduce the concept being checked and
438 the prototype parameter. Returns true if the constraint and prototype
439 can be deduced and false otherwise. Note that the CHECK and PROTO
440 arguments are set to NULL_TREE if this returns false. */
441
442 bool
deduce_constrained_parameter(tree expr,tree & check,tree & proto)443 deduce_constrained_parameter (tree expr, tree& check, tree& proto)
444 {
445 tree info = resolve_concept_check (expr);
446 if (info && info != error_mark_node)
447 {
448 check = TREE_VALUE (info);
449 tree arg = TREE_VEC_ELT (TREE_PURPOSE (info), 0);
450 if (ARGUMENT_PACK_P (arg))
451 arg = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0);
452 proto = TREE_TYPE (arg);
453 return true;
454 }
455
456 check = proto = NULL_TREE;
457 return false;
458 }
459
460 /* Given a call expression or template-id expression to a concept, EXPR,
461 deduce the concept being checked and return the template arguments.
462 Returns NULL_TREE if deduction fails. */
463 static tree
deduce_concept_introduction(tree check)464 deduce_concept_introduction (tree check)
465 {
466 tree info = resolve_concept_check (check);
467 if (info && info != error_mark_node)
468 return TREE_PURPOSE (info);
469 return NULL_TREE;
470 }
471
472 /* Build a constrained placeholder type where SPEC is a type-constraint.
473 SPEC can be anything were concept_definition_p is true.
474
475 If DECLTYPE_P is true, then the placeholder is decltype(auto).
476
477 Returns a pair whose FIRST is the concept being checked and whose
478 SECOND is the prototype parameter. */
479
480 tree_pair
finish_type_constraints(tree spec,tree args,tsubst_flags_t complain)481 finish_type_constraints (tree spec, tree args, tsubst_flags_t complain)
482 {
483 gcc_assert (concept_definition_p (spec));
484
485 /* Build an initial concept check. */
486 tree check = build_type_constraint (spec, args, complain);
487 if (check == error_mark_node)
488 return std::make_pair (error_mark_node, NULL_TREE);
489
490 /* Extract the concept and prototype parameter from the check. */
491 tree con;
492 tree proto;
493 if (!deduce_constrained_parameter (check, con, proto))
494 return std::make_pair (error_mark_node, NULL_TREE);
495
496 return std::make_pair (con, proto);
497 }
498
499 /*---------------------------------------------------------------------------
500 Expansion of concept definitions
501 ---------------------------------------------------------------------------*/
502
503 /* Returns the expression of a function concept. */
504
505 static tree
get_returned_expression(tree fn)506 get_returned_expression (tree fn)
507 {
508 /* Extract the body of the function minus the return expression. */
509 tree body = DECL_SAVED_TREE (fn);
510 if (!body)
511 return error_mark_node;
512 if (TREE_CODE (body) == BIND_EXPR)
513 body = BIND_EXPR_BODY (body);
514 if (TREE_CODE (body) != RETURN_EXPR)
515 return error_mark_node;
516
517 return TREE_OPERAND (body, 0);
518 }
519
520 /* Returns the initializer of a variable concept. */
521
522 static tree
get_variable_initializer(tree var)523 get_variable_initializer (tree var)
524 {
525 tree init = DECL_INITIAL (var);
526 if (!init)
527 return error_mark_node;
528 if (BRACE_ENCLOSED_INITIALIZER_P (init)
529 && CONSTRUCTOR_NELTS (init) == 1)
530 init = CONSTRUCTOR_ELT (init, 0)->value;
531 return init;
532 }
533
534 /* Returns the definition of a variable or function concept. */
535
536 static tree
get_concept_definition(tree decl)537 get_concept_definition (tree decl)
538 {
539 if (TREE_CODE (decl) == OVERLOAD)
540 decl = OVL_FIRST (decl);
541
542 if (TREE_CODE (decl) == TEMPLATE_DECL)
543 decl = DECL_TEMPLATE_RESULT (decl);
544
545 if (TREE_CODE (decl) == CONCEPT_DECL)
546 return DECL_INITIAL (decl);
547 if (VAR_P (decl))
548 return get_variable_initializer (decl);
549 if (TREE_CODE (decl) == FUNCTION_DECL)
550 return get_returned_expression (decl);
551 gcc_unreachable ();
552 }
553
554 /*---------------------------------------------------------------------------
555 Normalization of expressions
556
557 This set of functions will transform an expression into a constraint
558 in a sequence of steps.
559 ---------------------------------------------------------------------------*/
560
561 void
debug_parameter_mapping(tree map)562 debug_parameter_mapping (tree map)
563 {
564 for (tree p = map; p; p = TREE_CHAIN (p))
565 {
566 tree parm = TREE_VALUE (p);
567 tree arg = TREE_PURPOSE (p);
568 if (TYPE_P (parm))
569 verbatim ("MAP %qD TO %qT", TEMPLATE_TYPE_DECL (parm), arg);
570 else
571 verbatim ("MAP %qD TO %qE", TEMPLATE_PARM_DECL (parm), arg);
572 // debug_tree (parm);
573 // debug_tree (arg);
574 }
575 }
576
577 void
debug_argument_list(tree args)578 debug_argument_list (tree args)
579 {
580 for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
581 {
582 tree arg = TREE_VEC_ELT (args, i);
583 if (TYPE_P (arg))
584 verbatim ("argument %qT", arg);
585 else
586 verbatim ("argument %qE", arg);
587 }
588 }
589
590 /* Associate each parameter in PARMS with its corresponding template
591 argument in ARGS. */
592
593 static tree
map_arguments(tree parms,tree args)594 map_arguments (tree parms, tree args)
595 {
596 for (tree p = parms; p; p = TREE_CHAIN (p))
597 if (args)
598 {
599 int level;
600 int index;
601 template_parm_level_and_index (TREE_VALUE (p), &level, &index);
602 TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
603 }
604 else
605 TREE_PURPOSE (p) = template_parm_to_arg (p);
606
607 return parms;
608 }
609
610 /* Build the parameter mapping for EXPR using ARGS, where CTX_PARMS
611 are the template parameters in scope for EXPR. */
612
613 static tree
build_parameter_mapping(tree expr,tree args,tree ctx_parms)614 build_parameter_mapping (tree expr, tree args, tree ctx_parms)
615 {
616 tree parms = find_template_parameters (expr, ctx_parms);
617 tree map = map_arguments (parms, args);
618 return map;
619 }
620
621 /* True if the parameter mappings of two atomic constraints formed
622 from the same expression are equivalent. */
623
624 static bool
parameter_mapping_equivalent_p(tree t1,tree t2)625 parameter_mapping_equivalent_p (tree t1, tree t2)
626 {
627 tree map1 = ATOMIC_CONSTR_MAP (t1);
628 tree map2 = ATOMIC_CONSTR_MAP (t2);
629 while (map1 && map2)
630 {
631 gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2));
632 tree arg1 = TREE_PURPOSE (map1);
633 tree arg2 = TREE_PURPOSE (map2);
634 if (!template_args_equal (arg1, arg2))
635 return false;
636 map1 = TREE_CHAIN (map1);
637 map2 = TREE_CHAIN (map2);
638 }
639 gcc_checking_assert (!map1 && !map2);
640 return true;
641 }
642
643 /* Provides additional context for normalization. */
644
645 struct norm_info : subst_info
646 {
norm_infonorm_info647 explicit norm_info (tsubst_flags_t cmp)
648 : norm_info (NULL_TREE, cmp)
649 {}
650
651 /* Construct a top-level context for DECL. */
652
norm_infonorm_info653 norm_info (tree in_decl, tsubst_flags_t complain)
654 : subst_info (tf_warning_or_error | complain, in_decl)
655 {
656 if (in_decl)
657 {
658 initial_parms = DECL_TEMPLATE_PARMS (in_decl);
659 if (generate_diagnostics ())
660 context = build_tree_list (NULL_TREE, in_decl);
661 }
662 else
663 initial_parms = current_template_parms;
664 }
665
generate_diagnosticsnorm_info666 bool generate_diagnostics() const
667 {
668 return complain & tf_norm;
669 }
670
update_contextnorm_info671 void update_context(tree expr, tree args)
672 {
673 if (generate_diagnostics ())
674 {
675 tree map = build_parameter_mapping (expr, args, ctx_parms ());
676 context = tree_cons (map, expr, context);
677 }
678 in_decl = get_concept_check_template (expr);
679 }
680
681 /* Returns the template parameters that are in scope for the current
682 normalization context. */
683
ctx_parmsnorm_info684 tree ctx_parms()
685 {
686 if (in_decl)
687 return DECL_TEMPLATE_PARMS (in_decl);
688 else
689 return initial_parms;
690 }
691
692 /* Provides information about the source of a constraint. This is a
693 TREE_LIST whose VALUE is either a concept check or a constrained
694 declaration. The PURPOSE, for concept checks is a parameter mapping
695 for that check. */
696
697 tree context = NULL_TREE;
698
699 /* The declaration whose constraints we're normalizing. The targets
700 of the parameter mapping of each atom will be in terms of the
701 template parameters of ORIG_DECL. */
702
703 tree initial_parms = NULL_TREE;
704 };
705
706 static tree normalize_expression (tree, tree, norm_info);
707
708 /* Transform a logical-or or logical-and expression into either
709 a conjunction or disjunction. */
710
711 static tree
normalize_logical_operation(tree t,tree args,tree_code c,norm_info info)712 normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
713 {
714 tree t0 = normalize_expression (TREE_OPERAND (t, 0), args, info);
715 tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);
716
717 /* Build a new info object for the constraint. */
718 tree ci = info.generate_diagnostics()
719 ? build_tree_list (t, info.context)
720 : NULL_TREE;
721
722 return build2 (c, ci, t0, t1);
723 }
724
725 static tree
normalize_concept_check(tree check,tree args,norm_info info)726 normalize_concept_check (tree check, tree args, norm_info info)
727 {
728 tree id = unpack_concept_check (check);
729 tree tmpl = TREE_OPERAND (id, 0);
730 tree targs = TREE_OPERAND (id, 1);
731
732 /* A function concept is wrapped in an overload. */
733 if (TREE_CODE (tmpl) == OVERLOAD)
734 {
735 /* TODO: Can we diagnose this error during parsing? */
736 if (TREE_CODE (check) == TEMPLATE_ID_EXPR)
737 error_at (EXPR_LOC_OR_LOC (check, input_location),
738 "function concept must be called");
739 tmpl = OVL_FIRST (tmpl);
740 }
741
742 /* Substitute through the arguments of the concept check. */
743 if (args)
744 targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
745 if (targs == error_mark_node)
746 return error_mark_node;
747
748 /* Build the substitution for the concept definition. */
749 tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
750 /* Turn on template processing; coercing non-type template arguments
751 will automatically assume they're non-dependent. */
752 ++processing_template_decl;
753 tree subst = coerce_template_parms (parms, targs, tmpl);
754 --processing_template_decl;
755 if (subst == error_mark_node)
756 return error_mark_node;
757
758 /* The concept may have been ill-formed. */
759 tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
760 if (def == error_mark_node)
761 return error_mark_node;
762
763 info.update_context (check, args);
764 return normalize_expression (def, subst, info);
765 }
766
767 /* Used by normalize_atom to cache ATOMIC_CONSTRs. */
768
769 static GTY((deletable)) hash_table<atom_hasher> *atom_cache;
770
771 /* The normal form of an atom depends on the expression. The normal
772 form of a function call to a function concept is a check constraint
773 for that concept. The normal form of a reference to a variable
774 concept is a check constraint for that concept. Otherwise, the
775 constraint is a predicate constraint. */
776
777 static tree
normalize_atom(tree t,tree args,norm_info info)778 normalize_atom (tree t, tree args, norm_info info)
779 {
780 /* Concept checks are not atomic. */
781 if (concept_check_p (t))
782 return normalize_concept_check (t, args, info);
783
784 /* Build the parameter mapping for the atom. */
785 tree map = build_parameter_mapping (t, args, info.ctx_parms ());
786
787 /* Build a new info object for the atom. */
788 tree ci = build_tree_list (t, info.context);
789
790 tree atom = build1 (ATOMIC_CONSTR, ci, map);
791 if (!info.generate_diagnostics ())
792 {
793 /* Cache the ATOMIC_CONSTRs that we return, so that sat_hasher::equal
794 later can cheaply compare two atoms using just pointer equality. */
795 if (!atom_cache)
796 atom_cache = hash_table<atom_hasher>::create_ggc (31);
797 tree *slot = atom_cache->find_slot (atom, INSERT);
798 if (*slot)
799 return *slot;
800
801 /* Find all template parameters used in the targets of the parameter
802 mapping, and store a list of them in the TREE_TYPE of the mapping.
803 This list will be used by sat_hasher to determine the subset of
804 supplied template arguments that the satisfaction value of the atom
805 depends on. */
806 if (map)
807 {
808 tree targets = make_tree_vec (list_length (map));
809 int i = 0;
810 for (tree node = map; node; node = TREE_CHAIN (node))
811 {
812 tree target = TREE_PURPOSE (node);
813 TREE_VEC_ELT (targets, i++) = target;
814 }
815 tree target_parms = find_template_parameters (targets,
816 info.initial_parms);
817 TREE_TYPE (map) = target_parms;
818 }
819
820 *slot = atom;
821 }
822 return atom;
823 }
824
825 /* Returns the normal form of an expression. */
826
827 static tree
normalize_expression(tree t,tree args,norm_info info)828 normalize_expression (tree t, tree args, norm_info info)
829 {
830 if (!t)
831 return NULL_TREE;
832
833 if (t == error_mark_node)
834 return error_mark_node;
835
836 switch (TREE_CODE (t))
837 {
838 case TRUTH_ANDIF_EXPR:
839 return normalize_logical_operation (t, args, CONJ_CONSTR, info);
840 case TRUTH_ORIF_EXPR:
841 return normalize_logical_operation (t, args, DISJ_CONSTR, info);
842 default:
843 return normalize_atom (t, args, info);
844 }
845 }
846
847 /* Cache of the normalized form of constraints. Marked as deletable because it
848 can all be recalculated. */
849 static GTY((deletable)) hash_map<tree,tree> *normalized_map;
850
851 static tree
get_normalized_constraints(tree t,norm_info info)852 get_normalized_constraints (tree t, norm_info info)
853 {
854 auto_timevar time (TV_CONSTRAINT_NORM);
855 return normalize_expression (t, NULL_TREE, info);
856 }
857
858 /* Returns the normalized constraints from a constraint-info object
859 or NULL_TREE if the constraints are null. IN_DECL provides the
860 declaration to which the constraints belong. */
861
862 static tree
get_normalized_constraints_from_info(tree ci,tree in_decl,bool diag=false)863 get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
864 {
865 if (ci == NULL_TREE)
866 return NULL_TREE;
867
868 /* Substitution errors during normalization are fatal. */
869 ++processing_template_decl;
870 norm_info info (in_decl, diag ? tf_norm : tf_none);
871 tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci), info);
872 --processing_template_decl;
873
874 return t;
875 }
876
877 /* Returns the normalized constraints for the declaration D. */
878
879 static tree
get_normalized_constraints_from_decl(tree d,bool diag=false)880 get_normalized_constraints_from_decl (tree d, bool diag = false)
881 {
882 tree tmpl;
883 tree decl;
884
885 /* For inherited constructors, consider the original declaration;
886 it has the correct template information attached. */
887 d = strip_inheriting_ctors (d);
888
889 if (regenerated_lambda_fn_p (d))
890 {
891 /* If this lambda was regenerated, DECL_TEMPLATE_PARMS doesn't contain
892 all in-scope template parameters, but the lambda from which it was
893 ultimately regenerated does, so use that instead. */
894 tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (d));
895 lambda = most_general_lambda (lambda);
896 d = lambda_function (lambda);
897 }
898
899 if (TREE_CODE (d) == TEMPLATE_DECL)
900 {
901 tmpl = d;
902 decl = DECL_TEMPLATE_RESULT (tmpl);
903 }
904 else
905 {
906 if (tree ti = DECL_TEMPLATE_INFO (d))
907 tmpl = TI_TEMPLATE (ti);
908 else
909 tmpl = NULL_TREE;
910 decl = d;
911 }
912
913 /* Get the most general template for the declaration, and compute
914 arguments from that. This ensures that the arguments used for
915 normalization are always template parameters and not arguments
916 used for outer specializations. For example:
917
918 template<typename T>
919 struct S {
920 template<typename U> requires C<T, U> void f(U);
921 };
922
923 S<int>::f(0);
924
925 When we normalize the requirements for S<int>::f, we want the
926 arguments to be {T, U}, not {int, U}. One reason for this is that
927 accepting the latter causes the template parameter level of U
928 to be reduced in a way that makes it overly difficult substitute
929 concrete arguments (i.e., eventually {int, int} during satisfaction. */
930 if (tmpl)
931 {
932 if (DECL_LANG_SPECIFIC(tmpl) && !DECL_TEMPLATE_SPECIALIZATION (tmpl))
933 tmpl = most_general_template (tmpl);
934 }
935
936 d = tmpl ? tmpl : decl;
937
938 /* If we're not diagnosing errors, use cached constraints, if any. */
939 if (!diag)
940 if (tree *p = hash_map_safe_get (normalized_map, d))
941 return *p;
942
943 tree norm = NULL_TREE;
944 if (tree ci = get_constraints (d))
945 {
946 push_nested_class_guard pncs (DECL_CONTEXT (d));
947
948 temp_override<tree> ovr (current_function_decl);
949 if (TREE_CODE (decl) == FUNCTION_DECL)
950 current_function_decl = decl;
951
952 norm = get_normalized_constraints_from_info (ci, tmpl, diag);
953 }
954
955 if (!diag)
956 hash_map_safe_put<hm_ggc> (normalized_map, d, norm);
957
958 return norm;
959 }
960
961 /* Returns the normal form of TMPL's definition. */
962
963 static tree
normalize_concept_definition(tree tmpl,bool diag=false)964 normalize_concept_definition (tree tmpl, bool diag = false)
965 {
966 if (!diag)
967 if (tree *p = hash_map_safe_get (normalized_map, tmpl))
968 return *p;
969
970 gcc_assert (concept_definition_p (tmpl));
971 if (OVL_P (tmpl))
972 tmpl = OVL_FIRST (tmpl);
973 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
974 tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
975 ++processing_template_decl;
976 norm_info info (tmpl, diag ? tf_norm : tf_none);
977 tree norm = get_normalized_constraints (def, info);
978 --processing_template_decl;
979
980 if (!diag)
981 hash_map_safe_put<hm_ggc> (normalized_map, tmpl, norm);
982
983 return norm;
984 }
985
986 /* Normalize an EXPR as a constraint. */
987
988 static tree
normalize_constraint_expression(tree expr,norm_info info)989 normalize_constraint_expression (tree expr, norm_info info)
990 {
991 if (!expr || expr == error_mark_node)
992 return expr;
993
994 if (!info.generate_diagnostics ())
995 if (tree *p = hash_map_safe_get (normalized_map, expr))
996 return *p;
997
998 ++processing_template_decl;
999 tree norm = get_normalized_constraints (expr, info);
1000 --processing_template_decl;
1001
1002 if (!info.generate_diagnostics ())
1003 hash_map_safe_put<hm_ggc> (normalized_map, expr, norm);
1004
1005 return norm;
1006 }
1007
1008 /* 17.4.1.2p2. Two constraints are identical if they are formed
1009 from the same expression and the targets of the parameter mapping
1010 are equivalent. */
1011
1012 bool
atomic_constraints_identical_p(tree t1,tree t2)1013 atomic_constraints_identical_p (tree t1, tree t2)
1014 {
1015 gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR);
1016 gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR);
1017
1018 if (ATOMIC_CONSTR_EXPR (t1) != ATOMIC_CONSTR_EXPR (t2))
1019 return false;
1020
1021 if (!parameter_mapping_equivalent_p (t1, t2))
1022 return false;
1023
1024 return true;
1025 }
1026
1027 /* True if T1 and T2 are equivalent, meaning they have the same syntactic
1028 structure and all corresponding constraints are identical. */
1029
1030 bool
constraints_equivalent_p(tree t1,tree t2)1031 constraints_equivalent_p (tree t1, tree t2)
1032 {
1033 gcc_assert (CONSTR_P (t1));
1034 gcc_assert (CONSTR_P (t2));
1035
1036 if (TREE_CODE (t1) != TREE_CODE (t2))
1037 return false;
1038
1039 switch (TREE_CODE (t1))
1040 {
1041 case CONJ_CONSTR:
1042 case DISJ_CONSTR:
1043 if (!constraints_equivalent_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
1044 return false;
1045 if (!constraints_equivalent_p (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)))
1046 return false;
1047 break;
1048 case ATOMIC_CONSTR:
1049 if (!atomic_constraints_identical_p(t1, t2))
1050 return false;
1051 break;
1052 default:
1053 gcc_unreachable ();
1054 }
1055 return true;
1056 }
1057
1058 /* Compute the hash value for T. */
1059
1060 hashval_t
hash_atomic_constraint(tree t)1061 hash_atomic_constraint (tree t)
1062 {
1063 gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);
1064
1065 /* Hash the identity of the expression. */
1066 hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t));
1067
1068 /* Hash the targets of the parameter map. */
1069 tree p = ATOMIC_CONSTR_MAP (t);
1070 while (p)
1071 {
1072 val = iterative_hash_template_arg (TREE_PURPOSE (p), val);
1073 p = TREE_CHAIN (p);
1074 }
1075
1076 return val;
1077 }
1078
1079 namespace inchash
1080 {
1081
1082 static void
add_constraint(tree t,hash & h)1083 add_constraint (tree t, hash& h)
1084 {
1085 h.add_int(TREE_CODE (t));
1086 switch (TREE_CODE (t))
1087 {
1088 case CONJ_CONSTR:
1089 case DISJ_CONSTR:
1090 add_constraint (TREE_OPERAND (t, 0), h);
1091 add_constraint (TREE_OPERAND (t, 1), h);
1092 break;
1093 case ATOMIC_CONSTR:
1094 h.merge_hash (hash_atomic_constraint (t));
1095 break;
1096 default:
1097 gcc_unreachable ();
1098 }
1099 }
1100
1101 }
1102
1103 /* Computes a hash code for the constraint T. */
1104
1105 hashval_t
iterative_hash_constraint(tree t,hashval_t val)1106 iterative_hash_constraint (tree t, hashval_t val)
1107 {
1108 gcc_assert (CONSTR_P (t));
1109 inchash::hash h (val);
1110 inchash::add_constraint (t, h);
1111 return h.end ();
1112 }
1113
1114 // -------------------------------------------------------------------------- //
1115 // Constraint Semantic Processing
1116 //
1117 // The following functions are called by the parser and substitution rules
1118 // to create and evaluate constraint-related nodes.
1119
1120 // The constraints associated with the current template parameters.
1121 tree
current_template_constraints(void)1122 current_template_constraints (void)
1123 {
1124 if (!current_template_parms)
1125 return NULL_TREE;
1126 tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
1127 return build_constraints (tmpl_constr, NULL_TREE);
1128 }
1129
1130 /* If the recently parsed TYPE declares or defines a template or
1131 template specialization, get its corresponding constraints from the
1132 current template parameters and bind them to TYPE's declaration. */
1133
1134 tree
associate_classtype_constraints(tree type)1135 associate_classtype_constraints (tree type)
1136 {
1137 if (!type || type == error_mark_node || !CLASS_TYPE_P (type))
1138 return type;
1139
1140 /* An explicit class template specialization has no template parameters. */
1141 if (!current_template_parms)
1142 return type;
1143
1144 if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
1145 {
1146 tree decl = TYPE_STUB_DECL (type);
1147 tree ci = current_template_constraints ();
1148
1149 /* An implicitly instantiated member template declaration already
1150 has associated constraints. If it is defined outside of its
1151 class, then we need match these constraints against those of
1152 original declaration. */
1153 if (tree orig_ci = get_constraints (decl))
1154 {
1155 if (int extra_levels = (TMPL_PARMS_DEPTH (current_template_parms)
1156 - TMPL_ARGS_DEPTH (TYPE_TI_ARGS (type))))
1157 {
1158 /* If there is a discrepancy between the current template depth
1159 and the template depth of the original declaration, then we
1160 must be redeclaring a class template as part of a friend
1161 declaration within another class template. Before matching
1162 constraints, we need to reduce the template parameter level
1163 within the current constraints via substitution. */
1164 tree outer_gtargs = template_parms_to_args (current_template_parms);
1165 TREE_VEC_LENGTH (outer_gtargs) = extra_levels;
1166 ci = tsubst_constraint_info (ci, outer_gtargs, tf_none, NULL_TREE);
1167 }
1168 if (!equivalent_constraints (ci, orig_ci))
1169 {
1170 error ("%qT does not match original declaration", type);
1171 tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
1172 location_t loc = DECL_SOURCE_LOCATION (tmpl);
1173 inform (loc, "original template declaration here");
1174 /* Fall through, so that we define the type anyway. */
1175 }
1176 return type;
1177 }
1178 set_constraints (decl, ci);
1179 }
1180 return type;
1181 }
1182
1183 /* Create an empty constraint info block. */
1184
1185 static inline tree_constraint_info*
build_constraint_info()1186 build_constraint_info ()
1187 {
1188 return (tree_constraint_info *)make_node (CONSTRAINT_INFO);
1189 }
1190
1191 /* Build a constraint-info object that contains the associated constraints
1192 of a declaration. This also includes the declaration's template
1193 requirements (TREQS) and any trailing requirements for a function
1194 declarator (DREQS). Note that both TREQS and DREQS must be constraints.
1195
1196 If the declaration has neither template nor declaration requirements
1197 this returns NULL_TREE, indicating an unconstrained declaration. */
1198
1199 tree
build_constraints(tree tr,tree dr)1200 build_constraints (tree tr, tree dr)
1201 {
1202 if (!tr && !dr)
1203 return NULL_TREE;
1204
1205 tree_constraint_info* ci = build_constraint_info ();
1206 ci->template_reqs = tr;
1207 ci->declarator_reqs = dr;
1208 ci->associated_constr = combine_constraint_expressions (tr, dr);
1209
1210 return (tree)ci;
1211 }
1212
1213 /* Add constraint RHS to the end of CONSTRAINT_INFO ci. */
1214
1215 tree
append_constraint(tree ci,tree rhs)1216 append_constraint (tree ci, tree rhs)
1217 {
1218 tree tr = ci ? CI_TEMPLATE_REQS (ci) : NULL_TREE;
1219 tree dr = ci ? CI_DECLARATOR_REQS (ci) : NULL_TREE;
1220 dr = combine_constraint_expressions (dr, rhs);
1221 if (ci)
1222 {
1223 CI_DECLARATOR_REQS (ci) = dr;
1224 tree ac = combine_constraint_expressions (tr, dr);
1225 CI_ASSOCIATED_CONSTRAINTS (ci) = ac;
1226 }
1227 else
1228 ci = build_constraints (tr, dr);
1229 return ci;
1230 }
1231
1232 /* A mapping from declarations to constraint information. */
1233
1234 static GTY ((cache)) decl_tree_cache_map *decl_constraints;
1235
1236 /* Returns the template constraints of declaration T. If T is not
1237 constrained, return NULL_TREE. Note that T must be non-null. */
1238
1239 tree
get_constraints(const_tree t)1240 get_constraints (const_tree t)
1241 {
1242 if (!flag_concepts)
1243 return NULL_TREE;
1244 if (!decl_constraints)
1245 return NULL_TREE;
1246
1247 gcc_assert (DECL_P (t));
1248 if (TREE_CODE (t) == TEMPLATE_DECL)
1249 t = DECL_TEMPLATE_RESULT (t);
1250 tree* found = decl_constraints->get (CONST_CAST_TREE (t));
1251 if (found)
1252 return *found;
1253 else
1254 return NULL_TREE;
1255 }
1256
1257 /* Associate the given constraint information CI with the declaration
1258 T. If T is a template, then the constraints are associated with
1259 its underlying declaration. Don't build associations if CI is
1260 NULL_TREE. */
1261
1262 void
set_constraints(tree t,tree ci)1263 set_constraints (tree t, tree ci)
1264 {
1265 if (!ci)
1266 return;
1267 gcc_assert (t && flag_concepts);
1268 if (TREE_CODE (t) == TEMPLATE_DECL)
1269 t = DECL_TEMPLATE_RESULT (t);
1270 bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
1271 gcc_assert (!found);
1272 }
1273
1274 /* Remove the associated constraints of the declaration T. */
1275
1276 void
remove_constraints(tree t)1277 remove_constraints (tree t)
1278 {
1279 gcc_checking_assert (DECL_P (t));
1280 if (TREE_CODE (t) == TEMPLATE_DECL)
1281 t = DECL_TEMPLATE_RESULT (t);
1282
1283 if (decl_constraints)
1284 decl_constraints->remove (t);
1285 }
1286
1287 /* If DECL is a friend, substitute into REQS to produce requirements suitable
1288 for declaration matching. */
1289
1290 tree
maybe_substitute_reqs_for(tree reqs,const_tree decl_)1291 maybe_substitute_reqs_for (tree reqs, const_tree decl_)
1292 {
1293 if (reqs == NULL_TREE)
1294 return NULL_TREE;
1295
1296 tree decl = CONST_CAST_TREE (decl_);
1297 tree result = STRIP_TEMPLATE (decl);
1298
1299 if (DECL_UNIQUE_FRIEND_P (result))
1300 {
1301 tree tmpl = decl;
1302 if (TREE_CODE (decl) != TEMPLATE_DECL)
1303 tmpl = DECL_TI_TEMPLATE (result);
1304
1305 tree gargs = generic_targs_for (tmpl);
1306 processing_template_decl_sentinel s;
1307 if (uses_template_parms (gargs))
1308 ++processing_template_decl;
1309 reqs = tsubst_constraint (reqs, gargs,
1310 tf_warning_or_error, NULL_TREE);
1311 }
1312 return reqs;
1313 }
1314
1315 /* Returns the template-head requires clause for the template
1316 declaration T or NULL_TREE if none. */
1317
1318 tree
get_template_head_requirements(tree t)1319 get_template_head_requirements (tree t)
1320 {
1321 tree ci = get_constraints (t);
1322 if (!ci)
1323 return NULL_TREE;
1324 return CI_TEMPLATE_REQS (ci);
1325 }
1326
1327 /* Returns the trailing requires clause of the declarator of
1328 a template declaration T or NULL_TREE if none. */
1329
1330 tree
get_trailing_function_requirements(tree t)1331 get_trailing_function_requirements (tree t)
1332 {
1333 tree ci = get_constraints (t);
1334 if (!ci)
1335 return NULL_TREE;
1336 return CI_DECLARATOR_REQS (ci);
1337 }
1338
1339 /* Construct a sequence of template arguments by prepending
1340 ARG to REST. Either ARG or REST may be null. */
1341 static tree
build_concept_check_arguments(tree arg,tree rest)1342 build_concept_check_arguments (tree arg, tree rest)
1343 {
1344 gcc_assert (rest ? TREE_CODE (rest) == TREE_VEC : true);
1345 tree args;
1346 if (arg)
1347 {
1348 int n = rest ? TREE_VEC_LENGTH (rest) : 0;
1349 args = make_tree_vec (n + 1);
1350 TREE_VEC_ELT (args, 0) = arg;
1351 if (rest)
1352 for (int i = 0; i < n; ++i)
1353 TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i);
1354 int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0;
1355 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
1356 }
1357 else
1358 {
1359 args = rest;
1360 }
1361 return args;
1362 }
1363
1364 /* Builds an id-expression of the form `C<Args...>()` where C is a function
1365 concept. */
1366
1367 static tree
build_function_check(tree tmpl,tree args,tsubst_flags_t)1368 build_function_check (tree tmpl, tree args, tsubst_flags_t /*complain*/)
1369 {
1370 if (TREE_CODE (tmpl) == TEMPLATE_DECL)
1371 {
1372 /* If we just got a template, wrap it in an overload so it looks like any
1373 other template-id. */
1374 tmpl = ovl_make (tmpl);
1375 TREE_TYPE (tmpl) = boolean_type_node;
1376 }
1377
1378 /* Perform function concept resolution now so we always have a single
1379 function of the overload set (even if we started with only one; the
1380 resolution function converts template arguments). Note that we still
1381 wrap this in an overload set so we don't upset other parts of the
1382 compiler that expect template-ids referring to function concepts
1383 to have an overload set. */
1384 tree info = resolve_function_concept_overload (tmpl, args);
1385 if (info == error_mark_node)
1386 return error_mark_node;
1387 if (!info)
1388 {
1389 error ("no matching concepts for %qE", tmpl);
1390 return error_mark_node;
1391 }
1392 args = TREE_PURPOSE (info);
1393 tmpl = DECL_TI_TEMPLATE (TREE_VALUE (info));
1394
1395 /* Rebuild the singleton overload set; mark the type bool. */
1396 tmpl = ovl_make (tmpl, NULL_TREE);
1397 TREE_TYPE (tmpl) = boolean_type_node;
1398
1399 /* Build the id-expression around the overload set. */
1400 tree id = build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
1401
1402 /* Finally, build the call expression around the overload. */
1403 ++processing_template_decl;
1404 vec<tree, va_gc> *fargs = make_tree_vector ();
1405 tree call = build_min_nt_call_vec (id, fargs);
1406 TREE_TYPE (call) = boolean_type_node;
1407 release_tree_vector (fargs);
1408 --processing_template_decl;
1409
1410 return call;
1411 }
1412
1413 /* Builds an id-expression of the form `C<Args...>` where C is a variable
1414 concept. */
1415
1416 static tree
build_variable_check(tree tmpl,tree args,tsubst_flags_t complain)1417 build_variable_check (tree tmpl, tree args, tsubst_flags_t complain)
1418 {
1419 gcc_assert (variable_concept_p (tmpl));
1420 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
1421 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
1422 args = coerce_template_parms (parms, args, tmpl, complain);
1423 if (args == error_mark_node)
1424 return error_mark_node;
1425 return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
1426 }
1427
1428 /* Builds an id-expression of the form `C<Args...>` where C is a standard
1429 concept. */
1430
1431 static tree
build_standard_check(tree tmpl,tree args,tsubst_flags_t complain)1432 build_standard_check (tree tmpl, tree args, tsubst_flags_t complain)
1433 {
1434 gcc_assert (standard_concept_p (tmpl));
1435 gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
1436 tree parms = INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (tmpl));
1437 args = coerce_template_parms (parms, args, tmpl, complain);
1438 if (args == error_mark_node)
1439 return error_mark_node;
1440 return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
1441 }
1442
1443 /* Construct an expression that checks TARGET using ARGS. */
1444
1445 tree
build_concept_check(tree target,tree args,tsubst_flags_t complain)1446 build_concept_check (tree target, tree args, tsubst_flags_t complain)
1447 {
1448 return build_concept_check (target, NULL_TREE, args, complain);
1449 }
1450
1451 /* Construct an expression that checks the concept given by DECL. If
1452 concept_definition_p (DECL) is false, this returns null. */
1453
1454 tree
build_concept_check(tree decl,tree arg,tree rest,tsubst_flags_t complain)1455 build_concept_check (tree decl, tree arg, tree rest, tsubst_flags_t complain)
1456 {
1457 tree args = build_concept_check_arguments (arg, rest);
1458
1459 if (standard_concept_p (decl))
1460 return build_standard_check (decl, args, complain);
1461 if (variable_concept_p (decl))
1462 return build_variable_check (decl, args, complain);
1463 if (function_concept_p (decl))
1464 return build_function_check (decl, args, complain);
1465
1466 return error_mark_node;
1467 }
1468
1469 /* Build a template-id that can participate in a concept check. */
1470
1471 static tree
build_concept_id(tree decl,tree args)1472 build_concept_id (tree decl, tree args)
1473 {
1474 tree check = build_concept_check (decl, args, tf_warning_or_error);
1475 if (check == error_mark_node)
1476 return error_mark_node;
1477 return unpack_concept_check (check);
1478 }
1479
1480 /* Build a template-id that can participate in a concept check, preserving
1481 the source location of the original template-id. */
1482
1483 tree
build_concept_id(tree expr)1484 build_concept_id (tree expr)
1485 {
1486 gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR);
1487 tree id = build_concept_id (TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
1488 protected_set_expr_location (id, cp_expr_location (expr));
1489 return id;
1490 }
1491
1492 /* Build as template-id with a placeholder that can be used as a
1493 type constraint.
1494
1495 Note that this will diagnose errors if the initial concept check
1496 cannot be built. */
1497
1498 tree
build_type_constraint(tree decl,tree args,tsubst_flags_t complain)1499 build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
1500 {
1501 tree wildcard = build_nt (WILDCARD_DECL);
1502 ++processing_template_decl;
1503 tree check = build_concept_check (decl, wildcard, args, complain);
1504 --processing_template_decl;
1505 if (check == error_mark_node)
1506 return error_mark_node;
1507 return unpack_concept_check (check);
1508 }
1509
1510 /* Returns a TYPE_DECL that contains sufficient information to
1511 build a template parameter of the same kind as PROTO and
1512 constrained by the concept declaration CNC. Note that PROTO
1513 is the first template parameter of CNC.
1514
1515 If specified, ARGS provides additional arguments to the
1516 constraint check. */
1517 tree
build_constrained_parameter(tree cnc,tree proto,tree args)1518 build_constrained_parameter (tree cnc, tree proto, tree args)
1519 {
1520 tree name = DECL_NAME (cnc);
1521 tree type = TREE_TYPE (proto);
1522 tree decl = build_decl (input_location, TYPE_DECL, name, type);
1523 CONSTRAINED_PARM_PROTOTYPE (decl) = proto;
1524 CONSTRAINED_PARM_CONCEPT (decl) = cnc;
1525 CONSTRAINED_PARM_EXTRA_ARGS (decl) = args;
1526 return decl;
1527 }
1528
1529 /* Create a constraint expression for the given DECL that evaluates the
1530 requirements specified by CONSTR, a TYPE_DECL that contains all the
1531 information necessary to build the requirements (see finish_concept_name
1532 for the layout of that TYPE_DECL).
1533
1534 Note that the constraints are neither reduced nor decomposed. That is
1535 done only after the requires clause has been parsed (or not). */
1536
1537 tree
finish_shorthand_constraint(tree decl,tree constr)1538 finish_shorthand_constraint (tree decl, tree constr)
1539 {
1540 /* No requirements means no constraints. */
1541 if (!constr)
1542 return NULL_TREE;
1543
1544 if (error_operand_p (constr))
1545 return NULL_TREE;
1546
1547 tree proto = CONSTRAINED_PARM_PROTOTYPE (constr);
1548 tree con = CONSTRAINED_PARM_CONCEPT (constr);
1549 tree args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
1550
1551 /* The TS lets use shorthand to constrain a pack of arguments, but the
1552 standard does not.
1553
1554 For the TS, consider:
1555
1556 template<C... Ts> struct s;
1557
1558 If C is variadic (and because Ts is a pack), we associate the
1559 constraint C<Ts...>. In all other cases, we associate
1560 the constraint (C<Ts> && ...).
1561
1562 The standard behavior cannot be overridden by -fconcepts-ts. */
1563 bool variadic_concept_p = template_parameter_pack_p (proto);
1564 bool declared_pack_p = template_parameter_pack_p (decl);
1565 bool apply_to_each_p = (cxx_dialect >= cxx20) ? true : !variadic_concept_p;
1566
1567 /* Get the argument and overload used for the requirement
1568 and adjust it if we're going to expand later. */
1569 tree arg = template_parm_to_arg (decl);
1570 if (apply_to_each_p && declared_pack_p)
1571 arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0));
1572
1573 /* Build the concept constraint-expression. */
1574 tree tmpl = DECL_TI_TEMPLATE (con);
1575 tree check = tmpl;
1576 if (TREE_CODE (con) == FUNCTION_DECL)
1577 check = ovl_make (tmpl);
1578 check = build_concept_check (check, arg, args, tf_warning_or_error);
1579
1580 /* Make the check a fold-expression if needed. */
1581 if (apply_to_each_p && declared_pack_p)
1582 check = finish_left_unary_fold_expr (check, TRUTH_ANDIF_EXPR);
1583
1584 return check;
1585 }
1586
1587 /* Returns a conjunction of shorthand requirements for the template
1588 parameter list PARMS. Note that the requirements are stored in
1589 the TYPE of each tree node. */
1590
1591 tree
get_shorthand_constraints(tree parms)1592 get_shorthand_constraints (tree parms)
1593 {
1594 tree result = NULL_TREE;
1595 parms = INNERMOST_TEMPLATE_PARMS (parms);
1596 for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
1597 {
1598 tree parm = TREE_VEC_ELT (parms, i);
1599 tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
1600 result = combine_constraint_expressions (result, constr);
1601 }
1602 return result;
1603 }
1604
1605 /* Get the deduced wildcard from a DEDUCED placeholder. If the deduced
1606 wildcard is a pack, return the first argument of that pack. */
1607
1608 static tree
get_deduced_wildcard(tree wildcard)1609 get_deduced_wildcard (tree wildcard)
1610 {
1611 if (ARGUMENT_PACK_P (wildcard))
1612 wildcard = TREE_VEC_ELT (ARGUMENT_PACK_ARGS (wildcard), 0);
1613 gcc_assert (TREE_CODE (wildcard) == WILDCARD_DECL);
1614 return wildcard;
1615 }
1616
1617 /* Returns the prototype parameter for the nth deduced wildcard. */
1618
1619 static tree
get_introduction_prototype(tree wildcards,int index)1620 get_introduction_prototype (tree wildcards, int index)
1621 {
1622 return TREE_TYPE (get_deduced_wildcard (TREE_VEC_ELT (wildcards, index)));
1623 }
1624
1625 /* Introduce a type template parameter. */
1626
1627 static tree
introduce_type_template_parameter(tree wildcard,bool & non_type_p)1628 introduce_type_template_parameter (tree wildcard, bool& non_type_p)
1629 {
1630 non_type_p = false;
1631 return finish_template_type_parm (class_type_node, DECL_NAME (wildcard));
1632 }
1633
1634 /* Introduce a template template parameter. */
1635
1636 static tree
introduce_template_template_parameter(tree wildcard,bool & non_type_p)1637 introduce_template_template_parameter (tree wildcard, bool& non_type_p)
1638 {
1639 non_type_p = false;
1640 begin_template_parm_list ();
1641 current_template_parms = DECL_TEMPLATE_PARMS (TREE_TYPE (wildcard));
1642 end_template_parm_list ();
1643 return finish_template_template_parm (class_type_node, DECL_NAME (wildcard));
1644 }
1645
1646 /* Introduce a template non-type parameter. */
1647
1648 static tree
introduce_nontype_template_parameter(tree wildcard,bool & non_type_p)1649 introduce_nontype_template_parameter (tree wildcard, bool& non_type_p)
1650 {
1651 non_type_p = true;
1652 tree parm = copy_decl (TREE_TYPE (wildcard));
1653 DECL_NAME (parm) = DECL_NAME (wildcard);
1654 return parm;
1655 }
1656
1657 /* Introduce a single template parameter. */
1658
1659 static tree
build_introduced_template_parameter(tree wildcard,bool & non_type_p)1660 build_introduced_template_parameter (tree wildcard, bool& non_type_p)
1661 {
1662 tree proto = TREE_TYPE (wildcard);
1663
1664 tree parm;
1665 if (TREE_CODE (proto) == TYPE_DECL)
1666 parm = introduce_type_template_parameter (wildcard, non_type_p);
1667 else if (TREE_CODE (proto) == TEMPLATE_DECL)
1668 parm = introduce_template_template_parameter (wildcard, non_type_p);
1669 else
1670 parm = introduce_nontype_template_parameter (wildcard, non_type_p);
1671
1672 /* Wrap in a TREE_LIST for process_template_parm. Note that introduced
1673 parameters do not retain the defaults from the source parameter. */
1674 return build_tree_list (NULL_TREE, parm);
1675 }
1676
1677 /* Introduce a single template parameter. */
1678
1679 static tree
introduce_template_parameter(tree parms,tree wildcard)1680 introduce_template_parameter (tree parms, tree wildcard)
1681 {
1682 gcc_assert (!ARGUMENT_PACK_P (wildcard));
1683 tree proto = TREE_TYPE (wildcard);
1684 location_t loc = DECL_SOURCE_LOCATION (wildcard);
1685
1686 /* Diagnose the case where we have C{...Args}. */
1687 if (WILDCARD_PACK_P (wildcard))
1688 {
1689 tree id = DECL_NAME (wildcard);
1690 error_at (loc, "%qE cannot be introduced with an ellipsis %<...%>", id);
1691 inform (DECL_SOURCE_LOCATION (proto), "prototype declared here");
1692 }
1693
1694 bool non_type_p;
1695 tree parm = build_introduced_template_parameter (wildcard, non_type_p);
1696 return process_template_parm (parms, loc, parm, non_type_p, false);
1697 }
1698
1699 /* Introduce a template parameter pack. */
1700
1701 static tree
introduce_template_parameter_pack(tree parms,tree wildcard)1702 introduce_template_parameter_pack (tree parms, tree wildcard)
1703 {
1704 bool non_type_p;
1705 tree parm = build_introduced_template_parameter (wildcard, non_type_p);
1706 location_t loc = DECL_SOURCE_LOCATION (wildcard);
1707 return process_template_parm (parms, loc, parm, non_type_p, true);
1708 }
1709
1710 /* Introduce the nth template parameter. */
1711
1712 static tree
introduce_template_parameter(tree parms,tree wildcards,int & index)1713 introduce_template_parameter (tree parms, tree wildcards, int& index)
1714 {
1715 tree deduced = TREE_VEC_ELT (wildcards, index++);
1716 return introduce_template_parameter (parms, deduced);
1717 }
1718
1719 /* Introduce either a template parameter pack or a list of template
1720 parameters. */
1721
1722 static tree
introduce_template_parameters(tree parms,tree wildcards,int & index)1723 introduce_template_parameters (tree parms, tree wildcards, int& index)
1724 {
1725 /* If the prototype was a parameter, we better have deduced an
1726 argument pack, and that argument must be the last deduced value
1727 in the wildcard vector. */
1728 tree deduced = TREE_VEC_ELT (wildcards, index++);
1729 gcc_assert (ARGUMENT_PACK_P (deduced));
1730 gcc_assert (index == TREE_VEC_LENGTH (wildcards));
1731
1732 /* Introduce each element in the pack. */
1733 tree args = ARGUMENT_PACK_ARGS (deduced);
1734 for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
1735 {
1736 tree arg = TREE_VEC_ELT (args, i);
1737 if (WILDCARD_PACK_P (arg))
1738 parms = introduce_template_parameter_pack (parms, arg);
1739 else
1740 parms = introduce_template_parameter (parms, arg);
1741 }
1742
1743 return parms;
1744 }
1745
1746 /* Builds the template parameter list PARMS by chaining introduced
1747 parameters from the WILDCARD vector. INDEX is the position of
1748 the current parameter. */
1749
1750 static tree
process_introduction_parms(tree parms,tree wildcards,int & index)1751 process_introduction_parms (tree parms, tree wildcards, int& index)
1752 {
1753 tree proto = get_introduction_prototype (wildcards, index);
1754 if (template_parameter_pack_p (proto))
1755 return introduce_template_parameters (parms, wildcards, index);
1756 else
1757 return introduce_template_parameter (parms, wildcards, index);
1758 }
1759
1760 /* Ensure that all template parameters have been introduced for the concept
1761 named in CHECK. If not, emit a diagnostic.
1762
1763 Note that implicitly introducing a parameter with a default argument
1764 creates a case where a parameter is declared, but unnamed, making
1765 it unusable in the definition. */
1766
1767 static bool
check_introduction_list(tree intros,tree check)1768 check_introduction_list (tree intros, tree check)
1769 {
1770 check = unpack_concept_check (check);
1771 tree tmpl = TREE_OPERAND (check, 0);
1772 if (OVL_P (tmpl))
1773 tmpl = OVL_FIRST (tmpl);
1774
1775 tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
1776 if (TREE_VEC_LENGTH (intros) < TREE_VEC_LENGTH (parms))
1777 {
1778 error_at (input_location, "all template parameters of %qD must "
1779 "be introduced", tmpl);
1780 return false;
1781 }
1782
1783 return true;
1784 }
1785
1786 /* Associates a constraint check to the current template based on the
1787 introduction parameters. INTRO_LIST must be a TREE_VEC of WILDCARD_DECLs
1788 containing a chained PARM_DECL which contains the identifier as well as
1789 the source location. TMPL_DECL is the decl for the concept being used.
1790 If we take a concept, C, this will form a check in the form of
1791 C<INTRO_LIST> filling in any extra arguments needed by the defaults
1792 deduced.
1793
1794 Returns NULL_TREE if no concept could be matched and error_mark_node if
1795 an error occurred when matching. */
1796
1797 tree
finish_template_introduction(tree tmpl_decl,tree intro_list,location_t intro_loc)1798 finish_template_introduction (tree tmpl_decl,
1799 tree intro_list,
1800 location_t intro_loc)
1801 {
1802 /* Build a concept check to deduce the actual parameters. */
1803 tree expr = build_concept_check (tmpl_decl, intro_list, tf_none);
1804 if (expr == error_mark_node)
1805 {
1806 error_at (intro_loc, "cannot deduce template parameters from "
1807 "introduction list");
1808 return error_mark_node;
1809 }
1810
1811 if (!check_introduction_list (intro_list, expr))
1812 return error_mark_node;
1813
1814 tree parms = deduce_concept_introduction (expr);
1815 if (!parms)
1816 return NULL_TREE;
1817
1818 /* Build template parameter scope for introduction. */
1819 tree parm_list = NULL_TREE;
1820 begin_template_parm_list ();
1821 int nargs = MIN (TREE_VEC_LENGTH (parms), TREE_VEC_LENGTH (intro_list));
1822 for (int n = 0; n < nargs; )
1823 parm_list = process_introduction_parms (parm_list, parms, n);
1824 parm_list = end_template_parm_list (parm_list);
1825
1826 /* Update the number of arguments to reflect the number of deduced
1827 template parameter introductions. */
1828 nargs = TREE_VEC_LENGTH (parm_list);
1829
1830 /* Determine if any errors occurred during matching. */
1831 for (int i = 0; i < TREE_VEC_LENGTH (parm_list); ++i)
1832 if (TREE_VALUE (TREE_VEC_ELT (parm_list, i)) == error_mark_node)
1833 {
1834 end_template_decl ();
1835 return error_mark_node;
1836 }
1837
1838 /* Build a concept check for our constraint. */
1839 tree check_args = make_tree_vec (nargs);
1840 int n = 0;
1841 for (; n < TREE_VEC_LENGTH (parm_list); ++n)
1842 {
1843 tree parm = TREE_VEC_ELT (parm_list, n);
1844 TREE_VEC_ELT (check_args, n) = template_parm_to_arg (parm);
1845 }
1846 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (check_args, n);
1847
1848 /* If the template expects more parameters we should be able
1849 to use the defaults from our deduced concept. */
1850 for (; n < TREE_VEC_LENGTH (parms); ++n)
1851 TREE_VEC_ELT (check_args, n) = TREE_VEC_ELT (parms, n);
1852
1853 /* Associate the constraint. */
1854 tree check = build_concept_check (tmpl_decl,
1855 check_args,
1856 tf_warning_or_error);
1857 TEMPLATE_PARMS_CONSTRAINTS (current_template_parms) = check;
1858
1859 return parm_list;
1860 }
1861
1862
1863 /* Given the concept check T from a constrained-type-specifier, extract
1864 its TMPL and ARGS. FIXME why do we need two different forms of
1865 constrained-type-specifier? */
1866
1867 void
placeholder_extract_concept_and_args(tree t,tree & tmpl,tree & args)1868 placeholder_extract_concept_and_args (tree t, tree &tmpl, tree &args)
1869 {
1870 if (concept_check_p (t))
1871 {
1872 t = unpack_concept_check (t);
1873 tmpl = TREE_OPERAND (t, 0);
1874 if (TREE_CODE (tmpl) == OVERLOAD)
1875 tmpl = OVL_FIRST (tmpl);
1876 args = TREE_OPERAND (t, 1);
1877 return;
1878 }
1879
1880 if (TREE_CODE (t) == TYPE_DECL)
1881 {
1882 /* A constrained parameter. Build a constraint check
1883 based on the prototype parameter and then extract the
1884 arguments from that. */
1885 tree proto = CONSTRAINED_PARM_PROTOTYPE (t);
1886 tree check = finish_shorthand_constraint (proto, t);
1887 placeholder_extract_concept_and_args (check, tmpl, args);
1888 return;
1889 }
1890 }
1891
1892 /* Returns true iff the placeholders C1 and C2 are equivalent. C1
1893 and C2 can be either TEMPLATE_TYPE_PARM or template-ids. */
1894
1895 bool
equivalent_placeholder_constraints(tree c1,tree c2)1896 equivalent_placeholder_constraints (tree c1, tree c2)
1897 {
1898 if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
1899 /* A constrained auto. */
1900 c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
1901 if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
1902 c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);
1903
1904 if (c1 == c2)
1905 return true;
1906 if (!c1 || !c2)
1907 return false;
1908 if (c1 == error_mark_node || c2 == error_mark_node)
1909 /* We get here during satisfaction; when a deduction constraint
1910 fails, substitution can produce an error_mark_node for the
1911 placeholder constraints. */
1912 return false;
1913
1914 tree t1, t2, a1, a2;
1915 placeholder_extract_concept_and_args (c1, t1, a1);
1916 placeholder_extract_concept_and_args (c2, t2, a2);
1917
1918 if (t1 != t2)
1919 return false;
1920
1921 int len1 = TREE_VEC_LENGTH (a1);
1922 int len2 = TREE_VEC_LENGTH (a2);
1923 if (len1 != len2)
1924 return false;
1925
1926 /* Skip the first argument so we don't infinitely recurse.
1927 Also, they may differ in template parameter index. */
1928 for (int i = 1; i < len1; ++i)
1929 {
1930 tree t1 = TREE_VEC_ELT (a1, i);
1931 tree t2 = TREE_VEC_ELT (a2, i);
1932 if (!template_args_equal (t1, t2))
1933 return false;
1934 }
1935 return true;
1936 }
1937
1938 /* Return a hash value for the placeholder ATOMIC_CONSTR C. */
1939
1940 hashval_t
hash_placeholder_constraint(tree c)1941 hash_placeholder_constraint (tree c)
1942 {
1943 tree t, a;
1944 placeholder_extract_concept_and_args (c, t, a);
1945
1946 /* Like hash_tmpl_and_args, but skip the first argument. */
1947 hashval_t val = iterative_hash_object (DECL_UID (t), 0);
1948
1949 for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
1950 val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
1951
1952 return val;
1953 }
1954
1955 /* Substitute through the expression of a simple requirement or
1956 compound requirement. */
1957
1958 static tree
tsubst_valid_expression_requirement(tree t,tree args,sat_info info)1959 tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
1960 {
1961 tree r = tsubst_expr (t, args, tf_none, info.in_decl, false);
1962 if (convert_to_void (r, ICV_STATEMENT, tf_none) != error_mark_node)
1963 return r;
1964
1965 if (info.diagnose_unsatisfaction_p ())
1966 {
1967 location_t loc = cp_expr_loc_or_input_loc (t);
1968 if (diagnosing_failed_constraint::replay_errors_p ())
1969 {
1970 inform (loc, "the required expression %qE is invalid, because", t);
1971 if (r == error_mark_node)
1972 tsubst_expr (t, args, info.complain, info.in_decl, false);
1973 else
1974 convert_to_void (r, ICV_STATEMENT, info.complain);
1975 }
1976 else
1977 inform (loc, "the required expression %qE is invalid", t);
1978 }
1979 else if (info.noisy ())
1980 {
1981 r = tsubst_expr (t, args, info.complain, info.in_decl, false);
1982 convert_to_void (r, ICV_STATEMENT, info.complain);
1983 }
1984
1985 return error_mark_node;
1986 }
1987
1988
1989 /* Substitute through the simple requirement. */
1990
1991 static tree
tsubst_simple_requirement(tree t,tree args,sat_info info)1992 tsubst_simple_requirement (tree t, tree args, sat_info info)
1993 {
1994 tree t0 = TREE_OPERAND (t, 0);
1995 tree expr = tsubst_valid_expression_requirement (t0, args, info);
1996 if (expr == error_mark_node)
1997 return error_mark_node;
1998 return boolean_true_node;
1999 }
2000
2001 /* Subroutine of tsubst_type_requirement that performs the actual substitution
2002 and diagnosing. Also used by tsubst_compound_requirement. */
2003
2004 static tree
tsubst_type_requirement_1(tree t,tree args,sat_info info,location_t loc)2005 tsubst_type_requirement_1 (tree t, tree args, sat_info info, location_t loc)
2006 {
2007 tree r = tsubst (t, args, tf_none, info.in_decl);
2008 if (r != error_mark_node)
2009 return r;
2010
2011 if (info.diagnose_unsatisfaction_p ())
2012 {
2013 if (diagnosing_failed_constraint::replay_errors_p ())
2014 {
2015 /* Replay the substitution error. */
2016 inform (loc, "the required type %qT is invalid, because", t);
2017 tsubst (t, args, info.complain, info.in_decl);
2018 }
2019 else
2020 inform (loc, "the required type %qT is invalid", t);
2021 }
2022 else if (info.noisy ())
2023 tsubst (t, args, info.complain, info.in_decl);
2024
2025 return error_mark_node;
2026 }
2027
2028
2029 /* Substitute through the type requirement. */
2030
2031 static tree
tsubst_type_requirement(tree t,tree args,sat_info info)2032 tsubst_type_requirement (tree t, tree args, sat_info info)
2033 {
2034 tree t0 = TREE_OPERAND (t, 0);
2035 tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t));
2036 if (type == error_mark_node)
2037 return error_mark_node;
2038 return boolean_true_node;
2039 }
2040
2041 /* True if TYPE can be deduced from EXPR. */
2042
2043 static bool
type_deducible_p(tree expr,tree type,tree placeholder,tree args,subst_info info)2044 type_deducible_p (tree expr, tree type, tree placeholder, tree args,
2045 subst_info info)
2046 {
2047 /* Make sure deduction is performed against ( EXPR ), so that
2048 references are preserved in the result. */
2049 expr = force_paren_expr_uneval (expr);
2050
2051 /* When args is NULL, we're evaluating a non-templated requires expression,
2052 but even those are parsed under processing_template_decl == 1, and so the
2053 placeholder 'auto' inside this return-type-requirement has level 2. In
2054 order to have all parms and arguments match up for satisfaction, we need
2055 to pass an empty level of OUTER_TARGS in this case. */
2056 if (!args)
2057 args = make_tree_vec (0);
2058
2059 tree deduced_type = do_auto_deduction (type, expr, placeholder,
2060 info.complain, adc_requirement,
2061 /*outer_targs=*/args);
2062
2063 return deduced_type != error_mark_node;
2064 }
2065
2066 /* True if EXPR can not be converted to TYPE. */
2067
2068 static bool
expression_convertible_p(tree expr,tree type,subst_info info)2069 expression_convertible_p (tree expr, tree type, subst_info info)
2070 {
2071 tree conv =
2072 perform_direct_initialization_if_possible (type, expr, false,
2073 info.complain);
2074 if (conv == error_mark_node)
2075 return false;
2076 if (conv == NULL_TREE)
2077 {
2078 if (info.complain & tf_error)
2079 {
2080 location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
2081 error_at (loc, "cannot convert %qE to %qT", expr, type);
2082 }
2083 return false;
2084 }
2085 return true;
2086 }
2087
2088
2089 /* Substitute through the compound requirement. */
2090
2091 static tree
tsubst_compound_requirement(tree t,tree args,sat_info info)2092 tsubst_compound_requirement (tree t, tree args, sat_info info)
2093 {
2094 tree t0 = TREE_OPERAND (t, 0);
2095 tree t1 = TREE_OPERAND (t, 1);
2096 tree expr = tsubst_valid_expression_requirement (t0, args, info);
2097 if (expr == error_mark_node)
2098 return error_mark_node;
2099
2100 location_t loc = cp_expr_loc_or_input_loc (expr);
2101
2102 /* Check the noexcept condition. */
2103 bool noexcept_p = COMPOUND_REQ_NOEXCEPT_P (t);
2104 if (noexcept_p && !expr_noexcept_p (expr, tf_none))
2105 {
2106 if (info.diagnose_unsatisfaction_p ())
2107 inform (loc, "%qE is not %<noexcept%>", expr);
2108 else
2109 return error_mark_node;
2110 }
2111
2112 /* Substitute through the type expression, if any. */
2113 tree type = tsubst_type_requirement_1 (t1, args, info, EXPR_LOCATION (t));
2114 if (type == error_mark_node)
2115 return error_mark_node;
2116
2117 subst_info quiet (tf_none, info.in_decl);
2118
2119 /* Check expression against the result type. */
2120 if (type)
2121 {
2122 if (tree placeholder = type_uses_auto (type))
2123 {
2124 if (!type_deducible_p (expr, type, placeholder, args, quiet))
2125 {
2126 if (info.diagnose_unsatisfaction_p ())
2127 {
2128 if (diagnosing_failed_constraint::replay_errors_p ())
2129 {
2130 inform (loc,
2131 "%qE does not satisfy return-type-requirement, "
2132 "because", t0);
2133 /* Further explain the reason for the error. */
2134 type_deducible_p (expr, type, placeholder, args, info);
2135 }
2136 else
2137 inform (loc,
2138 "%qE does not satisfy return-type-requirement", t0);
2139 }
2140 return error_mark_node;
2141 }
2142 }
2143 else if (!expression_convertible_p (expr, type, quiet))
2144 {
2145 if (info.diagnose_unsatisfaction_p ())
2146 {
2147 if (diagnosing_failed_constraint::replay_errors_p ())
2148 {
2149 inform (loc, "cannot convert %qE to %qT because", t0, type);
2150 /* Further explain the reason for the error. */
2151 expression_convertible_p (expr, type, info);
2152 }
2153 else
2154 inform (loc, "cannot convert %qE to %qT", t0, type);
2155 }
2156 return error_mark_node;
2157 }
2158 }
2159
2160 return boolean_true_node;
2161 }
2162
2163 /* Substitute through the nested requirement. */
2164
2165 static tree
tsubst_nested_requirement(tree t,tree args,sat_info info)2166 tsubst_nested_requirement (tree t, tree args, sat_info info)
2167 {
2168 sat_info quiet (tf_none, info.in_decl);
2169 tree result = constraint_satisfaction_value (t, args, quiet);
2170 if (result == boolean_true_node)
2171 return boolean_true_node;
2172
2173 if (result == boolean_false_node
2174 && info.diagnose_unsatisfaction_p ())
2175 {
2176 tree expr = TREE_OPERAND (t, 0);
2177 location_t loc = cp_expr_location (t);
2178 if (diagnosing_failed_constraint::replay_errors_p ())
2179 {
2180 /* Replay the substitution error. */
2181 inform (loc, "nested requirement %qE is not satisfied, because", expr);
2182 constraint_satisfaction_value (t, args, info);
2183 }
2184 else
2185 inform (loc, "nested requirement %qE is not satisfied", expr);
2186 }
2187
2188 return error_mark_node;
2189 }
2190
2191 /* Substitute ARGS into the requirement T. */
2192
2193 static tree
tsubst_requirement(tree t,tree args,sat_info info)2194 tsubst_requirement (tree t, tree args, sat_info info)
2195 {
2196 iloc_sentinel loc_s (cp_expr_location (t));
2197 switch (TREE_CODE (t))
2198 {
2199 case SIMPLE_REQ:
2200 return tsubst_simple_requirement (t, args, info);
2201 case TYPE_REQ:
2202 return tsubst_type_requirement (t, args, info);
2203 case COMPOUND_REQ:
2204 return tsubst_compound_requirement (t, args, info);
2205 case NESTED_REQ:
2206 return tsubst_nested_requirement (t, args, info);
2207 default:
2208 break;
2209 }
2210 gcc_unreachable ();
2211 }
2212
2213 static tree
declare_constraint_vars(tree parms,tree vars)2214 declare_constraint_vars (tree parms, tree vars)
2215 {
2216 tree s = vars;
2217 for (tree t = parms; t; t = DECL_CHAIN (t))
2218 {
2219 if (DECL_PACK_P (t))
2220 {
2221 tree pack = extract_fnparm_pack (t, &s);
2222 register_local_specialization (pack, t);
2223 }
2224 else
2225 {
2226 register_local_specialization (s, t);
2227 s = DECL_CHAIN (s);
2228 }
2229 }
2230 return vars;
2231 }
2232
2233 /* Substitute through as if checking function parameter types. This
2234 will diagnose common parameter type errors. Returns error_mark_node
2235 if an error occurred. */
2236
2237 static tree
check_constraint_variables(tree t,tree args,subst_info info)2238 check_constraint_variables (tree t, tree args, subst_info info)
2239 {
2240 tree types = NULL_TREE;
2241 tree p = t;
2242 while (p && !VOID_TYPE_P (p))
2243 {
2244 types = tree_cons (NULL_TREE, TREE_TYPE (p), types);
2245 p = TREE_CHAIN (p);
2246 }
2247 types = chainon (nreverse (types), void_list_node);
2248 return tsubst_function_parms (types, args, info.complain, info.in_decl);
2249 }
2250
2251 /* A subroutine of tsubst_parameterized_constraint. Substitute ARGS
2252 into the parameter list T, producing a sequence of constraint
2253 variables, declared in the current scope.
2254
2255 Note that the caller must establish a local specialization stack
2256 prior to calling this function since this substitution will
2257 declare the substituted parameters. */
2258
2259 static tree
tsubst_constraint_variables(tree t,tree args,subst_info info)2260 tsubst_constraint_variables (tree t, tree args, subst_info info)
2261 {
2262 /* Perform a trial substitution to check for type errors. */
2263 tree parms = check_constraint_variables (t, args, info);
2264 if (parms == error_mark_node)
2265 return error_mark_node;
2266
2267 /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain
2268 of PARM_DECLs. */
2269 int saved_unevaluated_operand = cp_unevaluated_operand;
2270 cp_unevaluated_operand = 0;
2271 tree vars = tsubst (t, args, info.complain, info.in_decl);
2272 cp_unevaluated_operand = saved_unevaluated_operand;
2273 if (vars == error_mark_node)
2274 return error_mark_node;
2275 return declare_constraint_vars (t, vars);
2276 }
2277
2278 /* Substitute ARGS into the requires-expression T. [8.4.7]p6. The
2279 substitution of template arguments into a requires-expression
2280 may result in the formation of invalid types or expressions
2281 in its requirements ... In such cases, the expression evaluates
2282 to false; it does not cause the program to be ill-formed.
2283
2284 When substituting through a REQUIRES_EXPR as part of template
2285 instantiation, we call this routine with info.quiet() true.
2286
2287 When evaluating a REQUIRES_EXPR that appears outside a template in
2288 cp_parser_requires_expression, we call this routine with
2289 info.noisy() true.
2290
2291 Finally, when diagnosing unsatisfaction from diagnose_atomic_constraint
2292 and when diagnosing a false REQUIRES_EXPR via diagnose_constraints,
2293 we call this routine with info.diagnose_unsatisfaction_p() true. */
2294
2295 static tree
tsubst_requires_expr(tree t,tree args,sat_info info)2296 tsubst_requires_expr (tree t, tree args, sat_info info)
2297 {
2298 local_specialization_stack stack (lss_copy);
2299
2300 /* A requires-expression is an unevaluated context. */
2301 cp_unevaluated u;
2302
2303 args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args,
2304 info.complain, info.in_decl);
2305 if (processing_template_decl)
2306 {
2307 /* We're partially instantiating a generic lambda. Substituting into
2308 this requires-expression now may cause its requirements to get
2309 checked out of order, so instead just remember the template
2310 arguments and wait until we can substitute them all at once. */
2311 t = copy_node (t);
2312 REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain);
2313 return t;
2314 }
2315
2316 if (tree parms = REQUIRES_EXPR_PARMS (t))
2317 {
2318 parms = tsubst_constraint_variables (parms, args, info);
2319 if (parms == error_mark_node)
2320 return boolean_false_node;
2321 }
2322
2323 tree result = boolean_true_node;
2324 for (tree reqs = REQUIRES_EXPR_REQS (t); reqs; reqs = TREE_CHAIN (reqs))
2325 {
2326 tree req = TREE_VALUE (reqs);
2327 if (tsubst_requirement (req, args, info) == error_mark_node)
2328 {
2329 result = boolean_false_node;
2330 if (info.diagnose_unsatisfaction_p ())
2331 /* Keep going so that we diagnose all failed requirements. */;
2332 else
2333 break;
2334 }
2335 }
2336 return result;
2337 }
2338
2339 /* Public wrapper for the above. */
2340
2341 tree
tsubst_requires_expr(tree t,tree args,tsubst_flags_t complain,tree in_decl)2342 tsubst_requires_expr (tree t, tree args,
2343 tsubst_flags_t complain, tree in_decl)
2344 {
2345 sat_info info (complain, in_decl);
2346 return tsubst_requires_expr (t, args, info);
2347 }
2348
2349 /* Substitute ARGS into the constraint information CI, producing a new
2350 constraint record. */
2351
2352 tree
tsubst_constraint_info(tree t,tree args,tsubst_flags_t complain,tree in_decl)2353 tsubst_constraint_info (tree t, tree args,
2354 tsubst_flags_t complain, tree in_decl)
2355 {
2356 if (!t || t == error_mark_node || !check_constraint_info (t))
2357 return NULL_TREE;
2358
2359 tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t), args, complain, in_decl);
2360 tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t), args, complain, in_decl);
2361 return build_constraints (tr, dr);
2362 }
2363
2364 /* Substitute through a parameter mapping, in order to get the actual
2365 arguments used to instantiate an atomic constraint. This may fail
2366 if the substitution into arguments produces something ill-formed. */
2367
2368 static tree
tsubst_parameter_mapping(tree map,tree args,subst_info info)2369 tsubst_parameter_mapping (tree map, tree args, subst_info info)
2370 {
2371 if (!map)
2372 return NULL_TREE;
2373
2374 tsubst_flags_t complain = info.complain;
2375 tree in_decl = info.in_decl;
2376
2377 tree result = NULL_TREE;
2378 for (tree p = map; p; p = TREE_CHAIN (p))
2379 {
2380 if (p == error_mark_node)
2381 return error_mark_node;
2382 tree parm = TREE_VALUE (p);
2383 tree arg = TREE_PURPOSE (p);
2384 tree new_arg;
2385 if (ARGUMENT_PACK_P (arg))
2386 new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
2387 else
2388 {
2389 new_arg = tsubst_template_arg (arg, args, complain, in_decl);
2390 if (TYPE_P (new_arg))
2391 new_arg = canonicalize_type_argument (new_arg, complain);
2392 }
2393 if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
2394 {
2395 tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
2396 for (int i = 0; i < TREE_VEC_LENGTH (pack_args); i++)
2397 {
2398 tree& pack_arg = TREE_VEC_ELT (pack_args, i);
2399 if (TYPE_P (pack_arg))
2400 pack_arg = canonicalize_type_argument (pack_arg, complain);
2401 }
2402 }
2403 if (new_arg == error_mark_node)
2404 return error_mark_node;
2405
2406 result = tree_cons (new_arg, parm, result);
2407 }
2408 return nreverse (result);
2409 }
2410
2411 tree
tsubst_parameter_mapping(tree map,tree args,tsubst_flags_t complain,tree in_decl)2412 tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_decl)
2413 {
2414 return tsubst_parameter_mapping (map, args, subst_info (complain, in_decl));
2415 }
2416
2417 /*---------------------------------------------------------------------------
2418 Constraint satisfaction
2419 ---------------------------------------------------------------------------*/
2420
2421 /* True if we are currently satisfying a constraint. */
2422
2423 static bool satisfying_constraint;
2424
2425 /* A vector of incomplete types (and of declarations with undeduced return type),
2426 appended to by note_failed_type_completion_for_satisfaction. The
2427 satisfaction caches use this in order to keep track of "potentially unstable"
2428 satisfaction results.
2429
2430 Since references to entries in this vector are stored only in the
2431 GC-deletable sat_cache, it's safe to make this deletable as well. */
2432
2433 static GTY((deletable)) vec<tree, va_gc> *failed_type_completions;
2434
2435 /* Called whenever a type completion (or return type deduction) failure occurs
2436 that definitely affects the meaning of the program, by e.g. inducing
2437 substitution failure. */
2438
2439 void
note_failed_type_completion_for_satisfaction(tree t)2440 note_failed_type_completion_for_satisfaction (tree t)
2441 {
2442 if (satisfying_constraint)
2443 {
2444 gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))
2445 || (DECL_P (t) && undeduced_auto_decl (t)));
2446 vec_safe_push (failed_type_completions, t);
2447 }
2448 }
2449
2450 /* Returns true if the range [BEGIN, END) of elements within the
2451 failed_type_completions vector contains a complete type (or a
2452 declaration with a non-placeholder return type). */
2453
2454 static bool
some_type_complete_p(int begin,int end)2455 some_type_complete_p (int begin, int end)
2456 {
2457 for (int i = begin; i < end; i++)
2458 {
2459 tree t = (*failed_type_completions)[i];
2460 if (TYPE_P (t) && COMPLETE_TYPE_P (t))
2461 return true;
2462 if (DECL_P (t) && !undeduced_auto_decl (t))
2463 return true;
2464 }
2465 return false;
2466 }
2467
2468 /* Hash functions and data types for satisfaction cache entries. */
2469
2470 struct GTY((for_user)) sat_entry
2471 {
2472 /* The relevant ATOMIC_CONSTR. */
2473 tree atom;
2474
2475 /* The relevant template arguments. */
2476 tree args;
2477
2478 /* The result of satisfaction of ATOM+ARGS.
2479 This is either boolean_true_node, boolean_false_node or error_mark_node,
2480 where error_mark_node indicates ill-formed satisfaction.
2481 It's set to NULL_TREE while computing satisfaction of ATOM+ARGS for
2482 the first time. */
2483 tree result;
2484
2485 /* The value of input_location when satisfaction of ATOM+ARGS was first
2486 performed. */
2487 location_t location;
2488
2489 /* The range of elements appended to the failed_type_completions vector
2490 during computation of this satisfaction result, encoded as a begin/end
2491 pair of offsets. */
2492 int ftc_begin, ftc_end;
2493
2494 /* True if we want to diagnose the above instability when it's detected.
2495 We don't always want to do so, in order to avoid emitting duplicate
2496 diagnostics in some cases. */
2497 bool diagnose_instability;
2498
2499 /* True if we're in the middle of computing this satisfaction result.
2500 Used during both quiet and noisy satisfaction to detect self-recursive
2501 satisfaction. */
2502 bool evaluating;
2503 };
2504
2505 struct sat_hasher : ggc_ptr_hash<sat_entry>
2506 {
hashsat_hasher2507 static hashval_t hash (sat_entry *e)
2508 {
2509 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->atom))
2510 {
2511 /* Atoms with instantiated mappings are built during satisfaction.
2512 They live only inside the sat_cache, and we build one to query
2513 the cache with each time we instantiate a mapping. */
2514 gcc_assert (!e->args);
2515 return hash_atomic_constraint (e->atom);
2516 }
2517
2518 /* Atoms with uninstantiated mappings are built during normalization.
2519 Since normalize_atom caches the atoms it returns, we can assume
2520 pointer-based identity for fast hashing and comparison. Even if this
2521 assumption is violated, that's okay, we'll just get a cache miss. */
2522 hashval_t value = htab_hash_pointer (e->atom);
2523
2524 if (tree map = ATOMIC_CONSTR_MAP (e->atom))
2525 /* Only the parameters that are used in the targets of the mapping
2526 affect the satisfaction value of the atom. So we consider only
2527 the arguments for these parameters, and ignore the rest. */
2528 for (tree target_parms = TREE_TYPE (map);
2529 target_parms;
2530 target_parms = TREE_CHAIN (target_parms))
2531 {
2532 int level, index;
2533 tree parm = TREE_VALUE (target_parms);
2534 template_parm_level_and_index (parm, &level, &index);
2535 tree arg = TMPL_ARG (e->args, level, index);
2536 value = iterative_hash_template_arg (arg, value);
2537 }
2538 return value;
2539 }
2540
equalsat_hasher2541 static bool equal (sat_entry *e1, sat_entry *e2)
2542 {
2543 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)
2544 != ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom))
2545 return false;
2546
2547 /* See sat_hasher::hash. */
2548 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom))
2549 {
2550 gcc_assert (!e1->args && !e2->args);
2551 return atomic_constraints_identical_p (e1->atom, e2->atom);
2552 }
2553
2554 if (e1->atom != e2->atom)
2555 return false;
2556
2557 if (tree map = ATOMIC_CONSTR_MAP (e1->atom))
2558 for (tree target_parms = TREE_TYPE (map);
2559 target_parms;
2560 target_parms = TREE_CHAIN (target_parms))
2561 {
2562 int level, index;
2563 tree parm = TREE_VALUE (target_parms);
2564 template_parm_level_and_index (parm, &level, &index);
2565 tree arg1 = TMPL_ARG (e1->args, level, index);
2566 tree arg2 = TMPL_ARG (e2->args, level, index);
2567 if (!template_args_equal (arg1, arg2))
2568 return false;
2569 }
2570 return true;
2571 }
2572 };
2573
2574 /* Cache the result of satisfy_atom. */
2575 static GTY((deletable)) hash_table<sat_hasher> *sat_cache;
2576
2577 /* Cache the result of satisfy_declaration_constraints. */
2578 static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;
2579
2580 /* A tool used by satisfy_atom to help manage satisfaction caching and to
2581 diagnose "unstable" satisfaction values. We insert into the cache only
2582 when performing satisfaction quietly. */
2583
2584 struct satisfaction_cache
2585 {
2586 satisfaction_cache (tree, tree, sat_info);
2587 tree get ();
2588 tree save (tree);
2589
2590 sat_entry *entry;
2591 sat_info info;
2592 int ftc_begin;
2593 };
2594
2595 /* Constructor for the satisfaction_cache class. We're performing satisfaction
2596 of ATOM+ARGS according to INFO. */
2597
2598 satisfaction_cache
satisfaction_cache(tree atom,tree args,sat_info info)2599 ::satisfaction_cache (tree atom, tree args, sat_info info)
2600 : entry(nullptr), info(info), ftc_begin(-1)
2601 {
2602 if (!sat_cache)
2603 sat_cache = hash_table<sat_hasher>::create_ggc (31);
2604
2605 /* When noisy, we query the satisfaction cache in order to diagnose
2606 "unstable" satisfaction values. */
2607 if (info.noisy ())
2608 {
2609 /* When noisy, constraints have been re-normalized, and that breaks the
2610 pointer-based identity assumption of sat_cache (for atoms with
2611 uninstantiated mappings). So undo this re-normalization by looking in
2612 the atom_cache for the corresponding atom that was used during quiet
2613 satisfaction. */
2614 if (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
2615 {
2616 if (tree found = atom_cache->find (atom))
2617 atom = found;
2618 else
2619 /* The lookup should always succeed, but if it fails then let's
2620 just leave 'entry' empty, effectively disabling the cache. */
2621 return;
2622 }
2623 }
2624
2625 /* Look up or create the corresponding satisfaction entry. */
2626 sat_entry elt;
2627 elt.atom = atom;
2628 elt.args = args;
2629 sat_entry **slot = sat_cache->find_slot (&elt, INSERT);
2630 if (*slot)
2631 entry = *slot;
2632 else if (info.quiet ())
2633 {
2634 entry = ggc_alloc<sat_entry> ();
2635 entry->atom = atom;
2636 entry->args = args;
2637 entry->result = NULL_TREE;
2638 entry->location = input_location;
2639 entry->ftc_begin = entry->ftc_end = -1;
2640 entry->diagnose_instability = false;
2641 if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
2642 /* We always want to diagnose instability of an atom with an
2643 instantiated parameter mapping. For atoms with an uninstantiated
2644 mapping, we set this flag (in satisfy_atom) only if substitution
2645 into its mapping previously failed. */
2646 entry->diagnose_instability = true;
2647 entry->evaluating = false;
2648 *slot = entry;
2649 }
2650 else
2651 /* We shouldn't get here, but if we do, let's just leave 'entry'
2652 empty, effectively disabling the cache. */
2653 return;
2654 }
2655
2656 /* Returns the cached satisfaction result if we have one and we're not
2657 recomputing the satisfaction result from scratch. Otherwise returns
2658 NULL_TREE. */
2659
2660 tree
get()2661 satisfaction_cache::get ()
2662 {
2663 if (!entry)
2664 return NULL_TREE;
2665
2666 if (entry->evaluating)
2667 {
2668 /* If we get here, it means satisfaction is self-recursive. */
2669 gcc_checking_assert (!entry->result);
2670 if (info.noisy ())
2671 error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom)),
2672 "satisfaction of atomic constraint %qE depends on itself",
2673 entry->atom);
2674 return error_mark_node;
2675 }
2676
2677 /* This satisfaction result is "potentially unstable" if a type for which
2678 type completion failed during its earlier computation is now complete. */
2679 bool maybe_unstable = some_type_complete_p (entry->ftc_begin,
2680 entry->ftc_end);
2681
2682 if (info.noisy () || maybe_unstable || !entry->result)
2683 {
2684 /* We're computing the satisfaction result from scratch. */
2685 entry->evaluating = true;
2686 ftc_begin = vec_safe_length (failed_type_completions);
2687 return NULL_TREE;
2688 }
2689 else
2690 return entry->result;
2691 }
2692
2693 /* RESULT is the computed satisfaction result. If RESULT differs from the
2694 previously cached result, this routine issues an appropriate error.
2695 Otherwise, when evaluating quietly, updates the cache appropriately. */
2696
2697 tree
save(tree result)2698 satisfaction_cache::save (tree result)
2699 {
2700 if (!entry)
2701 return result;
2702
2703 gcc_checking_assert (entry->evaluating);
2704 entry->evaluating = false;
2705
2706 if (entry->result && result != entry->result)
2707 {
2708 if (info.quiet ())
2709 /* Return error_mark_node to force satisfaction to get replayed
2710 noisily. */
2711 return error_mark_node;
2712 else
2713 {
2714 if (entry->diagnose_instability)
2715 {
2716 auto_diagnostic_group d;
2717 error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom)),
2718 "satisfaction value of atomic constraint %qE changed "
2719 "from %qE to %qE", entry->atom, entry->result, result);
2720 inform (entry->location,
2721 "satisfaction value first evaluated to %qE from here",
2722 entry->result);
2723 }
2724 /* For sake of error recovery, allow this latest satisfaction result
2725 to prevail. */
2726 entry->result = result;
2727 return result;
2728 }
2729 }
2730
2731 if (info.quiet ())
2732 {
2733 entry->result = result;
2734 /* Store into this entry the list of relevant failed type completions
2735 that occurred during (re)computation of the satisfaction result. */
2736 gcc_checking_assert (ftc_begin != -1);
2737 entry->ftc_begin = ftc_begin;
2738 entry->ftc_end = vec_safe_length (failed_type_completions);
2739 }
2740
2741 return result;
2742 }
2743
2744 /* Substitute ARGS into constraint-expression T during instantiation of
2745 a member of a class template. */
2746
2747 tree
tsubst_constraint(tree t,tree args,tsubst_flags_t complain,tree in_decl)2748 tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
2749 {
2750 /* We also don't want to evaluate concept-checks when substituting the
2751 constraint-expressions of a declaration. */
2752 processing_constraint_expression_sentinel s;
2753 cp_unevaluated u;
2754 tree expr = tsubst_expr (t, args, complain, in_decl, false);
2755 return expr;
2756 }
2757
2758 static tree satisfy_constraint_r (tree, tree, sat_info info);
2759
2760 /* Compute the satisfaction of a conjunction. */
2761
2762 static tree
satisfy_conjunction(tree t,tree args,sat_info info)2763 satisfy_conjunction (tree t, tree args, sat_info info)
2764 {
2765 tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
2766 if (lhs == error_mark_node || lhs == boolean_false_node)
2767 return lhs;
2768 return satisfy_constraint_r (TREE_OPERAND (t, 1), args, info);
2769 }
2770
2771 /* The current depth at which we're replaying an error during recursive
2772 diagnosis of a constraint satisfaction failure. */
2773
2774 static int current_constraint_diagnosis_depth;
2775
2776 /* Whether CURRENT_CONSTRAINT_DIAGNOSIS_DEPTH has ever exceeded
2777 CONCEPTS_DIAGNOSTICS_MAX_DEPTH during recursive diagnosis of a constraint
2778 satisfaction error. */
2779
2780 static bool concepts_diagnostics_max_depth_exceeded_p;
2781
2782 /* Recursive subroutine of collect_operands_of_disjunction. T is a normalized
2783 subexpression of a constraint (composed of CONJ_CONSTRs and DISJ_CONSTRs)
2784 and E is the corresponding unnormalized subexpression (composed of
2785 TRUTH_ANDIF_EXPRs and TRUTH_ORIF_EXPRs). */
2786
2787 static void
collect_operands_of_disjunction_r(tree t,tree e,auto_vec<tree_pair> * operands)2788 collect_operands_of_disjunction_r (tree t, tree e,
2789 auto_vec<tree_pair> *operands)
2790 {
2791 if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
2792 {
2793 collect_operands_of_disjunction_r (TREE_OPERAND (t, 0),
2794 TREE_OPERAND (e, 0), operands);
2795 collect_operands_of_disjunction_r (TREE_OPERAND (t, 1),
2796 TREE_OPERAND (e, 1), operands);
2797 }
2798 else
2799 {
2800 tree_pair p = std::make_pair (t, e);
2801 operands->safe_push (p);
2802 }
2803 }
2804
2805 /* Recursively collect the normalized and unnormalized operands of the
2806 disjunction T and append them to OPERANDS in order. */
2807
2808 static void
collect_operands_of_disjunction(tree t,auto_vec<tree_pair> * operands)2809 collect_operands_of_disjunction (tree t, auto_vec<tree_pair> *operands)
2810 {
2811 collect_operands_of_disjunction_r (t, CONSTR_EXPR (t), operands);
2812 }
2813
2814 /* Compute the satisfaction of a disjunction. */
2815
2816 static tree
satisfy_disjunction(tree t,tree args,sat_info info)2817 satisfy_disjunction (tree t, tree args, sat_info info)
2818 {
2819 /* Evaluate each operand with unsatisfaction diagnostics disabled. */
2820 sat_info sub = info;
2821 sub.diagnose_unsatisfaction = false;
2822
2823 tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, sub);
2824 if (lhs == boolean_true_node || lhs == error_mark_node)
2825 return lhs;
2826
2827 tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, sub);
2828 if (rhs == boolean_true_node || rhs == error_mark_node)
2829 return rhs;
2830
2831 /* Both branches evaluated to false. Explain the satisfaction failure in
2832 each branch. */
2833 if (info.diagnose_unsatisfaction_p ())
2834 {
2835 diagnosing_failed_constraint failure (t, args, info.noisy ());
2836 cp_expr disj_expr = CONSTR_EXPR (t);
2837 inform (disj_expr.get_location (),
2838 "no operand of the disjunction is satisfied");
2839 if (diagnosing_failed_constraint::replay_errors_p ())
2840 {
2841 /* Replay the error in each branch of the disjunction. */
2842 auto_vec<tree_pair> operands;
2843 collect_operands_of_disjunction (t, &operands);
2844 for (unsigned i = 0; i < operands.length (); i++)
2845 {
2846 tree norm_op = operands[i].first;
2847 tree op = operands[i].second;
2848 location_t loc = make_location (cp_expr_location (op),
2849 disj_expr.get_start (),
2850 disj_expr.get_finish ());
2851 inform (loc, "the operand %qE is unsatisfied because", op);
2852 satisfy_constraint_r (norm_op, args, info);
2853 }
2854 }
2855 }
2856
2857 return boolean_false_node;
2858 }
2859
2860 /* Ensures that T is a truth value and not (accidentally, as sometimes
2861 happens) an integer value. */
2862
2863 tree
satisfaction_value(tree t)2864 satisfaction_value (tree t)
2865 {
2866 if (t == error_mark_node || t == boolean_true_node || t == boolean_false_node)
2867 return t;
2868
2869 gcc_assert (TREE_CODE (t) == INTEGER_CST
2870 && same_type_p (TREE_TYPE (t), boolean_type_node));
2871 if (integer_zerop (t))
2872 return boolean_false_node;
2873 else
2874 return boolean_true_node;
2875 }
2876
2877 /* Build a new template argument list with template arguments corresponding
2878 to the parameters used in an atomic constraint. */
2879
2880 tree
get_mapped_args(tree map)2881 get_mapped_args (tree map)
2882 {
2883 /* No map, no arguments. */
2884 if (!map)
2885 return NULL_TREE;
2886
2887 /* Find the mapped parameter with the highest level. */
2888 int count = 0;
2889 for (tree p = map; p; p = TREE_CHAIN (p))
2890 {
2891 int level;
2892 int index;
2893 template_parm_level_and_index (TREE_VALUE (p), &level, &index);
2894 if (level > count)
2895 count = level;
2896 }
2897
2898 /* Place each argument at its corresponding position in the argument
2899 list. Note that the list will be sparse (not all arguments supplied),
2900 but instantiation is guaranteed to only use the parameters in the
2901 mapping, so null arguments would never be used. */
2902 auto_vec< vec<tree> > lists (count);
2903 lists.quick_grow_cleared (count);
2904 for (tree p = map; p; p = TREE_CHAIN (p))
2905 {
2906 int level;
2907 int index;
2908 template_parm_level_and_index (TREE_VALUE (p), &level, &index);
2909
2910 /* Insert the argument into its corresponding position. */
2911 vec<tree> &list = lists[level - 1];
2912 if (index >= (int)list.length ())
2913 list.safe_grow_cleared (index + 1, true);
2914 list[index] = TREE_PURPOSE (p);
2915 }
2916
2917 /* Build the new argument list. */
2918 tree args = make_tree_vec (lists.length ());
2919 for (unsigned i = 0; i != lists.length (); ++i)
2920 {
2921 vec<tree> &list = lists[i];
2922 tree level = make_tree_vec (list.length ());
2923 for (unsigned j = 0; j < list.length(); ++j)
2924 TREE_VEC_ELT (level, j) = list[j];
2925 SET_TMPL_ARGS_LEVEL (args, i + 1, level);
2926 list.release ();
2927 }
2928 SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0);
2929
2930 return args;
2931 }
2932
2933 static void diagnose_atomic_constraint (tree, tree, tree, sat_info);
2934
2935 /* Compute the satisfaction of an atomic constraint. */
2936
2937 static tree
satisfy_atom(tree t,tree args,sat_info info)2938 satisfy_atom (tree t, tree args, sat_info info)
2939 {
2940 /* In case there is a diagnostic, we want to establish the context
2941 prior to printing errors. If no errors occur, this context is
2942 removed before returning. */
2943 diagnosing_failed_constraint failure (t, args, info.noisy ());
2944
2945 satisfaction_cache cache (t, args, info);
2946 if (tree r = cache.get ())
2947 return r;
2948
2949 /* Perform substitution quietly. */
2950 subst_info quiet (tf_none, NULL_TREE);
2951
2952 /* Instantiate the parameter mapping. */
2953 tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet);
2954 if (map == error_mark_node)
2955 {
2956 /* If instantiation of the parameter mapping fails, the constraint is
2957 not satisfied. Replay the substitution. */
2958 if (info.diagnose_unsatisfaction_p ())
2959 tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info);
2960 if (info.quiet ())
2961 /* Since instantiation of the parameter mapping failed, we
2962 want to diagnose potential instability of this satisfaction
2963 result. */
2964 cache.entry->diagnose_instability = true;
2965 return cache.save (boolean_false_node);
2966 }
2967
2968 /* Now build a new atom using the instantiated mapping. We use
2969 this atom as a second key to the satisfaction cache, and we
2970 also pass it to diagnose_atomic_constraint so that diagnostics
2971 which refer to the atom display the instantiated mapping. */
2972 t = copy_node (t);
2973 ATOMIC_CONSTR_MAP (t) = map;
2974 gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t));
2975 ATOMIC_CONSTR_MAP_INSTANTIATED_P (t) = true;
2976 satisfaction_cache inst_cache (t, /*args=*/NULL_TREE, info);
2977 if (tree r = inst_cache.get ())
2978 {
2979 cache.entry->location = inst_cache.entry->location;
2980 return cache.save (r);
2981 }
2982
2983 /* Rebuild the argument vector from the parameter mapping. */
2984 args = get_mapped_args (map);
2985
2986 /* Apply the parameter mapping (i.e., just substitute). */
2987 tree expr = ATOMIC_CONSTR_EXPR (t);
2988 tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl, false);
2989 if (result == error_mark_node)
2990 {
2991 /* If substitution results in an invalid type or expression, the constraint
2992 is not satisfied. Replay the substitution. */
2993 if (info.diagnose_unsatisfaction_p ())
2994 tsubst_expr (expr, args, info.complain, info.in_decl, false);
2995 return cache.save (inst_cache.save (boolean_false_node));
2996 }
2997
2998 /* [17.4.1.2] ... lvalue-to-rvalue conversion is performed as necessary,
2999 and EXPR shall be a constant expression of type bool. */
3000 result = force_rvalue (result, info.complain);
3001 if (result == error_mark_node)
3002 return cache.save (inst_cache.save (error_mark_node));
3003 if (!same_type_p (TREE_TYPE (result), boolean_type_node))
3004 {
3005 if (info.noisy ())
3006 diagnose_atomic_constraint (t, map, result, info);
3007 return cache.save (inst_cache.save (error_mark_node));
3008 }
3009
3010 /* Compute the value of the constraint. */
3011 if (info.noisy ())
3012 {
3013 iloc_sentinel ils (EXPR_LOCATION (result));
3014 result = cxx_constant_value (result);
3015 }
3016 else
3017 {
3018 result = maybe_constant_value (result, NULL_TREE,
3019 /*manifestly_const_eval=*/true);
3020 if (!TREE_CONSTANT (result))
3021 result = error_mark_node;
3022 }
3023 result = satisfaction_value (result);
3024 if (result == boolean_false_node && info.diagnose_unsatisfaction_p ())
3025 diagnose_atomic_constraint (t, map, result, info);
3026
3027 return cache.save (inst_cache.save (result));
3028 }
3029
3030 /* Determine if the normalized constraint T is satisfied.
3031 Returns boolean_true_node if the expression/constraint is
3032 satisfied, boolean_false_node if not, and error_mark_node
3033 if the there was an error evaluating the constraint.
3034
3035 The parameter mapping of atomic constraints is simply the
3036 set of template arguments that will be substituted into
3037 the expression, regardless of template parameters appearing
3038 withing. Whether a template argument is used in the atomic
3039 constraint only matters for subsumption. */
3040
3041 static tree
satisfy_constraint_r(tree t,tree args,sat_info info)3042 satisfy_constraint_r (tree t, tree args, sat_info info)
3043 {
3044 if (t == error_mark_node)
3045 return error_mark_node;
3046
3047 switch (TREE_CODE (t))
3048 {
3049 case CONJ_CONSTR:
3050 return satisfy_conjunction (t, args, info);
3051 case DISJ_CONSTR:
3052 return satisfy_disjunction (t, args, info);
3053 case ATOMIC_CONSTR:
3054 return satisfy_atom (t, args, info);
3055 default:
3056 gcc_unreachable ();
3057 }
3058 }
3059
3060 /* Check that the normalized constraint T is satisfied for ARGS. */
3061
3062 static tree
satisfy_normalized_constraints(tree t,tree args,sat_info info)3063 satisfy_normalized_constraints (tree t, tree args, sat_info info)
3064 {
3065 auto_timevar time (TV_CONSTRAINT_SAT);
3066
3067 auto ovr = make_temp_override (satisfying_constraint, true);
3068
3069 /* Turn off template processing. Constraint satisfaction only applies
3070 to non-dependent terms, so we want to ensure full checking here. */
3071 processing_template_decl_sentinel proc (true);
3072
3073 /* We need to check access during satisfaction. */
3074 deferring_access_check_sentinel acs (dk_no_deferred);
3075
3076 /* Constraints are unevaluated operands. */
3077 cp_unevaluated u;
3078
3079 return satisfy_constraint_r (t, args, info);
3080 }
3081
3082 /* Return the normal form of the constraints on the placeholder 'auto'
3083 type T. */
3084
3085 static tree
normalize_placeholder_type_constraints(tree t,bool diag)3086 normalize_placeholder_type_constraints (tree t, bool diag)
3087 {
3088 gcc_assert (is_auto (t));
3089 tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
3090 if (!ci)
3091 return NULL_TREE;
3092
3093 tree constr = TREE_VALUE (ci);
3094 /* The TREE_PURPOSE contains the set of template parameters that were in
3095 scope for this placeholder type; use them as the initial template
3096 parameters for normalization. */
3097 tree initial_parms = TREE_PURPOSE (ci);
3098
3099 if (!initial_parms && TEMPLATE_TYPE_LEVEL (t) == 2)
3100 /* This is a return-type-requirement of a non-templated requires-expression,
3101 which are parsed under processing_template_decl == 1 and empty
3102 current_template_parms; hence the 'auto' has level 2 and initial_parms
3103 is empty. Fix up initial_parms to be consistent with the value of
3104 processing_template_decl whence the 'auto' was created. */
3105 initial_parms = build_tree_list (size_int (1), make_tree_vec (0));
3106
3107 /* The 'auto' itself is used as the first argument in its own constraints,
3108 and its level is one greater than its template depth. So in order to
3109 capture all used template parameters, we need to add an extra level of
3110 template parameters to the context; a dummy level suffices. */
3111 initial_parms
3112 = tree_cons (size_int (initial_parms
3113 ? TMPL_PARMS_DEPTH (initial_parms) + 1 : 1),
3114 make_tree_vec (0), initial_parms);
3115
3116 norm_info info (diag ? tf_norm : tf_none);
3117 info.initial_parms = initial_parms;
3118 return normalize_constraint_expression (constr, info);
3119 }
3120
3121 /* Evaluate the constraints of T using ARGS, returning a satisfaction value.
3122 Here, T can be a concept-id, nested-requirement, placeholder 'auto', or
3123 requires-expression. */
3124
3125 static tree
satisfy_nondeclaration_constraints(tree t,tree args,sat_info info)3126 satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
3127 {
3128 if (t == error_mark_node)
3129 return error_mark_node;
3130
3131 /* Handle REQUIRES_EXPR directly, bypassing satisfaction. */
3132 if (TREE_CODE (t) == REQUIRES_EXPR)
3133 {
3134 auto ovr = make_temp_override (current_constraint_diagnosis_depth);
3135 if (info.noisy ())
3136 ++current_constraint_diagnosis_depth;
3137 return tsubst_requires_expr (t, args, info);
3138 }
3139
3140 /* Get the normalized constraints. */
3141 tree norm;
3142 if (concept_check_p (t))
3143 {
3144 gcc_assert (!args);
3145 tree id = unpack_concept_check (t);
3146 args = TREE_OPERAND (id, 1);
3147 tree tmpl = get_concept_check_template (id);
3148 norm = normalize_concept_definition (tmpl, info.noisy ());
3149 }
3150 else if (TREE_CODE (t) == NESTED_REQ)
3151 {
3152 norm_info ninfo (info.noisy () ? tf_norm : tf_none);
3153 /* The TREE_TYPE contains the set of template parameters that were in
3154 scope for this nested requirement; use them as the initial template
3155 parameters for normalization. */
3156 ninfo.initial_parms = TREE_TYPE (t);
3157 norm = normalize_constraint_expression (TREE_OPERAND (t, 0), ninfo);
3158 }
3159 else if (is_auto (t))
3160 {
3161 norm = normalize_placeholder_type_constraints (t, info.noisy ());
3162 if (!norm)
3163 return boolean_true_node;
3164 }
3165 else
3166 gcc_unreachable ();
3167
3168 /* Perform satisfaction. */
3169 return satisfy_normalized_constraints (norm, args, info);
3170 }
3171
3172 /* Evaluate the associated constraints of the template specialization T
3173 according to INFO, returning a satisfaction value. */
3174
3175 static tree
satisfy_declaration_constraints(tree t,sat_info info)3176 satisfy_declaration_constraints (tree t, sat_info info)
3177 {
3178 gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL);
3179 const tree saved_t = t;
3180
3181 /* For inherited constructors, consider the original declaration;
3182 it has the correct template information attached. */
3183 t = strip_inheriting_ctors (t);
3184 tree inh_ctor_targs = NULL_TREE;
3185 if (t != saved_t)
3186 if (tree ti = DECL_TEMPLATE_INFO (saved_t))
3187 /* The inherited constructor points to an instantiation of a constructor
3188 template; remember its template arguments. */
3189 inh_ctor_targs = TI_ARGS (ti);
3190
3191 /* Update the declaration for diagnostics. */
3192 info.in_decl = t;
3193
3194 if (info.quiet ())
3195 if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
3196 return *result;
3197
3198 tree args = NULL_TREE;
3199 if (tree ti = DECL_TEMPLATE_INFO (t))
3200 {
3201 /* The initial parameter mapping is the complete set of
3202 template arguments substituted into the declaration. */
3203 args = TI_ARGS (ti);
3204 if (inh_ctor_targs)
3205 args = add_outermost_template_args (args, inh_ctor_targs);
3206 }
3207
3208 if (regenerated_lambda_fn_p (t))
3209 {
3210 /* The TI_ARGS of a regenerated lambda contains only the innermost
3211 set of template arguments. Augment this with the outer template
3212 arguments that were used to regenerate the lambda. */
3213 gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
3214 tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
3215 tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
3216 if (args)
3217 args = add_to_template_args (outer_args, args);
3218 else
3219 args = outer_args;
3220 }
3221
3222 /* If any arguments depend on template parameters, we can't
3223 check constraints. Pretend they're satisfied for now. */
3224 if (uses_template_parms (args))
3225 return boolean_true_node;
3226
3227 /* Get the normalized constraints. */
3228 tree norm = get_normalized_constraints_from_decl (t, info.noisy ());
3229
3230 unsigned ftc_count = vec_safe_length (failed_type_completions);
3231
3232 tree result = boolean_true_node;
3233 if (norm)
3234 {
3235 if (!push_tinst_level (t))
3236 return result;
3237 push_access_scope (t);
3238 result = satisfy_normalized_constraints (norm, args, info);
3239 pop_access_scope (t);
3240 pop_tinst_level ();
3241 }
3242
3243 /* True if this satisfaction is (heuristically) potentially unstable, i.e.
3244 if its result may depend on where in the program it was performed. */
3245 bool maybe_unstable_satisfaction = false;
3246 if (ftc_count != vec_safe_length (failed_type_completions))
3247 /* Type completion failure occurred during satisfaction. The satisfaction
3248 result may (or may not) materially depend on the completeness of a type,
3249 so we consider it potentially unstable. */
3250 maybe_unstable_satisfaction = true;
3251
3252 if (maybe_unstable_satisfaction)
3253 /* Don't cache potentially unstable satisfaction, to allow satisfy_atom
3254 to check the stability the next time around. */;
3255 else if (info.quiet ())
3256 hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);
3257
3258 return result;
3259 }
3260
3261 /* Evaluate the associated constraints of the template T using ARGS as the
3262 innermost set of template arguments and according to INFO, returning a
3263 satisfaction value. */
3264
3265 static tree
satisfy_declaration_constraints(tree t,tree args,sat_info info)3266 satisfy_declaration_constraints (tree t, tree args, sat_info info)
3267 {
3268 /* Update the declaration for diagnostics. */
3269 info.in_decl = t;
3270
3271 gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);
3272
3273 if (regenerated_lambda_fn_p (t))
3274 {
3275 /* As in the two-parameter version of this function. */
3276 gcc_assert (TMPL_ARGS_DEPTH (args) == 1);
3277 tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
3278 tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
3279 args = add_to_template_args (outer_args, args);
3280 }
3281 else
3282 args = add_outermost_template_args (t, args);
3283
3284 /* If any arguments depend on template parameters, we can't
3285 check constraints. Pretend they're satisfied for now. */
3286 if (uses_template_parms (args))
3287 return boolean_true_node;
3288
3289 tree result = boolean_true_node;
3290 if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
3291 {
3292 if (!push_tinst_level (t, args))
3293 return result;
3294 tree pattern = DECL_TEMPLATE_RESULT (t);
3295 push_access_scope (pattern);
3296 result = satisfy_normalized_constraints (norm, args, info);
3297 pop_access_scope (pattern);
3298 pop_tinst_level ();
3299 }
3300
3301 return result;
3302 }
3303
3304 /* A wrapper around satisfy_declaration_constraints and
3305 satisfy_nondeclaration_constraints which additionally replays
3306 quiet ill-formed satisfaction noisily, so that ill-formed
3307 satisfaction always gets diagnosed. */
3308
3309 static tree
constraint_satisfaction_value(tree t,tree args,sat_info info)3310 constraint_satisfaction_value (tree t, tree args, sat_info info)
3311 {
3312 tree r;
3313 if (DECL_P (t))
3314 {
3315 if (args)
3316 r = satisfy_declaration_constraints (t, args, info);
3317 else
3318 r = satisfy_declaration_constraints (t, info);
3319 }
3320 else
3321 r = satisfy_nondeclaration_constraints (t, args, info);
3322 if (r == error_mark_node && info.quiet ()
3323 && !(DECL_P (t) && TREE_NO_WARNING (t)))
3324 {
3325 /* Replay the error noisily. */
3326 sat_info noisy (tf_warning_or_error, info.in_decl);
3327 constraint_satisfaction_value (t, args, noisy);
3328 if (DECL_P (t) && !args)
3329 /* Avoid giving these errors again. */
3330 TREE_NO_WARNING (t) = true;
3331 }
3332 return r;
3333 }
3334
3335 /* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
3336 and false otherwise, even in the case of errors.
3337
3338 Here, T can be:
3339 - a template declaration
3340 - a template specialization (in which case ARGS must be empty)
3341 - a concept-id (in which case ARGS must be empty)
3342 - a nested-requirement
3343 - a placeholder 'auto'
3344 - a requires-expression. */
3345
3346 bool
constraints_satisfied_p(tree t,tree args)3347 constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
3348 {
3349 if (!flag_concepts)
3350 return true;
3351
3352 sat_info quiet (tf_none, NULL_TREE);
3353 return constraint_satisfaction_value (t, args, quiet) == boolean_true_node;
3354 }
3355
3356 /* Evaluate a concept check of the form C<ARGS>. This is only used for the
3357 evaluation of template-ids as id-expressions. */
3358
3359 tree
evaluate_concept_check(tree check)3360 evaluate_concept_check (tree check)
3361 {
3362 if (check == error_mark_node)
3363 return error_mark_node;
3364
3365 gcc_assert (concept_check_p (check));
3366
3367 /* Check for satisfaction without diagnostics. */
3368 sat_info quiet (tf_none, NULL_TREE);
3369 return constraint_satisfaction_value (check, /*args=*/NULL_TREE, quiet);
3370 }
3371
3372 /* Evaluate the requires-expression T, returning either boolean_true_node
3373 or boolean_false_node. This is used during folding and constexpr
3374 evaluation. */
3375
3376 tree
evaluate_requires_expr(tree t)3377 evaluate_requires_expr (tree t)
3378 {
3379 gcc_assert (TREE_CODE (t) == REQUIRES_EXPR);
3380 sat_info quiet (tf_none, NULL_TREE);
3381 return constraint_satisfaction_value (t, /*args=*/NULL_TREE, quiet);
3382 }
3383
3384 /*---------------------------------------------------------------------------
3385 Semantic analysis of requires-expressions
3386 ---------------------------------------------------------------------------*/
3387
3388 /* Finish a requires expression for the given PARMS (possibly
3389 null) and the non-empty sequence of requirements. */
3390
3391 tree
finish_requires_expr(location_t loc,tree parms,tree reqs)3392 finish_requires_expr (location_t loc, tree parms, tree reqs)
3393 {
3394 /* Build the node. */
3395 tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs, NULL_TREE);
3396 TREE_SIDE_EFFECTS (r) = false;
3397 TREE_CONSTANT (r) = true;
3398 SET_EXPR_LOCATION (r, loc);
3399 return r;
3400 }
3401
3402 /* Construct a requirement for the validity of EXPR. */
3403
3404 tree
finish_simple_requirement(location_t loc,tree expr)3405 finish_simple_requirement (location_t loc, tree expr)
3406 {
3407 tree r = build_nt (SIMPLE_REQ, expr);
3408 SET_EXPR_LOCATION (r, loc);
3409 return r;
3410 }
3411
3412 /* Construct a requirement for the validity of TYPE. */
3413
3414 tree
finish_type_requirement(location_t loc,tree type)3415 finish_type_requirement (location_t loc, tree type)
3416 {
3417 tree r = build_nt (TYPE_REQ, type);
3418 SET_EXPR_LOCATION (r, loc);
3419 return r;
3420 }
3421
3422 /* Construct a requirement for the validity of EXPR, along with
3423 its properties. if TYPE is non-null, then it specifies either
3424 an implicit conversion or argument deduction constraint,
3425 depending on whether any placeholders occur in the type name.
3426 NOEXCEPT_P is true iff the noexcept keyword was specified. */
3427
3428 tree
finish_compound_requirement(location_t loc,tree expr,tree type,bool noexcept_p)3429 finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept_p)
3430 {
3431 tree req = build_nt (COMPOUND_REQ, expr, type);
3432 SET_EXPR_LOCATION (req, loc);
3433 COMPOUND_REQ_NOEXCEPT_P (req) = noexcept_p;
3434 return req;
3435 }
3436
3437 /* Finish a nested requirement. */
3438
3439 tree
finish_nested_requirement(location_t loc,tree expr)3440 finish_nested_requirement (location_t loc, tree expr)
3441 {
3442 /* Build the requirement, saving the set of in-scope template
3443 parameters as its type. */
3444 tree r = build1 (NESTED_REQ, current_template_parms, expr);
3445 SET_EXPR_LOCATION (r, loc);
3446 return r;
3447 }
3448
3449 /* Check that FN satisfies the structural requirements of a
3450 function concept definition. */
3451 tree
check_function_concept(tree fn)3452 check_function_concept (tree fn)
3453 {
3454 /* Check that the function is comprised of only a return statement. */
3455 tree body = DECL_SAVED_TREE (fn);
3456 if (TREE_CODE (body) == BIND_EXPR)
3457 body = BIND_EXPR_BODY (body);
3458
3459 /* Sometimes a function call results in the creation of clean up
3460 points. Allow these to be preserved in the body of the
3461 constraint, as we might actually need them for some constexpr
3462 evaluations. */
3463 if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
3464 body = TREE_OPERAND (body, 0);
3465
3466 /* Check that the definition is written correctly. */
3467 if (TREE_CODE (body) != RETURN_EXPR)
3468 {
3469 location_t loc = DECL_SOURCE_LOCATION (fn);
3470 if (TREE_CODE (body) == STATEMENT_LIST && !STATEMENT_LIST_HEAD (body))
3471 {
3472 if (seen_error ())
3473 /* The definition was probably erroneous, not empty. */;
3474 else
3475 error_at (loc, "definition of concept %qD is empty", fn);
3476 }
3477 else
3478 error_at (loc, "definition of concept %qD has multiple statements", fn);
3479 }
3480
3481 return NULL_TREE;
3482 }
3483
3484
3485 // Check that a constrained friend declaration function declaration,
3486 // FN, is admissible. This is the case only when the declaration depends
3487 // on template parameters and does not declare a specialization.
3488 void
check_constrained_friend(tree fn,tree reqs)3489 check_constrained_friend (tree fn, tree reqs)
3490 {
3491 if (fn == error_mark_node)
3492 return;
3493 gcc_assert (TREE_CODE (fn) == FUNCTION_DECL);
3494
3495 // If there are not constraints, this cannot be an error.
3496 if (!reqs)
3497 return;
3498
3499 // Constrained friend functions that don't depend on template
3500 // arguments are effectively meaningless.
3501 if (!uses_template_parms (TREE_TYPE (fn)))
3502 {
3503 error_at (location_of (fn),
3504 "constrained friend does not depend on template parameters");
3505 return;
3506 }
3507 }
3508
3509 /*---------------------------------------------------------------------------
3510 Equivalence of constraints
3511 ---------------------------------------------------------------------------*/
3512
3513 /* Returns true when A and B are equivalent constraints. */
3514 bool
equivalent_constraints(tree a,tree b)3515 equivalent_constraints (tree a, tree b)
3516 {
3517 gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
3518 gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
3519 return cp_tree_equal (a, b);
3520 }
3521
3522 /* Returns true if the template declarations A and B have equivalent
3523 constraints. This is the case when A's constraints subsume B's and
3524 when B's also constrain A's. */
3525 bool
equivalently_constrained(tree d1,tree d2)3526 equivalently_constrained (tree d1, tree d2)
3527 {
3528 gcc_assert (TREE_CODE (d1) == TREE_CODE (d2));
3529 return equivalent_constraints (get_constraints (d1), get_constraints (d2));
3530 }
3531
3532 /*---------------------------------------------------------------------------
3533 Partial ordering of constraints
3534 ---------------------------------------------------------------------------*/
3535
3536 /* Returns true when the constraints in A subsume those in B. */
3537
3538 bool
subsumes_constraints(tree a,tree b)3539 subsumes_constraints (tree a, tree b)
3540 {
3541 gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
3542 gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
3543 return subsumes (a, b);
3544 }
3545
3546 /* Returns true when the constraints in CI strictly subsume
3547 the associated constraints of TMPL. */
3548
3549 bool
strictly_subsumes(tree ci,tree tmpl)3550 strictly_subsumes (tree ci, tree tmpl)
3551 {
3552 tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
3553 tree n2 = get_normalized_constraints_from_decl (tmpl);
3554
3555 return subsumes (n1, n2) && !subsumes (n2, n1);
3556 }
3557
3558 /* Returns true when the constraints in CI subsume the
3559 associated constraints of TMPL. */
3560
3561 bool
weakly_subsumes(tree ci,tree tmpl)3562 weakly_subsumes (tree ci, tree tmpl)
3563 {
3564 tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
3565 tree n2 = get_normalized_constraints_from_decl (tmpl);
3566
3567 return subsumes (n1, n2);
3568 }
3569
3570 /* Determines which of the declarations, A or B, is more constrained.
3571 That is, which declaration's constraints subsume but are not subsumed
3572 by the other's?
3573
3574 Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
3575 than D1, and 0 otherwise. */
3576
3577 int
more_constrained(tree d1,tree d2)3578 more_constrained (tree d1, tree d2)
3579 {
3580 tree n1 = get_normalized_constraints_from_decl (d1);
3581 tree n2 = get_normalized_constraints_from_decl (d2);
3582
3583 int winner = 0;
3584 if (subsumes (n1, n2))
3585 ++winner;
3586 if (subsumes (n2, n1))
3587 --winner;
3588 return winner;
3589 }
3590
3591 /* Return whether D1 is at least as constrained as D2. */
3592
3593 bool
at_least_as_constrained(tree d1,tree d2)3594 at_least_as_constrained (tree d1, tree d2)
3595 {
3596 tree n1 = get_normalized_constraints_from_decl (d1);
3597 tree n2 = get_normalized_constraints_from_decl (d2);
3598
3599 return subsumes (n1, n2);
3600 }
3601
3602 /*---------------------------------------------------------------------------
3603 Constraint diagnostics
3604 ---------------------------------------------------------------------------*/
3605
3606 /* Returns the best location to diagnose a constraint error. */
3607
3608 static location_t
get_constraint_error_location(tree t)3609 get_constraint_error_location (tree t)
3610 {
3611 if (location_t loc = cp_expr_location (t))
3612 return loc;
3613
3614 /* If we have a specific location give it. */
3615 tree expr = CONSTR_EXPR (t);
3616 if (location_t loc = cp_expr_location (expr))
3617 return loc;
3618
3619 /* If the constraint is normalized from a requires-clause, give
3620 the location as that of the constrained declaration. */
3621 tree cxt = CONSTR_CONTEXT (t);
3622 tree src = cxt ? TREE_VALUE (cxt) : NULL_TREE;
3623 if (!src)
3624 /* TODO: This only happens for constrained non-template declarations. */
3625 ;
3626 else if (DECL_P (src))
3627 return DECL_SOURCE_LOCATION (src);
3628 /* Otherwise, give the location as the defining concept. */
3629 else if (concept_check_p (src))
3630 {
3631 tree id = unpack_concept_check (src);
3632 tree tmpl = TREE_OPERAND (id, 0);
3633 if (OVL_P (tmpl))
3634 tmpl = OVL_FIRST (tmpl);
3635 return DECL_SOURCE_LOCATION (tmpl);
3636 }
3637
3638 return input_location;
3639 }
3640
3641 /* Emit a diagnostic for a failed trait. */
3642
3643 static void
diagnose_trait_expr(tree expr,tree args)3644 diagnose_trait_expr (tree expr, tree args)
3645 {
3646 location_t loc = cp_expr_location (expr);
3647
3648 /* Build a "fake" version of the instantiated trait, so we can
3649 get the instantiated types from result. */
3650 ++processing_template_decl;
3651 expr = tsubst_expr (expr, args, tf_none, NULL_TREE, false);
3652 --processing_template_decl;
3653
3654 tree t1 = TRAIT_EXPR_TYPE1 (expr);
3655 tree t2 = TRAIT_EXPR_TYPE2 (expr);
3656 switch (TRAIT_EXPR_KIND (expr))
3657 {
3658 case CPTK_HAS_NOTHROW_ASSIGN:
3659 inform (loc, " %qT is not %<nothrow%> copy assignable", t1);
3660 break;
3661 case CPTK_HAS_NOTHROW_CONSTRUCTOR:
3662 inform (loc, " %qT is not %<nothrow%> default constructible", t1);
3663 break;
3664 case CPTK_HAS_NOTHROW_COPY:
3665 inform (loc, " %qT is not %<nothrow%> copy constructible", t1);
3666 break;
3667 case CPTK_HAS_TRIVIAL_ASSIGN:
3668 inform (loc, " %qT is not trivially copy assignable", t1);
3669 break;
3670 case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
3671 inform (loc, " %qT is not trivially default constructible", t1);
3672 break;
3673 case CPTK_HAS_TRIVIAL_COPY:
3674 inform (loc, " %qT is not trivially copy constructible", t1);
3675 break;
3676 case CPTK_HAS_TRIVIAL_DESTRUCTOR:
3677 inform (loc, " %qT is not trivially destructible", t1);
3678 break;
3679 case CPTK_HAS_VIRTUAL_DESTRUCTOR:
3680 inform (loc, " %qT does not have a virtual destructor", t1);
3681 break;
3682 case CPTK_IS_ABSTRACT:
3683 inform (loc, " %qT is not an abstract class", t1);
3684 break;
3685 case CPTK_IS_BASE_OF:
3686 inform (loc, " %qT is not a base of %qT", t1, t2);
3687 break;
3688 case CPTK_IS_CLASS:
3689 inform (loc, " %qT is not a class", t1);
3690 break;
3691 case CPTK_IS_EMPTY:
3692 inform (loc, " %qT is not an empty class", t1);
3693 break;
3694 case CPTK_IS_ENUM:
3695 inform (loc, " %qT is not an enum", t1);
3696 break;
3697 case CPTK_IS_FINAL:
3698 inform (loc, " %qT is not a final class", t1);
3699 break;
3700 case CPTK_IS_LITERAL_TYPE:
3701 inform (loc, " %qT is not a literal type", t1);
3702 break;
3703 case CPTK_IS_POD:
3704 inform (loc, " %qT is not a POD type", t1);
3705 break;
3706 case CPTK_IS_POLYMORPHIC:
3707 inform (loc, " %qT is not a polymorphic type", t1);
3708 break;
3709 case CPTK_IS_SAME_AS:
3710 inform (loc, " %qT is not the same as %qT", t1, t2);
3711 break;
3712 case CPTK_IS_STD_LAYOUT:
3713 inform (loc, " %qT is not an standard layout type", t1);
3714 break;
3715 case CPTK_IS_TRIVIAL:
3716 inform (loc, " %qT is not a trivial type", t1);
3717 break;
3718 case CPTK_IS_UNION:
3719 inform (loc, " %qT is not a union", t1);
3720 break;
3721 default:
3722 gcc_unreachable ();
3723 }
3724 }
3725
3726 /* Diagnose a substitution failure in the atomic constraint T when applied
3727 with the instantiated parameter mapping MAP. */
3728
3729 static void
diagnose_atomic_constraint(tree t,tree map,tree result,sat_info info)3730 diagnose_atomic_constraint (tree t, tree map, tree result, sat_info info)
3731 {
3732 /* If the constraint is already ill-formed, we've previously diagnosed
3733 the reason. We should still say why the constraints aren't satisfied. */
3734 if (t == error_mark_node)
3735 {
3736 location_t loc;
3737 if (info.in_decl)
3738 loc = DECL_SOURCE_LOCATION (info.in_decl);
3739 else
3740 loc = input_location;
3741 inform (loc, "invalid constraints");
3742 return;
3743 }
3744
3745 location_t loc = get_constraint_error_location (t);
3746 iloc_sentinel loc_s (loc);
3747
3748 /* Generate better diagnostics for certain kinds of expressions. */
3749 tree expr = ATOMIC_CONSTR_EXPR (t);
3750 STRIP_ANY_LOCATION_WRAPPER (expr);
3751 tree args = get_mapped_args (map);
3752 switch (TREE_CODE (expr))
3753 {
3754 case TRAIT_EXPR:
3755 diagnose_trait_expr (expr, args);
3756 break;
3757 case REQUIRES_EXPR:
3758 gcc_checking_assert (info.diagnose_unsatisfaction_p ());
3759 /* Clear in_decl before replaying the substitution to avoid emitting
3760 seemingly unhelpful "in declaration ..." notes that follow some
3761 substitution failure error messages. */
3762 info.in_decl = NULL_TREE;
3763 tsubst_requires_expr (expr, args, info);
3764 break;
3765 default:
3766 if (!same_type_p (TREE_TYPE (result), boolean_type_node))
3767 error_at (loc, "constraint %qE has type %qT, not %<bool%>",
3768 t, TREE_TYPE (result));
3769 else
3770 inform (loc, "the expression %qE evaluated to %<false%>", t);
3771 }
3772 }
3773
3774 GTY(()) tree current_failed_constraint;
3775
3776 diagnosing_failed_constraint::
diagnosing_failed_constraint(tree t,tree args,bool diag)3777 diagnosing_failed_constraint (tree t, tree args, bool diag)
3778 : diagnosing_error (diag)
3779 {
3780 if (diagnosing_error)
3781 {
3782 current_failed_constraint
3783 = tree_cons (args, t, current_failed_constraint);
3784 ++current_constraint_diagnosis_depth;
3785 }
3786 }
3787
3788 diagnosing_failed_constraint::
~diagnosing_failed_constraint()3789 ~diagnosing_failed_constraint ()
3790 {
3791 if (diagnosing_error)
3792 {
3793 --current_constraint_diagnosis_depth;
3794 if (current_failed_constraint)
3795 current_failed_constraint = TREE_CHAIN (current_failed_constraint);
3796 }
3797
3798 }
3799
3800 /* Whether we are allowed to replay an error that underlies a constraint failure
3801 at the current diagnosis depth. */
3802
3803 bool
replay_errors_p()3804 diagnosing_failed_constraint::replay_errors_p ()
3805 {
3806 if (current_constraint_diagnosis_depth >= concepts_diagnostics_max_depth)
3807 {
3808 concepts_diagnostics_max_depth_exceeded_p = true;
3809 return false;
3810 }
3811 else
3812 return true;
3813 }
3814
3815 /* Emit diagnostics detailing the failure ARGS to satisfy the constraints
3816 of T. Here, T and ARGS are as in constraints_satisfied_p. */
3817
3818 void
diagnose_constraints(location_t loc,tree t,tree args)3819 diagnose_constraints (location_t loc, tree t, tree args)
3820 {
3821 inform (loc, "constraints not satisfied");
3822
3823 if (concepts_diagnostics_max_depth == 0)
3824 return;
3825
3826 /* Replay satisfaction, but diagnose unsatisfaction. */
3827 sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
3828 constraint_satisfaction_value (t, args, noisy);
3829
3830 static bool suggested_p;
3831 if (concepts_diagnostics_max_depth_exceeded_p
3832 && current_constraint_diagnosis_depth == 0
3833 && !suggested_p)
3834 {
3835 inform (UNKNOWN_LOCATION,
3836 "set %qs to at least %d for more detail",
3837 "-fconcepts-diagnostics-depth=",
3838 concepts_diagnostics_max_depth + 1);
3839 suggested_p = true;
3840 }
3841 }
3842
3843 #include "gt-cp-constraint.h"
3844