LCOV - code coverage report
Current view: top level - gcc/cp - constraint.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.3 % 1548 1429
Test Date: 2026-09-12 16:25:28 Functions: 98.3 % 121 119
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Processing rules for constraints.
       2              :    Copyright (C) 2013-2026 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    219075704 : processing_constraint_expression_sentinel::
      56              : processing_constraint_expression_sentinel ()
      57              : {
      58    219075704 :   ++scope_chain->x_processing_constraint;
      59    219075704 : }
      60              : 
      61    219075704 : processing_constraint_expression_sentinel::
      62              : ~processing_constraint_expression_sentinel ()
      63              : {
      64    219075704 :   --scope_chain->x_processing_constraint;
      65    219075704 : }
      66              : 
      67              : bool
      68      9534216 : processing_constraint_expression_p ()
      69              : {
      70      9534216 :   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              : {
      81   1184733662 :   subst_info (tsubst_flags_t cmp, tree in)
      82   1184733662 :     : complain (cmp), in_decl (in)
      83              :   { }
      84              : 
      85              :   /* True if we should not diagnose errors.  */
      86   2684700004 :   bool quiet () const
      87              :   {
      88   2684700004 :     return !(complain & tf_warning_or_error);
      89              :   }
      90              : 
      91              :   /* True if we should diagnose errors.  */
      92   1962663942 :   bool noisy () const
      93              :   {
      94   1990658038 :     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              : {
     131   1104896864 :   sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false)
     132   1104896864 :     : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat)
     133              :   {
     134   1104896864 :     if (diagnose_unsatisfaction_p ())
     135         1382 :       gcc_checking_assert (noisy ());
     136              :   }
     137              : 
     138              :   /* True if we should diagnose the cause of satisfaction failure.
     139              :      Implies noisy().  */
     140              :   bool
     141   1114295906 :   diagnose_unsatisfaction_p () const
     142              :   {
     143   1114295906 :     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
     155     32479320 : known_non_bool_p (tree t)
     156              : {
     157     32479320 :   return (t && !WILDCARD_TYPE_P (t) && TREE_CODE (t) != BOOLEAN_TYPE);
     158              : }
     159              : 
     160              : static bool
     161     32479320 : check_constraint_atom (cp_expr expr)
     162              : {
     163     32479320 :   if (known_non_bool_p (TREE_TYPE (expr)))
     164              :     {
     165           10 :       error_at (expr.get_location (),
     166              :                 "constraint expression does not have type %<bool%>");
     167           10 :       return false;
     168              :     }
     169              : 
     170              :   return true;
     171              : }
     172              : 
     173              : static bool
     174      9528070 : check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
     175              : {
     176      9528070 :   return check_constraint_atom (lhs) && check_constraint_atom (rhs);
     177              : }
     178              : 
     179              : /* Validate the semantic properties of the constraint expression.  */
     180              : 
     181              : static cp_expr
     182      9528076 : finish_constraint_binary_op (location_t loc,
     183              :                              tree_code code,
     184              :                              cp_expr lhs,
     185              :                              cp_expr rhs)
     186              : {
     187      9528076 :   gcc_assert (processing_constraint_expression_p ());
     188      9528076 :   if (lhs == error_mark_node || rhs == error_mark_node)
     189            6 :     return error_mark_node;
     190      9528070 :   if (!check_constraint_operands (loc, lhs, rhs))
     191            0 :     return error_mark_node;
     192      9528070 :   cp_expr expr
     193      9528070 :     = build_min_nt_loc (loc, code, lhs.get_value (), rhs.get_value ());
     194      9528070 :   expr.set_range (lhs.get_start (), rhs.get_finish ());
     195      9528070 :   return expr;
     196              : }
     197              : 
     198              : cp_expr
     199       482894 : finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
     200              : {
     201       482894 :   return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
     202              : }
     203              : 
     204              : cp_expr
     205      9045182 : finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
     206              : {
     207      9045182 :   return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
     208              : }
     209              : 
     210              : cp_expr
     211     13423212 : finish_constraint_primary_expr (cp_expr expr)
     212              : {
     213     13423212 :   if (expr == error_mark_node)
     214           32 :     return error_mark_node;
     215     13423180 :   if (!check_constraint_atom (expr))
     216           10 :     return cp_expr (error_mark_node, expr.get_location ());
     217     13423170 :   return expr;
     218              : }
     219              : 
     220              : /* Combine two constraint-expressions with a logical-and.  */
     221              : 
     222              : tree
     223    201778196 : combine_constraint_expressions (tree lhs, tree rhs)
     224              : {
     225    201778196 :   processing_constraint_expression_sentinel pce;
     226    201778196 :   if (!lhs)
     227              :     return rhs;
     228     27751872 :   if (!rhs)
     229              :     return lhs;
     230              :   /* Use UNKNOWN_LOCATION so write_template_args can tell the difference
     231              :      between this and a && the user wrote.  */
     232      5673046 :   return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs);
     233    201778196 : }
     234              : 
     235              : /* Extract the TEMPLATE_DECL from a concept check.  */
     236              : 
     237              : tree
     238     24641783 : get_concept_check_template (tree t)
     239              : {
     240     24641783 :   gcc_assert (concept_check_p (t));
     241     24641783 :   return TREE_OPERAND (t, 0);
     242              : }
     243              : 
     244              : /*---------------------------------------------------------------------------
     245              :                        Expansion of concept definitions
     246              : ---------------------------------------------------------------------------*/
     247              : 
     248              : /* Returns the definition of a concept.  */
     249              : 
     250              : static tree
     251     22072900 : get_concept_definition (tree decl)
     252              : {
     253     22072900 :   gcc_assert (TREE_CODE (decl) == CONCEPT_DECL);
     254     22072900 :   return DECL_INITIAL (decl);
     255              : }
     256              : 
     257              : /*---------------------------------------------------------------------------
     258              :                       Normalization of expressions
     259              : 
     260              : This set of functions will transform an expression into a constraint
     261              : in a sequence of steps.
     262              : ---------------------------------------------------------------------------*/
     263              : 
     264              : void
     265            0 : debug_parameter_mapping (tree map)
     266              : {
     267            0 :   for (tree p = map; p; p = TREE_CHAIN (p))
     268              :     {
     269            0 :       tree parm = TREE_VALUE (p);
     270            0 :       tree arg = TREE_PURPOSE (p);
     271            0 :       if (TYPE_P (parm))
     272            0 :         verbatim ("MAP %qD TO %qT", TEMPLATE_TYPE_DECL (parm), arg);
     273              :       else
     274            0 :         verbatim ("MAP %qD TO %qE", TEMPLATE_PARM_DECL (parm), arg);
     275              :       // debug_tree (parm);
     276              :       // debug_tree (arg);
     277              :     }
     278            0 : }
     279              : 
     280              : void
     281            0 : debug_argument_list (tree args)
     282              : {
     283            0 :   for (int i = 0; i < TREE_VEC_LENGTH (args); ++i)
     284              :     {
     285            0 :       tree arg = TREE_VEC_ELT (args, i);
     286            0 :       if (TYPE_P (arg))
     287            0 :         verbatim ("argument %qT", arg);
     288              :       else
     289            0 :         verbatim ("argument %qE", arg);
     290              :     }
     291            0 : }
     292              : 
     293              : /* Associate each parameter in PARMS with its corresponding template
     294              :    argument in ARGS.  */
     295              : 
     296              : static tree
     297     25003897 : map_arguments (tree parms, tree args)
     298              : {
     299     68501161 :   for (tree p = parms; p; p = TREE_CHAIN (p))
     300     43497264 :     if (args)
     301              :       {
     302     37179465 :         int level;
     303     37179465 :         int index;
     304     37179465 :         template_parm_level_and_index (TREE_VALUE (p), &level, &index);
     305     37179465 :         TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
     306              :       }
     307              :     else
     308      6317799 :       TREE_PURPOSE (p) = template_parm_to_arg (p);
     309              : 
     310     25003897 :   return parms;
     311              : }
     312              : 
     313              : /* Build the parameter mapping for EXPR using ARGS, where CTX_PARMS
     314              :    are the template parameters in scope for EXPR.  */
     315              : 
     316              : static tree
     317     25003897 : build_parameter_mapping (tree expr, tree args, tree ctx_parms)
     318              : {
     319     25003897 :   tree parms = find_template_parameters (expr, ctx_parms);
     320     25003897 :   tree map = map_arguments (parms, args);
     321     25003897 :   return map;
     322              : }
     323              : 
     324              : /* True if the parameter mappings of two atomic constraints formed
     325              :    from the same expression are equivalent.  */
     326              : 
     327              : static bool
     328     59025895 : parameter_mapping_equivalent_p (tree t1, tree t2)
     329              : {
     330     59025895 :   tree map1 = ATOMIC_CONSTR_MAP (t1);
     331     59025895 :   tree map2 = ATOMIC_CONSTR_MAP (t2);
     332    123371820 :   while (map1 && map2)
     333              :     {
     334     89492585 :       gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2));
     335     89492585 :       tree arg1 = TREE_PURPOSE (map1);
     336     89492585 :       tree arg2 = TREE_PURPOSE (map2);
     337     89492585 :       if (!template_args_equal (arg1, arg2))
     338              :         return false;
     339     64345925 :       map1 = TREE_CHAIN (map1);
     340     64345925 :       map2 = TREE_CHAIN (map2);
     341              :     }
     342     33879235 :   gcc_checking_assert (!map1 && !map2);
     343              :   return true;
     344              : }
     345              : 
     346              : /* Provides additional context for normalization.  */
     347              : 
     348              : struct norm_info : subst_info
     349              : {
     350      9617030 :   explicit norm_info (bool diag)
     351      9617030 :     : norm_info (NULL_TREE, diag)
     352              :   {}
     353              : 
     354              :   /* Construct a top-level context for DECL.  */
     355              : 
     356     13293843 :   norm_info (tree in_decl, bool diag)
     357              :     : subst_info (tf_warning_or_error|tf_partial, in_decl),
     358     13293843 :       generate_diagnostics (diag)
     359              :   {
     360      3676813 :     if (in_decl)
     361              :       {
     362      2972006 :         initial_parms = DECL_TEMPLATE_PARMS (in_decl);
     363      2972006 :         if (generate_diagnostics)
     364         1372 :           context = build_tree_list (NULL_TREE, in_decl);
     365              :       }
     366              :     else
     367       704807 :       initial_parms = current_template_parms;
     368      3676813 :   }
     369              : 
     370     21724980 :   void update_context (tree expr, tree args)
     371              :   {
     372     21724980 :     if (generate_diagnostics)
     373              :       {
     374         3467 :         tree map = build_parameter_mapping (expr, args, ctx_parms ());
     375         3467 :         context = tree_cons (map, expr, context);
     376              :       }
     377     21724980 :     in_decl = get_concept_check_template (expr);
     378     21724980 :   }
     379              : 
     380              :   /* Returns the template parameters that are in scope for the current
     381              :      normalization context.  */
     382              : 
     383     25003897 :   tree ctx_parms ()
     384              :   {
     385     25003897 :     if (in_decl)
     386     24512624 :       return DECL_TEMPLATE_PARMS (in_decl);
     387              :     else
     388       491273 :       return initial_parms;
     389              :   }
     390              : 
     391              :   /* Provides information about the source of a constraint.  This is a
     392              :      TREE_LIST whose VALUE is either a concept check or a constrained
     393              :      declaration.  The PURPOSE, for concept checks is a parameter mapping
     394              :      for that check.  */
     395              : 
     396              :   tree context = NULL_TREE;
     397              : 
     398              :   /* The declaration whose constraints we're normalizing.  The targets
     399              :      of the parameter mapping of each atom will be in terms of the
     400              :      template parameters of ORIG_DECL.  */
     401              : 
     402              :   tree initial_parms = NULL_TREE;
     403              : 
     404              :   /* Whether to build diagnostic information during normalization.  */
     405              : 
     406              :   bool generate_diagnostics;
     407              : };
     408              : 
     409              : static tree normalize_expression (tree, tree, norm_info);
     410              : 
     411              : /* Transform a logical-or or logical-and expression into either
     412              :    a conjunction or disjunction.  */
     413              : 
     414              : static tree
     415     24864227 : normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
     416              : {
     417     24864227 :   tree t0 = normalize_expression (TREE_OPERAND (t, 0), args, info);
     418     24864227 :   tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);
     419              : 
     420              :   /* Build a new info object for the constraint.  */
     421     24864227 :   tree ci = (info.generate_diagnostics
     422     24864227 :              ? build_tree_list (t, info.context) : NULL_TREE);
     423              : 
     424     24864227 :   return build2 (c, ci, t0, t1);
     425              : }
     426              : 
     427              : /* Data types and hash functions for caching the normal form of a concept-id.
     428              :    This essentially memoizes calls to normalize_concept_check.  */
     429              : 
     430              : struct GTY((for_user)) norm_entry
     431              : {
     432              :   /* The CONCEPT_DECL of the concept-id.  */
     433              :   tree tmpl;
     434              :   /* The arguments of the concept-id.  */
     435              :   tree args;
     436              :   /* The normal form of the concept-id.  */
     437              :   tree norm;
     438              : };
     439              : 
     440              : struct norm_hasher : ggc_ptr_hash<norm_entry>
     441              : {
     442    208183223 :   static hashval_t hash (norm_entry *e)
     443              :   {
     444    208183223 :     ++comparing_specializations;
     445    208183223 :     hashval_t val = iterative_hash_template_arg (e->tmpl, 0);
     446    208183223 :     val = iterative_hash_template_arg (e->args, val);
     447    208183223 :     --comparing_specializations;
     448    208183223 :     return val;
     449              :   }
     450              : 
     451    232779283 :   static bool equal (norm_entry *e1, norm_entry *e2)
     452              :   {
     453    232779283 :     ++comparing_specializations;
     454    232779283 :     bool eq = e1->tmpl == e2->tmpl
     455    232779283 :       && template_args_equal (e1->args, e2->args);
     456    232779283 :     --comparing_specializations;
     457    232779283 :     return eq;
     458              :   }
     459              : };
     460              : 
     461              : static GTY((deletable)) hash_table<norm_hasher> *norm_cache;
     462              : 
     463              : /* Normalize the concept check CHECK where ARGS are the
     464              :    arguments to be substituted into CHECK's arguments.  */
     465              : 
     466              : static tree
     467     26988528 : normalize_concept_check (tree check, tree args, norm_info info)
     468              : {
     469     26988528 :   gcc_assert (concept_check_p (check));
     470     26988528 :   tree tmpl = TREE_OPERAND (check, 0);
     471     26988528 :   tree targs = TREE_OPERAND (check, 1);
     472              : 
     473              :   /* Substitute through the arguments of the concept check.  */
     474     26988528 :   if (args)
     475     19638014 :     targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
     476     26988528 :   if (targs == error_mark_node)
     477              :     return error_mark_node;
     478     26988528 :   if (template_args_equal (targs, generic_targs_for (tmpl)))
     479              :     /* Canonicalize generic arguments as NULL_TREE, as an optimization.  */
     480      3544207 :     targs = NULL_TREE;
     481              : 
     482              :   /* Build the substitution for the concept definition.  */
     483     26988528 :   tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
     484     26988528 :   if (targs && args)
     485              :     /* As an optimization, coerce the arguments only if necessary
     486              :        (i.e. if they were substituted).  */
     487     19233328 :     targs = coerce_template_parms (parms, targs, tmpl, tf_none);
     488     26988528 :   if (targs == error_mark_node)
     489              :     return error_mark_node;
     490              : 
     491     26988528 :   if (!norm_cache)
     492        84875 :     norm_cache = hash_table<norm_hasher>::create_ggc (31);
     493     26988528 :   norm_entry *entry = nullptr;
     494     26988528 :   if (!info.generate_diagnostics)
     495              :     {
     496              :       /* Cache the normal form of the substituted concept-id (when not
     497              :          diagnosing).  */
     498     26985061 :       norm_entry elt = {tmpl, targs, NULL_TREE};
     499     26985061 :       norm_entry **slot = norm_cache->find_slot (&elt, INSERT);
     500     26985061 :       if (*slot)
     501      5263548 :         return (*slot)->norm;
     502     21721513 :       entry = ggc_alloc<norm_entry> ();
     503     21721513 :       *entry = elt;
     504     21721513 :       *slot = entry;
     505              :     }
     506              : 
     507     21724980 :   tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
     508     21724980 :   info.update_context (check, args);
     509     21724980 :   tree norm = normalize_expression (def, targs, info);
     510     21724980 :   if (entry)
     511     21721513 :     entry->norm = norm;
     512              :   return norm;
     513              : }
     514              : 
     515              : /* A structural hasher for ATOMIC_CONSTRs.  */
     516              : 
     517              : struct atom_hasher : default_hash_traits<tree>
     518              : {
     519    193156775 :   static hashval_t hash (tree t)
     520              :   {
     521    193156775 :     ++comparing_specializations;
     522    193156775 :     hashval_t val = hash_atomic_constraint (t);
     523    193156775 :     --comparing_specializations;
     524    193156775 :     return val;
     525              :   }
     526              : 
     527    174617302 :   static bool equal (tree t1, tree t2)
     528              :   {
     529    174617302 :     ++comparing_specializations;
     530    174617302 :     bool eq = atomic_constraints_identical_p (t1, t2);
     531    174617302 :     --comparing_specializations;
     532    174617302 :     return eq;
     533              :   }
     534              : };
     535              : 
     536              : /* Used by normalize_atom to cache ATOMIC_CONSTRs.  */
     537              : 
     538              : static GTY((deletable)) hash_table<atom_hasher> *atom_cache;
     539              : 
     540              : /* The normal form of an atom is an atomic constraint.  */
     541              : 
     542              : static tree
     543     51988958 : normalize_atom (tree t, tree args, norm_info info)
     544              : {
     545              :   /* Concept checks are not atomic.  */
     546     51988958 :   if (concept_check_p (t))
     547     26988528 :     return normalize_concept_check (t, args, info);
     548              : 
     549              :   /* Build the parameter mapping for the atom.  */
     550     25000430 :   tree map = build_parameter_mapping (t, args, info.ctx_parms ());
     551              : 
     552              :   /* Build a new info object for the atom.  */
     553     25000430 :   tree ci = build_tree_list (t, info.context);
     554              : 
     555     25000430 :   tree atom = build1 (ATOMIC_CONSTR, ci, map);
     556              : 
     557              :   /* Remember whether the expression of this atomic constraint belongs to
     558              :      a concept definition by inspecting in_decl, which should always be set
     559              :      in this case either by norm_info::update_context (when recursing into a
     560              :      concept-id during normalization) or by normalize_concept_definition
     561              :      (when starting out with a concept-id).  */
     562     49509719 :   if (info.in_decl && concept_definition_p (info.in_decl))
     563     22261070 :     ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (atom) = true;
     564              : 
     565     25000430 :   if (!info.generate_diagnostics)
     566              :     {
     567              :       /* Cache the ATOMIC_CONSTRs that we return, so that sat_hasher::equal
     568              :          later can cheaply compare two atoms using just pointer equality.  */
     569     24995876 :       if (!atom_cache)
     570        95288 :         atom_cache = hash_table<atom_hasher>::create_ggc (31);
     571     24995876 :       tree *slot = atom_cache->find_slot (atom, INSERT);
     572     24995876 :       if (*slot)
     573              :         return *slot;
     574              : 
     575              :       /* Find all template parameters used in the targets of the parameter
     576              :          mapping, and store a list of them in the TREE_TYPE of the mapping.
     577              :          This list will be used by sat_hasher to determine the subset of
     578              :          supplied template arguments that the satisfaction value of the atom
     579              :          depends on.  */
     580     24319795 :       if (map)
     581              :         {
     582     24319035 :           tree targets = make_tree_vec (list_length (map));
     583     24319035 :           int i = 0;
     584     91394993 :           for (tree node = map; node; node = TREE_CHAIN (node))
     585              :             {
     586     42756923 :               tree target = TREE_PURPOSE (node);
     587     42756923 :               TREE_VEC_ELT (targets, i++) = target;
     588              :             }
     589     24319035 :           tree target_parms = find_template_parameters (targets,
     590              :                                                         info.initial_parms);
     591     24319035 :           TREE_TYPE (map) = target_parms;
     592              :         }
     593              : 
     594     24319795 :       *slot = atom;
     595              :     }
     596              :   return atom;
     597              : }
     598              : 
     599              : /* Returns the normal form of an expression.  */
     600              : 
     601              : static tree
     602     76853308 : normalize_expression (tree t, tree args, norm_info info)
     603              : {
     604     76853308 :   if (!t)
     605              :     return NULL_TREE;
     606              : 
     607     76853308 :   if (t == error_mark_node)
     608              :     return error_mark_node;
     609              : 
     610     76853185 :   switch (TREE_CODE (t))
     611              :     {
     612     23981735 :     case TRUTH_ANDIF_EXPR:
     613     23981735 :       return normalize_logical_operation (t, args, CONJ_CONSTR, info);
     614       882492 :     case TRUTH_ORIF_EXPR:
     615       882492 :       return normalize_logical_operation (t, args, DISJ_CONSTR, info);
     616     51988958 :     default:
     617     51988958 :       return normalize_atom (t, args, info);
     618              :     }
     619              : }
     620              : 
     621              : /* Cache of the normalized form of constraints.  Marked as deletable because it
     622              :    can all be recalculated.  */
     623              : static GTY((deletable)) hash_map<tree,tree> *normalized_map;
     624              : 
     625              : static tree
     626      5399874 : get_normalized_constraints (tree t, norm_info info)
     627              : {
     628      5399874 :   auto_timevar time (TV_CONSTRAINT_NORM);
     629      5399874 :   return normalize_expression (t, NULL_TREE, info);
     630      5399874 : }
     631              : 
     632              : /* Returns the normalized constraints from a constraint-info object
     633              :    or NULL_TREE if the constraints are null.  IN_DECL provides the
     634              :    declaration to which the constraints belong.  */
     635              : 
     636              : static tree
     637      3328901 : get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
     638              : {
     639      3328901 :   if (ci == NULL_TREE)
     640              :     return NULL_TREE;
     641              : 
     642              :   /* Substitution errors during normalization are fatal.  */
     643      3328893 :   ++processing_template_decl;
     644      3328893 :   norm_info info (in_decl, diag);
     645      6657786 :   tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci), info);
     646      3328893 :   --processing_template_decl;
     647              : 
     648      3328893 :   return t;
     649              : }
     650              : 
     651              : /* Returns the normalized constraints for the declaration D.  */
     652              : 
     653              : static tree
     654    431143645 : get_normalized_constraints_from_decl (tree d, bool diag = false)
     655              : {
     656    431143645 :   tree tmpl;
     657    431143645 :   tree decl;
     658              : 
     659              :   /* For inherited constructors, consider the original declaration;
     660              :      it has the correct template information attached.  */
     661    431143645 :   d = strip_inheriting_ctors (d);
     662              : 
     663    431143645 :   if (regenerated_lambda_fn_p (d))
     664              :     {
     665              :       /* If this lambda was regenerated, DECL_TEMPLATE_PARMS doesn't contain
     666              :          all in-scope template parameters, but the lambda from which it was
     667              :          ultimately regenerated does, so use that instead.  */
     668       498249 :       tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (d));
     669       498249 :       lambda = most_general_lambda (lambda);
     670       498249 :       d = lambda_function (lambda);
     671              :     }
     672              : 
     673    431143645 :   if (TREE_CODE (d) == TEMPLATE_DECL)
     674              :     {
     675    303904721 :       tmpl = d;
     676    303904721 :       decl = DECL_TEMPLATE_RESULT (tmpl);
     677              :     }
     678              :   else
     679              :     {
     680    127238924 :       if (tree ti = DECL_TEMPLATE_INFO (d))
     681     87333067 :         tmpl = TI_TEMPLATE (ti);
     682              :       else
     683              :         tmpl = NULL_TREE;
     684     87333067 :       decl = d;
     685              :     }
     686              : 
     687              :   /* Get the most general template for the declaration, and compute
     688              :      arguments from that.  This ensures that the arguments used for
     689              :      normalization are always template parameters and not arguments
     690              :      used for outer specializations.  For example:
     691              : 
     692              :         template<typename T>
     693              :         struct S {
     694              :           template<typename U> requires C<T, U> void f(U);
     695              :         };
     696              : 
     697              :         S<int>::f(0);
     698              : 
     699              :      When we normalize the requirements for S<int>::f, we want the
     700              :      arguments to be {T, U}, not {int, U}.  One reason for this is that
     701              :      accepting the latter causes the template parameter level of U
     702              :      to be reduced in a way that makes it overly difficult substitute
     703              :      concrete arguments (i.e., eventually {int, int} during satisfaction.  */
     704    391237788 :   if (tmpl && DECL_LANG_SPECIFIC (tmpl)
     705    478570840 :       && (!DECL_TEMPLATE_SPECIALIZATION (tmpl)
     706              :           /* DECL_TEMPLATE_SPECIALIZATION means TMPL is either a partial
     707              :              specialization, or an explicit specialization of a member
     708              :              template.  In the former case all is well: TMPL's constraints
     709              :              are in terms of its parameters.  But in the latter case TMPL's
     710              :              parameters are partially instantiated whereas its constraints
     711              :              aren't, so we need to instead use (the parameters of) the most
     712              :              general template.  The following test distinguishes between a
     713              :              partial specialization and such an explicit specialization.  */
     714     27740524 :           || (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
     715     13870262 :               < TMPL_ARGS_DEPTH (DECL_TI_ARGS (tmpl)))))
     716    377368903 :     tmpl = most_general_template (tmpl);
     717              : 
     718    431143645 :   d = tmpl ? tmpl : decl;
     719              : 
     720              :   /* If we're not diagnosing errors, use cached constraints, if any.  */
     721    431143645 :   if (!diag)
     722    862129339 :     if (tree *p = hash_map_safe_get (normalized_map, d))
     723    346215129 :       return *p;
     724              : 
     725     84928516 :   tree norm = NULL_TREE;
     726     84928516 :   if (tree ci = get_constraints (d))
     727              :     {
     728      2623999 :       push_access_scope_guard pas (decl);
     729      2623999 :       norm = get_normalized_constraints_from_info (ci, tmpl, diag);
     730      2623999 :     }
     731              : 
     732     84928516 :   if (!diag)
     733     84927466 :     hash_map_safe_put<hm_ggc> (normalized_map, d, norm);
     734              : 
     735     84928516 :   return norm;
     736              : }
     737              : 
     738              : /* Returns the normal form of TMPL's definition.  */
     739              : 
     740              : static tree
     741      2771784 : normalize_concept_definition (tree tmpl, bool diag)
     742              : {
     743      2771784 :   if (!norm_cache)
     744         2582 :     norm_cache = hash_table<norm_hasher>::create_ggc (31);
     745      2771784 :   norm_entry entry = {tmpl, NULL_TREE, NULL_TREE};
     746              : 
     747      2771784 :   if (!diag)
     748      2771462 :     if (norm_entry *found = norm_cache->find (&entry))
     749      2423864 :       return found->norm;
     750              : 
     751       347920 :   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
     752       347920 :   tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
     753       347920 :   ++processing_template_decl;
     754       347920 :   norm_info info (tmpl, diag);
     755       347920 :   tree norm = get_normalized_constraints (def, info);
     756       347920 :   --processing_template_decl;
     757              : 
     758       347920 :   if (!diag)
     759              :     {
     760       347598 :       norm_entry **slot = norm_cache->find_slot (&entry, INSERT);
     761       347598 :       entry.norm = norm;
     762       347598 :       *slot = ggc_alloc<norm_entry> ();
     763       347598 :       **slot = entry;
     764              :     }
     765              : 
     766              :   return norm;
     767              : }
     768              : 
     769              : /* Normalize an EXPR as a constraint.  */
     770              : 
     771              : static tree
     772      9617030 : normalize_constraint_expression (tree expr, norm_info info)
     773              : {
     774      9617030 :   if (!expr || expr == error_mark_node)
     775              :     return expr;
     776              : 
     777      9617030 :   if (!info.generate_diagnostics)
     778     19233656 :     if (tree *p = hash_map_safe_get (normalized_map, expr))
     779      7893969 :       return *p;
     780              : 
     781      1723061 :   ++processing_template_decl;
     782      1723061 :   tree norm = get_normalized_constraints (expr, info);
     783      1723061 :   --processing_template_decl;
     784              : 
     785      1723061 :   if (!info.generate_diagnostics)
     786      1722908 :     hash_map_safe_put<hm_ggc> (normalized_map, expr, norm);
     787              : 
     788              :   return norm;
     789              : }
     790              : 
     791              : /* 17.4.1.2p2.  Two constraints are identical if they are formed
     792              :    from the same expression and the targets of the parameter mapping
     793              :    are equivalent.  */
     794              : 
     795              : bool
     796    338548220 : atomic_constraints_identical_p (tree t1, tree t2)
     797              : {
     798    338548220 :   gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR);
     799    338548220 :   gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR);
     800              : 
     801    338548220 :   if (ATOMIC_CONSTR_EXPR (t1) != ATOMIC_CONSTR_EXPR (t2))
     802              :     return false;
     803              : 
     804     59025895 :   if (!parameter_mapping_equivalent_p (t1, t2))
     805              :     return false;
     806              : 
     807              :   return true;
     808              : }
     809              : 
     810              : /* True if T1 and T2 are equivalent, meaning they have the same syntactic
     811              :    structure and all corresponding constraints are identical.  */
     812              : 
     813              : bool
     814      4153999 : constraints_equivalent_p (tree t1, tree t2)
     815              : {
     816      7808377 :   gcc_assert (CONSTR_P (t1));
     817      7808377 :   gcc_assert (CONSTR_P (t2));
     818              : 
     819      7808377 :   if (TREE_CODE (t1) != TREE_CODE (t2))
     820              :     return false;
     821              : 
     822      7614517 :   switch (TREE_CODE (t1))
     823              :     {
     824      3888875 :     case CONJ_CONSTR:
     825      3888875 :     case DISJ_CONSTR:
     826      3888875 :       if (!constraints_equivalent_p (TREE_OPERAND (t1, 0),
     827      3888875 :                                      TREE_OPERAND (t2, 0)))
     828              :         return false;
     829      3654378 :       if (!constraints_equivalent_p (TREE_OPERAND (t1, 1),
     830      3654378 :                                      TREE_OPERAND (t2, 1)))
     831              :         return false;
     832              :       break;
     833      3725642 :     case ATOMIC_CONSTR:
     834      3725642 :       if (!atomic_constraints_identical_p (t1, t2))
     835              :         return false;
     836              :       break;
     837              :     default:
     838              :       gcc_unreachable ();
     839              :     }
     840              :   return true;
     841              : }
     842              : 
     843              : /* Compute the hash value for T.  */
     844              : 
     845              : hashval_t
     846   1299528923 : hash_atomic_constraint (tree t)
     847              : {
     848   1299528923 :   gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);
     849              : 
     850              :   /* Hash the identity of the expression.  */
     851   1299528923 :   hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t));
     852              : 
     853              :   /* Hash the targets of the parameter map.  */
     854   1299528923 :   tree p = ATOMIC_CONSTR_MAP (t);
     855   3384547684 :   while (p)
     856              :     {
     857   2085018761 :       val = iterative_hash_template_arg (TREE_PURPOSE (p), val);
     858   2085018761 :       p = TREE_CHAIN (p);
     859              :     }
     860              : 
     861   1299528923 :   return val;
     862              : }
     863              : 
     864              : namespace inchash
     865              : {
     866              : 
     867              : static void
     868     71369714 : add_constraint (tree t, hash& h)
     869              : {
     870    141990908 :   h.add_int (TREE_CODE (t));
     871    141990908 :   switch (TREE_CODE (t))
     872              :     {
     873     70621194 :     case CONJ_CONSTR:
     874     70621194 :     case DISJ_CONSTR:
     875     70621194 :       add_constraint (TREE_OPERAND (t, 0), h);
     876     70621194 :       add_constraint (TREE_OPERAND (t, 1), h);
     877     70621194 :       break;
     878     71369714 :     case ATOMIC_CONSTR:
     879     71369714 :       h.merge_hash (hash_atomic_constraint (t));
     880     71369714 :       break;
     881            0 :     default:
     882            0 :       gcc_unreachable ();
     883              :     }
     884     71369714 : }
     885              : 
     886              : }
     887              : 
     888              : /* Computes a hash code for the constraint T.  */
     889              : 
     890              : hashval_t
     891       748520 : iterative_hash_constraint (tree t, hashval_t val)
     892              : {
     893       748520 :   gcc_assert (CONSTR_P (t));
     894       748520 :   inchash::hash h (val);
     895       748520 :   inchash::add_constraint (t, h);
     896       748520 :   return h.end ();
     897              : }
     898              : 
     899              : // -------------------------------------------------------------------------- //
     900              : // Constraint Semantic Processing
     901              : //
     902              : // The following functions are called by the parser and substitution rules
     903              : // to create and evaluate constraint-related nodes.
     904              : 
     905              : // The constraints associated with the current template parameters.
     906              : tree
     907    109290021 : current_template_constraints (void)
     908              : {
     909    109290021 :   if (!current_template_parms)
     910              :     return NULL_TREE;
     911    109290018 :   tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
     912    109290018 :   return build_constraints (tmpl_constr, NULL_TREE);
     913              : }
     914              : 
     915              : /* If the recently parsed TYPE declares or defines a template or
     916              :    template specialization, get its corresponding constraints from the
     917              :    current template parameters and bind them to TYPE's declaration.  */
     918              : 
     919              : tree
     920     41039003 : associate_classtype_constraints (tree type)
     921              : {
     922     41039003 :   if (!type || type == error_mark_node || !CLASS_TYPE_P (type))
     923              :     return type;
     924              : 
     925              :   /* An explicit class template specialization has no template parameters.  */
     926     41038233 :   if (!current_template_parms)
     927              :     return type;
     928              : 
     929     29869864 :   if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
     930              :     {
     931     28657328 :       tree decl = TYPE_STUB_DECL (type);
     932     28657328 :       tree ci = current_template_constraints ();
     933              : 
     934              :       /* An implicitly instantiated member template declaration already
     935              :          has associated constraints.  If it is defined outside of its
     936              :          class, then we need match these constraints against those of
     937              :          original declaration.  */
     938     28657328 :       if (tree orig_ci = get_constraints (decl))
     939              :         {
     940      1311935 :           if (int extra_levels = (TMPL_PARMS_DEPTH (current_template_parms)
     941      8090295 :                                   - TMPL_ARGS_DEPTH (TYPE_TI_ARGS (type))))
     942              :             {
     943              :               /* If there is a discrepancy between the current template depth
     944              :                  and the template depth of the original declaration, then we
     945              :                  must be redeclaring a class template as part of a friend
     946              :                  declaration within another class template.  Before matching
     947              :                  constraints, we need to reduce the template parameter level
     948              :                  within the current constraints via substitution.  */
     949            9 :               tree outer_gtargs = template_parms_to_args (current_template_parms);
     950            9 :               TREE_VEC_LENGTH (outer_gtargs) = extra_levels;
     951            9 :               ci = tsubst_constraint_info (ci, outer_gtargs, tf_none, NULL_TREE);
     952              :             }
     953      1311935 :           if (!equivalent_constraints (ci, orig_ci))
     954              :             {
     955            6 :               auto_diagnostic_group d;
     956            6 :               error ("%qT does not match original declaration", type);
     957            6 :               tree tmpl = CLASSTYPE_TI_TEMPLATE (type);
     958            6 :               location_t loc = DECL_SOURCE_LOCATION (tmpl);
     959            6 :               inform (loc, "original template declaration here");
     960              :               /* Fall through, so that we define the type anyway.  */
     961            6 :             }
     962              :           return type;
     963              :         }
     964     27345393 :       set_constraints (decl, ci);
     965              :     }
     966              :   return type;
     967              : }
     968              : 
     969              : /* Create an empty constraint info block.  */
     970              : 
     971              : static inline tree_constraint_info*
     972     22628953 : build_constraint_info ()
     973              : {
     974     22628953 :   return (tree_constraint_info *)make_node (CONSTRAINT_INFO);
     975              : }
     976              : 
     977              : /* Build a constraint-info object that contains the associated constraints
     978              :    of a declaration.  This also includes the declaration's template
     979              :    requirements (TREQS) and any trailing requirements for a function
     980              :    declarator (DREQS).  Note that both TREQS and DREQS must be constraints.
     981              : 
     982              :    If the declaration has neither template nor declaration requirements
     983              :    this returns NULL_TREE, indicating an unconstrained declaration.  */
     984              : 
     985              : tree
     986    320535556 : build_constraints (tree tr, tree dr)
     987              : {
     988    320535556 :   if (!tr && !dr)
     989              :     return NULL_TREE;
     990              : 
     991     22628953 :   tree_constraint_info* ci = build_constraint_info ();
     992     22628953 :   ci->template_reqs = tr;
     993     22628953 :   ci->declarator_reqs = dr;
     994     22628953 :   ci->associated_constr = combine_constraint_expressions (tr, dr);
     995              : 
     996     22628953 :   return (tree)ci;
     997              : }
     998              : 
     999              : /* Add constraint RHS to the end of CONSTRAINT_INFO ci.  */
    1000              : 
    1001              : tree
    1002           79 : append_constraint (tree ci, tree rhs)
    1003              : {
    1004           79 :   tree tr = ci ? CI_TEMPLATE_REQS (ci) : NULL_TREE;
    1005           24 :   tree dr = ci ? CI_DECLARATOR_REQS (ci) : NULL_TREE;
    1006           79 :   dr = combine_constraint_expressions (dr, rhs);
    1007           79 :   if (ci)
    1008              :     {
    1009           12 :       CI_DECLARATOR_REQS (ci) = dr;
    1010           12 :       tree ac = combine_constraint_expressions (tr, dr);
    1011           24 :       CI_ASSOCIATED_CONSTRAINTS (ci) = ac;
    1012              :     }
    1013              :   else
    1014           67 :     ci = build_constraints (tr, dr);
    1015           79 :   return ci;
    1016              : }
    1017              : 
    1018              : /* A mapping from declarations to constraint information.  */
    1019              : 
    1020              : static GTY ((cache)) decl_tree_cache_map *decl_constraints;
    1021              : 
    1022              : /* Returns the template constraints of declaration T.  If T is not
    1023              :    constrained, return NULL_TREE.  Note that T must be non-null.  */
    1024              : 
    1025              : tree
    1026   1065408060 : get_constraints (const_tree t)
    1027              : {
    1028   1065408060 :   if (!flag_concepts)
    1029              :     return NULL_TREE;
    1030   1057306081 :   if (!decl_constraints)
    1031              :     return NULL_TREE;
    1032              : 
    1033   1043737481 :   gcc_assert (DECL_P (t));
    1034   1043737481 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1035    203553387 :     t = DECL_TEMPLATE_RESULT (t);
    1036   1043737481 :   tree* found = decl_constraints->get (const_cast<tree> (t));
    1037   1043737481 :   if (found)
    1038    102174949 :     return *found;
    1039              :   else
    1040              :     return NULL_TREE;
    1041              : }
    1042              : 
    1043              : /* Associate the given constraint information CI with the declaration
    1044              :    T.  If T is a template, then the constraints are associated with
    1045              :    its underlying declaration.  Don't build associations if CI is
    1046              :    NULL_TREE.  */
    1047              : 
    1048              : void
    1049    307204640 : set_constraints (tree t, tree ci)
    1050              : {
    1051    307204640 :   if (!ci)
    1052              :     return;
    1053     38377717 :   gcc_assert (t && flag_concepts);
    1054     38377717 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1055        91676 :     t = DECL_TEMPLATE_RESULT (t);
    1056     38377717 :   bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
    1057     38377717 :   gcc_assert (!found);
    1058              : }
    1059              : 
    1060              : /* Remove the associated constraints of the declaration T.  */
    1061              : 
    1062              : void
    1063     15946652 : remove_constraints (tree t)
    1064              : {
    1065     15946652 :   gcc_checking_assert (DECL_P (t));
    1066     15946652 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1067          186 :     t = DECL_TEMPLATE_RESULT (t);
    1068              : 
    1069     15946652 :   if (decl_constraints)
    1070     15311493 :     decl_constraints->remove (t);
    1071     15946652 : }
    1072              : 
    1073              : /* If DECL is a friend, substitute into REQS to produce requirements suitable
    1074              :    for declaration matching.  */
    1075              : 
    1076              : tree
    1077    142928099 : maybe_substitute_reqs_for (tree reqs, const_tree decl)
    1078              : {
    1079    142928099 :   if (reqs == NULL_TREE)
    1080              :     return NULL_TREE;
    1081              : 
    1082     11016865 :   decl = STRIP_TEMPLATE (decl);
    1083     11016865 :   if (DECL_UNIQUE_FRIEND_P (decl) && DECL_TEMPLATE_INFO (decl))
    1084              :     {
    1085       198879 :       tree tmpl = DECL_TI_TEMPLATE (decl);
    1086       198879 :       tree outer_args = outer_template_args (decl);
    1087       198879 :       processing_template_decl_sentinel s;
    1088       198879 :       if (PRIMARY_TEMPLATE_P (tmpl)
    1089       198879 :           || uses_template_parms (outer_args))
    1090       198879 :         ++processing_template_decl;
    1091       198879 :       reqs = tsubst_constraint (reqs, outer_args,
    1092              :                                 tf_warning_or_error, NULL_TREE);
    1093       198879 :     }
    1094              :   return reqs;
    1095              : }
    1096              : 
    1097              : /* Returns the trailing requires clause of the declarator of
    1098              :    a template declaration T or NULL_TREE if none.  */
    1099              : 
    1100              : tree
    1101    335520292 : get_trailing_function_requirements (tree t)
    1102              : {
    1103    335520292 :   tree ci = get_constraints (t);
    1104    335520292 :   if (!ci)
    1105              :     return NULL_TREE;
    1106     64111304 :   return CI_DECLARATOR_REQS (ci);
    1107              : }
    1108              : 
    1109              : /* Construct a sequence of template arguments by prepending
    1110              :    ARG to REST.  Either ARG or REST may be null.  */
    1111              : 
    1112              : static tree
    1113     43829363 : build_concept_check_arguments (tree arg, tree rest)
    1114              : {
    1115     43829363 :   gcc_assert (!rest || TREE_CODE (rest) == TREE_VEC);
    1116     43829363 :   tree args;
    1117     43829363 :   if (arg)
    1118              :     {
    1119     33876241 :       int n = rest ? TREE_VEC_LENGTH (rest) : 0;
    1120     23063319 :       args = make_tree_vec (n + 1);
    1121     23063319 :       TREE_VEC_ELT (args, 0) = arg;
    1122     23063319 :       if (rest)
    1123     23361716 :         for (int i = 0; i < n; ++i)
    1124     12548794 :           TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i);
    1125     10812922 :       int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0;
    1126     23063319 :       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
    1127              :     }
    1128              :   else
    1129              :     args = rest;
    1130     43829363 :   return args;
    1131              : }
    1132              : 
    1133              : /* Construct an expression that checks TMPL using ARGS.  */
    1134              : 
    1135              : tree
    1136     20766044 : build_concept_check (tree tmpl, tree args, tsubst_flags_t complain)
    1137              : {
    1138     20766044 :   return build_concept_check (tmpl, NULL_TREE, args, complain);
    1139              : }
    1140              : 
    1141              : /* Construct an expression that checks the concept given by TMPL.  */
    1142              : 
    1143              : tree
    1144     43829363 : build_concept_check (tree tmpl, tree arg, tree rest, tsubst_flags_t complain)
    1145              : {
    1146     43829363 :   if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl)))
    1147            9 :     warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE);
    1148              : 
    1149     43829363 :   tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
    1150     43829363 :   tree args = build_concept_check_arguments (arg, rest);
    1151     43829363 :   args = coerce_template_parms (parms, args, tmpl, complain);
    1152     43829363 :   if (args == error_mark_node)
    1153              :     return error_mark_node;
    1154     41168290 :   return build2 (TEMPLATE_ID_EXPR, boolean_type_node, tmpl, args);
    1155              : }
    1156              : 
    1157              : /* Build a template-id that can participate in a concept check.  */
    1158              : 
    1159              : static tree
    1160     17387910 : build_concept_id (tree decl, tree args)
    1161              : {
    1162            0 :   return build_concept_check (decl, args, tf_warning_or_error);
    1163              : }
    1164              : 
    1165              : /* Build a template-id that can participate in a concept check, preserving
    1166              :    the source location of the original template-id.  */
    1167              : 
    1168              : tree
    1169     17387910 : build_concept_id (tree expr)
    1170              : {
    1171     17387910 :   gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR);
    1172     17387910 :   tree id = build_concept_id (TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
    1173     17387910 :   protected_set_expr_location (id, cp_expr_location (expr));
    1174     17387910 :   return id;
    1175              : }
    1176              : 
    1177              : /* Build as template-id with a placeholder that can be used as a
    1178              :    type constraint.
    1179              : 
    1180              :    Note that this will diagnose errors if the initial concept check
    1181              :    cannot be built.  */
    1182              : 
    1183              : tree
    1184     12900753 : build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
    1185              : {
    1186     12900753 :   tree proto = template_parm_to_arg (concept_prototype_parameter (decl));
    1187     12900753 :   ++processing_template_decl;
    1188     12900753 :   tree check = build_concept_check (decl, proto, args, complain);
    1189     12900753 :   --processing_template_decl;
    1190     12900753 :   return check;
    1191              : }
    1192              : 
    1193              : /* Returns a TYPE_DECL that contains sufficient information to
    1194              :    build a template parameter of the same kind as PROTO and
    1195              :    constrained by the concept declaration CNC.  Note that PROTO
    1196              :    is the first template parameter of CNC.
    1197              : 
    1198              :    If specified, ARGS provides additional arguments to the
    1199              :    constraint check.  */
    1200              : tree
    1201      8598657 : build_constrained_parameter (tree cnc, tree proto, tree args)
    1202              : {
    1203      8598657 :   tree name = DECL_NAME (cnc);
    1204      8598657 :   tree type = TREE_TYPE (proto);
    1205      8598657 :   tree decl = build_decl (input_location, TYPE_DECL, name, type);
    1206      8598657 :   CONSTRAINED_PARM_PROTOTYPE (decl) = proto;
    1207      8598657 :   CONSTRAINED_PARM_CONCEPT (decl) = cnc;
    1208      8598657 :   CONSTRAINED_PARM_EXTRA_ARGS (decl) = args;
    1209      8598657 :   return decl;
    1210              : }
    1211              : 
    1212              : /* Create a constraint expression for the given DECL that evaluates the
    1213              :    requirements specified by CONSTR, a TYPE_DECL that contains all the
    1214              :    information necessary to build the requirements (see finish_concept_name
    1215              :    for the layout of that TYPE_DECL).
    1216              : 
    1217              :    Note that the constraints are neither reduced nor decomposed.  That is
    1218              :    done only after the requires clause has been parsed (or not).  */
    1219              : 
    1220              : tree
    1221    176906410 : finish_shorthand_constraint (tree decl, tree constr, bool is_non_type)
    1222              : {
    1223              :   /* No requirements means no constraints.  */
    1224    176906410 :   if (!constr)
    1225              :     return NULL_TREE;
    1226              : 
    1227      8598742 :   if (error_operand_p (constr))
    1228              :     return NULL_TREE;
    1229              : 
    1230      8598742 :   tree proto, con, args;
    1231      8598742 :   if (is_non_type)
    1232              :     {
    1233              :       /* This function should not see constrained auto&, auto* NTTPs, and a
    1234              :          simple constrained auto NTTP type should by now have been replaced
    1235              :          by ordinary auto; see finish_constrained_parameter.  */
    1236          109 :       gcc_checking_assert (is_auto (TREE_TYPE (decl))
    1237              :                            && !is_constrained_auto (TREE_TYPE (decl)));
    1238          109 :       gcc_checking_assert (TREE_CODE (constr) == TEMPLATE_ID_EXPR);
    1239          109 :       tree tmpl = TREE_OPERAND (constr, 0);
    1240          109 :       proto = concept_prototype_parameter (tmpl);
    1241          109 :       con = DECL_TEMPLATE_RESULT (tmpl);
    1242          109 :       args = TREE_OPERAND (constr, 1);
    1243              :     }
    1244              :   else
    1245              :     {
    1246      8598633 :       proto = CONSTRAINED_PARM_PROTOTYPE (constr);
    1247      8598633 :       con = CONSTRAINED_PARM_CONCEPT (constr);
    1248      8598633 :       args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
    1249              :     }
    1250              : 
    1251      8598742 :   bool variadic_concept_p = template_parameter_pack_p (proto);
    1252      8598742 :   bool declared_pack_p = template_parameter_pack_p (decl);
    1253      8598742 :   bool apply_to_each_p = (cxx_dialect >= cxx20) ? true : !variadic_concept_p;
    1254              : 
    1255              :   /* Get the argument and overload used for the requirement
    1256              :      and adjust it if we're going to expand later.  */
    1257      8598742 :   tree arg = template_parm_to_arg (decl);
    1258      8598742 :   if (apply_to_each_p && declared_pack_p)
    1259        22756 :     arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0));
    1260              : 
    1261              :   /* Build the concept constraint-expression.  */
    1262      8598742 :   tree tmpl = DECL_TI_TEMPLATE (con);
    1263      8598742 :   tree check;
    1264      8598742 :   if (is_non_type)
    1265              :     {
    1266          109 :       arg = finish_decltype_type (arg, /*id_expr=*/true, tf_warning_or_error);
    1267          109 :       if (ARGUMENT_PACK_P (TREE_VEC_ELT (args, 0)))
    1268            5 :         args = expand_template_argument_pack (args);
    1269              :       else
    1270          104 :         args = copy_template_args (args);
    1271          109 :       TREE_VEC_ELT (args, 0) = arg;
    1272          109 :       check = build_concept_check (tmpl, args, tf_warning_or_error);
    1273              :     }
    1274              :   else
    1275      8598633 :     check = build_concept_check (tmpl, arg, args, tf_warning_or_error);
    1276              : 
    1277              :   /* Make the check a fold-expression if needed.
    1278              :      Use UNKNOWN_LOCATION so write_template_args can tell the
    1279              :      difference between this and a fold the user wrote.  */
    1280      8598742 :   if (apply_to_each_p && declared_pack_p)
    1281        22756 :     check = finish_left_unary_fold_expr (UNKNOWN_LOCATION,
    1282              :                                          check, TRUTH_ANDIF_EXPR);
    1283              : 
    1284              :   return check;
    1285              : }
    1286              : 
    1287              : /* Returns a conjunction of shorthand requirements for the template
    1288              :    parameter list PARMS.  Note that the requirements are stored in
    1289              :    the TYPE of each tree node.  */
    1290              : 
    1291              : tree
    1292     93498891 : get_shorthand_constraints (tree parms)
    1293              : {
    1294     93498891 :   tree result = NULL_TREE;
    1295     93498891 :   parms = INNERMOST_TEMPLATE_PARMS (parms);
    1296    266893499 :   for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
    1297              :     {
    1298    173394608 :       tree parm = TREE_VEC_ELT (parms, i);
    1299    173394608 :       tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
    1300    173394608 :       result = combine_constraint_expressions (result, constr);
    1301              :     }
    1302     93498891 :   return result;
    1303              : }
    1304              : 
    1305              : /* Returns true iff the placeholders C1 and C2 are equivalent.  C1
    1306              :    and C2 can be either TEMPLATE_TYPE_PARM or template-ids.  */
    1307              : 
    1308              : bool
    1309    620671593 : equivalent_placeholder_constraints (tree c1, tree c2)
    1310              : {
    1311    620671593 :   if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
    1312              :     /* A constrained auto.  */
    1313    620671593 :     c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
    1314    620671593 :   if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
    1315    620671593 :     c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);
    1316              : 
    1317    620671593 :   if (c1 == c2)
    1318              :     return true;
    1319      6095574 :   if (!c1 || !c2)
    1320              :     return false;
    1321      5501392 :   if (c1 == error_mark_node || c2 == error_mark_node)
    1322              :     /* We get here during satisfaction; when a deduction constraint
    1323              :        fails, substitution can produce an error_mark_node for the
    1324              :        placeholder constraints.  */
    1325              :     return false;
    1326              : 
    1327      5501392 :   gcc_assert (concept_check_p (c1) && concept_check_p (c2));
    1328      5501392 :   tree t1 = TREE_OPERAND (c1, 0);
    1329      5501392 :   tree a1 = TREE_OPERAND (c1, 1);
    1330      5501392 :   tree t2 = TREE_OPERAND (c2, 0);
    1331      5501392 :   tree a2 = TREE_OPERAND (c2, 1);
    1332              : 
    1333      5501392 :   if (t1 != t2)
    1334              :     return false;
    1335              : 
    1336      2963841 :   int len1 = TREE_VEC_LENGTH (a1);
    1337      2963841 :   int len2 = TREE_VEC_LENGTH (a2);
    1338      2963841 :   if (len1 != len2)
    1339              :     return false;
    1340              : 
    1341              :   /* Skip the first argument so we don't infinitely recurse.
    1342              :      Also, they may differ in template parameter index.  */
    1343      4152701 :   for (int i = 1; i < len1; ++i)
    1344      1774157 :     if (!template_args_equal (TREE_VEC_ELT (a1, i),
    1345      1774157 :                               TREE_VEC_ELT (a2, i)))
    1346              :       return false;
    1347              :   return true;
    1348              : }
    1349              : 
    1350              : /* Return a hash value for the placeholder ATOMIC_CONSTR C.  */
    1351              : 
    1352              : hashval_t
    1353    356016368 : iterative_hash_placeholder_constraint (tree c, hashval_t val)
    1354              : {
    1355    356016368 :   gcc_assert (concept_check_p (c));
    1356    356016368 :   tree t = TREE_OPERAND (c, 0);
    1357    356016368 :   tree a = TREE_OPERAND (c, 1);
    1358              : 
    1359              :   /* Like hash_tmpl_and_args, but skip the first argument.  */
    1360    356016368 :   val = iterative_hash_object (DECL_UID (t), val);
    1361              : 
    1362    587056467 :   for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
    1363    231040099 :     val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
    1364              : 
    1365    356016368 :   return val;
    1366              : }
    1367              : 
    1368              : /* Substitute through the expression of a simple requirement or
    1369              :    compound requirement.  */
    1370              : 
    1371              : static tree
    1372     13988759 : tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
    1373              : {
    1374     13988759 :   tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
    1375     13988759 :   tree r = tsubst_expr (t, args, quiet, info.in_decl);
    1376     13986059 :   if (r != error_mark_node
    1377     13986059 :       && (processing_template_decl
    1378     13438461 :           || convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node))
    1379              :     return r;
    1380              : 
    1381       543893 :   if (info.diagnose_unsatisfaction_p ())
    1382              :     {
    1383          195 :       location_t loc = cp_expr_loc_or_input_loc (t);
    1384          195 :       if (diagnosing_failed_constraint::replay_errors_p ())
    1385              :         {
    1386           10 :           inform (loc, "the required expression %qE is invalid, because", t);
    1387           10 :           auto_diagnostic_nesting_level sentinel;
    1388           10 :           if (r == error_mark_node)
    1389            8 :             tsubst_expr (t, args, info.complain, info.in_decl);
    1390              :           else
    1391            2 :             convert_to_void (r, ICV_STATEMENT, info.complain);
    1392           10 :         }
    1393              :       else
    1394          185 :         inform (loc, "the required expression %qE is invalid", t);
    1395              :     }
    1396       543698 :   else if (info.noisy ())
    1397              :     {
    1398            0 :       r = tsubst_expr (t, args, info.complain, info.in_decl);
    1399            0 :       convert_to_void (r, ICV_STATEMENT, info.complain);
    1400              :     }
    1401              : 
    1402       543893 :   return error_mark_node;
    1403              : }
    1404              : 
    1405              : 
    1406              : /* Substitute through the simple requirement.  */
    1407              : 
    1408              : static tree
    1409      4852314 : tsubst_simple_requirement (tree t, tree args, sat_info info)
    1410              : {
    1411      4852314 :   tree t0 = TREE_OPERAND (t, 0);
    1412      4852314 :   tree expr = tsubst_valid_expression_requirement (t0, args, info);
    1413      4849614 :   if (expr == error_mark_node)
    1414              :     return error_mark_node;
    1415      4411456 :   if (processing_template_decl)
    1416          397 :     return finish_simple_requirement (EXPR_LOCATION (t), expr);
    1417      4411059 :   return boolean_true_node;
    1418              : }
    1419              : 
    1420              : /* Subroutine of tsubst_type_requirement that performs the actual substitution
    1421              :    and diagnosing.  Also used by tsubst_compound_requirement.  */
    1422              : 
    1423              : static tree
    1424     13494802 : tsubst_type_requirement_1 (tree t, tree args, sat_info info, location_t loc)
    1425              : {
    1426     13494802 :   tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
    1427     13494802 :   tree r = tsubst (t, args, quiet, info.in_decl);
    1428     13494802 :   if (r != error_mark_node)
    1429              :     return r;
    1430              : 
    1431       399267 :   if (info.diagnose_unsatisfaction_p ())
    1432              :     {
    1433           33 :       if (diagnosing_failed_constraint::replay_errors_p ())
    1434              :         {
    1435              :           /* Replay the substitution error.  */
    1436            4 :           inform (loc, "the required type %qT is invalid, because", t);
    1437            4 :           tsubst (t, args, info.complain, info.in_decl);
    1438              :         }
    1439              :       else
    1440           29 :         inform (loc, "the required type %qT is invalid", t);
    1441              :     }
    1442       399234 :   else if (info.noisy ())
    1443            0 :     tsubst (t, args, info.complain, info.in_decl);
    1444              : 
    1445       399267 :   return error_mark_node;
    1446              : }
    1447              : 
    1448              : 
    1449              : /* Substitute through the type requirement.  */
    1450              : 
    1451              : static tree
    1452      4464224 : tsubst_type_requirement (tree t, tree args, sat_info info)
    1453              : {
    1454      4464224 :   tree t0 = TREE_OPERAND (t, 0);
    1455      4464224 :   tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t));
    1456      4464224 :   if (type == error_mark_node)
    1457              :     return error_mark_node;
    1458      4064957 :   if (processing_template_decl)
    1459            4 :     return finish_type_requirement (EXPR_LOCATION (t), type);
    1460      4064953 :   return boolean_true_node;
    1461              : }
    1462              : 
    1463              : /* True if TYPE can be deduced from EXPR.  */
    1464              : 
    1465              : static bool
    1466      8763790 : type_deducible_p (tree expr, tree type, tree placeholder, tree args,
    1467              :                   subst_info info)
    1468              : {
    1469              :   /* Make sure deduction is performed against ( EXPR ), so that
    1470              :      references are preserved in the result.  */
    1471      8763790 :   expr = force_paren_expr_uneval (expr);
    1472              : 
    1473      8763790 :   tree deduced_type = do_auto_deduction (type, expr, placeholder,
    1474              :                                          info.complain, adc_requirement,
    1475              :                                          /*outer_targs=*/args);
    1476              : 
    1477      8763790 :   return deduced_type != error_mark_node;
    1478              : }
    1479              : 
    1480              : /* True if EXPR can not be converted to TYPE.  */
    1481              : 
    1482              : static bool
    1483            5 : expression_convertible_p (tree expr, tree type, subst_info info)
    1484              : {
    1485            5 :   tree conv =
    1486            5 :     perform_direct_initialization_if_possible (type, expr, false,
    1487              :                                                info.complain);
    1488            5 :   if (conv == error_mark_node)
    1489              :     return false;
    1490            0 :   if (conv == NULL_TREE)
    1491              :     {
    1492            0 :       if (info.complain & tf_error)
    1493              :         {
    1494            0 :           location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
    1495            0 :           error_at (loc, "cannot convert %qE to %qT", expr, type);
    1496              :         }
    1497              :       return false;
    1498              :     }
    1499              :   return true;
    1500              : }
    1501              : 
    1502              : 
    1503              : /* Substitute through the compound requirement.  */
    1504              : 
    1505              : static tree
    1506      9136445 : tsubst_compound_requirement (tree t, tree args, sat_info info)
    1507              : {
    1508      9136445 :   tree t0 = TREE_OPERAND (t, 0);
    1509      9136445 :   tree t1 = TREE_OPERAND (t, 1);
    1510      9136445 :   tree noex = TREE_OPERAND (t, 2);
    1511      9136445 :   tree expr = tsubst_valid_expression_requirement (t0, args, info);
    1512      9136445 :   if (expr == error_mark_node)
    1513              :     return error_mark_node;
    1514              : 
    1515      9030710 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    1516              : 
    1517      9030710 :   subst_info quiet (info.complain & ~tf_warning_or_error, info.in_decl);
    1518              : 
    1519              :   /* Check the noexcept condition.  */
    1520      9030710 :   noex = tsubst_expr (noex, args, info.complain, info.in_decl);
    1521      9030710 :   if (!instantiation_dependent_expression_p (noex))
    1522              :     {
    1523      9030710 :       noex = build_converted_constant_bool_expr (noex, info.complain);
    1524      9030710 :       noex = instantiate_non_dependent_expr (noex, info.complain);
    1525      9030710 :       noex = cxx_constant_value (noex, info.complain);
    1526              :     }
    1527      9030710 :   if (noex == error_mark_node)
    1528              :     return error_mark_node;
    1529      9030656 :   if (!processing_template_decl
    1530      9027334 :       && integer_nonzerop (noex)
    1531      9294129 :       && !expr_noexcept_p (expr, quiet.complain))
    1532              :     {
    1533           83 :       if (info.diagnose_unsatisfaction_p ())
    1534            5 :         inform (loc, "%qE is not %<noexcept%>", expr);
    1535              :       else
    1536           78 :         return error_mark_node;
    1537              :     }
    1538              : 
    1539              :   /* Substitute through the type expression, if any.  */
    1540      9030578 :   tree type = tsubst_type_requirement_1 (t1, args, info, EXPR_LOCATION (t));
    1541      9030578 :   if (type == error_mark_node)
    1542              :     return error_mark_node;
    1543              : 
    1544              :   /* Check expression against the result type.  */
    1545      9030578 :   if (type && !processing_template_decl)
    1546              :     {
    1547      8763783 :       if (tree placeholder = type_uses_auto (type))
    1548              :         {
    1549      8763778 :           if (!type_deducible_p (expr, type, placeholder, args, quiet))
    1550              :             {
    1551        23224 :               if (info.diagnose_unsatisfaction_p ())
    1552              :                 {
    1553           40 :                   if (diagnosing_failed_constraint::replay_errors_p ())
    1554              :                     {
    1555           12 :                       inform (loc,
    1556              :                               "%qE does not satisfy return-type-requirement, "
    1557              :                               "because", t0);
    1558              :                       /* Further explain the reason for the error.  */
    1559           12 :                       type_deducible_p (expr, type, placeholder, args, info);
    1560              :                     }
    1561              :                   else
    1562           28 :                     inform (loc,
    1563              :                             "%qE does not satisfy return-type-requirement", t0);
    1564              :                 }
    1565        23224 :               return error_mark_node;
    1566              :             }
    1567              :         }
    1568            5 :       else if (!expression_convertible_p (expr, type, quiet))
    1569              :         {
    1570            5 :           if (info.diagnose_unsatisfaction_p ())
    1571              :             {
    1572            0 :               if (diagnosing_failed_constraint::replay_errors_p ())
    1573              :                 {
    1574            0 :                   inform (loc, "cannot convert %qE to %qT because", t0, type);
    1575              :                   /* Further explain the reason for the error.  */
    1576            0 :                   expression_convertible_p (expr, type, info);
    1577              :                 }
    1578              :               else
    1579            0 :                 inform (loc, "cannot convert %qE to %qT", t0, type);
    1580              :             }
    1581            5 :           return error_mark_node;
    1582              :         }
    1583              :     }
    1584              : 
    1585      9007349 :   if (processing_template_decl)
    1586         3322 :     return finish_compound_requirement (EXPR_LOCATION (t), expr, type, noex);
    1587      9004027 :   return boolean_true_node;
    1588              : }
    1589              : 
    1590              : /* Substitute through the nested requirement.  */
    1591              : 
    1592              : static tree
    1593       852737 : tsubst_nested_requirement (tree t, tree args, sat_info info)
    1594              : {
    1595       852737 :   if (processing_template_decl)
    1596              :     {
    1597            0 :       tree req = TREE_OPERAND (t, 0);
    1598            0 :       req = tsubst_constraint (req, args, info.complain, info.in_decl);
    1599            0 :       if (req == error_mark_node)
    1600              :         return error_mark_node;
    1601            0 :       return finish_nested_requirement (EXPR_LOCATION (t), req);
    1602              :     }
    1603              : 
    1604       852737 :   sat_info quiet (info.complain & ~tf_warning_or_error, info.in_decl);
    1605       852737 :   tree result = constraint_satisfaction_value (t, args, quiet);
    1606       852737 :   if (result == boolean_true_node)
    1607              :     return boolean_true_node;
    1608              : 
    1609        32273 :   if (result == boolean_false_node
    1610        32273 :       && info.diagnose_unsatisfaction_p ())
    1611              :     {
    1612           77 :       tree expr = TREE_OPERAND (t, 0);
    1613           77 :       location_t loc = cp_expr_location (t);
    1614           77 :       if (diagnosing_failed_constraint::replay_errors_p ())
    1615              :         {
    1616              :           /* Replay the substitution error.  */
    1617           27 :           inform (loc, "nested requirement %qE is not satisfied, because", expr);
    1618           27 :           constraint_satisfaction_value (t, args, info);
    1619              :         }
    1620              :       else
    1621           50 :         inform (loc, "nested requirement %qE is not satisfied", expr);
    1622              :     }
    1623              : 
    1624        32273 :   return error_mark_node;
    1625              : }
    1626              : 
    1627              : /* Substitute ARGS into the requirement T.  */
    1628              : 
    1629              : static tree
    1630     19305720 : tsubst_requirement (tree t, tree args, sat_info info)
    1631              : {
    1632     19305720 :   iloc_sentinel loc_s (cp_expr_location (t));
    1633     19305720 :   switch (TREE_CODE (t))
    1634              :     {
    1635      4852314 :     case SIMPLE_REQ:
    1636      4852314 :       return tsubst_simple_requirement (t, args, info);
    1637      4464224 :     case TYPE_REQ:
    1638      4464224 :       return tsubst_type_requirement (t, args, info);
    1639      9136445 :     case COMPOUND_REQ:
    1640      9136445 :       return tsubst_compound_requirement (t, args, info);
    1641       852737 :     case NESTED_REQ:
    1642       852737 :       return tsubst_nested_requirement (t, args, info);
    1643            0 :     default:
    1644            0 :       break;
    1645              :     }
    1646            0 :   gcc_unreachable ();
    1647     19303020 : }
    1648              : 
    1649              : static tree
    1650      5544841 : declare_constraint_vars (tree parms, tree vars)
    1651              : {
    1652      5544841 :   tree s = vars;
    1653     14277948 :   for (tree t = parms; t; t = DECL_CHAIN (t))
    1654              :     {
    1655      8733107 :       if (DECL_PACK_P (t))
    1656              :         {
    1657         3801 :           tree pack = extract_fnparm_pack (t, &s);
    1658         3801 :           register_local_specialization (pack, t);
    1659              :         }
    1660              :       else
    1661              :         {
    1662      8729306 :           register_local_specialization (s, t);
    1663      8729306 :           s = DECL_CHAIN (s);
    1664              :         }
    1665              :     }
    1666      5544841 :   return vars;
    1667              : }
    1668              : 
    1669              : /* Substitute through as if checking function parameter types.  This
    1670              :    will diagnose common parameter type errors.  Returns error_mark_node
    1671              :    if an error occurred.  */
    1672              : 
    1673              : static tree
    1674      5544883 : check_constraint_variables (tree t, tree args, subst_info info)
    1675              : {
    1676      5544883 :   tree types = NULL_TREE;
    1677      5544883 :   tree p = t;
    1678     14278039 :   while (p && !VOID_TYPE_P (p))
    1679              :     {
    1680      8733156 :       types = tree_cons (NULL_TREE, TREE_TYPE (p), types);
    1681      8733156 :       p = TREE_CHAIN (p);
    1682              :     }
    1683      5544883 :   types = chainon (nreverse (types), void_list_node);
    1684      5544883 :   return tsubst_function_parms (types, args, info.complain, info.in_decl);
    1685              : }
    1686              : 
    1687              : /* A subroutine of tsubst_parameterized_constraint.  Substitute ARGS
    1688              :    into the parameter list T, producing a sequence of constraint
    1689              :    variables, declared in the current scope.
    1690              : 
    1691              :    Note that the caller must establish a local specialization stack
    1692              :    prior to calling this function since this substitution will
    1693              :    declare the substituted parameters.  */
    1694              : 
    1695              : static tree
    1696      5544883 : tsubst_constraint_variables (tree t, tree args, subst_info info)
    1697              : {
    1698              :   /* Perform a trial substitution to check for type errors.  */
    1699      5544883 :   tree parms = check_constraint_variables (t, args, info);
    1700      5544883 :   if (parms == error_mark_node)
    1701              :     return error_mark_node;
    1702              : 
    1703              :   /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain
    1704              :      of PARM_DECLs.  */
    1705      5544841 :   int saved_unevaluated_operand = cp_unevaluated_operand;
    1706      5544841 :   int saved_unevaluated_typeid_cutoff = cp_unevaluated_typeid_cutoff;
    1707      5544841 :   cp_unevaluated_operand = 0;
    1708      5544841 :   cp_unevaluated_typeid_cutoff = 0;
    1709      5544841 :   tree vars = tsubst (t, args, info.complain, info.in_decl);
    1710      5544841 :   cp_unevaluated_operand = saved_unevaluated_operand;
    1711      5544841 :   cp_unevaluated_typeid_cutoff = saved_unevaluated_typeid_cutoff;
    1712      5544841 :   if (vars == error_mark_node)
    1713              :     return error_mark_node;
    1714      5544841 :   return declare_constraint_vars (t, vars);
    1715              : }
    1716              : 
    1717              : /* Substitute ARGS into the requires-expression T. [8.4.7]p6.  The
    1718              :    substitution of template arguments into a requires-expression
    1719              :    may result in the formation of invalid types or expressions
    1720              :    in its requirements ...  In such cases, the expression evaluates
    1721              :    to false; it does not cause the program to be ill-formed.
    1722              : 
    1723              :    When substituting through a REQUIRES_EXPR as part of template
    1724              :    instantiation, we call this routine with info.quiet() true.
    1725              : 
    1726              :    When evaluating a REQUIRES_EXPR that appears outside a template in
    1727              :    cp_parser_requires_expression, we call this routine with
    1728              :    info.noisy() true.
    1729              : 
    1730              :    Finally, when diagnosing unsatisfaction from diagnose_atomic_constraint
    1731              :    and when diagnosing a false REQUIRES_EXPR via diagnose_constraints,
    1732              :    we call this routine with info.diagnose_unsatisfaction_p() true.  */
    1733              : 
    1734              : static tree
    1735     12076658 : tsubst_requires_expr (tree t, tree args, sat_info info)
    1736              : {
    1737     12076658 :   local_specialization_stack stack (lss_copy);
    1738              : 
    1739              :   /* We need to check access during the substitution.  */
    1740     12076658 :   deferring_access_check_sentinel acs (dk_no_deferred);
    1741              : 
    1742              :   /* A requires-expression is an unevaluated context.  */
    1743     12076658 :   cp_unevaluated u;
    1744              : 
    1745     12076658 :   args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args,
    1746              :                          info.complain, info.in_decl);
    1747     12076658 :   if (processing_template_decl
    1748     12076658 :       && !processing_constraint_expression_p ())
    1749              :     {
    1750              :       /* We're partially instantiating a generic lambda.  Substituting into
    1751              :          this requires-expression now may cause its requirements to get
    1752              :          checked out of order, so instead just remember the template
    1753              :          arguments and wait until we can substitute them all at once.
    1754              : 
    1755              :          Except if this requires-expr is part of associated constraints
    1756              :          that we're substituting into directly (for e.g. declaration
    1757              :          matching or dguide constraint rewriting), in which case we need
    1758              :          to partially substitute.  */
    1759         3176 :       t = copy_node (t);
    1760         3176 :       REQUIRES_EXPR_EXTRA_ARGS (t) = NULL_TREE;
    1761         3176 :       REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain);
    1762         3176 :       return t;
    1763              :     }
    1764              : 
    1765     12073482 :   tree parms = REQUIRES_EXPR_PARMS (t);
    1766     12073482 :   if (parms)
    1767              :     {
    1768      5544883 :       parms = tsubst_constraint_variables (parms, args, info);
    1769      5544883 :       if (parms == error_mark_node)
    1770           42 :         return boolean_false_node;
    1771              :     }
    1772              : 
    1773     12073440 :   tree result = boolean_true_node;
    1774     12073440 :   if (processing_template_decl)
    1775         2964 :     result = NULL_TREE;
    1776     30378023 :   for (tree reqs = REQUIRES_EXPR_REQS (t); reqs; reqs = TREE_CHAIN (reqs))
    1777              :     {
    1778     19305720 :       tree req = TREE_VALUE (reqs);
    1779     19305720 :       req = tsubst_requirement (req, args, info);
    1780     19303020 :       if (req == error_mark_node)
    1781              :         {
    1782       998794 :           result = boolean_false_node;
    1783       998794 :           if (info.diagnose_unsatisfaction_p ())
    1784              :             /* Keep going so that we diagnose all failed requirements.  */;
    1785              :           else
    1786              :             break;
    1787              :         }
    1788     18304226 :       else if (processing_template_decl)
    1789         3723 :         result = tree_cons (NULL_TREE, req, result);
    1790              :     }
    1791     12070740 :   if (processing_template_decl && result != boolean_false_node)
    1792         2964 :     result = finish_requires_expr (REQUIRES_EXPR_LOCATION (t), parms,
    1793              :                                    nreverse (result));
    1794              :   return result;
    1795     12073958 : }
    1796              : 
    1797              : /* Public wrapper for the above.  */
    1798              : 
    1799              : tree
    1800     12076091 : tsubst_requires_expr (tree t, tree args,
    1801              :                       tsubst_flags_t complain, tree in_decl)
    1802              : {
    1803     12076091 :   sat_info info (complain, in_decl);
    1804     12076091 :   return tsubst_requires_expr (t, args, info);
    1805              : }
    1806              : 
    1807              : /* Substitute ARGS into the constraint information CI, producing a new
    1808              :    constraint record.  */
    1809              : 
    1810              : tree
    1811       648110 : tsubst_constraint_info (tree t, tree args,
    1812              :                         tsubst_flags_t complain, tree in_decl)
    1813              : {
    1814       648110 :   if (!t || t == error_mark_node || !check_constraint_info (t))
    1815              :     return NULL_TREE;
    1816              : 
    1817       170384 :   tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t), args, complain, in_decl);
    1818       170384 :   tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t), args, complain, in_decl);
    1819        85192 :   return build_constraints (tr, dr);
    1820              : }
    1821              : 
    1822              : /* Substitute through a parameter mapping, in order to get the actual
    1823              :    arguments used to instantiate an atomic constraint.  This may fail
    1824              :    if the substitution into arguments produces something ill-formed.  */
    1825              : 
    1826              : static tree
    1827     57512253 : tsubst_parameter_mapping (tree map, tree args, subst_info info)
    1828              : {
    1829     57512253 :   if (!map)
    1830              :     return NULL_TREE;
    1831              : 
    1832     57511430 :   tsubst_flags_t complain = info.complain;
    1833     57511430 :   tree in_decl = info.in_decl;
    1834              : 
    1835     57511430 :   tree result = NULL_TREE;
    1836    155809654 :   for (tree p = map; p; p = TREE_CHAIN (p))
    1837              :     {
    1838     98311501 :       if (p == error_mark_node)
    1839              :         return error_mark_node;
    1840     98311501 :       tree parm = TREE_VALUE (p);
    1841     98311501 :       tree arg = TREE_PURPOSE (p);
    1842     98311501 :       tree new_arg;
    1843     98311501 :       if (ARGUMENT_PACK_P (arg))
    1844      3330543 :         new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
    1845              :       else
    1846              :         {
    1847     94980958 :           new_arg = tsubst_template_arg (arg, args, complain, in_decl);
    1848     94980958 :           if (TYPE_P (new_arg))
    1849     94745088 :             new_arg = canonicalize_type_argument (new_arg, complain);
    1850              :         }
    1851     98311501 :       if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
    1852              :         {
    1853      3311471 :           tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
    1854      6816117 :           for (tree& pack_arg : tree_vec_range (pack_args))
    1855      3504646 :             if (TYPE_P (pack_arg))
    1856      3504646 :               pack_arg = canonicalize_type_argument (pack_arg, complain);
    1857              :         }
    1858     98311501 :       if (new_arg == error_mark_node)
    1859              :         return error_mark_node;
    1860              : 
    1861     98298224 :       result = tree_cons (new_arg, parm, result);
    1862              :     }
    1863     57498153 :   return nreverse (result);
    1864              : }
    1865              : 
    1866              : tree
    1867         1157 : tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_decl)
    1868              : {
    1869         1157 :   return tsubst_parameter_mapping (map, args, subst_info (complain, in_decl));
    1870              : }
    1871              : 
    1872              : /*---------------------------------------------------------------------------
    1873              :                         Constraint satisfaction
    1874              : ---------------------------------------------------------------------------*/
    1875              : 
    1876              : /* True if we are currently satisfying a constraint.  */
    1877              : 
    1878              : static bool satisfying_constraint;
    1879              : 
    1880              : /* A vector of incomplete types (and of declarations with undeduced return type),
    1881              :    appended to by note_failed_type_completion.  The
    1882              :    satisfaction caches use this in order to keep track of "potentially unstable"
    1883              :    satisfaction results.
    1884              : 
    1885              :    Since references to entries in this vector are stored only in the
    1886              :    GC-deletable sat_cache, it's safe to make this deletable as well.  */
    1887              : 
    1888              : static GTY((deletable)) vec<tree, va_gc> *failed_type_completions;
    1889              : 
    1890              : /* A map of where types were found to be incomplete in SFINAE context, for
    1891              :    warning if they are later completed.  */
    1892              : 
    1893              : static GTY((cache)) hash_map<tree, location_t, decl_location_traits> *failed_completions_map;
    1894              : 
    1895              : /* Called whenever a type completion (or return type deduction) failure occurs
    1896              :    that definitely affects the meaning of the program, by e.g. inducing
    1897              :    substitution failure.  */
    1898              : 
    1899              : void
    1900         6999 : note_failed_type_completion (tree t, tsubst_flags_t complain)
    1901              : {
    1902         6999 :   if (dependent_template_arg_p (t))
    1903              :     return;
    1904              : 
    1905         6962 :   gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))
    1906              :                        || (DECL_P (t) && undeduced_auto_decl (t)));
    1907              : 
    1908         6962 :   if (satisfying_constraint)
    1909          193 :     vec_safe_push (failed_type_completions, t);
    1910              : 
    1911         6962 :   if (TYPE_P (t))
    1912              :     {
    1913         4217 :       if (!CLASS_TYPE_P (t))
    1914              :         return;
    1915         3806 :       t = TYPE_MAIN_DECL (t);
    1916              :     }
    1917         6551 :   if (!(complain & tf_error)
    1918        12465 :       && warning_enabled_at (DECL_SOURCE_LOCATION (t),
    1919         5914 :                              OPT_Wsfinae_incomplete_))
    1920              :     {
    1921         5912 :       if (warn_sfinae_incomplete > 1)
    1922              :         {
    1923            0 :           if (TREE_CODE (t) == TYPE_DECL)
    1924            0 :             warning (OPT_Wsfinae_incomplete_,
    1925            0 :                      "failed to complete %qT in SFINAE context", TREE_TYPE (t));
    1926              :           else
    1927            0 :             warning (OPT_Wsfinae_incomplete_,
    1928              :                      "failed to deduce %qD in SFINAE context", t);
    1929              :         }
    1930         5912 :       if (!failed_completions_map)
    1931          126 :         failed_completions_map
    1932          126 :           = hash_map<tree, location_t, decl_location_traits>::create_ggc ();
    1933         5912 :       failed_completions_map->put (t, input_location);
    1934              :     }
    1935              : }
    1936              : 
    1937              : /* If T was previously found to be incomplete in SFINAE context, return the
    1938              :    location where that happened, otherwise UNKNOWN_LOCATION.  */
    1939              : 
    1940              : location_t
    1941     54557405 : failed_completion_location (tree t)
    1942              : {
    1943     54557405 :   if (failed_completions_map)
    1944              :     {
    1945       111578 :       if (TYPE_P (t))
    1946        96176 :         t = TYPE_MAIN_DECL (t);
    1947       111578 :       if (location_t *p = failed_completions_map->get (t))
    1948           17 :         return *p;
    1949              :     }
    1950              :   return UNKNOWN_LOCATION;
    1951              : }
    1952              : 
    1953              : /* Returns true if the range [BEGIN, END) of elements within the
    1954              :    failed_type_completions vector contains a complete type (or a
    1955              :    declaration with a non-placeholder return type).  */
    1956              : 
    1957              : static bool
    1958    533179985 : some_type_complete_p (int begin, int end)
    1959              : {
    1960    533180588 :   for (int i = begin; i < end; i++)
    1961              :     {
    1962          666 :       tree t = (*failed_type_completions)[i];
    1963          666 :       if (TYPE_P (t) && COMPLETE_TYPE_P (t))
    1964              :         return true;
    1965          621 :       if (DECL_P (t) && !undeduced_auto_decl (t))
    1966              :         return true;
    1967              :     }
    1968              :   return false;
    1969              : }
    1970              : 
    1971              : /* Hash functions and data types for satisfaction cache entries.  */
    1972              : 
    1973              : struct GTY((for_user)) sat_entry
    1974              : {
    1975              :   /* The relevant ATOMIC_CONSTR.  */
    1976              :   tree atom;
    1977              : 
    1978              :   /* The relevant template arguments.  */
    1979              :   tree args;
    1980              : 
    1981              :   /* The result of satisfaction of ATOM+ARGS.
    1982              :      This is either boolean_true_node, boolean_false_node or error_mark_node,
    1983              :      where error_mark_node indicates ill-formed satisfaction.
    1984              :      It's set to NULL_TREE while computing satisfaction of ATOM+ARGS for
    1985              :      the first time.  */
    1986              :   tree result;
    1987              : 
    1988              :   /* For a !ATOMIC_CONSTR_MAP_INSTANTIATED_P atom, this conveniently points to
    1989              :      the entry for the corresponding atom after instantiating its mapping.  */
    1990              :   sat_entry *inst_entry;
    1991              : 
    1992              :   /* The value of input_location when satisfaction of ATOM+ARGS was first
    1993              :      performed.  */
    1994              :   location_t location;
    1995              : 
    1996              :   /* The range of elements appended to the failed_type_completions vector
    1997              :      during computation of this satisfaction result, encoded as a begin/end
    1998              :      pair of offsets.  */
    1999              :   int ftc_begin, ftc_end;
    2000              : 
    2001              :   /* True if we want to diagnose the above instability when it's detected.
    2002              :      We don't always want to do so, in order to avoid emitting duplicate
    2003              :      diagnostics in some cases.  */
    2004              :   bool diagnose_instability;
    2005              : 
    2006              :   /* True if we're in the middle of computing this satisfaction result.
    2007              :      Used during both quiet and noisy satisfaction to detect self-recursive
    2008              :      satisfaction.  */
    2009              :   bool evaluating;
    2010              : };
    2011              : 
    2012              : struct sat_hasher : ggc_ptr_hash<sat_entry>
    2013              : {
    2014   3524329089 :   static hashval_t hash (sat_entry *e)
    2015              :   {
    2016   3524329089 :     auto cso = make_temp_override (comparing_specializations);
    2017   3524329089 :     ++comparing_specializations;
    2018              : 
    2019   3524329089 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->atom))
    2020              :       {
    2021              :         /* Atoms with instantiated mappings are built during satisfaction.
    2022              :            They live only inside the sat_cache, and we build one to query
    2023              :            the cache with each time we instantiate a mapping.  */
    2024   1035002434 :         gcc_assert (!e->args);
    2025   1035002434 :         return hash_atomic_constraint (e->atom);
    2026              :       }
    2027              : 
    2028              :     /* Atoms with uninstantiated mappings are built during normalization.
    2029              :        Since normalize_atom caches the atoms it returns, we can assume
    2030              :        pointer-based identity for fast hashing and comparison.  Even if this
    2031              :        assumption is violated, that's okay, we'll just get a cache miss.  */
    2032   2489326655 :     hashval_t value = htab_hash_pointer (e->atom);
    2033              : 
    2034   2489326655 :     if (tree map = ATOMIC_CONSTR_MAP (e->atom))
    2035              :       /* Only the parameters that are used in the targets of the mapping
    2036              :          affect the satisfaction value of the atom.  So we consider only
    2037              :          the arguments for these parameters, and ignore the rest.  */
    2038   2489321988 :       for (tree target_parms = TREE_TYPE (map);
    2039   5560157207 :            target_parms;
    2040   3070835219 :            target_parms = TREE_CHAIN (target_parms))
    2041              :         {
    2042   3070835219 :           int level, index;
    2043   3070835219 :           tree parm = TREE_VALUE (target_parms);
    2044   3070835219 :           template_parm_level_and_index (parm, &level, &index);
    2045   3070835219 :           tree arg = TMPL_ARG (e->args, level, index);
    2046   3070835219 :           value = iterative_hash_template_arg (arg, value);
    2047              :         }
    2048              :     return value;
    2049   3524329089 :   }
    2050              : 
    2051   3794230521 :   static bool equal (sat_entry *e1, sat_entry *e2)
    2052              :   {
    2053   3794230521 :     auto cso = make_temp_override (comparing_specializations);
    2054   3794230521 :     ++comparing_specializations;
    2055              : 
    2056   3794230521 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)
    2057   3794230521 :         != ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom))
    2058              :       return false;
    2059              : 
    2060              :     /* See sat_hasher::hash.  */
    2061   2598119580 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom))
    2062              :       {
    2063    160205276 :         gcc_assert (!e1->args && !e2->args);
    2064    160205276 :         return atomic_constraints_identical_p (e1->atom, e2->atom);
    2065              :       }
    2066              : 
    2067   2437914304 :     if (e1->atom != e2->atom)
    2068              :       return false;
    2069              : 
    2070    425463635 :     if (tree map = ATOMIC_CONSTR_MAP (e1->atom))
    2071    425462075 :       for (tree target_parms = TREE_TYPE (map);
    2072    873032724 :            target_parms;
    2073    447570649 :            target_parms = TREE_CHAIN (target_parms))
    2074              :         {
    2075    454859395 :           int level, index;
    2076    454859395 :           tree parm = TREE_VALUE (target_parms);
    2077    454859395 :           template_parm_level_and_index (parm, &level, &index);
    2078    454859395 :           tree arg1 = TMPL_ARG (e1->args, level, index);
    2079    454859395 :           tree arg2 = TMPL_ARG (e2->args, level, index);
    2080    454859395 :           if (!template_args_equal (arg1, arg2))
    2081      7288746 :             return false;
    2082              :         }
    2083              :     return true;
    2084   3794230521 :   }
    2085              : };
    2086              : 
    2087              : /* Cache the result of satisfy_atom.  */
    2088              : static GTY((deletable)) hash_table<sat_hasher> *sat_cache;
    2089              : 
    2090              : /* Cache the result of satisfy_declaration_constraints.  */
    2091              : static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;
    2092              : 
    2093              : /* A tool used by satisfy_atom to help manage satisfaction caching and to
    2094              :    diagnose "unstable" satisfaction values.  We insert into the cache only
    2095              :    when performing satisfaction quietly.  */
    2096              : 
    2097              : struct satisfaction_cache
    2098              : {
    2099              :   satisfaction_cache (tree, tree, sat_info);
    2100              :   tree get ();
    2101              :   tree save (tree);
    2102              : 
    2103              :   sat_entry *entry;
    2104              :   sat_info info;
    2105              :   int ftc_begin;
    2106              : };
    2107              : 
    2108              : /* Constructor for the satisfaction_cache class.  We're performing satisfaction
    2109              :    of ATOM+ARGS according to INFO.  */
    2110              : 
    2111    533180027 : satisfaction_cache
    2112              : ::satisfaction_cache (tree atom, tree args, sat_info info)
    2113    533180027 :   : entry(nullptr), info(info), ftc_begin(-1)
    2114              : {
    2115    533180027 :   if (!sat_cache)
    2116        76433 :     sat_cache = hash_table<sat_hasher>::create_ggc (31);
    2117              : 
    2118              :   /* When noisy, we query the satisfaction cache in order to diagnose
    2119              :      "unstable" satisfaction values.  */
    2120    533180027 :   if (info.noisy ())
    2121              :     {
    2122              :       /* When noisy, constraints have been re-normalized, and that breaks the
    2123              :          pointer-based identity assumption of sat_cache (for atoms with
    2124              :          uninstantiated mappings).  So undo this re-normalization by looking in
    2125              :          the atom_cache for the corresponding atom that was used during quiet
    2126              :          satisfaction.  */
    2127         7514 :       if (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
    2128              :         {
    2129         3770 :           if (tree found = atom_cache->find (atom))
    2130         3770 :             atom = found;
    2131              :           else
    2132              :             /* The lookup should always succeed, but if it fails then let's
    2133              :                just leave 'entry' empty, effectively disabling the cache.  */
    2134            0 :             return;
    2135              :         }
    2136              :     }
    2137              : 
    2138              :   /* Look up or create the corresponding satisfaction entry.  */
    2139    533180027 :   sat_entry elt;
    2140    533180027 :   elt.atom = atom;
    2141    533180027 :   elt.args = args;
    2142    533180027 :   sat_entry **slot = sat_cache->find_slot (&elt, INSERT);
    2143    533180027 :   if (*slot)
    2144    447668187 :     entry = *slot;
    2145     85511840 :   else if (info.quiet ())
    2146              :     {
    2147     85511834 :       entry = ggc_alloc<sat_entry> ();
    2148     85511834 :       entry->atom = atom;
    2149     85511834 :       entry->args = args;
    2150     85511834 :       entry->result = NULL_TREE;
    2151     85511834 :       entry->inst_entry = nullptr;
    2152     85511834 :       entry->location = input_location;
    2153     85511834 :       entry->ftc_begin = entry->ftc_end = -1;
    2154     85511834 :       entry->diagnose_instability = false;
    2155     85511834 :       if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
    2156              :         /* We always want to diagnose instability of an atom with an
    2157              :            instantiated parameter mapping.  For atoms with an uninstantiated
    2158              :            mapping, we set this flag (in satisfy_atom) only if substitution
    2159              :            into its mapping previously failed.  */
    2160     28004522 :         entry->diagnose_instability = true;
    2161     85511834 :       entry->evaluating = false;
    2162     85511834 :       *slot = entry;
    2163              :     }
    2164              :   else
    2165              :     {
    2166              :       /* We're evaluating this atom for the first time, and doing so noisily.
    2167              :          This shouldn't happen outside of error recovery situations involving
    2168              :          unstable satisfaction.  Let's just leave 'entry' empty, effectively
    2169              :          disabling the cache, and remove the empty slot.  */
    2170            6 :       gcc_checking_assert (seen_error ());
    2171              :       /* Appease hash_table::check_complete_insertion.  */
    2172            6 :       *slot = ggc_alloc<sat_entry> ();
    2173            6 :       sat_cache->clear_slot (slot);
    2174              :     }
    2175              : }
    2176              : 
    2177              : /* Returns the cached satisfaction result if we have one and we're not
    2178              :    recomputing the satisfaction result from scratch.  Otherwise returns
    2179              :    NULL_TREE.  */
    2180              : 
    2181              : tree
    2182    533180027 : satisfaction_cache::get ()
    2183              : {
    2184    533180027 :   if (!entry)
    2185              :     return NULL_TREE;
    2186              : 
    2187    533180021 :   if (entry->evaluating)
    2188              :     {
    2189              :       /* If we get here, it means satisfaction is self-recursive.  */
    2190           36 :       gcc_checking_assert (!entry->result || seen_error ());
    2191              :       /* Prefer printing the instantiated mapping.  */
    2192           36 :       tree atom = entry->inst_entry ? entry->inst_entry->atom : entry->atom;
    2193           36 :       if (info.noisy ())
    2194           18 :         error_at (cp_expr_location (ATOMIC_CONSTR_EXPR (atom)),
    2195              :                   "satisfaction of atomic constraint %qE depends on itself",
    2196              :                   atom);
    2197           36 :       return error_mark_node;
    2198              :     }
    2199              : 
    2200              :   /* This satisfaction result is "potentially unstable" if a type for which
    2201              :      type completion failed during its earlier computation is now complete.  */
    2202    533179985 :   bool maybe_unstable = some_type_complete_p (entry->ftc_begin,
    2203              :                                               entry->ftc_end);
    2204              : 
    2205    533179985 :   if (info.noisy () || maybe_unstable || !entry->result)
    2206              :     {
    2207              :       /* We're computing the satisfaction result from scratch.  */
    2208     85519366 :       entry->evaluating = true;
    2209     85519366 :       ftc_begin = vec_safe_length (failed_type_completions);
    2210     85519366 :       return NULL_TREE;
    2211              :     }
    2212              :   else
    2213              :     return entry->result;
    2214              : }
    2215              : 
    2216              : /* RESULT is the computed satisfaction result.  If RESULT differs from the
    2217              :    previously cached result, this routine issues an appropriate error.
    2218              :    Otherwise, when evaluating quietly, updates the cache appropriately.  */
    2219              : 
    2220              : tree
    2221     85513972 : satisfaction_cache::save (tree result)
    2222              : {
    2223     85513972 :   if (!entry)
    2224              :     return result;
    2225              : 
    2226     85513966 :   gcc_checking_assert (entry->evaluating);
    2227     85513966 :   entry->evaluating = false;
    2228              : 
    2229     85513966 :   if (entry->result && result != entry->result)
    2230              :     {
    2231           42 :       if (info.quiet ())
    2232              :         /* Return error_mark_node to force satisfaction to get replayed
    2233              :            noisily.  */
    2234           21 :         return error_mark_node;
    2235              :       else
    2236              :         {
    2237           21 :           if (entry->diagnose_instability)
    2238              :             {
    2239           12 :               auto_diagnostic_group d;
    2240           12 :               error_at (cp_expr_location (ATOMIC_CONSTR_EXPR (entry->atom)),
    2241              :                         "satisfaction value of atomic constraint %qE changed "
    2242           12 :                         "from %qE to %qE", entry->atom, entry->result, result);
    2243           12 :               inform (entry->location,
    2244              :                       "satisfaction value first evaluated to %qE from here",
    2245           12 :                       entry->result);
    2246           12 :             }
    2247              :           /* For sake of error recovery, allow this latest satisfaction result
    2248              :              to prevail.  */
    2249           21 :           entry->result = result;
    2250           21 :           return result;
    2251              :         }
    2252              :     }
    2253              : 
    2254     85513924 :   if (info.quiet ())
    2255              :     {
    2256     85506455 :       entry->result = result;
    2257              :       /* Store into this entry the list of relevant failed type completions
    2258              :          that occurred during (re)computation of the satisfaction result.  */
    2259     85506455 :       gcc_checking_assert (ftc_begin != -1);
    2260     85506455 :       entry->ftc_begin = ftc_begin;
    2261     85694652 :       entry->ftc_end = vec_safe_length (failed_type_completions);
    2262              :     }
    2263              : 
    2264              :   return result;
    2265              : }
    2266              : 
    2267              : /* Substitute ARGS into constraint-expression T during instantiation of
    2268              :    a member of a class template.  */
    2269              : 
    2270              : tree
    2271      1693656 : tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
    2272              : {
    2273              :   /* We also don't want to evaluate concept-checks when substituting the
    2274              :      constraint-expressions of a declaration.  */
    2275      1693656 :   processing_constraint_expression_sentinel s;
    2276      1693656 :   cp_unevaluated u;
    2277      1693656 :   tree expr = tsubst_expr (t, args, complain, in_decl);
    2278      3387312 :   return expr;
    2279      1693656 : }
    2280              : 
    2281              : static tree satisfy_constraint_r (tree, tree, sat_info info);
    2282              : 
    2283              : /* Compute the satisfaction of a conjunction.  */
    2284              : 
    2285              : static tree
    2286    400731803 : satisfy_conjunction (tree t, tree args, sat_info info)
    2287              : {
    2288    400731803 :   tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
    2289    400731803 :   if (lhs == error_mark_node || lhs == boolean_false_node)
    2290              :     return lhs;
    2291    392621429 :   return satisfy_constraint_r (TREE_OPERAND (t, 1), args, info);
    2292              : }
    2293              : 
    2294              : /* The current depth at which we're replaying an error during recursive
    2295              :    diagnosis of a constraint satisfaction failure.  */
    2296              : 
    2297              : static int current_constraint_diagnosis_depth;
    2298              : 
    2299              : /* Whether CURRENT_CONSTRAINT_DIAGNOSIS_DEPTH has ever exceeded
    2300              :    CONCEPTS_DIAGNOSTICS_MAX_DEPTH during recursive diagnosis of a constraint
    2301              :    satisfaction error.  */
    2302              : 
    2303              : static bool concepts_diagnostics_max_depth_exceeded_p;
    2304              : 
    2305              : /* Recursive subroutine of collect_operands_of_disjunction.  T is a normalized
    2306              :    subexpression of a constraint (composed of CONJ_CONSTRs and DISJ_CONSTRs)
    2307              :    and E is the corresponding unnormalized subexpression (composed of
    2308              :    TRUTH_ANDIF_EXPRs and TRUTH_ORIF_EXPRs).  */
    2309              : 
    2310              : static void
    2311           22 : collect_operands_of_disjunction_r (tree t, tree e,
    2312              :                                    auto_vec<tree_pair> *operands)
    2313              : {
    2314           36 :   if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
    2315              :     {
    2316           14 :       collect_operands_of_disjunction_r (TREE_OPERAND (t, 0),
    2317           14 :                                          TREE_OPERAND (e, 0), operands);
    2318           14 :       collect_operands_of_disjunction_r (TREE_OPERAND (t, 1),
    2319           14 :                                          TREE_OPERAND (e, 1), operands);
    2320              :     }
    2321              :   else
    2322              :     {
    2323           22 :       tree_pair p = std::make_pair (t, e);
    2324           22 :       operands->safe_push (p);
    2325              :     }
    2326           22 : }
    2327              : 
    2328              : /* Recursively collect the normalized and unnormalized operands of the
    2329              :    disjunction T and append them to OPERANDS in order.  */
    2330              : 
    2331              : static void
    2332            8 : collect_operands_of_disjunction (tree t, auto_vec<tree_pair> *operands)
    2333              : {
    2334            8 :   collect_operands_of_disjunction_r (t, CONSTR_EXPR (t), operands);
    2335            8 : }
    2336              : 
    2337              : /* Compute the satisfaction of a disjunction.  */
    2338              : 
    2339              : static tree
    2340     41450963 : satisfy_disjunction (tree t, tree args, sat_info info)
    2341              : {
    2342              :   /* Evaluate each operand with unsatisfaction diagnostics disabled.  */
    2343     41450963 :   sat_info sub = info;
    2344     41450963 :   sub.diagnose_unsatisfaction = false;
    2345              : 
    2346     41450963 :   tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, sub);
    2347     41450963 :   if (lhs == boolean_true_node || lhs == error_mark_node)
    2348              :     return lhs;
    2349              : 
    2350     20487176 :   tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, sub);
    2351     20487176 :   if (rhs == boolean_true_node || rhs == error_mark_node)
    2352              :     return rhs;
    2353              : 
    2354              :   /* Both branches evaluated to false.  Explain the satisfaction failure in
    2355              :      each branch.  */
    2356      3689836 :   if (info.diagnose_unsatisfaction_p ())
    2357              :     {
    2358           69 :       diagnosing_failed_constraint failure (t, args, info.noisy ());
    2359           69 :       cp_expr disj_expr = CONSTR_EXPR (t);
    2360           69 :       inform (disj_expr.get_location (),
    2361              :               "no operand of the disjunction is satisfied");
    2362           69 :       if (diagnosing_failed_constraint::replay_errors_p ())
    2363              :         {
    2364            8 :           auto_diagnostic_nesting_level sentinel;
    2365              :           /* Replay the error in each branch of the disjunction.  */
    2366            8 :           auto_vec<tree_pair> operands;
    2367            8 :           collect_operands_of_disjunction (t, &operands);
    2368           38 :           for (unsigned i = 0; i < operands.length (); i++)
    2369              :             {
    2370           22 :               tree norm_op = operands[i].first;
    2371           22 :               tree op = operands[i].second;
    2372           22 :               location_t loc = make_location (cp_expr_location (op),
    2373              :                                               disj_expr.get_start (),
    2374              :                                               disj_expr.get_finish ());
    2375           22 :               inform (loc, "the operand %qE is unsatisfied because", op);
    2376           22 :               auto_diagnostic_nesting_level sentinel;
    2377           22 :               satisfy_constraint_r (norm_op, args, info);
    2378           22 :             }
    2379            8 :         }
    2380           69 :     }
    2381              : 
    2382      3689836 :   return boolean_false_node;
    2383              : }
    2384              : 
    2385              : /* Ensures that T is a truth value and not (accidentally, as sometimes
    2386              :    happens) an integer value.  */
    2387              : 
    2388              : tree
    2389     27994038 : satisfaction_value (tree t)
    2390              : {
    2391     27994038 :   if (t == error_mark_node || t == boolean_true_node || t == boolean_false_node)
    2392              :     return t;
    2393              : 
    2394            2 :   gcc_assert (TREE_CODE (t) == INTEGER_CST
    2395              :               && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t),
    2396              :                                                             boolean_type_node));
    2397            2 :   if (integer_zerop (t))
    2398            0 :     return boolean_false_node;
    2399              :   else
    2400            2 :     return boolean_true_node;
    2401              : }
    2402              : 
    2403              : /* Build a new template argument vector corresponding to the parameter
    2404              :    mapping of the atomic constraint T, using arguments from ARGS.  */
    2405              : 
    2406              : static tree
    2407     28008284 : get_mapped_args (tree t, tree args)
    2408              : {
    2409     28008284 :   tree map = ATOMIC_CONSTR_MAP (t);
    2410              : 
    2411              :   /* No map, no arguments.  */
    2412     28008284 :   if (!map)
    2413              :     return NULL_TREE;
    2414              : 
    2415              :   /* Determine the depth of the resulting argument vector.  */
    2416     28007461 :   int depth;
    2417     28007461 :   if (ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (t))
    2418              :     /* The expression of this atomic constraint comes from a concept
    2419              :        definition, whose template depth is always one, so the resulting
    2420              :        argument vector will also have depth one.  */
    2421              :     depth = 1;
    2422              :   else
    2423              :     /* Otherwise, the expression of this atomic constraint comes from
    2424              :        the context of the constrained entity, whose template depth is that
    2425              :        of ARGS.  */
    2426     21345070 :     depth = TMPL_ARGS_DEPTH (args);
    2427              : 
    2428              :   /* Place each argument at its corresponding position in the argument
    2429              :      list.  Note that the list will be sparse (not all arguments supplied),
    2430              :      but instantiation is guaranteed to only use the parameters in the
    2431              :      mapping, so null arguments would never be used.  */
    2432     28007461 :   auto_vec< vec<tree> > lists (depth);
    2433     28007461 :   lists.quick_grow_cleared (depth);
    2434     99457034 :   for (tree p = map; p; p = TREE_CHAIN (p))
    2435              :     {
    2436     43442112 :       int level;
    2437     43442112 :       int index;
    2438     43442112 :       template_parm_level_and_index (TREE_VALUE (p), &level, &index);
    2439              : 
    2440              :       /* Insert the argument into its corresponding position.  */
    2441     43442112 :       vec<tree> &list = lists[level - 1];
    2442     58066026 :       if (index >= (int)list.length ())
    2443     40019268 :         list.safe_grow_cleared (index + 1, /*exact=*/false);
    2444     43442112 :       list[index] = TREE_PURPOSE (p);
    2445              :     }
    2446              : 
    2447              :   /* Build the new argument list.  */
    2448     28007461 :   args = make_tree_vec (lists.length ());
    2449    142568571 :   for (unsigned i = 0; i != lists.length (); ++i)
    2450              :     {
    2451     29273094 :       vec<tree> &list = lists[i];
    2452     29273094 :       tree level = make_tree_vec (list.length ());
    2453    103023218 :       for (unsigned j = 0; j < list.length (); ++j)
    2454     44477030 :         TREE_VEC_ELT (level, j) = list[j];
    2455     29273094 :       SET_TMPL_ARGS_LEVEL (args, i + 1, level);
    2456     29273094 :       list.release ();
    2457              :     }
    2458     28007461 :   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0);
    2459              : 
    2460     28007461 :   if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)
    2461     28007461 :       && TMPL_ARGS_DEPTH (args) == 1)
    2462              :     {
    2463              :       /* Get rid of the redundant outer TREE_VEC.  */
    2464     26749758 :       tree level = TMPL_ARGS_LEVEL (args, 1);
    2465     26749758 :       ggc_free (args);
    2466     26749758 :       args = level;
    2467              :     }
    2468              : 
    2469     28007461 :   return args;
    2470     28007461 : }
    2471              : 
    2472              : static void diagnose_atomic_constraint (tree, tree, tree, sat_info);
    2473              : 
    2474              : /* Compute the satisfaction of an atomic constraint.  */
    2475              : 
    2476              : static tree
    2477    475682204 : satisfy_atom (tree t, tree args, sat_info info)
    2478              : {
    2479              :   /* In case there is a diagnostic, we want to establish the context
    2480              :      prior to printing errors.  If no errors occur, this context is
    2481              :      removed before returning.  */
    2482    475682204 :   diagnosing_failed_constraint failure (t, args, info.noisy ());
    2483              : 
    2484    475682204 :   satisfaction_cache cache (t, args, info);
    2485    475682204 :   if (tree r = cache.get ())
    2486              :     return r;
    2487              : 
    2488              :   /* Perform substitution quietly.  */
    2489     57511088 :   subst_info quiet (tf_none, NULL_TREE);
    2490              : 
    2491              :   /* Instantiate the parameter mapping.  */
    2492     57511088 :   tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet);
    2493     57511088 :   if (map == error_mark_node)
    2494              :     {
    2495              :       /* If instantiation of the parameter mapping fails, the constraint is
    2496              :          not satisfied.  Replay the substitution.  */
    2497        13265 :       if (info.diagnose_unsatisfaction_p ())
    2498            8 :         tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info);
    2499        13265 :       if (info.quiet ())
    2500              :         /* Since instantiation of the parameter mapping failed, we
    2501              :            want to diagnose potential instability of this satisfaction
    2502              :            result.  */
    2503        13257 :         cache.entry->diagnose_instability = true;
    2504        13265 :       return cache.save (boolean_false_node);
    2505              :     }
    2506              : 
    2507              :   /* Now build a new atom using the instantiated mapping.  We use
    2508              :      this atom as a second key to the satisfaction cache, and we
    2509              :      also pass it to diagnose_atomic_constraint so that diagnostics
    2510              :      which refer to the atom display the instantiated mapping.  */
    2511     57497823 :   t = copy_node (t);
    2512     57497823 :   ATOMIC_CONSTR_MAP (t) = map;
    2513     57497823 :   gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t));
    2514     57497823 :   ATOMIC_CONSTR_MAP_INSTANTIATED_P (t) = true;
    2515     57497823 :   satisfaction_cache inst_cache (t, /*args=*/NULL_TREE, info);
    2516     57497823 :   if (cache.entry && inst_cache.entry)
    2517     57497820 :     cache.entry->inst_entry = inst_cache.entry;
    2518     57497823 :   if (tree r = inst_cache.get ())
    2519              :     {
    2520     29489539 :       cache.entry->location = inst_cache.entry->location;
    2521     29489539 :       return cache.save (r);
    2522              :     }
    2523              : 
    2524              :   /* Rebuild the argument vector from the parameter mapping.  */
    2525     28008284 :   args = get_mapped_args (t, args);
    2526              : 
    2527              :   /* Apply the parameter mapping (i.e., just substitute).  */
    2528     28008284 :   tree expr = ATOMIC_CONSTR_EXPR (t);
    2529     28008284 :   tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl);
    2530     28005584 :   if (result == error_mark_node)
    2531              :     {
    2532              :       /* If substitution results in an invalid type or expression, the
    2533              :          constraint is not satisfied.  Replay the substitution.  */
    2534        11488 :       if (info.diagnose_unsatisfaction_p ())
    2535           20 :         tsubst_expr (expr, args, info.complain, info.in_decl);
    2536        11488 :       return cache.save (inst_cache.save (boolean_false_node));
    2537              :     }
    2538              : 
    2539              :   /* [17.4.1.2] ... lvalue-to-rvalue conversion is performed as necessary,
    2540              :      and EXPR shall be a constant expression of type bool.  */
    2541     27994096 :   result = force_rvalue (result, info.complain);
    2542     27994096 :   if (result == error_mark_node)
    2543            0 :     return cache.save (inst_cache.save (error_mark_node));
    2544     27994096 :   tree substituted = result;
    2545     27994096 :   if (!same_type_p (TREE_TYPE (result), boolean_type_node))
    2546              :     {
    2547           58 :       if (info.noisy ())
    2548           32 :         diagnose_atomic_constraint (t, args, substituted, info);
    2549           58 :       return cache.save (inst_cache.save (error_mark_node));
    2550              :     }
    2551              : 
    2552              :   /* Compute the value of the constraint.  */
    2553     27994038 :   if (info.noisy ())
    2554              :     {
    2555         3683 :       iloc_sentinel ils (EXPR_LOCATION (result));
    2556         3683 :       result = cxx_constant_value (result);
    2557         3683 :     }
    2558              :   else
    2559              :     {
    2560     27990355 :       result = maybe_constant_value (result, NULL_TREE, mce_true);
    2561     27990355 :       if (!TREE_CONSTANT (result))
    2562           22 :         result = error_mark_node;
    2563              :     }
    2564     27994038 :   result = satisfaction_value (result);
    2565     27994038 :   if (result == boolean_false_node && info.diagnose_unsatisfaction_p ())
    2566         1254 :     diagnose_atomic_constraint (t, args, substituted, info);
    2567              : 
    2568     27994038 :   return cache.save (inst_cache.save (result));
    2569    475679504 : }
    2570              : 
    2571              : /* Determine if the normalized constraint T is satisfied.
    2572              :    Returns boolean_true_node if the expression/constraint is
    2573              :    satisfied, boolean_false_node if not, and error_mark_node
    2574              :    if there was an error evaluating the constraint.
    2575              : 
    2576              :    The parameter mapping of atomic constraints is simply the
    2577              :    set of template arguments that will be substituted into
    2578              :    the expression, regardless of template parameters appearing
    2579              :    within.  Whether a template argument is used in the atomic
    2580              :    constraint only matters for subsumption.  */
    2581              : 
    2582              : static tree
    2583    917865117 : satisfy_constraint_r (tree t, tree args, sat_info info)
    2584              : {
    2585    917865117 :   if (t == error_mark_node)
    2586              :     return error_mark_node;
    2587              : 
    2588    917864970 :   switch (TREE_CODE (t))
    2589              :     {
    2590    400731803 :     case CONJ_CONSTR:
    2591    400731803 :       return satisfy_conjunction (t, args, info);
    2592     41450963 :     case DISJ_CONSTR:
    2593     41450963 :       return satisfy_disjunction (t, args, info);
    2594    475682204 :     case ATOMIC_CONSTR:
    2595    475682204 :       return satisfy_atom (t, args, info);
    2596            0 :     default:
    2597            0 :       gcc_unreachable ();
    2598              :     }
    2599              : }
    2600              : 
    2601              : /* Check that the normalized constraint T is satisfied for ARGS.  */
    2602              : 
    2603              : static tree
    2604     62573724 : satisfy_normalized_constraints (tree t, tree args, sat_info info)
    2605              : {
    2606     62573724 :   auto_timevar time (TV_CONSTRAINT_SAT);
    2607              : 
    2608     62573724 :   auto ovr = make_temp_override (satisfying_constraint, true);
    2609              : 
    2610              :   /* Turn off template processing.  Constraint satisfaction only applies
    2611              :      to non-dependent terms, so we want to ensure full checking here.  */
    2612     62573724 :   processing_template_decl_sentinel proc (true);
    2613              : 
    2614              :   /* We need to check access during satisfaction.  */
    2615     62573724 :   deferring_access_check_sentinel acs (dk_no_deferred);
    2616              : 
    2617              :   /* Constraints are unevaluated operands.  */
    2618     62573724 :   cp_unevaluated u;
    2619              : 
    2620     62573724 :   return satisfy_constraint_r (t, args, info);
    2621     62571024 : }
    2622              : 
    2623              : /* Return the normal form of the constraints on the placeholder 'auto'
    2624              :    type T.  */
    2625              : 
    2626              : static tree
    2627      8764254 : normalize_placeholder_type_constraints (tree t, bool diag)
    2628              : {
    2629      8764254 :   gcc_assert (is_auto (t));
    2630      8764254 :   tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
    2631      8764254 :   if (!ci)
    2632              :     return NULL_TREE;
    2633              : 
    2634      8764254 :   tree constr = TREE_VALUE (ci);
    2635              :   /* The TREE_PURPOSE contains the set of template parameters that were in
    2636              :      scope for this placeholder type; use them as the initial template
    2637              :      parameters for normalization.  */
    2638      8764254 :   tree initial_parms = TREE_PURPOSE (ci);
    2639              : 
    2640              :   /* The 'auto' itself is used as the first argument in its own constraints,
    2641              :      and its level is one greater than its template depth.  So in order to
    2642              :      capture all used template parameters, we need to add an extra level of
    2643              :      template parameters to the context; a dummy level suffices.  */
    2644      8764254 :   initial_parms
    2645     17528244 :     = tree_cons (size_int (initial_parms
    2646              :                            ? TMPL_PARMS_DEPTH (initial_parms) + 1 : 1),
    2647              :                  make_tree_vec (0), initial_parms);
    2648              : 
    2649      8764254 :   norm_info info (diag);
    2650      8764254 :   info.initial_parms = initial_parms;
    2651      8764254 :   return normalize_constraint_expression (constr, info);
    2652              : }
    2653              : 
    2654              : /* Evaluate the constraints of T using ARGS, returning a satisfaction value.
    2655              :    Here, T can be a concept-id, nested-requirement, placeholder 'auto', or
    2656              :    requires-expression.  */
    2657              : 
    2658              : static tree
    2659     12389076 : satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
    2660              : {
    2661     12389076 :   if (t == error_mark_node)
    2662              :     return error_mark_node;
    2663              : 
    2664              :   /* Handle REQUIRES_EXPR directly, bypassing satisfaction.  */
    2665     12389072 :   if (TREE_CODE (t) == REQUIRES_EXPR)
    2666              :     {
    2667          258 :       auto ovr = make_temp_override (current_constraint_diagnosis_depth);
    2668          258 :       if (info.noisy ())
    2669           35 :         ++current_constraint_diagnosis_depth;
    2670          258 :       return tsubst_requires_expr (t, args, info);
    2671          258 :     }
    2672              : 
    2673              :   /* Get the normalized constraints.  */
    2674     12388814 :   tree norm;
    2675     12388814 :   if (concept_check_p (t))
    2676              :     {
    2677      2771784 :       gcc_assert (!args);
    2678      2771784 :       args = TREE_OPERAND (t, 1);
    2679      2771784 :       tree tmpl = get_concept_check_template (t);
    2680      2771784 :       norm = normalize_concept_definition (tmpl, info.noisy ());
    2681              :     }
    2682      9617030 :   else if (TREE_CODE (t) == NESTED_REQ)
    2683              :     {
    2684       852776 :       norm_info ninfo (info.noisy ());
    2685              :       /* The TREE_TYPE contains the set of template parameters that were in
    2686              :          scope for this nested requirement; use them as the initial template
    2687              :          parameters for normalization.  */
    2688       852776 :       ninfo.initial_parms = TREE_TYPE (t);
    2689       852776 :       norm = normalize_constraint_expression (TREE_OPERAND (t, 0), ninfo);
    2690              :     }
    2691      8764254 :   else if (is_auto (t))
    2692              :     {
    2693      8764254 :       norm = normalize_placeholder_type_constraints (t, info.noisy ());
    2694      8764254 :       if (!norm)
    2695            0 :         return boolean_true_node;
    2696              :     }
    2697              :   else
    2698            0 :     gcc_unreachable ();
    2699              : 
    2700              :   /* Perform satisfaction.  */
    2701     12388814 :   return satisfy_normalized_constraints (norm, args, info);
    2702              : }
    2703              : 
    2704              : /* Evaluate the associated constraints of the template specialization T
    2705              :    according to INFO, returning a satisfaction value.  */
    2706              : 
    2707              : static tree
    2708    673107482 : satisfy_declaration_constraints (tree t, sat_info info)
    2709              : {
    2710    673107482 :   gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL);
    2711    673107482 :   const tree saved_t = t;
    2712              : 
    2713              :   /* For inherited constructors, consider the original declaration;
    2714              :      it has the correct template information attached.  */
    2715    673107482 :   t = strip_inheriting_ctors (t);
    2716    673107482 :   tree inh_ctor_targs = NULL_TREE;
    2717    673107482 :   if (t != saved_t)
    2718       328231 :     if (tree ti = DECL_TEMPLATE_INFO (saved_t))
    2719              :       /* The inherited constructor points to an instantiation of a constructor
    2720              :          template; remember its template arguments.  */
    2721        34604 :       inh_ctor_targs = TI_ARGS (ti);
    2722              : 
    2723              :   /* Update the declaration for diagnostics.  */
    2724    673107482 :   info.in_decl = t;
    2725              : 
    2726    673107482 :   if (info.quiet ())
    2727   1346065017 :     if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
    2728    550983957 :       return *result;
    2729              : 
    2730    122123525 :   tree args = NULL_TREE;
    2731    122123525 :   if (tree ti = DECL_TEMPLATE_INFO (t))
    2732              :     {
    2733              :       /* The initial parameter mapping is the complete set of
    2734              :          template arguments substituted into the declaration.  */
    2735     82817521 :       args = TI_ARGS (ti);
    2736     82817521 :       if (inh_ctor_targs)
    2737        14563 :         args = add_outermost_template_args (args, inh_ctor_targs);
    2738              :     }
    2739              : 
    2740    122123525 :   if (regenerated_lambda_fn_p (t))
    2741              :     {
    2742              :       /* The TI_ARGS of a regenerated lambda contains only the innermost
    2743              :          set of template arguments.  Augment this with the outer template
    2744              :          arguments that were used to regenerate the lambda.  */
    2745       463465 :       gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
    2746       328994 :       tree regen_args = lambda_regenerating_args (t);
    2747       328994 :       if (args)
    2748       134471 :         args = add_to_template_args (regen_args, args);
    2749              :       else
    2750              :         args = regen_args;
    2751              :     }
    2752              : 
    2753              :   /* If the innermost arguments are dependent, or if the outer arguments
    2754              :      are dependent and are needed by the constraints, we can't check
    2755              :      satisfaction yet so pretend they're satisfied for now.  */
    2756    122123525 :   if (uses_template_parms (args)
    2757    122123525 :       && ((DECL_TEMPLATE_INFO (t)
    2758       331237 :            && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))
    2759       105108 :            && (TMPL_ARGS_DEPTH (args) == 1
    2760        25242 :                || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args))))
    2761       303968 :           || uses_outer_template_parms_in_constraints (t)))
    2762        27351 :     return boolean_true_node;
    2763              : 
    2764              :   /* Get the normalized constraints.  */
    2765    122096174 :   tree norm = get_normalized_constraints_from_decl (t, info.noisy ());
    2766              : 
    2767    122096174 :   unsigned ftc_count = vec_safe_length (failed_type_completions);
    2768              : 
    2769    122096174 :   tree result = boolean_true_node;
    2770    122096174 :   if (norm)
    2771              :     {
    2772      2963598 :       if (!push_tinst_level (t))
    2773              :         return result;
    2774      2962663 :       push_to_top_level ();
    2775      2962663 :       push_access_scope (t);
    2776      2962663 :       result = satisfy_normalized_constraints (norm, args, info);
    2777      2962663 :       pop_access_scope (t);
    2778      2962663 :       pop_from_top_level ();
    2779      2962663 :       pop_tinst_level ();
    2780              :     }
    2781              : 
    2782              :   /* True if this satisfaction is (heuristically) potentially unstable, i.e.
    2783              :      if its result may depend on where in the program it was performed.  */
    2784    122095239 :   bool maybe_unstable_satisfaction = false;
    2785    122183821 :   if (ftc_count != vec_safe_length (failed_type_completions))
    2786              :     /* Type completion failure occurred during satisfaction.  The satisfaction
    2787              :        result may (or may not) materially depend on the completeness of a type,
    2788              :        so we consider it potentially unstable.   */
    2789              :     maybe_unstable_satisfaction = true;
    2790              : 
    2791    122095239 :   if (maybe_unstable_satisfaction)
    2792              :     /* Don't cache potentially unstable satisfaction, to allow satisfy_atom
    2793              :        to check the stability the next time around.  */;
    2794    122095239 :   else if (info.quiet ())
    2795    122095149 :     hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);
    2796              : 
    2797    122095239 :   return result;
    2798              : }
    2799              : 
    2800              : /* Evaluate the associated constraints of the template T using ARGS as the
    2801              :    innermost set of template arguments and according to INFO, returning a
    2802              :    satisfaction value.  */
    2803              : 
    2804              : static tree
    2805    407324242 : satisfy_declaration_constraints (tree t, tree args, sat_info info)
    2806              : {
    2807    407324242 :   tree orig_args = args;
    2808              : 
    2809              :   /* Update the declaration for diagnostics.  */
    2810    407324242 :   info.in_decl = t;
    2811              : 
    2812    407324242 :   gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);
    2813              : 
    2814    407324242 :   if (regenerated_lambda_fn_p (t))
    2815              :     {
    2816              :       /* As in the two-parameter version of this function.  */
    2817       338572 :       gcc_assert (TMPL_ARGS_DEPTH (args) == 1);
    2818       169286 :       tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
    2819       169286 :       tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
    2820       169286 :       args = add_to_template_args (outer_args, args);
    2821              :     }
    2822              :   else
    2823    407154956 :     args = add_outermost_template_args (t, args);
    2824              : 
    2825              :   /* If the innermost arguments are dependent, or if the outer arguments
    2826              :      are dependent and are needed by the constraints, we can't check
    2827              :      satisfaction yet so pretend they're satisfied for now.  */
    2828    407324242 :   if (uses_template_parms (args)
    2829    529829393 :       && (TMPL_ARGS_DEPTH (args) == 1
    2830      7847065 :           || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args))
    2831       372970 :           || uses_outer_template_parms_in_constraints (t)))
    2832    122132181 :     return boolean_true_node;
    2833              : 
    2834    285192061 :   tree result = boolean_true_node;
    2835    285192061 :   if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
    2836              :     {
    2837     47222247 :       if (!push_tinst_level (t, orig_args))
    2838              :         return result;
    2839     47222247 :       tree pattern = DECL_TEMPLATE_RESULT (t);
    2840     47222247 :       push_to_top_level ();
    2841     47222247 :       push_access_scope (pattern);
    2842     47222247 :       {
    2843              :         /* For reconstruct_lambda_capture_pack.  */
    2844     48313859 :         local_specialization_stack lss (LAMBDA_FUNCTION_P (t)
    2845     94444494 :                                         ? lss_blank : lss_nop);
    2846     47222247 :         result = satisfy_normalized_constraints (norm, args, info);
    2847     47219547 :       }
    2848     47219547 :       pop_access_scope (pattern);
    2849     47219547 :       pop_from_top_level ();
    2850     47219547 :       pop_tinst_level ();
    2851              :     }
    2852              : 
    2853              :   return result;
    2854              : }
    2855              : 
    2856              : /* A wrapper around satisfy_declaration_constraints and
    2857              :    satisfy_nondeclaration_constraints which additionally replays
    2858              :    quiet ill-formed satisfaction noisily, so that ill-formed
    2859              :    satisfaction always gets diagnosed.  */
    2860              : 
    2861              : static tree
    2862   1092820800 : constraint_satisfaction_value (tree t, tree args, sat_info info)
    2863              : {
    2864   1092820800 :   tree r;
    2865   1092820800 :   if (DECL_P (t))
    2866              :     {
    2867   1080431724 :       if (args)
    2868    407324242 :         r = satisfy_declaration_constraints (t, args, info);
    2869              :       else
    2870    673107482 :         r = satisfy_declaration_constraints (t, info);
    2871              :     }
    2872              :   else
    2873     12389076 :     r = satisfy_nondeclaration_constraints (t, args, info);
    2874          330 :   if (r == error_mark_node && info.quiet ()
    2875   1092818253 :       && !(DECL_P (t) && warning_suppressed_p (t)))
    2876              :     {
    2877              :       /* Replay the error noisily.  */
    2878          153 :       sat_info noisy (tf_warning_or_error, info.in_decl);
    2879          153 :       constraint_satisfaction_value (t, args, noisy);
    2880          153 :       if (DECL_P (t) && !args)
    2881              :         /* Avoid giving these errors again.  */
    2882            0 :         suppress_warning (t);
    2883              :     }
    2884   1092818100 :   return r;
    2885              : }
    2886              : 
    2887              : /* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
    2888              :    and false otherwise, even in the case of errors.
    2889              : 
    2890              :    Here, T can be:
    2891              :      - a template declaration
    2892              :      - a template specialization (in which case ARGS must be empty)
    2893              :      - a concept-id (in which case ARGS must be empty)
    2894              :      - a nested-requirement
    2895              :      - a placeholder 'auto'
    2896              :      - a requires-expression.  */
    2897              : 
    2898              : bool
    2899   1090980883 : constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
    2900              : {
    2901   1090980883 :   if (!flag_concepts)
    2902              :     return true;
    2903              : 
    2904   1089194816 :   sat_info quiet (tf_none, NULL_TREE);
    2905   1089194816 :   return constraint_satisfaction_value (t, args, quiet) == boolean_true_node;
    2906              : }
    2907              : 
    2908              : /* Evaluate a concept check of the form C<ARGS>.  This is only used for the
    2909              :    evaluation of template-ids as id-expressions.  */
    2910              : 
    2911              : tree
    2912      2771462 : evaluate_concept_check (tree check)
    2913              : {
    2914      2771462 :   if (check == error_mark_node)
    2915              :     return error_mark_node;
    2916              : 
    2917      2771462 :   gcc_assert (concept_check_p (check));
    2918              : 
    2919              :   /* We don't want any declarations instantiated from a concept evaluation
    2920              :      to enter the binding table for the current scope, such as lambdas, so
    2921              :      leave that scope.  But maintain the access context (PR104111).  */
    2922      2771462 :   tree scope = current_scope ();
    2923      2771462 :   if (CLASS_TYPE_P (scope))
    2924       656937 :     scope = TYPE_MAIN_DECL (scope);
    2925      2114525 :   else if (TREE_CODE (scope) != FUNCTION_DECL)
    2926       187569 :     scope = NULL_TREE;
    2927              : 
    2928       656937 :   push_to_top_level ();
    2929      2771462 :   if (scope)
    2930      2583893 :     push_access_scope (scope);
    2931              : 
    2932              :   /* Check for satisfaction without diagnostics.  */
    2933      2771462 :   sat_info quiet (tf_none, NULL_TREE);
    2934      2771462 :   tree r = constraint_satisfaction_value (check, /*args=*/NULL_TREE, quiet);
    2935              : 
    2936      2771462 :   if (scope)
    2937      2583893 :     pop_access_scope (scope);
    2938      2771462 :   pop_from_top_level ();
    2939      2771462 :   return r;
    2940              : }
    2941              : 
    2942              : /* Evaluate the requires-expression T, returning either boolean_true_node
    2943              :    or boolean_false_node.  This is used during folding and constexpr
    2944              :    evaluation.  */
    2945              : 
    2946              : tree
    2947          223 : evaluate_requires_expr (tree t)
    2948              : {
    2949          223 :   gcc_assert (TREE_CODE (t) == REQUIRES_EXPR);
    2950          223 :   sat_info quiet (tf_none, NULL_TREE);
    2951          223 :   return constraint_satisfaction_value (t, /*args=*/NULL_TREE, quiet);
    2952              : }
    2953              : 
    2954              : /*---------------------------------------------------------------------------
    2955              :                 Semantic analysis of requires-expressions
    2956              : ---------------------------------------------------------------------------*/
    2957              : 
    2958              : /* Finish a requires expression for the given PARMS (possibly
    2959              :    null) and the non-empty sequence of requirements.  */
    2960              : 
    2961              : tree
    2962      3103716 : finish_requires_expr (location_t loc, tree parms, tree reqs)
    2963              : {
    2964              :   /* Build the node.  */
    2965      3103716 :   tree r = make_node (REQUIRES_EXPR);
    2966      3103716 :   TREE_TYPE (r) = boolean_type_node;
    2967      3103716 :   REQUIRES_EXPR_PARMS (r) = parms;
    2968      3103716 :   REQUIRES_EXPR_REQS (r) = reqs;
    2969      3103716 :   REQUIRES_EXPR_LOCATION (r) = loc;
    2970      3103716 :   TREE_SIDE_EFFECTS (r) = false;
    2971      3103716 :   TREE_CONSTANT (r) = true;
    2972      3103716 :   return r;
    2973              : }
    2974              : 
    2975              : /* Construct a requirement for the validity of EXPR.   */
    2976              : 
    2977              : tree
    2978      1646168 : finish_simple_requirement (location_t loc, tree expr)
    2979              : {
    2980      1646168 :   tree r = build_nt (SIMPLE_REQ, expr);
    2981      1646168 :   SET_EXPR_LOCATION (r, loc);
    2982      1646168 :   return r;
    2983              : }
    2984              : 
    2985              : /* Construct a requirement for the validity of TYPE.  */
    2986              : 
    2987              : tree
    2988       821969 : finish_type_requirement (location_t loc, tree type)
    2989              : {
    2990       821969 :   tree r = build_nt (TYPE_REQ, type);
    2991       821969 :   SET_EXPR_LOCATION (r, loc);
    2992       821969 :   return r;
    2993              : }
    2994              : 
    2995              : /* Construct a requirement for the validity of EXPR, along with
    2996              :    its properties.  If TYPE is non-null, then it specifies either
    2997              :    an implicit conversion or argument deduction constraint,
    2998              :    depending on whether any placeholders occur in the type name.
    2999              :    NOEX is boolean_true_node iff the noexcept keyword was specified
    3000              :    or expression if noexcept (expr) was specified.  */
    3001              : 
    3002              : tree
    3003      1555128 : finish_compound_requirement (location_t loc, tree expr, tree type,
    3004              :                              tree noex)
    3005              : {
    3006      1555128 :   if (check_for_bare_parameter_packs (noex))
    3007            0 :     noex = error_mark_node;
    3008      1555128 :   tree req = build_nt (COMPOUND_REQ, expr, type, noex);
    3009      1555128 :   SET_EXPR_LOCATION (req, loc);
    3010      1555128 :   return req;
    3011              : }
    3012              : 
    3013              : /* Finish a nested requirement.  */
    3014              : 
    3015              : tree
    3016       265616 : finish_nested_requirement (location_t loc, tree expr)
    3017              : {
    3018              :   /* Build the requirement, saving the set of in-scope template
    3019              :      parameters as its type.  */
    3020       265616 :   tree r = build1 (NESTED_REQ, current_template_parms, expr);
    3021       265616 :   SET_EXPR_LOCATION (r, loc);
    3022       265616 :   return r;
    3023              : }
    3024              : 
    3025              : /*---------------------------------------------------------------------------
    3026              :                         Equivalence of constraints
    3027              : ---------------------------------------------------------------------------*/
    3028              : 
    3029              : /* Returns true when A and B are equivalent constraints.  */
    3030              : bool
    3031     30406920 : equivalent_constraints (tree a, tree b)
    3032              : {
    3033     30406920 :   gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
    3034     30406920 :   gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
    3035     30406920 :   return cp_tree_equal (a, b);
    3036              : }
    3037              : 
    3038              : /* Returns true if the template declarations A and B have equivalent
    3039              :    constraints.  This is the case when A's constraints subsume B's and
    3040              :    when B's also constrain A's.  */
    3041              : bool
    3042          146 : equivalently_constrained (tree d1, tree d2)
    3043              : {
    3044          146 :   gcc_assert (TREE_CODE (d1) == TREE_CODE (d2));
    3045          146 :   return equivalent_constraints (get_constraints (d1), get_constraints (d2));
    3046              : }
    3047              : 
    3048              : /*---------------------------------------------------------------------------
    3049              :                      Partial ordering of constraints
    3050              : ---------------------------------------------------------------------------*/
    3051              : 
    3052              : /* Returns true when the constraints in CI strictly subsume
    3053              :    the associated constraints of TMPL.  */
    3054              : 
    3055              : bool
    3056       704815 : strictly_subsumes (tree ci, tree tmpl)
    3057              : {
    3058       704815 :   tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
    3059       704815 :   tree n2 = get_normalized_constraints_from_decl (tmpl);
    3060              : 
    3061       704815 :   return subsumes (n1, n2) && !subsumes (n2, n1);
    3062              : }
    3063              : 
    3064              : /* Returns true when the template template parameter constraints in CI
    3065              :    subsume the associated constraints of the template template argument
    3066              :    TMPL.  */
    3067              : 
    3068              : bool
    3069           87 : ttp_subsumes (tree ci, tree tmpl)
    3070              : {
    3071           87 :   tree n1 = get_normalized_constraints_from_info (ci, tmpl);
    3072           87 :   tree n2 = get_normalized_constraints_from_decl (tmpl);
    3073              : 
    3074           87 :   return subsumes (n1, n2);
    3075              : }
    3076              : 
    3077              : /* Determines which of the declarations, A or B, is more constrained.
    3078              :    That is, which declaration's constraints subsume but are not subsumed
    3079              :    by the other's?
    3080              : 
    3081              :    Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
    3082              :    than D1, and 0 otherwise.  */
    3083              : 
    3084              : int
    3085      2494893 : more_constrained (tree d1, tree d2)
    3086              : {
    3087      2494893 :   tree n1 = get_normalized_constraints_from_decl (d1);
    3088      2494893 :   tree n2 = get_normalized_constraints_from_decl (d2);
    3089              : 
    3090      2494893 :   int winner = 0;
    3091      2494893 :   if (subsumes (n1, n2))
    3092      2178673 :     ++winner;
    3093      2494893 :   if (subsumes (n2, n1))
    3094      1811200 :     --winner;
    3095      2494893 :   return winner;
    3096              : }
    3097              : 
    3098              : /* Return whether D1 is at least as constrained as D2.  */
    3099              : 
    3100              : bool
    3101      9080361 : at_least_as_constrained (tree d1, tree d2)
    3102              : {
    3103      9080361 :   tree n1 = get_normalized_constraints_from_decl (d1);
    3104      9080361 :   tree n2 = get_normalized_constraints_from_decl (d2);
    3105              : 
    3106      9080361 :   return subsumes (n1, n2);
    3107              : }
    3108              : 
    3109              : /*---------------------------------------------------------------------------
    3110              :                         Constraint diagnostics
    3111              : ---------------------------------------------------------------------------*/
    3112              : 
    3113              : /* Returns the best location to diagnose a constraint error.  */
    3114              : 
    3115              : static location_t
    3116         1286 : get_constraint_error_location (tree t)
    3117              : {
    3118         1286 :   if (location_t loc = cp_expr_location (t))
    3119              :     return loc;
    3120              : 
    3121              :   /* If we have a specific location give it.  */
    3122         1286 :   tree expr = CONSTR_EXPR (t);
    3123         1286 :   if (location_t loc = cp_expr_location (expr))
    3124              :     return loc;
    3125              : 
    3126              :   /* If the constraint is normalized from a requires-clause, give
    3127              :      the location as that of the constrained declaration.  */
    3128           80 :   tree cxt = CONSTR_CONTEXT (t);
    3129           80 :   tree src = cxt ? TREE_VALUE (cxt) : NULL_TREE;
    3130           75 :   if (!src)
    3131              :     /* TODO: This only happens for constrained non-template declarations.  */
    3132              :     ;
    3133           75 :   else if (DECL_P (src))
    3134           60 :     return DECL_SOURCE_LOCATION (src);
    3135              :   /* Otherwise, give the location as the defining concept.  */
    3136           15 :   else if (concept_check_p (src))
    3137              :     {
    3138           15 :       tree tmpl = TREE_OPERAND (src, 0);
    3139           15 :       return DECL_SOURCE_LOCATION (tmpl);
    3140              :     }
    3141              : 
    3142            5 :   return input_location;
    3143              : }
    3144              : 
    3145              : /* Emit a diagnostic for a failed trait.  */
    3146              : 
    3147              : void
    3148          812 : diagnose_trait_expr (location_t loc, tree expr, tree args)
    3149              : {
    3150              :   /* Build a "fake" version of the instantiated trait, so we can
    3151              :      get the instantiated types from result.  */
    3152          812 :   ++processing_template_decl;
    3153          812 :   expr = tsubst_expr (expr, args, tf_none, NULL_TREE);
    3154          812 :   --processing_template_decl;
    3155              : 
    3156          812 :   tree t1 = TRAIT_EXPR_TYPE1 (expr);
    3157          812 :   tree t2 = TRAIT_EXPR_TYPE2 (expr);
    3158          812 :   gcc_checking_assert (t1 != error_mark_node && t2 != error_mark_node);
    3159              : 
    3160          812 :   iloc_sentinel ils (loc);
    3161              : 
    3162              :   /* For traits intrinsically about the properties of user-defined types,
    3163              :      decl_loc will point to the declaration of that type.  */
    3164          812 :   location_t decl_loc = location_of (t1);
    3165          812 :   if (decl_loc == input_location)
    3166          523 :     decl_loc = loc;
    3167              : 
    3168          812 :   switch (TRAIT_EXPR_KIND (expr))
    3169              :     {
    3170            4 :     case CPTK_HAS_NOTHROW_ASSIGN:
    3171            4 :       inform (decl_loc, "%qT is not nothrow copy assignable", t1);
    3172            4 :       break;
    3173            4 :     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
    3174            4 :       inform (decl_loc, "%qT is not nothrow default constructible", t1);
    3175            4 :       break;
    3176            4 :     case CPTK_HAS_NOTHROW_COPY:
    3177            4 :       inform (decl_loc, "%qT is not nothrow copy constructible", t1);
    3178            4 :       break;
    3179            4 :     case CPTK_HAS_TRIVIAL_ASSIGN:
    3180            4 :       inform (decl_loc, "%qT is not trivially copy assignable", t1);
    3181            4 :       break;
    3182            4 :     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
    3183            4 :       inform (decl_loc, "%qT is not trivially default constructible", t1);
    3184            4 :       break;
    3185            4 :     case CPTK_HAS_TRIVIAL_COPY:
    3186            4 :       inform (decl_loc, "%qT is not trivially copy constructible", t1);
    3187            4 :       break;
    3188            4 :     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
    3189            4 :       inform (decl_loc, "%qT is not trivially destructible", t1);
    3190            4 :       break;
    3191           33 :     case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
    3192           33 :       inform (decl_loc, "%qT does not have unique object "
    3193              :               "representations, because", t1);
    3194           33 :       type_has_unique_obj_representations (t1, /*explain=*/true);
    3195           33 :       break;
    3196           19 :     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
    3197           19 :       {
    3198           19 :         location_t dtor_loc = decl_loc;
    3199           19 :         if (NON_UNION_CLASS_TYPE_P (t1))
    3200            6 :           if (tree dtor = CLASSTYPE_DESTRUCTOR (t1))
    3201            3 :             dtor_loc = DECL_SOURCE_LOCATION (dtor);
    3202           19 :         inform (dtor_loc, "%qT does not have a virtual destructor", t1);
    3203              :       }
    3204           19 :       break;
    3205            4 :     case CPTK_IS_ABSTRACT:
    3206            4 :       inform (decl_loc, "%qT is not an abstract class", t1);
    3207            4 :       break;
    3208            3 :     case CPTK_IS_AGGREGATE:
    3209            3 :       inform (decl_loc, "%qT is not an aggregate", t1);
    3210            3 :       break;
    3211            0 :     case CPTK_IS_ARRAY:
    3212            0 :       inform (loc, "%qT is not an array", t1);
    3213            0 :       break;
    3214           15 :     case CPTK_IS_ASSIGNABLE:
    3215           15 :       inform (loc, "%qT is not assignable from %qT, because", t1, t2);
    3216           15 :       is_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3217           15 :       break;
    3218            1 :     case CPTK_IS_BASE_OF:
    3219            1 :       inform (location_of (t2), "%qT is not a base of %qT", t1, t2);
    3220            1 :       break;
    3221            0 :     case CPTK_IS_BOUNDED_ARRAY:
    3222            0 :       inform (loc, "%qT is not a bounded array", t1);
    3223            0 :       break;
    3224          103 :     case CPTK_IS_CLASS:
    3225          103 :       inform (decl_loc, "%qT is not a class", t1);
    3226          103 :       break;
    3227            0 :     case CPTK_IS_CONST:
    3228            0 :       inform (loc, "%qT is not a const type", t1);
    3229            0 :       break;
    3230          141 :     case CPTK_IS_CONSTRUCTIBLE:
    3231          141 :       if (!TREE_VEC_LENGTH (t2))
    3232           76 :         inform (loc, "%qT is not default constructible, because", t1);
    3233              :       else
    3234           65 :         inform (loc, "%qT is not constructible from %qT, because", t1, t2);
    3235          141 :       is_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3236          141 :       break;
    3237           17 :     case CPTK_IS_CONVERTIBLE:
    3238              :       /* The errors produced here all seem to mention "convertible" in the
    3239              :          diagnostic, so an extra inform here appears redundant.  */
    3240           17 :       is_convertible (t1, t2, /*explain=*/true);
    3241           17 :       break;
    3242           12 :     case CPTK_IS_DESTRUCTIBLE:
    3243           12 :       inform (loc, "%qT is not destructible, because", t1);
    3244           12 :       is_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3245           12 :       break;
    3246            4 :     case CPTK_IS_EMPTY:
    3247            4 :       inform (decl_loc, "%qT is not an empty class", t1);
    3248            4 :       break;
    3249            0 :     case CPTK_IS_ENUM:
    3250            0 :       inform (decl_loc, "%qT is not an enum", t1);
    3251            0 :       break;
    3252            4 :     case CPTK_IS_FINAL:
    3253            4 :       inform (decl_loc, "%qT is not a final class", t1);
    3254            4 :       break;
    3255            0 :     case CPTK_IS_FUNCTION:
    3256            0 :       inform (loc, "%qT is not a function", t1);
    3257            0 :       break;
    3258            8 :     case CPTK_IS_IMPLICIT_LIFETIME:
    3259            8 :       inform (decl_loc, "%qT is not an implicit-lifetime type", t1);
    3260            8 :       break;
    3261           20 :     case CPTK_IS_INVOCABLE:
    3262           20 :       {
    3263           20 :         if (!TREE_VEC_LENGTH (t2))
    3264           11 :           inform (loc, "%qT is not invocable, because", t1);
    3265              :         else
    3266            9 :           inform (loc, "%qT is not invocable by %qT, because", t1, t2);
    3267           20 :         build_invoke (t1, t2, tf_error);
    3268              :       }
    3269           20 :       break;
    3270           24 :     case CPTK_IS_LAYOUT_COMPATIBLE:
    3271           24 :       inform (loc, "%qT is not layout compatible with %qT, because", t1, t2);
    3272           24 :       layout_compatible_type_p (t1, t2, /*explain=*/true);
    3273           24 :       break;
    3274            0 :     case CPTK_IS_LITERAL_TYPE:
    3275            0 :       inform (decl_loc, "%qT is not a literal type", t1);
    3276            0 :       break;
    3277            0 :     case CPTK_IS_MEMBER_FUNCTION_POINTER:
    3278            0 :       inform (loc, "%qT is not a member function pointer", t1);
    3279            0 :       break;
    3280            0 :     case CPTK_IS_MEMBER_OBJECT_POINTER:
    3281            0 :       inform (loc, "%qT is not a member object pointer", t1);
    3282            0 :       break;
    3283            0 :     case CPTK_IS_MEMBER_POINTER:
    3284            0 :       inform (loc, "%qT is not a member pointer", t1);
    3285            0 :       break;
    3286            6 :     case CPTK_IS_NOTHROW_ASSIGNABLE:
    3287            6 :       inform (loc, "%qT is not nothrow assignable from %qT, because", t1, t2);
    3288            6 :       is_nothrow_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3289            6 :       break;
    3290           15 :     case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
    3291           15 :       if (!TREE_VEC_LENGTH (t2))
    3292            6 :         inform (loc, "%qT is not nothrow default constructible, because", t1);
    3293              :       else
    3294            9 :         inform (loc, "%qT is not nothrow constructible from %qT, because",
    3295              :                 t1, t2);
    3296           15 :       is_nothrow_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3297           15 :       break;
    3298            6 :     case CPTK_IS_NOTHROW_CONVERTIBLE:
    3299            6 :       inform (loc, "%qT is not nothrow convertible from %qT, because", t1, t2);
    3300            6 :       is_nothrow_convertible (t1, t2, /*explain=*/true);
    3301            6 :       break;
    3302            8 :     case CPTK_IS_NOTHROW_DESTRUCTIBLE:
    3303            8 :       inform (loc, "%qT is not nothrow destructible, because", t1);
    3304            8 :       is_nothrow_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3305            8 :       break;
    3306            9 :     case CPTK_IS_NOTHROW_INVOCABLE:
    3307            9 :       {
    3308            9 :         if (!TREE_VEC_LENGTH (t2))
    3309            6 :           inform (loc, "%qT is not nothrow invocable, because", t1);
    3310              :         else
    3311            3 :           inform (loc, "%qT is not nothrow invocable by %qT, because", t1, t2);
    3312            9 :         tree call = build_invoke (t1, t2, tf_error);
    3313            9 :         if (call != error_mark_node)
    3314            9 :           explain_not_noexcept (call);
    3315              :       }
    3316              :       break;
    3317           48 :     case CPTK_IS_OBJECT:
    3318           48 :       inform (loc, "%qT is not an object type", t1);
    3319           48 :       break;
    3320           15 :     case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
    3321           15 :       inform (location_of (t2),
    3322              :               "%qT is not a pointer-interconvertible base of %qT, because",
    3323              :               t1, t2);
    3324           15 :       pointer_interconvertible_base_of_p (t1, t2, /*explain=*/true);
    3325           15 :       break;
    3326            4 :     case CPTK_IS_POD:
    3327            4 :       inform (loc, "%qT is not a POD type", t1);
    3328            4 :       break;
    3329            0 :     case CPTK_IS_POINTER:
    3330            0 :       inform (loc, "%qT is not a pointer", t1);
    3331            0 :       break;
    3332            4 :     case CPTK_IS_POLYMORPHIC:
    3333            4 :       inform (decl_loc, "%qT is not a polymorphic type", t1);
    3334            4 :       break;
    3335            0 :     case CPTK_IS_REFERENCE:
    3336            0 :       inform (loc, "%qT is not a reference", t1);
    3337            0 :       break;
    3338          188 :     case CPTK_IS_SAME:
    3339          188 :       inform (loc, "%q#T is not the same as %q#T", t1, t2);
    3340          188 :       break;
    3341            0 :     case CPTK_IS_SCOPED_ENUM:
    3342            0 :       inform (decl_loc, "%qT is not a scoped enum", t1);
    3343            0 :       break;
    3344            4 :     case CPTK_IS_STD_LAYOUT:
    3345            4 :       inform (decl_loc, "%qT is not a standard layout type", t1);
    3346            4 :       break;
    3347            4 :     case CPTK_IS_TRIVIAL:
    3348            4 :       inform (decl_loc, "%qT is not a trivial type", t1);
    3349            4 :       break;
    3350            6 :     case CPTK_IS_TRIVIALLY_ASSIGNABLE:
    3351            6 :       inform (loc, "%qT is not trivially assignable from %qT, because", t1, t2);
    3352            6 :       is_trivially_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3353            6 :       break;
    3354           15 :     case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
    3355           15 :       if (!TREE_VEC_LENGTH (t2))
    3356            6 :         inform (loc, "%qT is not trivially default constructible, because", t1);
    3357              :       else
    3358            9 :         inform (loc, "%qT is not trivially constructible from %qT, because",
    3359              :                 t1, t2);
    3360           15 :       is_trivially_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3361           15 :       break;
    3362            7 :     case CPTK_IS_TRIVIALLY_COPYABLE:
    3363            7 :       inform (decl_loc, "%qT is not trivially copyable", t1);
    3364            7 :       break;
    3365            6 :     case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
    3366            6 :       inform (loc, "%qT is not trivially destructible, because", t1);
    3367            6 :       is_trivially_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3368            6 :       break;
    3369            0 :     case CPTK_IS_UNBOUNDED_ARRAY:
    3370            0 :       inform (loc, "%qT is not an unbounded array", t1);
    3371            0 :       break;
    3372            4 :     case CPTK_IS_UNION:
    3373            4 :       inform (decl_loc, "%qT is not a union", t1);
    3374            4 :       break;
    3375            6 :     case CPTK_IS_VIRTUAL_BASE_OF:
    3376            6 :       inform (location_of (t2), "%qT is not a virtual base of %qT", t1, t2);
    3377            6 :       break;
    3378            0 :     case CPTK_IS_VOLATILE:
    3379            0 :       inform (loc, "%qT is not a volatile type", t1);
    3380            0 :       break;
    3381            0 :     case CPTK_IS_STRUCTURAL:
    3382            0 :       inform (decl_loc, "%qT is not a structural type", t1);
    3383            0 :       structural_type_p (t1, /*explain=*/true);
    3384            0 :       break;
    3385            0 :     case CPTK_RANK:
    3386            0 :       inform (loc, "%qT cannot yield a rank", t1);
    3387            0 :       break;
    3388            0 :     case CPTK_TYPE_ORDER:
    3389            0 :       inform (loc, "%qT and %qT cannot be ordered", t1, t2);
    3390            0 :       break;
    3391            0 :     case CPTK_STRUCTURED_BINDING_SIZE:
    3392            0 :       inform (loc, "%qT is not destructurable", t1);
    3393            0 :       break;
    3394            0 :     case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
    3395            0 :       inform (loc, "%qT is not a reference that binds to a temporary "
    3396              :               "object of type %qT (direct-initialization)", t1, t2);
    3397            0 :       break;
    3398            0 :     case CPTK_REF_CONVERTS_FROM_TEMPORARY:
    3399            0 :       inform (loc, "%qT is not a reference that binds to a temporary "
    3400              :               "object of type %qT (copy-initialization)", t1, t2);
    3401            0 :       break;
    3402           21 :     case CPTK_IS_DEDUCIBLE:
    3403           21 :       inform (loc, "%qD is not deducible from %qT", t1, t2);
    3404           21 :       break;
    3405              : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
    3406              :     case CPTK_##CODE:
    3407              : #include "cp-trait.def"
    3408              : #undef DEFTRAIT_TYPE
    3409              :       /* Type-yielding traits aren't expressions.  */
    3410            0 :       gcc_unreachable ();
    3411              :     /* We deliberately omit the default case so that when adding a new
    3412              :        trait we'll get reminded (by way of a warning) to handle it here.  */
    3413              :     }
    3414          812 : }
    3415              : 
    3416              : /* Attempt to detect if this is a standard type trait, defined in terms
    3417              :    of a compiler builtin (above).  If so, this will allow us to provide
    3418              :    more helpful diagnostics.   */
    3419              : 
    3420              : bool
    3421         2222 : maybe_diagnose_standard_trait (location_t loc, tree expr)
    3422              : {
    3423         2222 :   gcc_assert (TREE_CODE (expr) != TRAIT_EXPR);
    3424         2222 :   expr = tree_strip_nop_conversions (expr);
    3425              : 
    3426              :   /* TODO: in some cases it would be possible to provide more helpful
    3427              :      diagnostics for negations of traits, e.g. '!is_same_v<T1, T2>'.  */
    3428              : 
    3429         2222 :   tree args = NULL_TREE;
    3430         2222 :   if (VAR_P (expr) && DECL_LANG_SPECIFIC (expr) && DECL_USE_TEMPLATE (expr))
    3431              :     {
    3432          917 :       tree tinfo = DECL_TEMPLATE_INFO (expr);
    3433          917 :       if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) && TI_PARTIAL_INFO (tinfo))
    3434           12 :         tinfo = TI_PARTIAL_INFO (tinfo);
    3435          905 :       else if (DECL_TEMPLATE_SPECIALIZATION (expr))
    3436              :         /* In an explicit specialisation we no longer know what the original
    3437              :            initializer looked like.  */
    3438              :         tinfo = NULL_TREE;
    3439              : 
    3440          908 :       if (tinfo)
    3441              :         {
    3442          908 :           expr = DECL_INITIAL (DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)));
    3443          908 :           args = TI_ARGS (tinfo);
    3444              :         }
    3445              :     }
    3446              : 
    3447         2222 :   if (expr && TREE_CODE (expr) == TRAIT_EXPR)
    3448              :     {
    3449          439 :       diagnose_trait_expr (loc, expr, args);
    3450          439 :       return true;
    3451              :     }
    3452              : 
    3453              :   return false;
    3454              : }
    3455              : 
    3456              : /* Diagnose a substitution failure in the atomic constraint T using ARGS.  */
    3457              : 
    3458              : static void
    3459         1286 : diagnose_atomic_constraint (tree t, tree args, tree substituted, sat_info info)
    3460              : {
    3461              :   /* If the constraint is already ill-formed, we've previously diagnosed
    3462              :      the reason.  We should still say why the constraints aren't satisfied.  */
    3463         1286 :   if (t == error_mark_node)
    3464              :     {
    3465            0 :       location_t loc;
    3466            0 :       if (info.in_decl)
    3467            0 :         loc = DECL_SOURCE_LOCATION (info.in_decl);
    3468              :       else
    3469            0 :         loc = input_location;
    3470            0 :       inform (loc, "invalid constraints");
    3471            0 :       return;
    3472              :     }
    3473              : 
    3474         1286 :   location_t loc = get_constraint_error_location (t);
    3475         1286 :   iloc_sentinel loc_s (loc);
    3476              : 
    3477              :   /* Generate better diagnostics for certain kinds of expressions.  */
    3478         1286 :   tree expr = ATOMIC_CONSTR_EXPR (t);
    3479         1286 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    3480              : 
    3481         1286 :   if (TREE_CODE (expr) == REQUIRES_EXPR)
    3482              :     {
    3483          309 :       gcc_checking_assert (info.diagnose_unsatisfaction_p ());
    3484              :       /* Clear in_decl before replaying the substitution to avoid emitting
    3485              :          seemingly unhelpful "in declaration ..." notes that follow some
    3486              :          substitution failure error messages.  */
    3487          309 :       info.in_decl = NULL_TREE;
    3488          309 :       tsubst_requires_expr (expr, args, info);
    3489              :     }
    3490          977 :   else if (!same_type_p (TREE_TYPE (substituted), boolean_type_node))
    3491           32 :     error_at (loc, "constraint %qE has type %qT, not %<bool%>",
    3492           32 :               t, TREE_TYPE (substituted));
    3493              :   else
    3494              :     {
    3495          945 :       inform (loc, "the expression %qE evaluated to %<false%>", t);
    3496          945 :       if (TREE_CODE (expr) == TRAIT_EXPR)
    3497          373 :         diagnose_trait_expr (loc, expr, args);
    3498              :       else
    3499          572 :         maybe_diagnose_standard_trait (loc, substituted);
    3500              :     }
    3501         1286 : }
    3502              : 
    3503              : GTY(()) tree current_failed_constraint;
    3504              : 
    3505    475682273 : diagnosing_failed_constraint::
    3506              : diagnosing_failed_constraint (tree t, tree args, bool diag)
    3507    475682273 :   : diagnosing_error (diag)
    3508              : {
    3509    475682273 :   if (diagnosing_error)
    3510              :     {
    3511         3839 :       current_failed_constraint
    3512         3839 :         = tree_cons (args, t, current_failed_constraint);
    3513         3839 :       ++current_constraint_diagnosis_depth;
    3514              :     }
    3515    475682273 : }
    3516              : 
    3517    475679573 : diagnosing_failed_constraint::
    3518              : ~diagnosing_failed_constraint ()
    3519              : {
    3520    475679573 :   if (diagnosing_error)
    3521              :     {
    3522         3839 :       --current_constraint_diagnosis_depth;
    3523         3839 :       if (current_failed_constraint)
    3524         2399 :         current_failed_constraint = TREE_CHAIN (current_failed_constraint);
    3525              :     }
    3526              : 
    3527    475679573 : }
    3528              : 
    3529              : /* Whether we are allowed to replay an error that underlies a constraint failure
    3530              :    at the current diagnosis depth.  */
    3531              : 
    3532              : bool
    3533          414 : diagnosing_failed_constraint::replay_errors_p ()
    3534              : {
    3535          414 :   if (current_constraint_diagnosis_depth >= concepts_diagnostics_max_depth)
    3536              :     {
    3537          353 :       concepts_diagnostics_max_depth_exceeded_p = true;
    3538          353 :       return false;
    3539              :     }
    3540              :   else
    3541              :     return true;
    3542              : }
    3543              : 
    3544              : /* Emit diagnostics detailing the failure ARGS to satisfy the constraints
    3545              :    of T.  Here, T and ARGS are as in constraints_satisfied_p.  */
    3546              : 
    3547              : void
    3548         1382 : diagnose_constraints (location_t loc, tree t, tree args)
    3549              : {
    3550         1382 :   inform (loc, "constraints not satisfied");
    3551              : 
    3552         1382 :   if (concepts_diagnostics_max_depth == 0)
    3553            0 :     return;
    3554              : 
    3555         1382 :   auto_diagnostic_nesting_level sentinel;
    3556              : 
    3557              :   /* Replay satisfaction, but diagnose unsatisfaction.  */
    3558         1382 :   sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
    3559         1382 :   constraint_satisfaction_value (t, args, noisy);
    3560              : 
    3561         1382 :   static bool suggested_p;
    3562         1382 :   if (concepts_diagnostics_max_depth_exceeded_p
    3563          362 :       && current_constraint_diagnosis_depth == 0
    3564          359 :       && !suggested_p)
    3565              :     {
    3566          143 :       inform (UNKNOWN_LOCATION,
    3567              :               "set %qs to at least %d for more detail",
    3568              :               "-fconcepts-diagnostics-depth=",
    3569          143 :               concepts_diagnostics_max_depth + 1);
    3570          143 :       suggested_p = true;
    3571              :     }
    3572         1382 : }
    3573              : 
    3574              : #include "gt-cp-constraint.h"
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.