LCOV - code coverage report
Current view: top level - gcc/cp - constraint.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.4 % 1550 1432
Test Date: 2026-10-03 16:17:38 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    220058903 : processing_constraint_expression_sentinel::
      56              : processing_constraint_expression_sentinel ()
      57              : {
      58    220058903 :   ++scope_chain->x_processing_constraint;
      59    220058903 : }
      60              : 
      61    220058903 : processing_constraint_expression_sentinel::
      62              : ~processing_constraint_expression_sentinel ()
      63              : {
      64    220058903 :   --scope_chain->x_processing_constraint;
      65    220058903 : }
      66              : 
      67              : bool
      68      9543796 : processing_constraint_expression_p ()
      69              : {
      70      9543796 :   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   1192370486 :   subst_info (tsubst_flags_t cmp, tree in)
      82   1192370486 :     : complain (cmp), in_decl (in)
      83              :   { }
      84              : 
      85              :   /* True if we should not diagnose errors.  */
      86   2693606895 :   bool quiet () const
      87              :   {
      88   2693606895 :     return !(complain & tf_warning_or_error);
      89              :   }
      90              : 
      91              :   /* True if we should diagnose errors.  */
      92   1966709583 :   bool noisy () const
      93              :   {
      94   1994754512 :     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   1112392837 :   sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false)
     132   1112392837 :     : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat)
     133              :   {
     134   1112392837 :     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   1121808623 :   diagnose_unsatisfaction_p () const
     142              :   {
     143   1121808623 :     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     32529682 : known_non_bool_p (tree t)
     156              : {
     157     32529682 :   return (t && !WILDCARD_TYPE_P (t) && TREE_CODE (t) != BOOLEAN_TYPE);
     158              : }
     159              : 
     160              : static bool
     161     32529682 : check_constraint_atom (cp_expr expr)
     162              : {
     163     32529682 :   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      9537648 : check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
     175              : {
     176      9537648 :   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      9537654 : finish_constraint_binary_op (location_t loc,
     183              :                              tree_code code,
     184              :                              cp_expr lhs,
     185              :                              cp_expr rhs)
     186              : {
     187      9537654 :   gcc_assert (processing_constraint_expression_p ());
     188      9537654 :   if (lhs == error_mark_node || rhs == error_mark_node)
     189            6 :     return error_mark_node;
     190      9537648 :   if (!check_constraint_operands (loc, lhs, rhs))
     191            0 :     return error_mark_node;
     192      9537648 :   cp_expr expr
     193      9537648 :     = build_min_nt_loc (loc, code, lhs.get_value (), rhs.get_value ());
     194      9537648 :   expr.set_range (lhs.get_start (), rhs.get_finish ());
     195      9537648 :   return expr;
     196              : }
     197              : 
     198              : cp_expr
     199       483601 : finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
     200              : {
     201       483601 :   return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
     202              : }
     203              : 
     204              : cp_expr
     205      9054053 : finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
     206              : {
     207      9054053 :   return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
     208              : }
     209              : 
     210              : cp_expr
     211     13454418 : finish_constraint_primary_expr (cp_expr expr)
     212              : {
     213     13454418 :   if (expr == error_mark_node)
     214           32 :     return error_mark_node;
     215     13454386 :   if (!check_constraint_atom (expr))
     216           10 :     return cp_expr (error_mark_node, expr.get_location ());
     217     13454376 :   return expr;
     218              : }
     219              : 
     220              : /* Combine two constraint-expressions with a logical-and.  */
     221              : 
     222              : tree
     223    202722644 : combine_constraint_expressions (tree lhs, tree rhs)
     224              : {
     225    202722644 :   processing_constraint_expression_sentinel pce;
     226    202722644 :   if (!lhs)
     227              :     return rhs;
     228     27861978 :   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      5678604 :   return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs);
     233    202722644 : }
     234              : 
     235              : /* Extract the TEMPLATE_DECL from a concept check.  */
     236              : 
     237              : tree
     238     24716413 : get_concept_check_template (tree t)
     239              : {
     240     24716413 :   gcc_assert (concept_check_p (t));
     241     24716413 :   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     22143405 : get_concept_definition (tree decl)
     252              : {
     253     22143405 :   gcc_assert (TREE_CODE (decl) == CONCEPT_DECL);
     254     22143405 :   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     25082582 : map_arguments (tree parms, tree args)
     298              : {
     299     68705050 :   for (tree p = parms; p; p = TREE_CHAIN (p))
     300     43622468 :     if (args)
     301              :       {
     302     37289082 :         int level;
     303     37289082 :         int index;
     304     37289082 :         template_parm_level_and_index (TREE_VALUE (p), &level, &index);
     305     37289082 :         TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
     306              :       }
     307              :     else
     308      6333386 :       TREE_PURPOSE (p) = template_parm_to_arg (p);
     309              : 
     310     25082582 :   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     25082582 : build_parameter_mapping (tree expr, tree args, tree ctx_parms)
     318              : {
     319     25082582 :   tree parms = find_template_parameters (expr, ctx_parms);
     320     25082582 :   tree map = map_arguments (parms, args);
     321     25082582 :   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     59170172 : parameter_mapping_equivalent_p (tree t1, tree t2)
     329              : {
     330     59170172 :   tree map1 = ATOMIC_CONSTR_MAP (t1);
     331     59170172 :   tree map2 = ATOMIC_CONSTR_MAP (t2);
     332    123578275 :   while (map1 && map2)
     333              :     {
     334     89658836 :       gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2));
     335     89658836 :       tree arg1 = TREE_PURPOSE (map1);
     336     89658836 :       tree arg2 = TREE_PURPOSE (map2);
     337     89658836 :       if (!template_args_equal (arg1, arg2))
     338              :         return false;
     339     64408103 :       map1 = TREE_CHAIN (map1);
     340     64408103 :       map2 = TREE_CHAIN (map2);
     341              :     }
     342     33919439 :   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      9632179 :   explicit norm_info (bool diag)
     351      9632179 :     : norm_info (NULL_TREE, diag)
     352              :   {}
     353              : 
     354              :   /* Construct a top-level context for DECL.  */
     355              : 
     356     13330237 :   norm_info (tree in_decl, bool diag)
     357              :     : subst_info (tf_warning_or_error|tf_partial, in_decl),
     358     13330237 :       generate_diagnostics (diag)
     359              :   {
     360      3698058 :     if (in_decl)
     361              :       {
     362      2979028 :         initial_parms = DECL_TEMPLATE_PARMS (in_decl);
     363      2979028 :         if (generate_diagnostics)
     364         1375 :           context = build_tree_list (NULL_TREE, in_decl);
     365              :       }
     366              :     else
     367       719030 :       initial_parms = current_template_parms;
     368      3698058 :   }
     369              : 
     370     21794892 :   void update_context (tree expr, tree args)
     371              :   {
     372     21794892 :     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     21794892 :     in_decl = get_concept_check_template (expr);
     378     21794892 :   }
     379              : 
     380              :   /* Returns the template parameters that are in scope for the current
     381              :      normalization context.  */
     382              : 
     383     25082582 :   tree ctx_parms ()
     384              :   {
     385     25082582 :     if (in_decl)
     386     24590599 :       return DECL_TEMPLATE_PARMS (in_decl);
     387              :     else
     388       491983 :       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     24928999 : normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
     416              : {
     417     24928999 :   tree t0 = normalize_expression (TREE_OPERAND (t, 0), args, info);
     418     24928999 :   tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);
     419              : 
     420              :   /* Build a new info object for the constraint.  */
     421     24928999 :   tree ci = (info.generate_diagnostics
     422     24928999 :              ? build_tree_list (t, info.context) : NULL_TREE);
     423              : 
     424     24928999 :   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    224140312 :   static hashval_t hash (norm_entry *e)
     443              :   {
     444    224140312 :     ++comparing_specializations;
     445    224140312 :     hashval_t val = iterative_hash_template_arg (e->tmpl, 0);
     446    224140312 :     val = iterative_hash_template_arg (e->args, val);
     447    224140312 :     --comparing_specializations;
     448    224140312 :     return val;
     449              :   }
     450              : 
     451    248747117 :   static bool equal (norm_entry *e1, norm_entry *e2)
     452              :   {
     453    248747117 :     ++comparing_specializations;
     454    248747117 :     bool eq = e1->tmpl == e2->tmpl
     455    248747117 :       && template_args_equal (e1->args, e2->args);
     456    248747117 :     --comparing_specializations;
     457    248747117 :     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     27071051 : normalize_concept_check (tree check, tree args, norm_info info)
     468              : {
     469     27071051 :   gcc_assert (concept_check_p (check));
     470     27071051 :   tree tmpl = TREE_OPERAND (check, 0);
     471     27071051 :   tree targs = TREE_OPERAND (check, 1);
     472              : 
     473              :   /* Substitute through the arguments of the concept check.  */
     474     27071051 :   if (args)
     475     19690885 :     targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
     476     27071051 :   if (targs == error_mark_node)
     477              :     return error_mark_node;
     478     27071051 :   if (template_args_equal (targs, generic_targs_for (tmpl)))
     479              :     /* Canonicalize generic arguments as NULL_TREE, as an optimization.  */
     480      3550965 :     targs = NULL_TREE;
     481              : 
     482              :   /* Build the substitution for the concept definition.  */
     483     27071051 :   tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
     484     27071051 :   if (targs && args)
     485              :     /* As an optimization, coerce the arguments only if necessary
     486              :        (i.e. if they were substituted).  */
     487     19285611 :     targs = coerce_template_parms (parms, targs, tmpl, tf_none);
     488     27071051 :   if (targs == error_mark_node)
     489              :     return error_mark_node;
     490              : 
     491     27071051 :   if (!norm_cache)
     492        85048 :     norm_cache = hash_table<norm_hasher>::create_ggc (31);
     493     27071051 :   norm_entry *entry = nullptr;
     494     27071051 :   if (!info.generate_diagnostics)
     495              :     {
     496              :       /* Cache the normal form of the substituted concept-id (when not
     497              :          diagnosing).  */
     498     27067584 :       norm_entry elt = {tmpl, targs, NULL_TREE};
     499     27067584 :       norm_entry **slot = norm_cache->find_slot (&elt, INSERT);
     500     27067584 :       if (*slot)
     501      5276159 :         return (*slot)->norm;
     502     21791425 :       entry = ggc_alloc<norm_entry> ();
     503     21791425 :       *entry = elt;
     504     21791425 :       *slot = entry;
     505              :     }
     506              : 
     507     21794892 :   tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
     508     21794892 :   info.update_context (check, args);
     509     21794892 :   tree norm = normalize_expression (def, targs, info);
     510     21794892 :   if (entry)
     511     21791425 :     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    194112430 :   static hashval_t hash (tree t)
     520              :   {
     521    194112430 :     ++comparing_specializations;
     522    194112430 :     hashval_t val = hash_atomic_constraint (t);
     523    194112430 :     --comparing_specializations;
     524    194112430 :     return val;
     525              :   }
     526              : 
     527    175538522 :   static bool equal (tree t1, tree t2)
     528              :   {
     529    175538522 :     ++comparing_specializations;
     530    175538522 :     bool eq = atomic_constraints_identical_p (t1, t2);
     531    175538522 :     --comparing_specializations;
     532    175538522 :     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     52150166 : normalize_atom (tree t, tree args, norm_info info)
     544              : {
     545              :   /* Concept checks are not atomic.  */
     546     52150166 :   if (concept_check_p (t))
     547     27071051 :     return normalize_concept_check (t, args, info);
     548              : 
     549              :   /* Build the parameter mapping for the atom.  */
     550     25079115 :   tree map = build_parameter_mapping (t, args, info.ctx_parms ());
     551              : 
     552              :   /* Build a new info object for the atom.  */
     553     25079115 :   tree ci = build_tree_list (t, info.context);
     554              : 
     555     25079115 :   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     49666379 :   if (info.in_decl && concept_definition_p (info.in_decl))
     563     22332188 :     ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (atom) = true;
     564              : 
     565     25079115 :   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     25074558 :       if (!atom_cache)
     570        95431 :         atom_cache = hash_table<atom_hasher>::create_ggc (31);
     571     25074558 :       tree *slot = atom_cache->find_slot (atom, INSERT);
     572     25074558 :       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     24396752 :       if (map)
     581              :         {
     582     24395992 :           tree targets = make_tree_vec (list_length (map));
     583     24395992 :           int i = 0;
     584     91672283 :           for (tree node = map; node; node = TREE_CHAIN (node))
     585              :             {
     586     42880299 :               tree target = TREE_PURPOSE (node);
     587     42880299 :               TREE_VEC_ELT (targets, i++) = target;
     588              :             }
     589     24395992 :           tree target_parms = find_template_parameters (targets,
     590              :                                                         info.initial_parms);
     591     24395992 :           TREE_TYPE (map) = target_parms;
     592              :         }
     593              : 
     594     24396752 :       *slot = atom;
     595              :     }
     596              :   return atom;
     597              : }
     598              : 
     599              : /* Returns the normal form of an expression.  */
     600              : 
     601              : static tree
     602     77079288 : normalize_expression (tree t, tree args, norm_info info)
     603              : {
     604     77079288 :   if (!t)
     605              :     return NULL_TREE;
     606              : 
     607     77079288 :   if (t == error_mark_node)
     608              :     return error_mark_node;
     609              : 
     610     77079165 :   switch (TREE_CODE (t))
     611              :     {
     612     24043546 :     case TRUTH_ANDIF_EXPR:
     613     24043546 :       return normalize_logical_operation (t, args, CONJ_CONSTR, info);
     614       885453 :     case TRUTH_ORIF_EXPR:
     615       885453 :       return normalize_logical_operation (t, args, DISJ_CONSTR, info);
     616     52150166 :     default:
     617     52150166 :       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      5426398 : get_normalized_constraints (tree t, norm_info info)
     627              : {
     628      5426398 :   auto_timevar time (TV_CONSTRAINT_NORM);
     629      5426398 :   return normalize_expression (t, NULL_TREE, info);
     630      5426398 : }
     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      3349553 : get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
     638              : {
     639      3349553 :   if (ci == NULL_TREE)
     640              :     return NULL_TREE;
     641              : 
     642              :   /* Substitution errors during normalization are fatal.  */
     643      3349545 :   ++processing_template_decl;
     644      3349545 :   norm_info info (in_decl, diag);
     645      6699090 :   tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci), info);
     646      3349545 :   --processing_template_decl;
     647              : 
     648      3349545 :   return t;
     649              : }
     650              : 
     651              : /* Returns the normalized constraints for the declaration D.  */
     652              : 
     653              : static tree
     654    433125165 : get_normalized_constraints_from_decl (tree d, bool diag = false)
     655              : {
     656    433125165 :   tree tmpl;
     657    433125165 :   tree decl;
     658              : 
     659              :   /* For inherited constructors, consider the original declaration;
     660              :      it has the correct template information attached.  */
     661    433125165 :   d = strip_inheriting_ctors (d);
     662              : 
     663    433125165 :   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       498850 :       tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (d));
     669       498850 :       lambda = most_general_lambda (lambda);
     670       498850 :       d = lambda_function (lambda);
     671              :     }
     672              : 
     673    433125165 :   if (TREE_CODE (d) == TEMPLATE_DECL)
     674              :     {
     675    305863566 :       tmpl = d;
     676    305863566 :       decl = DECL_TEMPLATE_RESULT (tmpl);
     677              :     }
     678              :   else
     679              :     {
     680    127261599 :       if (tree ti = DECL_TEMPLATE_INFO (d))
     681     87393274 :         tmpl = TI_TEMPLATE (ti);
     682              :       else
     683              :         tmpl = NULL_TREE;
     684     87393274 :       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    393256840 :   if (tmpl && DECL_LANG_SPECIFIC (tmpl)
     705    480650099 :       && (!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     27792900 :           || (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
     715     13896450 :               < TMPL_ARGS_DEPTH (DECL_TI_ARGS (tmpl)))))
     716    379361759 :     tmpl = most_general_template (tmpl);
     717              : 
     718    433125165 :   d = tmpl ? tmpl : decl;
     719              : 
     720              :   /* If we're not diagnosing errors, use cached constraints, if any.  */
     721    433125165 :   if (!diag)
     722    866092092 :     if (tree *p = hash_map_safe_get (normalized_map, d))
     723    348171849 :       return *p;
     724              : 
     725     84953316 :   tree norm = NULL_TREE;
     726     84953316 :   if (tree ci = get_constraints (d))
     727              :     {
     728      2630428 :       push_access_scope_guard pas (decl);
     729      2630428 :       norm = get_normalized_constraints_from_info (ci, tmpl, diag);
     730      2630428 :     }
     731              : 
     732     84953316 :   if (!diag)
     733     84952263 :     hash_map_safe_put<hm_ggc> (normalized_map, d, norm);
     734              : 
     735     84953316 :   return norm;
     736              : }
     737              : 
     738              : /* Returns the normal form of TMPL's definition.  */
     739              : 
     740              : static tree
     741      2776264 : normalize_concept_definition (tree tmpl, bool diag)
     742              : {
     743      2776264 :   if (!norm_cache)
     744         2543 :     norm_cache = hash_table<norm_hasher>::create_ggc (31);
     745      2776264 :   norm_entry entry = {tmpl, NULL_TREE, NULL_TREE};
     746              : 
     747      2776264 :   if (!diag)
     748      2775942 :     if (norm_entry *found = norm_cache->find (&entry))
     749      2427751 :       return found->norm;
     750              : 
     751       348513 :   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
     752       348513 :   tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
     753       348513 :   ++processing_template_decl;
     754       348513 :   norm_info info (tmpl, diag);
     755       348513 :   tree norm = get_normalized_constraints (def, info);
     756       348513 :   --processing_template_decl;
     757              : 
     758       348513 :   if (!diag)
     759              :     {
     760       348191 :       norm_entry **slot = norm_cache->find_slot (&entry, INSERT);
     761       348191 :       entry.norm = norm;
     762       348191 :       *slot = ggc_alloc<norm_entry> ();
     763       348191 :       **slot = entry;
     764              :     }
     765              : 
     766              :   return norm;
     767              : }
     768              : 
     769              : /* Normalize an EXPR as a constraint.  */
     770              : 
     771              : static tree
     772      9632179 : normalize_constraint_expression (tree expr, norm_info info)
     773              : {
     774      9632179 :   if (!expr || expr == error_mark_node)
     775              :     return expr;
     776              : 
     777      9632179 :   if (!info.generate_diagnostics)
     778     19263953 :     if (tree *p = hash_map_safe_get (normalized_map, expr))
     779      7903839 :       return *p;
     780              : 
     781      1728340 :   ++processing_template_decl;
     782      1728340 :   tree norm = get_normalized_constraints (expr, info);
     783      1728340 :   --processing_template_decl;
     784              : 
     785      1728340 :   if (!info.generate_diagnostics)
     786      1728187 :     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    339826362 : atomic_constraints_identical_p (tree t1, tree t2)
     797              : {
     798    339826362 :   gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR);
     799    339826362 :   gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR);
     800              : 
     801    339826362 :   if (ATOMIC_CONSTR_EXPR (t1) != ATOMIC_CONSTR_EXPR (t2))
     802              :     return false;
     803              : 
     804     59170172 :   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      4158646 : constraints_equivalent_p (tree t1, tree t2)
     815              : {
     816      7811808 :   gcc_assert (CONSTR_P (t1));
     817      7811808 :   gcc_assert (CONSTR_P (t2));
     818              : 
     819      7811808 :   if (TREE_CODE (t1) != TREE_CODE (t2))
     820              :     return false;
     821              : 
     822      7615460 :   switch (TREE_CODE (t1))
     823              :     {
     824      3891248 :     case CONJ_CONSTR:
     825      3891248 :     case DISJ_CONSTR:
     826      3891248 :       if (!constraints_equivalent_p (TREE_OPERAND (t1, 0),
     827      3891248 :                                      TREE_OPERAND (t2, 0)))
     828              :         return false;
     829      3653162 :       if (!constraints_equivalent_p (TREE_OPERAND (t1, 1),
     830      3653162 :                                      TREE_OPERAND (t2, 1)))
     831              :         return false;
     832              :       break;
     833      3724212 :     case ATOMIC_CONSTR:
     834      3724212 :       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   1313581757 : hash_atomic_constraint (tree t)
     847              : {
     848   1313581757 :   gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);
     849              : 
     850              :   /* Hash the identity of the expression.  */
     851   1313581757 :   hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t));
     852              : 
     853              :   /* Hash the targets of the parameter map.  */
     854   1313581757 :   tree p = ATOMIC_CONSTR_MAP (t);
     855   3415734428 :   while (p)
     856              :     {
     857   2102152671 :       val = iterative_hash_template_arg (TREE_PURPOSE (p), val);
     858   2102152671 :       p = TREE_CHAIN (p);
     859              :     }
     860              : 
     861   1313581757 :   return val;
     862              : }
     863              : 
     864              : namespace inchash
     865              : {
     866              : 
     867              : static void
     868     70991985 : add_constraint (tree t, hash& h)
     869              : {
     870    141231876 :   h.add_int (TREE_CODE (t));
     871    141231876 :   switch (TREE_CODE (t))
     872              :     {
     873     70239891 :     case CONJ_CONSTR:
     874     70239891 :     case DISJ_CONSTR:
     875     70239891 :       add_constraint (TREE_OPERAND (t, 0), h);
     876     70239891 :       add_constraint (TREE_OPERAND (t, 1), h);
     877     70239891 :       break;
     878     70991985 :     case ATOMIC_CONSTR:
     879     70991985 :       h.merge_hash (hash_atomic_constraint (t));
     880     70991985 :       break;
     881            0 :     default:
     882            0 :       gcc_unreachable ();
     883              :     }
     884     70991985 : }
     885              : 
     886              : }
     887              : 
     888              : /* Computes a hash code for the constraint T.  */
     889              : 
     890              : hashval_t
     891       752094 : iterative_hash_constraint (tree t, hashval_t val)
     892              : {
     893       752094 :   gcc_assert (CONSTR_P (t));
     894       752094 :   inchash::hash h (val);
     895       752094 :   inchash::add_constraint (t, h);
     896       752094 :   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    109951809 : current_template_constraints (void)
     908              : {
     909    109951809 :   if (!current_template_parms)
     910              :     return NULL_TREE;
     911    109951806 :   tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
     912    109951806 :   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     41246413 : associate_classtype_constraints (tree type)
     921              : {
     922     41246413 :   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     41245643 :   if (!current_template_parms)
     927              :     return type;
     928              : 
     929     30056609 :   if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
     930              :     {
     931     28842998 :       tree decl = TYPE_STUB_DECL (type);
     932     28842998 :       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     28842998 :       if (tree orig_ci = get_constraints (decl))
     939              :         {
     940      1327049 :           if (int extra_levels = (TMPL_PARMS_DEPTH (current_template_parms)
     941      8181279 :                                   - 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      1327049 :           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     27515949 :       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     22736229 : build_constraint_info ()
     973              : {
     974     22736229 :   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    322192660 : build_constraints (tree tr, tree dr)
     987              : {
     988    322192660 :   if (!tr && !dr)
     989              :     return NULL_TREE;
     990              : 
     991     22736229 :   tree_constraint_info* ci = build_constraint_info ();
     992     22736229 :   ci->template_reqs = tr;
     993     22736229 :   ci->declarator_reqs = dr;
     994     22736229 :   ci->associated_constr = combine_constraint_expressions (tr, dr);
     995              : 
     996     22736229 :   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   1072710076 : get_constraints (const_tree t)
    1027              : {
    1028   1072710076 :   if (!flag_concepts)
    1029              :     return NULL_TREE;
    1030   1064617080 :   if (!decl_constraints)
    1031              :     return NULL_TREE;
    1032              : 
    1033   1051013853 :   gcc_assert (DECL_P (t));
    1034   1051013853 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1035    204608059 :     t = DECL_TEMPLATE_RESULT (t);
    1036   1051013853 :   tree* found = decl_constraints->get (const_cast<tree> (t));
    1037   1051013853 :   if (found)
    1038    103424056 :     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    308664392 : set_constraints (tree t, tree ci)
    1050              : {
    1051    308664392 :   if (!ci)
    1052              :     return;
    1053     38468166 :   gcc_assert (t && flag_concepts);
    1054     38468166 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1055        91931 :     t = DECL_TEMPLATE_RESULT (t);
    1056     38468166 :   bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
    1057     38468166 :   gcc_assert (!found);
    1058              : }
    1059              : 
    1060              : /* Remove the associated constraints of the declaration T.  */
    1061              : 
    1062              : void
    1063     16157353 : remove_constraints (tree t)
    1064              : {
    1065     16157353 :   gcc_checking_assert (DECL_P (t));
    1066     16157353 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1067          186 :     t = DECL_TEMPLATE_RESULT (t);
    1068              : 
    1069     16157353 :   if (decl_constraints)
    1070     15518757 :     decl_constraints->remove (t);
    1071     16157353 : }
    1072              : 
    1073              : /* If DECL is a friend, substitute into REQS to produce requirements suitable
    1074              :    for declaration matching.  */
    1075              : 
    1076              : tree
    1077    148090385 : maybe_substitute_reqs_for (tree reqs, const_tree decl)
    1078              : {
    1079    148090385 :   if (reqs == NULL_TREE)
    1080              :     return NULL_TREE;
    1081              : 
    1082     11381220 :   decl = STRIP_TEMPLATE (decl);
    1083     11381220 :   if (DECL_UNIQUE_FRIEND_P (decl) && DECL_TEMPLATE_INFO (decl))
    1084              :     {
    1085       199216 :       tree tmpl = DECL_TI_TEMPLATE (decl);
    1086       199216 :       tree outer_args = outer_template_args (decl);
    1087       199216 :       processing_template_decl_sentinel s;
    1088       199216 :       if (PRIMARY_TEMPLATE_P (tmpl)
    1089       199216 :           || uses_template_parms (outer_args))
    1090       199216 :         ++processing_template_decl;
    1091       199216 :       reqs = tsubst_constraint (reqs, outer_args,
    1092              :                                 tf_warning_or_error, NULL_TREE);
    1093       199216 :     }
    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    340961982 : get_trailing_function_requirements (tree t)
    1102              : {
    1103    340961982 :   tree ci = get_constraints (t);
    1104    340961982 :   if (!ci)
    1105              :     return NULL_TREE;
    1106     66302820 :   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     43952582 : build_concept_check_arguments (tree arg, tree rest)
    1114              : {
    1115     43952582 :   gcc_assert (!rest || TREE_CODE (rest) == TREE_VEC);
    1116     43952582 :   tree args;
    1117     43952582 :   if (arg)
    1118              :     {
    1119     33962695 :       int n = rest ? TREE_VEC_LENGTH (rest) : 0;
    1120     23113305 :       args = make_tree_vec (n + 1);
    1121     23113305 :       TREE_VEC_ELT (args, 0) = arg;
    1122     23113305 :       if (rest)
    1123     23436963 :         for (int i = 0; i < n; ++i)
    1124     12587573 :           TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i);
    1125     10849390 :       int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0;
    1126     23113305 :       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
    1127              :     }
    1128              :   else
    1129              :     args = rest;
    1130     43952582 :   return args;
    1131              : }
    1132              : 
    1133              : /* Construct an expression that checks TMPL using ARGS.  */
    1134              : 
    1135              : tree
    1136     20839277 : build_concept_check (tree tmpl, tree args, tsubst_flags_t complain)
    1137              : {
    1138     20839277 :   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     43952582 : build_concept_check (tree tmpl, tree arg, tree rest, tsubst_flags_t complain)
    1145              : {
    1146     43952582 :   if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl)))
    1147            9 :     warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE);
    1148              : 
    1149     43952582 :   tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
    1150     43952582 :   tree args = build_concept_check_arguments (arg, rest);
    1151     43952582 :   args = coerce_template_parms (parms, args, tmpl, complain);
    1152     43952582 :   if (args == error_mark_node)
    1153              :     return error_mark_node;
    1154     41265697 :   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     17455746 : 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     17455746 : build_concept_id (tree expr)
    1170              : {
    1171     17455746 :   gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR);
    1172     17455746 :   tree id = build_concept_id (TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
    1173     17455746 :   protected_set_expr_location (id, cp_expr_location (expr));
    1174     17455746 :   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     12938703 : build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
    1185              : {
    1186     12938703 :   tree proto = template_parm_to_arg (concept_prototype_parameter (decl));
    1187     12938703 :   ++processing_template_decl;
    1188     12938703 :   tree check = build_concept_check (decl, proto, args, complain);
    1189     12938703 :   --processing_template_decl;
    1190     12938703 :   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      8608733 : build_constrained_parameter (tree cnc, tree proto, tree args)
    1202              : {
    1203      8608733 :   tree name = DECL_NAME (cnc);
    1204      8608733 :   tree type = TREE_TYPE (proto);
    1205      8608733 :   tree decl = build_decl (input_location, TYPE_DECL, name, type);
    1206      8608733 :   CONSTRAINED_PARM_PROTOTYPE (decl) = proto;
    1207      8608733 :   CONSTRAINED_PARM_CONCEPT (decl) = cnc;
    1208      8608733 :   CONSTRAINED_PARM_EXTRA_ARGS (decl) = args;
    1209      8608733 :   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    177740940 : finish_shorthand_constraint (tree decl, tree constr, bool is_non_type)
    1222              : {
    1223              :   /* No requirements means no constraints.  */
    1224    177740940 :   if (!constr)
    1225              :     return NULL_TREE;
    1226              : 
    1227      8608818 :   if (error_operand_p (constr))
    1228              :     return NULL_TREE;
    1229              : 
    1230      8608818 :   tree proto, con, args;
    1231      8608818 :   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      8608709 :       proto = CONSTRAINED_PARM_PROTOTYPE (constr);
    1247      8608709 :       con = CONSTRAINED_PARM_CONCEPT (constr);
    1248      8608709 :       args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
    1249              :     }
    1250              : 
    1251      8608818 :   bool variadic_concept_p = template_parameter_pack_p (proto);
    1252      8608818 :   bool declared_pack_p = template_parameter_pack_p (decl);
    1253      8608818 :   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      8608818 :   tree arg = template_parm_to_arg (decl);
    1258      8608818 :   if (apply_to_each_p && declared_pack_p)
    1259        22823 :     arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0));
    1260              : 
    1261              :   /* Build the concept constraint-expression.  */
    1262      8608818 :   tree tmpl = DECL_TI_TEMPLATE (con);
    1263      8608818 :   tree check;
    1264      8608818 :   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      8608709 :     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      8608818 :   if (apply_to_each_p && declared_pack_p)
    1281        22823 :     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     93970490 : get_shorthand_constraints (tree parms)
    1293              : {
    1294     93970490 :   tree result = NULL_TREE;
    1295     93970490 :   parms = INNERMOST_TEMPLATE_PARMS (parms);
    1296    268181673 :   for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
    1297              :     {
    1298    174211183 :       tree parm = TREE_VEC_ELT (parms, i);
    1299    174211183 :       tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
    1300    174211183 :       result = combine_constraint_expressions (result, constr);
    1301              :     }
    1302     93970490 :   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    626772664 : equivalent_placeholder_constraints (tree c1, tree c2)
    1310              : {
    1311    626772664 :   if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
    1312              :     /* A constrained auto.  */
    1313    626772664 :     c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
    1314    626772664 :   if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
    1315    626772664 :     c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);
    1316              : 
    1317    626772664 :   if (c1 == c2)
    1318              :     return true;
    1319      6117363 :   if (!c1 || !c2)
    1320              :     return false;
    1321      5492676 :   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      5492676 :   gcc_assert (concept_check_p (c1) && concept_check_p (c2));
    1328      5492676 :   tree t1 = TREE_OPERAND (c1, 0);
    1329      5492676 :   tree a1 = TREE_OPERAND (c1, 1);
    1330      5492676 :   tree t2 = TREE_OPERAND (c2, 0);
    1331      5492676 :   tree a2 = TREE_OPERAND (c2, 1);
    1332              : 
    1333      5492676 :   if (t1 != t2)
    1334              :     return false;
    1335              : 
    1336      2968687 :   int len1 = TREE_VEC_LENGTH (a1);
    1337      2968687 :   int len2 = TREE_VEC_LENGTH (a2);
    1338      2968687 :   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      4159384 :   for (int i = 1; i < len1; ++i)
    1344      1775936 :     if (!template_args_equal (TREE_VEC_ELT (a1, i),
    1345      1775936 :                               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    347270329 : iterative_hash_placeholder_constraint (tree c, hashval_t val)
    1354              : {
    1355    347270329 :   gcc_assert (concept_check_p (c));
    1356    347270329 :   tree t = TREE_OPERAND (c, 0);
    1357    347270329 :   tree a = TREE_OPERAND (c, 1);
    1358              : 
    1359              :   /* Like hash_tmpl_and_args, but skip the first argument.  */
    1360    347270329 :   val = iterative_hash_object (DECL_UID (t), val);
    1361              : 
    1362    556383157 :   for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
    1363    209112828 :     val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
    1364              : 
    1365    347270329 :   return val;
    1366              : }
    1367              : 
    1368              : /* Substitute through the expression of a simple requirement or
    1369              :    compound requirement.  */
    1370              : 
    1371              : static tree
    1372     14011187 : tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
    1373              : {
    1374     14011187 :   tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
    1375     14011187 :   tree r = tsubst_expr (t, args, quiet, info.in_decl);
    1376     14008487 :   if (r != error_mark_node
    1377     14008487 :       && (processing_template_decl
    1378     13459935 :           || convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node))
    1379              :     return r;
    1380              : 
    1381       544847 :   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       544652 :   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       544847 :   return error_mark_node;
    1403              : }
    1404              : 
    1405              : 
    1406              : /* Substitute through the simple requirement.  */
    1407              : 
    1408              : static tree
    1409      4860414 : tsubst_simple_requirement (tree t, tree args, sat_info info)
    1410              : {
    1411      4860414 :   tree t0 = TREE_OPERAND (t, 0);
    1412      4860414 :   tree expr = tsubst_valid_expression_requirement (t0, args, info);
    1413      4857714 :   if (expr == error_mark_node)
    1414              :     return error_mark_node;
    1415      4418754 :   if (processing_template_decl)
    1416          397 :     return finish_simple_requirement (EXPR_LOCATION (t), expr);
    1417      4418357 :   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     13517603 : tsubst_type_requirement_1 (tree t, tree args, sat_info info, location_t loc)
    1425              : {
    1426     13517603 :   tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
    1427     13517603 :   tree r = tsubst (t, args, quiet, info.in_decl);
    1428     13517603 :   if (r != error_mark_node)
    1429              :     return r;
    1430              : 
    1431       400450 :   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       400417 :   else if (info.noisy ())
    1443            0 :     tsubst (t, args, info.complain, info.in_decl);
    1444              : 
    1445       400450 :   return error_mark_node;
    1446              : }
    1447              : 
    1448              : 
    1449              : /* Substitute through the type requirement.  */
    1450              : 
    1451              : static tree
    1452      4472849 : tsubst_type_requirement (tree t, tree args, sat_info info)
    1453              : {
    1454      4472849 :   tree t0 = TREE_OPERAND (t, 0);
    1455      4472849 :   tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t));
    1456      4472849 :   if (type == error_mark_node)
    1457              :     return error_mark_node;
    1458      4072399 :   if (processing_template_decl)
    1459            4 :     return finish_type_requirement (EXPR_LOCATION (t), type);
    1460      4072395 :   return boolean_true_node;
    1461              : }
    1462              : 
    1463              : /* True if TYPE can be deduced from EXPR.  */
    1464              : 
    1465              : static bool
    1466      8777500 : 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      8777500 :   expr = force_paren_expr_uneval (expr);
    1472              : 
    1473      8777500 :   tree deduced_type = do_auto_deduction (type, expr, placeholder,
    1474              :                                          info.complain, adc_requirement,
    1475              :                                          /*outer_targs=*/args);
    1476              : 
    1477      8777500 :   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      9150773 : tsubst_compound_requirement (tree t, tree args, sat_info info)
    1507              : {
    1508      9150773 :   tree t0 = TREE_OPERAND (t, 0);
    1509      9150773 :   tree t1 = TREE_OPERAND (t, 1);
    1510      9150773 :   tree noex = TREE_OPERAND (t, 2);
    1511      9150773 :   tree expr = tsubst_valid_expression_requirement (t0, args, info);
    1512      9150773 :   if (expr == error_mark_node)
    1513              :     return error_mark_node;
    1514              : 
    1515      9044886 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    1516              : 
    1517      9044886 :   subst_info quiet (info.complain & ~tf_warning_or_error, info.in_decl);
    1518              : 
    1519              :   /* Check the noexcept condition.  */
    1520      9044886 :   noex = tsubst_expr (noex, args, info.complain, info.in_decl);
    1521      9044886 :   if (!instantiation_dependent_expression_p (noex))
    1522              :     {
    1523      9044886 :       noex = build_converted_constant_bool_expr (noex, info.complain);
    1524      9044886 :       noex = instantiate_non_dependent_expr (noex, info.complain);
    1525      9044886 :       noex = cxx_constant_value (noex, info.complain);
    1526              :     }
    1527      9044886 :   if (noex == error_mark_node)
    1528              :     return error_mark_node;
    1529      9044832 :   if (!processing_template_decl
    1530      9041510 :       && integer_nonzerop (noex)
    1531      9308771 :       && !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      9044754 :   tree type = tsubst_type_requirement_1 (t1, args, info, EXPR_LOCATION (t));
    1541      9044754 :   if (type == error_mark_node)
    1542              :     return error_mark_node;
    1543              : 
    1544              :   /* Check expression against the result type.  */
    1545      9044754 :   if (type && !processing_template_decl)
    1546              :     {
    1547      8777493 :       if (tree placeholder = type_uses_auto (type))
    1548              :         {
    1549      8777488 :           if (!type_deducible_p (expr, type, placeholder, args, quiet))
    1550              :             {
    1551        23257 :               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        23257 :               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      9021492 :   if (processing_template_decl)
    1586         3322 :     return finish_compound_requirement (EXPR_LOCATION (t), expr, type, noex);
    1587      9018170 :   return boolean_true_node;
    1588              : }
    1589              : 
    1590              : /* Substitute through the nested requirement.  */
    1591              : 
    1592              : static tree
    1593       854176 : tsubst_nested_requirement (tree t, tree args, sat_info info)
    1594              : {
    1595       854176 :   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       854176 :   sat_info quiet (info.complain & ~tf_warning_or_error, info.in_decl);
    1605       854176 :   tree result = constraint_satisfaction_value (t, args, quiet);
    1606       854176 :   if (result == boolean_true_node)
    1607              :     return boolean_true_node;
    1608              : 
    1609        32345 :   if (result == boolean_false_node
    1610        32345 :       && 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        32345 :   return error_mark_node;
    1625              : }
    1626              : 
    1627              : /* Substitute ARGS into the requirement T.  */
    1628              : 
    1629              : static tree
    1630     19338212 : tsubst_requirement (tree t, tree args, sat_info info)
    1631              : {
    1632     19338212 :   iloc_sentinel loc_s (cp_expr_location (t));
    1633     19338212 :   switch (TREE_CODE (t))
    1634              :     {
    1635      4860414 :     case SIMPLE_REQ:
    1636      4860414 :       return tsubst_simple_requirement (t, args, info);
    1637      4472849 :     case TYPE_REQ:
    1638      4472849 :       return tsubst_type_requirement (t, args, info);
    1639      9150773 :     case COMPOUND_REQ:
    1640      9150773 :       return tsubst_compound_requirement (t, args, info);
    1641       854176 :     case NESTED_REQ:
    1642       854176 :       return tsubst_nested_requirement (t, args, info);
    1643            0 :     default:
    1644            0 :       break;
    1645              :     }
    1646            0 :   gcc_unreachable ();
    1647     19335512 : }
    1648              : 
    1649              : static tree
    1650      5553988 : declare_constraint_vars (tree parms, tree vars)
    1651              : {
    1652      5553988 :   tree s = vars;
    1653     14301137 :   for (tree t = parms; t; t = DECL_CHAIN (t))
    1654              :     {
    1655      8747149 :       if (DECL_PACK_P (t))
    1656              :         {
    1657         3813 :           tree pack = extract_fnparm_pack (t, &s);
    1658         3813 :           register_local_specialization (pack, t);
    1659              :         }
    1660              :       else
    1661              :         {
    1662      8743336 :           register_local_specialization (s, t);
    1663      8743336 :           s = DECL_CHAIN (s);
    1664              :         }
    1665              :     }
    1666      5553988 :   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      5554030 : check_constraint_variables (tree t, tree args, subst_info info)
    1675              : {
    1676      5554030 :   tree types = NULL_TREE;
    1677      5554030 :   tree p = t;
    1678     14301228 :   while (p && !VOID_TYPE_P (p))
    1679              :     {
    1680      8747198 :       types = tree_cons (NULL_TREE, TREE_TYPE (p), types);
    1681      8747198 :       p = TREE_CHAIN (p);
    1682              :     }
    1683      5554030 :   types = chainon (nreverse (types), void_list_node);
    1684      5554030 :   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      5554030 : tsubst_constraint_variables (tree t, tree args, subst_info info)
    1697              : {
    1698              :   /* Perform a trial substitution to check for type errors.  */
    1699      5554030 :   tree parms = check_constraint_variables (t, args, info);
    1700      5554030 :   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      5553988 :   int saved_unevaluated_operand = cp_unevaluated_operand;
    1706      5553988 :   int saved_unevaluated_typeid_cutoff = cp_unevaluated_typeid_cutoff;
    1707      5553988 :   cp_unevaluated_operand = 0;
    1708      5553988 :   cp_unevaluated_typeid_cutoff = 0;
    1709      5553988 :   tree vars = tsubst (t, args, info.complain, info.in_decl);
    1710      5553988 :   cp_unevaluated_operand = saved_unevaluated_operand;
    1711      5553988 :   cp_unevaluated_typeid_cutoff = saved_unevaluated_typeid_cutoff;
    1712      5553988 :   if (vars == error_mark_node)
    1713              :     return error_mark_node;
    1714      5553988 :   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     12098031 : tsubst_requires_expr (tree t, tree args, sat_info info)
    1736              : {
    1737     12098031 :   local_specialization_stack stack (lss_copy);
    1738              : 
    1739              :   /* We need to check access during the substitution.  */
    1740     12098031 :   deferring_access_check_sentinel acs (dk_no_deferred);
    1741              : 
    1742              :   /* A requires-expression is an unevaluated context.  */
    1743     12098031 :   cp_unevaluated u;
    1744              : 
    1745     12098031 :   args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args,
    1746              :                          info.complain, info.in_decl);
    1747     12098031 :   if (processing_template_decl
    1748     12098031 :       && !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         3178 :       t = copy_node (t);
    1760         3178 :       REQUIRES_EXPR_EXTRA_ARGS (t) = NULL_TREE;
    1761         3178 :       REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain);
    1762         3178 :       return t;
    1763              :     }
    1764              : 
    1765     12094853 :   tree parms = REQUIRES_EXPR_PARMS (t);
    1766     12094853 :   if (parms)
    1767              :     {
    1768      5554030 :       parms = tsubst_constraint_variables (parms, args, info);
    1769      5554030 :       if (parms == error_mark_node)
    1770           42 :         return boolean_false_node;
    1771              :     }
    1772              : 
    1773     12094811 :   tree result = boolean_true_node;
    1774     12094811 :   if (processing_template_decl)
    1775         2964 :     result = NULL_TREE;
    1776     30429644 :   for (tree reqs = REQUIRES_EXPR_REQS (t); reqs; reqs = TREE_CHAIN (reqs))
    1777              :     {
    1778     19338212 :       tree req = TREE_VALUE (reqs);
    1779     19338212 :       req = tsubst_requirement (req, args, info);
    1780     19335512 :       if (req == error_mark_node)
    1781              :         {
    1782      1001036 :           result = boolean_false_node;
    1783      1001036 :           if (info.diagnose_unsatisfaction_p ())
    1784              :             /* Keep going so that we diagnose all failed requirements.  */;
    1785              :           else
    1786              :             break;
    1787              :         }
    1788     18334476 :       else if (processing_template_decl)
    1789         3723 :         result = tree_cons (NULL_TREE, req, result);
    1790              :     }
    1791     12092111 :   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     12095331 : }
    1796              : 
    1797              : /* Public wrapper for the above.  */
    1798              : 
    1799              : tree
    1800     12097456 : tsubst_requires_expr (tree t, tree args,
    1801              :                       tsubst_flags_t complain, tree in_decl)
    1802              : {
    1803     12097456 :   sat_info info (complain, in_decl);
    1804     12097456 :   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       649464 : tsubst_constraint_info (tree t, tree args,
    1812              :                         tsubst_flags_t complain, tree in_decl)
    1813              : {
    1814       649464 :   if (!t || t == error_mark_node || !check_constraint_info (t))
    1815              :     return NULL_TREE;
    1816              : 
    1817       170850 :   tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t), args, complain, in_decl);
    1818       170850 :   tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t), args, complain, in_decl);
    1819        85425 :   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     57602534 : tsubst_parameter_mapping (tree map, tree args, subst_info info)
    1828              : {
    1829     57602534 :   if (!map)
    1830              :     return NULL_TREE;
    1831              : 
    1832     57601711 :   tsubst_flags_t complain = info.complain;
    1833     57601711 :   tree in_decl = info.in_decl;
    1834              : 
    1835     57601711 :   tree result = NULL_TREE;
    1836    156056130 :   for (tree p = map; p; p = TREE_CHAIN (p))
    1837              :     {
    1838     98467717 :       if (p == error_mark_node)
    1839              :         return error_mark_node;
    1840     98467717 :       tree parm = TREE_VALUE (p);
    1841     98467717 :       tree arg = TREE_PURPOSE (p);
    1842     98467717 :       tree new_arg;
    1843     98467717 :       if (ARGUMENT_PACK_P (arg))
    1844      3335971 :         new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
    1845              :       else
    1846              :         {
    1847     95131746 :           new_arg = tsubst_template_arg (arg, args, complain, in_decl);
    1848     95131746 :           if (TYPE_P (new_arg))
    1849     94895111 :             new_arg = canonicalize_type_argument (new_arg, complain);
    1850              :         }
    1851     98467717 :       if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
    1852              :         {
    1853      3316897 :           tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
    1854      6826926 :           for (tree& pack_arg : tree_vec_range (pack_args))
    1855      3510029 :             if (TYPE_P (pack_arg))
    1856      3510029 :               pack_arg = canonicalize_type_argument (pack_arg, complain);
    1857              :         }
    1858     98467717 :       if (new_arg == error_mark_node)
    1859              :         return error_mark_node;
    1860              : 
    1861     98454419 :       result = tree_cons (new_arg, parm, result);
    1862              :     }
    1863     57588413 :   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         6252 : note_failed_type_completion (tree t, tsubst_flags_t complain)
    1901              : {
    1902         6252 :   if (dependent_template_arg_p (t))
    1903              :     return;
    1904              : 
    1905         6215 :   gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))
    1906              :                        || (DECL_P (t) && undeduced_auto_decl (t)));
    1907              : 
    1908         6215 :   if (satisfying_constraint)
    1909          193 :     vec_safe_push (failed_type_completions, t);
    1910              : 
    1911         6215 :   if (TYPE_P (t))
    1912              :     {
    1913         4220 :       if (!CLASS_TYPE_P (t))
    1914              :         return;
    1915         3806 :       t = TYPE_MAIN_DECL (t);
    1916              :     }
    1917         5801 :   if (!(complain & tf_error)
    1918        10965 :       && warning_enabled_at (DECL_SOURCE_LOCATION (t),
    1919         5164 :                              OPT_Wsfinae_incomplete_))
    1920              :     {
    1921         5162 :       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         5162 :       if (!failed_completions_map)
    1931          126 :         failed_completions_map
    1932          126 :           = hash_map<tree, location_t, decl_location_traits>::create_ggc ();
    1933         5162 :       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     54674510 : failed_completion_location (tree t)
    1942              : {
    1943     54674510 :   if (failed_completions_map)
    1944              :     {
    1945       111576 :       if (TYPE_P (t))
    1946        96174 :         t = TYPE_MAIN_DECL (t);
    1947       111576 :       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    533900689 : some_type_complete_p (int begin, int end)
    1959              : {
    1960    533901292 :   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   3524430619 :   static hashval_t hash (sat_entry *e)
    2015              :   {
    2016   3524430619 :     auto cso = make_temp_override (comparing_specializations);
    2017   3524430619 :     ++comparing_specializations;
    2018              : 
    2019   3524430619 :     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   1048477342 :         gcc_assert (!e->args);
    2025   1048477342 :         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   2475953277 :     hashval_t value = htab_hash_pointer (e->atom);
    2033              : 
    2034   2475953277 :     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   2475945804 :       for (tree target_parms = TREE_TYPE (map);
    2039   5520473527 :            target_parms;
    2040   3044527723 :            target_parms = TREE_CHAIN (target_parms))
    2041              :         {
    2042   3044527723 :           int level, index;
    2043   3044527723 :           tree parm = TREE_VALUE (target_parms);
    2044   3044527723 :           template_parm_level_and_index (parm, &level, &index);
    2045   3044527723 :           tree arg = TMPL_ARG (e->args, level, index);
    2046   3044527723 :           value = iterative_hash_template_arg (arg, value);
    2047              :         }
    2048              :     return value;
    2049   3524430619 :   }
    2050              : 
    2051   3794931014 :   static bool equal (sat_entry *e1, sat_entry *e2)
    2052              :   {
    2053   3794931014 :     auto cso = make_temp_override (comparing_specializations);
    2054   3794931014 :     ++comparing_specializations;
    2055              : 
    2056   3794931014 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)
    2057   3794931014 :         != ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom))
    2058              :       return false;
    2059              : 
    2060              :     /* See sat_hasher::hash.  */
    2061   2586076851 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom))
    2062              :       {
    2063    160563628 :         gcc_assert (!e1->args && !e2->args);
    2064    160563628 :         return atomic_constraints_identical_p (e1->atom, e2->atom);
    2065              :       }
    2066              : 
    2067   2425513223 :     if (e1->atom != e2->atom)
    2068              :       return false;
    2069              : 
    2070    425941178 :     if (tree map = ATOMIC_CONSTR_MAP (e1->atom))
    2071    425939616 :       for (tree target_parms = TREE_TYPE (map);
    2072    874104070 :            target_parms;
    2073    448164454 :            target_parms = TREE_CHAIN (target_parms))
    2074              :         {
    2075    455390577 :           int level, index;
    2076    455390577 :           tree parm = TREE_VALUE (target_parms);
    2077    455390577 :           template_parm_level_and_index (parm, &level, &index);
    2078    455390577 :           tree arg1 = TMPL_ARG (e1->args, level, index);
    2079    455390577 :           tree arg2 = TMPL_ARG (e2->args, level, index);
    2080    455390577 :           if (!template_args_equal (arg1, arg2))
    2081      7226123 :             return false;
    2082              :         }
    2083              :     return true;
    2084   3794931014 :   }
    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    533900731 : satisfaction_cache
    2112              : ::satisfaction_cache (tree atom, tree args, sat_info info)
    2113    533900731 :   : entry(nullptr), info(info), ftc_begin(-1)
    2114              : {
    2115    533900731 :   if (!sat_cache)
    2116        76558 :     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    533900731 :   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         7520 :       if (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
    2128              :         {
    2129         3773 :           if (tree found = atom_cache->find (atom))
    2130         3773 :             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    533900731 :   sat_entry elt;
    2140    533900731 :   elt.atom = atom;
    2141    533900731 :   elt.args = args;
    2142    533900731 :   sat_entry **slot = sat_cache->find_slot (&elt, INSERT);
    2143    533900731 :   if (*slot)
    2144    448247768 :     entry = *slot;
    2145     85652963 :   else if (info.quiet ())
    2146              :     {
    2147     85652957 :       entry = ggc_alloc<sat_entry> ();
    2148     85652957 :       entry->atom = atom;
    2149     85652957 :       entry->args = args;
    2150     85652957 :       entry->result = NULL_TREE;
    2151     85652957 :       entry->inst_entry = nullptr;
    2152     85652957 :       entry->location = input_location;
    2153     85652957 :       entry->ftc_begin = entry->ftc_end = -1;
    2154     85652957 :       entry->diagnose_instability = false;
    2155     85652957 :       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     28055367 :         entry->diagnose_instability = true;
    2161     85652957 :       entry->evaluating = false;
    2162     85652957 :       *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    533900731 : satisfaction_cache::get ()
    2183              : {
    2184    533900731 :   if (!entry)
    2185              :     return NULL_TREE;
    2186              : 
    2187    533900725 :   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    533900689 :   bool maybe_unstable = some_type_complete_p (entry->ftc_begin,
    2203              :                                               entry->ftc_end);
    2204              : 
    2205    533900689 :   if (info.noisy () || maybe_unstable || !entry->result)
    2206              :     {
    2207              :       /* We're computing the satisfaction result from scratch.  */
    2208     85660495 :       entry->evaluating = true;
    2209     85660495 :       ftc_begin = vec_safe_length (failed_type_completions);
    2210     85660495 :       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     85655101 : satisfaction_cache::save (tree result)
    2222              : {
    2223     85655101 :   if (!entry)
    2224              :     return result;
    2225              : 
    2226     85655095 :   gcc_checking_assert (entry->evaluating);
    2227     85655095 :   entry->evaluating = false;
    2228              : 
    2229     85655095 :   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     85655053 :   if (info.quiet ())
    2255              :     {
    2256     85647578 :       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     85647578 :       gcc_checking_assert (ftc_begin != -1);
    2260     85647578 :       entry->ftc_begin = ftc_begin;
    2261     85828024 :       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      1697241 : 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      1697241 :   processing_constraint_expression_sentinel s;
    2276      1697241 :   cp_unevaluated u;
    2277      1697241 :   tree expr = tsubst_expr (t, args, complain, in_decl);
    2278      3394482 :   return expr;
    2279      1697241 : }
    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    401265518 : satisfy_conjunction (tree t, tree args, sat_info info)
    2287              : {
    2288    401265518 :   tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
    2289    401265518 :   if (lhs == error_mark_node || lhs == boolean_false_node)
    2290              :     return lhs;
    2291    393122493 :   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     41505329 : satisfy_disjunction (tree t, tree args, sat_info info)
    2341              : {
    2342              :   /* Evaluate each operand with unsatisfaction diagnostics disabled.  */
    2343     41505329 :   sat_info sub = info;
    2344     41505329 :   sub.diagnose_unsatisfaction = false;
    2345              : 
    2346     41505329 :   tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, sub);
    2347     41505329 :   if (lhs == boolean_true_node || lhs == error_mark_node)
    2348              :     return lhs;
    2349              : 
    2350     20513531 :   tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, sub);
    2351     20513531 :   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      3694901 :   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      3694901 :   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     28044871 : satisfaction_value (tree t)
    2390              : {
    2391     28044871 :   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     28059132 : get_mapped_args (tree t, tree args)
    2408              : {
    2409     28059132 :   tree map = ATOMIC_CONSTR_MAP (t);
    2410              : 
    2411              :   /* No map, no arguments.  */
    2412     28059132 :   if (!map)
    2413              :     return NULL_TREE;
    2414              : 
    2415              :   /* Determine the depth of the resulting argument vector.  */
    2416     28058309 :   int depth;
    2417     28058309 :   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     21387270 :     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     28058309 :   auto_vec< vec<tree> > lists (depth);
    2433     28058309 :   lists.quick_grow_cleared (depth);
    2434     99641463 :   for (tree p = map; p; p = TREE_CHAIN (p))
    2435              :     {
    2436     43524845 :       int level;
    2437     43524845 :       int index;
    2438     43524845 :       template_parm_level_and_index (TREE_VALUE (p), &level, &index);
    2439              : 
    2440              :       /* Insert the argument into its corresponding position.  */
    2441     43524845 :       vec<tree> &list = lists[level - 1];
    2442     58177564 :       if (index >= (int)list.length ())
    2443     40095664 :         list.safe_grow_cleared (index + 1, /*exact=*/false);
    2444     43524845 :       list[index] = TREE_PURPOSE (p);
    2445              :     }
    2446              : 
    2447              :   /* Build the new argument list.  */
    2448     28058309 :   args = make_tree_vec (lists.length ());
    2449    142830553 :   for (unsigned i = 0; i != lists.length (); ++i)
    2450              :     {
    2451     29327813 :       vec<tree> &list = lists[i];
    2452     29327813 :       tree level = make_tree_vec (list.length ());
    2453    103217430 :       for (unsigned j = 0; j < list.length (); ++j)
    2454     44561804 :         TREE_VEC_ELT (level, j) = list[j];
    2455     29327813 :       SET_TMPL_ARGS_LEVEL (args, i + 1, level);
    2456     29327813 :       list.release ();
    2457              :     }
    2458     28058309 :   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0);
    2459              : 
    2460     28058309 :   if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)
    2461     28058309 :       && TMPL_ARGS_DEPTH (args) == 1)
    2462              :     {
    2463              :       /* Get rid of the redundant outer TREE_VEC.  */
    2464     26796733 :       tree level = TMPL_ARGS_LEVEL (args, 1);
    2465     26796733 :       ggc_free (args);
    2466     26796733 :       args = level;
    2467              :     }
    2468              : 
    2469     28058309 :   return args;
    2470     28058309 : }
    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    476312648 : 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    476312648 :   diagnosing_failed_constraint failure (t, args, info.noisy ());
    2483              : 
    2484    476312648 :   satisfaction_cache cache (t, args, info);
    2485    476312648 :   if (tree r = cache.get ())
    2486              :     return r;
    2487              : 
    2488              :   /* Perform substitution quietly.  */
    2489     57601369 :   subst_info quiet (tf_none, NULL_TREE);
    2490              : 
    2491              :   /* Instantiate the parameter mapping.  */
    2492     57601369 :   tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet);
    2493     57601369 :   if (map == error_mark_node)
    2494              :     {
    2495              :       /* If instantiation of the parameter mapping fails, the constraint is
    2496              :          not satisfied.  Replay the substitution.  */
    2497        13286 :       if (info.diagnose_unsatisfaction_p ())
    2498            8 :         tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info);
    2499        13286 :       if (info.quiet ())
    2500              :         /* Since instantiation of the parameter mapping failed, we
    2501              :            want to diagnose potential instability of this satisfaction
    2502              :            result.  */
    2503        13278 :         cache.entry->diagnose_instability = true;
    2504        13286 :       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     57588083 :   t = copy_node (t);
    2512     57588083 :   ATOMIC_CONSTR_MAP (t) = map;
    2513     57588083 :   gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t));
    2514     57588083 :   ATOMIC_CONSTR_MAP_INSTANTIATED_P (t) = true;
    2515     57588083 :   satisfaction_cache inst_cache (t, /*args=*/NULL_TREE, info);
    2516     57588083 :   if (cache.entry && inst_cache.entry)
    2517     57588080 :     cache.entry->inst_entry = inst_cache.entry;
    2518     57588083 :   if (tree r = inst_cache.get ())
    2519              :     {
    2520     29528951 :       cache.entry->location = inst_cache.entry->location;
    2521     29528951 :       return cache.save (r);
    2522              :     }
    2523              : 
    2524              :   /* Rebuild the argument vector from the parameter mapping.  */
    2525     28059132 :   args = get_mapped_args (t, args);
    2526              : 
    2527              :   /* Apply the parameter mapping (i.e., just substitute).  */
    2528     28059132 :   tree expr = ATOMIC_CONSTR_EXPR (t);
    2529     28059132 :   tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl);
    2530     28056432 :   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        11503 :       if (info.diagnose_unsatisfaction_p ())
    2535           20 :         tsubst_expr (expr, args, info.complain, info.in_decl);
    2536        11503 :       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     28044929 :   result = force_rvalue (result, info.complain);
    2542     28044929 :   if (result == error_mark_node)
    2543            0 :     return cache.save (inst_cache.save (error_mark_node));
    2544     28044929 :   tree substituted = result;
    2545     28044929 :   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     28044871 :   if (info.noisy ())
    2554              :     {
    2555         3686 :       iloc_sentinel ils (EXPR_LOCATION (result));
    2556         3686 :       if (require_constant_expression (result))
    2557         3670 :         result = cxx_constant_value (result);
    2558              :       else
    2559           16 :         result = error_mark_node;
    2560         3686 :     }
    2561              :   else
    2562              :     {
    2563     28041185 :       result = maybe_constant_value (result, NULL_TREE, mce_true);
    2564     28041185 :       if (!TREE_CONSTANT (result))
    2565           25 :         result = error_mark_node;
    2566              :     }
    2567     28044871 :   result = satisfaction_value (result);
    2568     28044871 :   if (result == boolean_false_node && info.diagnose_unsatisfaction_p ())
    2569         1254 :     diagnose_atomic_constraint (t, args, substituted, info);
    2570              : 
    2571     28044871 :   return cache.save (inst_cache.save (result));
    2572    476309948 : }
    2573              : 
    2574              : /* Determine if the normalized constraint T is satisfied.
    2575              :    Returns boolean_true_node if the expression/constraint is
    2576              :    satisfied, boolean_false_node if not, and error_mark_node
    2577              :    if there was an error evaluating the constraint.
    2578              : 
    2579              :    The parameter mapping of atomic constraints is simply the
    2580              :    set of template arguments that will be substituted into
    2581              :    the expression, regardless of template parameters appearing
    2582              :    within.  Whether a template argument is used in the atomic
    2583              :    constraint only matters for subsumption.  */
    2584              : 
    2585              : static tree
    2586    919083642 : satisfy_constraint_r (tree t, tree args, sat_info info)
    2587              : {
    2588    919083642 :   if (t == error_mark_node)
    2589              :     return error_mark_node;
    2590              : 
    2591    919083495 :   switch (TREE_CODE (t))
    2592              :     {
    2593    401265518 :     case CONJ_CONSTR:
    2594    401265518 :       return satisfy_conjunction (t, args, info);
    2595     41505329 :     case DISJ_CONSTR:
    2596     41505329 :       return satisfy_disjunction (t, args, info);
    2597    476312648 :     case ATOMIC_CONSTR:
    2598    476312648 :       return satisfy_atom (t, args, info);
    2599            0 :     default:
    2600            0 :       gcc_unreachable ();
    2601              :     }
    2602              : }
    2603              : 
    2604              : /* Check that the normalized constraint T is satisfied for ARGS.  */
    2605              : 
    2606              : static tree
    2607     62676749 : satisfy_normalized_constraints (tree t, tree args, sat_info info)
    2608              : {
    2609     62676749 :   auto_timevar time (TV_CONSTRAINT_SAT);
    2610              : 
    2611     62676749 :   auto ovr = make_temp_override (satisfying_constraint, true);
    2612              : 
    2613              :   /* Turn off template processing.  Constraint satisfaction only applies
    2614              :      to non-dependent terms, so we want to ensure full checking here.  */
    2615     62676749 :   processing_template_decl_sentinel proc (true);
    2616              : 
    2617              :   /* We need to check access during satisfaction.  */
    2618     62676749 :   deferring_access_check_sentinel acs (dk_no_deferred);
    2619              : 
    2620              :   /* Constraints are unevaluated operands.  */
    2621     62676749 :   cp_unevaluated u;
    2622              : 
    2623     62676749 :   return satisfy_constraint_r (t, args, info);
    2624     62674049 : }
    2625              : 
    2626              : /* Return the normal form of the constraints on the placeholder 'auto'
    2627              :    type T.  */
    2628              : 
    2629              : static tree
    2630      8777964 : normalize_placeholder_type_constraints (tree t, bool diag)
    2631              : {
    2632      8777964 :   gcc_assert (is_auto (t));
    2633      8777964 :   tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
    2634      8777964 :   if (!ci)
    2635              :     return NULL_TREE;
    2636              : 
    2637      8777964 :   tree constr = TREE_VALUE (ci);
    2638              :   /* The TREE_PURPOSE contains the set of template parameters that were in
    2639              :      scope for this placeholder type; use them as the initial template
    2640              :      parameters for normalization.  */
    2641      8777964 :   tree initial_parms = TREE_PURPOSE (ci);
    2642              : 
    2643              :   /* The 'auto' itself is used as the first argument in its own constraints,
    2644              :      and its level is one greater than its template depth.  So in order to
    2645              :      capture all used template parameters, we need to add an extra level of
    2646              :      template parameters to the context; a dummy level suffices.  */
    2647      8777964 :   initial_parms
    2648     17555662 :     = tree_cons (size_int (initial_parms
    2649              :                            ? TMPL_PARMS_DEPTH (initial_parms) + 1 : 1),
    2650              :                  make_tree_vec (0), initial_parms);
    2651              : 
    2652      8777964 :   norm_info info (diag);
    2653      8777964 :   info.initial_parms = initial_parms;
    2654      8777964 :   return normalize_constraint_expression (constr, info);
    2655              : }
    2656              : 
    2657              : /* Evaluate the constraints of T using ARGS, returning a satisfaction value.
    2658              :    Here, T can be a concept-id, nested-requirement, placeholder 'auto', or
    2659              :    requires-expression.  */
    2660              : 
    2661              : static tree
    2662     12408713 : satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
    2663              : {
    2664     12408713 :   if (t == error_mark_node)
    2665              :     return error_mark_node;
    2666              : 
    2667              :   /* Handle REQUIRES_EXPR directly, bypassing satisfaction.  */
    2668     12408709 :   if (TREE_CODE (t) == REQUIRES_EXPR)
    2669              :     {
    2670          266 :       auto ovr = make_temp_override (current_constraint_diagnosis_depth);
    2671          266 :       if (info.noisy ())
    2672           35 :         ++current_constraint_diagnosis_depth;
    2673          266 :       return tsubst_requires_expr (t, args, info);
    2674          266 :     }
    2675              : 
    2676              :   /* Get the normalized constraints.  */
    2677     12408443 :   tree norm;
    2678     12408443 :   if (concept_check_p (t))
    2679              :     {
    2680      2776264 :       gcc_assert (!args);
    2681      2776264 :       args = TREE_OPERAND (t, 1);
    2682      2776264 :       tree tmpl = get_concept_check_template (t);
    2683      2776264 :       norm = normalize_concept_definition (tmpl, info.noisy ());
    2684              :     }
    2685      9632179 :   else if (TREE_CODE (t) == NESTED_REQ)
    2686              :     {
    2687       854215 :       norm_info ninfo (info.noisy ());
    2688              :       /* The TREE_TYPE contains the set of template parameters that were in
    2689              :          scope for this nested requirement; use them as the initial template
    2690              :          parameters for normalization.  */
    2691       854215 :       ninfo.initial_parms = TREE_TYPE (t);
    2692       854215 :       norm = normalize_constraint_expression (TREE_OPERAND (t, 0), ninfo);
    2693              :     }
    2694      8777964 :   else if (is_auto (t))
    2695              :     {
    2696      8777964 :       norm = normalize_placeholder_type_constraints (t, info.noisy ());
    2697      8777964 :       if (!norm)
    2698            0 :         return boolean_true_node;
    2699              :     }
    2700              :   else
    2701            0 :     gcc_unreachable ();
    2702              : 
    2703              :   /* Perform satisfaction.  */
    2704     12408443 :   return satisfy_normalized_constraints (norm, args, info);
    2705              : }
    2706              : 
    2707              : /* Evaluate the associated constraints of the template specialization T
    2708              :    according to INFO, returning a satisfaction value.  */
    2709              : 
    2710              : static tree
    2711    677699585 : satisfy_declaration_constraints (tree t, sat_info info)
    2712              : {
    2713    677699585 :   gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL);
    2714    677699585 :   const tree saved_t = t;
    2715              : 
    2716              :   /* For inherited constructors, consider the original declaration;
    2717              :      it has the correct template information attached.  */
    2718    677699585 :   t = strip_inheriting_ctors (t);
    2719    677699585 :   tree inh_ctor_targs = NULL_TREE;
    2720    677699585 :   if (t != saved_t)
    2721       328643 :     if (tree ti = DECL_TEMPLATE_INFO (saved_t))
    2722              :       /* The inherited constructor points to an instantiation of a constructor
    2723              :          template; remember its template arguments.  */
    2724        34632 :       inh_ctor_targs = TI_ARGS (ti);
    2725              : 
    2726              :   /* Update the declaration for diagnostics.  */
    2727    677699585 :   info.in_decl = t;
    2728              : 
    2729    677699585 :   if (info.quiet ())
    2730   1355248929 :     if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
    2731    555562916 :       return *result;
    2732              : 
    2733    122136669 :   tree args = NULL_TREE;
    2734    122136669 :   if (tree ti = DECL_TEMPLATE_INFO (t))
    2735              :     {
    2736              :       /* The initial parameter mapping is the complete set of
    2737              :          template arguments substituted into the declaration.  */
    2738     82868919 :       args = TI_ARGS (ti);
    2739     82868919 :       if (inh_ctor_targs)
    2740        14577 :         args = add_outermost_template_args (args, inh_ctor_targs);
    2741              :     }
    2742              : 
    2743    122136669 :   if (regenerated_lambda_fn_p (t))
    2744              :     {
    2745              :       /* The TI_ARGS of a regenerated lambda contains only the innermost
    2746              :          set of template arguments.  Augment this with the outer template
    2747              :          arguments that were used to regenerate the lambda.  */
    2748       464105 :       gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
    2749       329427 :       tree regen_args = lambda_regenerating_args (t);
    2750       329427 :       if (args)
    2751       134678 :         args = add_to_template_args (regen_args, args);
    2752              :       else
    2753              :         args = regen_args;
    2754              :     }
    2755              : 
    2756              :   /* If the innermost arguments are dependent, or if the outer arguments
    2757              :      are dependent and are needed by the constraints, we can't check
    2758              :      satisfaction yet so pretend they're satisfied for now.  */
    2759    122136669 :   if (uses_template_parms (args)
    2760    122136669 :       && ((DECL_TEMPLATE_INFO (t)
    2761       322175 :            && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))
    2762       105232 :            && (TMPL_ARGS_DEPTH (args) == 1
    2763        25271 :                || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args))))
    2764       294873 :           || uses_outer_template_parms_in_constraints (t)))
    2765        27384 :     return boolean_true_node;
    2766              : 
    2767              :   /* Get the normalized constraints.  */
    2768    122109285 :   tree norm = get_normalized_constraints_from_decl (t, info.noisy ());
    2769              : 
    2770    122109285 :   unsigned ftc_count = vec_safe_length (failed_type_completions);
    2771              : 
    2772    122109285 :   tree result = boolean_true_node;
    2773    122109285 :   if (norm)
    2774              :     {
    2775      2969520 :       if (!push_tinst_level (t))
    2776              :         return result;
    2777      2968585 :       push_to_top_level ();
    2778      2968585 :       push_access_scope (t);
    2779      2968585 :       result = satisfy_normalized_constraints (norm, args, info);
    2780      2968585 :       pop_access_scope (t);
    2781      2968585 :       pop_from_top_level ();
    2782      2968585 :       pop_tinst_level ();
    2783              :     }
    2784              : 
    2785              :   /* True if this satisfaction is (heuristically) potentially unstable, i.e.
    2786              :      if its result may depend on where in the program it was performed.  */
    2787    122108350 :   bool maybe_unstable_satisfaction = false;
    2788    122192717 :   if (ftc_count != vec_safe_length (failed_type_completions))
    2789              :     /* Type completion failure occurred during satisfaction.  The satisfaction
    2790              :        result may (or may not) materially depend on the completeness of a type,
    2791              :        so we consider it potentially unstable.   */
    2792              :     maybe_unstable_satisfaction = true;
    2793              : 
    2794    122108350 :   if (maybe_unstable_satisfaction)
    2795              :     /* Don't cache potentially unstable satisfaction, to allow satisfy_atom
    2796              :        to check the stability the next time around.  */;
    2797    122108350 :   else if (info.quiet ())
    2798    122108257 :     hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);
    2799              : 
    2800    122108350 :   return result;
    2801              : }
    2802              : 
    2803              : /* Evaluate the associated constraints of the template T using ARGS as the
    2804              :    innermost set of template arguments and according to INFO, returning a
    2805              :    satisfaction value.  */
    2806              : 
    2807              : static tree
    2808    410187110 : satisfy_declaration_constraints (tree t, tree args, sat_info info)
    2809              : {
    2810    410187110 :   tree orig_args = args;
    2811              : 
    2812              :   /* Update the declaration for diagnostics.  */
    2813    410187110 :   info.in_decl = t;
    2814              : 
    2815    410187110 :   gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);
    2816              : 
    2817    410187110 :   if (regenerated_lambda_fn_p (t))
    2818              :     {
    2819              :       /* As in the two-parameter version of this function.  */
    2820       338908 :       gcc_assert (TMPL_ARGS_DEPTH (args) == 1);
    2821       169454 :       tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
    2822       169454 :       tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
    2823       169454 :       args = add_to_template_args (outer_args, args);
    2824              :     }
    2825              :   else
    2826    410017656 :     args = add_outermost_template_args (t, args);
    2827              : 
    2828              :   /* If the innermost arguments are dependent, or if the outer arguments
    2829              :      are dependent and are needed by the constraints, we can't check
    2830              :      satisfaction yet so pretend they're satisfied for now.  */
    2831    410187110 :   if (uses_template_parms (args)
    2832    533616871 :       && (TMPL_ARGS_DEPTH (args) == 1
    2833      8130239 :           || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args))
    2834       373616 :           || uses_outer_template_parms_in_constraints (t)))
    2835    123056145 :     return boolean_true_node;
    2836              : 
    2837    287130965 :   tree result = boolean_true_node;
    2838    287130965 :   if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
    2839              :     {
    2840     47299721 :       if (!push_tinst_level (t, orig_args))
    2841              :         return result;
    2842     47299721 :       tree pattern = DECL_TEMPLATE_RESULT (t);
    2843     47299721 :       push_to_top_level ();
    2844     47299721 :       push_access_scope (pattern);
    2845     47299721 :       {
    2846              :         /* For reconstruct_lambda_capture_pack.  */
    2847     48392850 :         local_specialization_stack lss (LAMBDA_FUNCTION_P (t)
    2848     94599442 :                                         ? lss_blank : lss_nop);
    2849     47299721 :         result = satisfy_normalized_constraints (norm, args, info);
    2850     47297021 :       }
    2851     47297021 :       pop_access_scope (pattern);
    2852     47297021 :       pop_from_top_level ();
    2853     47297021 :       pop_tinst_level ();
    2854              :     }
    2855              : 
    2856              :   return result;
    2857              : }
    2858              : 
    2859              : /* A wrapper around satisfy_declaration_constraints and
    2860              :    satisfy_nondeclaration_constraints which additionally replays
    2861              :    quiet ill-formed satisfaction noisily, so that ill-formed
    2862              :    satisfaction always gets diagnosed.  */
    2863              : 
    2864              : static tree
    2865   1100295408 : constraint_satisfaction_value (tree t, tree args, sat_info info)
    2866              : {
    2867   1100295408 :   tree r;
    2868   1100295408 :   if (DECL_P (t))
    2869              :     {
    2870   1087886695 :       if (args)
    2871    410187110 :         r = satisfy_declaration_constraints (t, args, info);
    2872              :       else
    2873    677699585 :         r = satisfy_declaration_constraints (t, info);
    2874              :     }
    2875              :   else
    2876     12408713 :     r = satisfy_nondeclaration_constraints (t, args, info);
    2877          336 :   if (r == error_mark_node && info.quiet ()
    2878   1100292864 :       && !(DECL_P (t) && warning_suppressed_p (t)))
    2879              :     {
    2880              :       /* Replay the error noisily.  */
    2881          156 :       sat_info noisy (tf_warning_or_error, info.in_decl);
    2882          156 :       constraint_satisfaction_value (t, args, noisy);
    2883          156 :       if (DECL_P (t) && !args)
    2884              :         /* Avoid giving these errors again.  */
    2885            3 :         suppress_warning (t);
    2886              :     }
    2887   1100292708 :   return r;
    2888              : }
    2889              : 
    2890              : /* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
    2891              :    and false otherwise, even in the case of errors.
    2892              : 
    2893              :    Here, T can be:
    2894              :      - a template declaration
    2895              :      - a template specialization (in which case ARGS must be empty)
    2896              :      - a concept-id (in which case ARGS must be empty)
    2897              :      - a nested-requirement
    2898              :      - a placeholder 'auto'
    2899              :      - a requires-expression.  */
    2900              : 
    2901              : bool
    2902   1098450006 : constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
    2903              : {
    2904   1098450006 :   if (!flag_concepts)
    2905              :     return true;
    2906              : 
    2907   1096663494 :   sat_info quiet (tf_none, NULL_TREE);
    2908   1096663494 :   return constraint_satisfaction_value (t, args, quiet) == boolean_true_node;
    2909              : }
    2910              : 
    2911              : /* Evaluate a concept check of the form C<ARGS>.  This is only used for the
    2912              :    evaluation of template-ids as id-expressions.  */
    2913              : 
    2914              : tree
    2915      2775942 : evaluate_concept_check (tree check)
    2916              : {
    2917      2775942 :   if (check == error_mark_node)
    2918              :     return error_mark_node;
    2919              : 
    2920      2775942 :   gcc_assert (concept_check_p (check));
    2921              : 
    2922              :   /* We don't want any declarations instantiated from a concept evaluation
    2923              :      to enter the binding table for the current scope, such as lambdas, so
    2924              :      leave that scope.  But maintain the access context (PR104111).  */
    2925      2775942 :   tree scope = current_scope ();
    2926      2775942 :   if (CLASS_TYPE_P (scope))
    2927       658066 :     scope = TYPE_MAIN_DECL (scope);
    2928      2117876 :   else if (TREE_CODE (scope) != FUNCTION_DECL)
    2929       187886 :     scope = NULL_TREE;
    2930              : 
    2931       658066 :   push_to_top_level ();
    2932      2775942 :   if (scope)
    2933      2588056 :     push_access_scope (scope);
    2934              : 
    2935              :   /* Check for satisfaction without diagnostics.  */
    2936      2775942 :   sat_info quiet (tf_none, NULL_TREE);
    2937      2775942 :   tree r = constraint_satisfaction_value (check, /*args=*/NULL_TREE, quiet);
    2938              : 
    2939      2775942 :   if (scope)
    2940      2588056 :     pop_access_scope (scope);
    2941      2775942 :   pop_from_top_level ();
    2942      2775942 :   return r;
    2943              : }
    2944              : 
    2945              : /* Evaluate the requires-expression T, returning either boolean_true_node
    2946              :    or boolean_false_node.  This is used during folding and constexpr
    2947              :    evaluation.  */
    2948              : 
    2949              : tree
    2950          231 : evaluate_requires_expr (tree t)
    2951              : {
    2952          231 :   gcc_assert (TREE_CODE (t) == REQUIRES_EXPR);
    2953          231 :   sat_info quiet (tf_none, NULL_TREE);
    2954          231 :   return constraint_satisfaction_value (t, /*args=*/NULL_TREE, quiet);
    2955              : }
    2956              : 
    2957              : /*---------------------------------------------------------------------------
    2958              :                 Semantic analysis of requires-expressions
    2959              : ---------------------------------------------------------------------------*/
    2960              : 
    2961              : /* Finish a requires expression for the given PARMS (possibly
    2962              :    null) and the non-empty sequence of requirements.  */
    2963              : 
    2964              : tree
    2965      3107884 : finish_requires_expr (location_t loc, tree parms, tree reqs)
    2966              : {
    2967              :   /* Build the node.  */
    2968      3107884 :   tree r = make_node (REQUIRES_EXPR);
    2969      3107884 :   TREE_TYPE (r) = boolean_type_node;
    2970      3107884 :   REQUIRES_EXPR_PARMS (r) = parms;
    2971      3107884 :   REQUIRES_EXPR_REQS (r) = reqs;
    2972      3107884 :   REQUIRES_EXPR_LOCATION (r) = loc;
    2973      3107884 :   TREE_SIDE_EFFECTS (r) = false;
    2974      3107884 :   TREE_CONSTANT (r) = true;
    2975      3107884 :   return r;
    2976              : }
    2977              : 
    2978              : /* Construct a requirement for the validity of EXPR.   */
    2979              : 
    2980              : tree
    2981      1648413 : finish_simple_requirement (location_t loc, tree expr)
    2982              : {
    2983      1648413 :   tree r = build_nt (SIMPLE_REQ, expr);
    2984      1648413 :   SET_EXPR_LOCATION (r, loc);
    2985      1648413 :   return r;
    2986              : }
    2987              : 
    2988              : /* Construct a requirement for the validity of TYPE.  */
    2989              : 
    2990              : tree
    2991       822991 : finish_type_requirement (location_t loc, tree type)
    2992              : {
    2993       822991 :   tree r = build_nt (TYPE_REQ, type);
    2994       822991 :   SET_EXPR_LOCATION (r, loc);
    2995       822991 :   return r;
    2996              : }
    2997              : 
    2998              : /* Construct a requirement for the validity of EXPR, along with
    2999              :    its properties.  If TYPE is non-null, then it specifies either
    3000              :    an implicit conversion or argument deduction constraint,
    3001              :    depending on whether any placeholders occur in the type name.
    3002              :    NOEX is boolean_true_node iff the noexcept keyword was specified
    3003              :    or expression if noexcept (expr) was specified.  */
    3004              : 
    3005              : tree
    3006      1557079 : finish_compound_requirement (location_t loc, tree expr, tree type,
    3007              :                              tree noex)
    3008              : {
    3009      1557079 :   if (check_for_bare_parameter_packs (noex))
    3010            0 :     noex = error_mark_node;
    3011      1557079 :   tree req = build_nt (COMPOUND_REQ, expr, type, noex);
    3012      1557079 :   SET_EXPR_LOCATION (req, loc);
    3013      1557079 :   return req;
    3014              : }
    3015              : 
    3016              : /* Finish a nested requirement.  */
    3017              : 
    3018              : tree
    3019       265968 : finish_nested_requirement (location_t loc, tree expr)
    3020              : {
    3021              :   /* Build the requirement, saving the set of in-scope template
    3022              :      parameters as its type.  */
    3023       265968 :   tree r = build1 (NESTED_REQ, current_template_parms, expr);
    3024       265968 :   SET_EXPR_LOCATION (r, loc);
    3025       265968 :   return r;
    3026              : }
    3027              : 
    3028              : /*---------------------------------------------------------------------------
    3029              :                         Equivalence of constraints
    3030              : ---------------------------------------------------------------------------*/
    3031              : 
    3032              : /* Returns true when A and B are equivalent constraints.  */
    3033              : bool
    3034     30562869 : equivalent_constraints (tree a, tree b)
    3035              : {
    3036     30562869 :   gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
    3037     30562869 :   gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
    3038     30562869 :   return cp_tree_equal (a, b);
    3039              : }
    3040              : 
    3041              : /* Returns true if the template declarations A and B have equivalent
    3042              :    constraints.  This is the case when A's constraints subsume B's and
    3043              :    when B's also constrain A's.  */
    3044              : bool
    3045          146 : equivalently_constrained (tree d1, tree d2)
    3046              : {
    3047          146 :   gcc_assert (TREE_CODE (d1) == TREE_CODE (d2));
    3048          146 :   return equivalent_constraints (get_constraints (d1), get_constraints (d2));
    3049              : }
    3050              : 
    3051              : /*---------------------------------------------------------------------------
    3052              :                      Partial ordering of constraints
    3053              : ---------------------------------------------------------------------------*/
    3054              : 
    3055              : /* Returns true when the constraints in CI strictly subsume
    3056              :    the associated constraints of TMPL.  */
    3057              : 
    3058              : bool
    3059       719038 : strictly_subsumes (tree ci, tree tmpl)
    3060              : {
    3061       719038 :   tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
    3062       719038 :   tree n2 = get_normalized_constraints_from_decl (tmpl);
    3063              : 
    3064       719038 :   return subsumes (n1, n2) && !subsumes (n2, n1);
    3065              : }
    3066              : 
    3067              : /* Returns true when the template template parameter constraints in CI
    3068              :    subsume the associated constraints of the template template argument
    3069              :    TMPL.  */
    3070              : 
    3071              : bool
    3072           87 : ttp_subsumes (tree ci, tree tmpl)
    3073              : {
    3074           87 :   tree n1 = get_normalized_constraints_from_info (ci, tmpl);
    3075           87 :   tree n2 = get_normalized_constraints_from_decl (tmpl);
    3076              : 
    3077           87 :   return subsumes (n1, n2);
    3078              : }
    3079              : 
    3080              : /* Determines which of the declarations, A or B, is more constrained.
    3081              :    That is, which declaration's constraints subsume but are not subsumed
    3082              :    by the other's?
    3083              : 
    3084              :    Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
    3085              :    than D1, and 0 otherwise.  */
    3086              : 
    3087              : int
    3088      2499601 : more_constrained (tree d1, tree d2)
    3089              : {
    3090      2499601 :   tree n1 = get_normalized_constraints_from_decl (d1);
    3091      2499601 :   tree n2 = get_normalized_constraints_from_decl (d2);
    3092              : 
    3093      2499601 :   int winner = 0;
    3094      2499601 :   if (subsumes (n1, n2))
    3095      2182514 :     ++winner;
    3096      2499601 :   if (subsumes (n2, n1))
    3097      1814571 :     --winner;
    3098      2499601 :   return winner;
    3099              : }
    3100              : 
    3101              : /* Return whether D1 is at least as constrained as D2.  */
    3102              : 
    3103              : bool
    3104      9083294 : at_least_as_constrained (tree d1, tree d2)
    3105              : {
    3106      9083294 :   tree n1 = get_normalized_constraints_from_decl (d1);
    3107      9083294 :   tree n2 = get_normalized_constraints_from_decl (d2);
    3108              : 
    3109      9083294 :   return subsumes (n1, n2);
    3110              : }
    3111              : 
    3112              : /*---------------------------------------------------------------------------
    3113              :                         Constraint diagnostics
    3114              : ---------------------------------------------------------------------------*/
    3115              : 
    3116              : /* Returns the best location to diagnose a constraint error.  */
    3117              : 
    3118              : static location_t
    3119         1286 : get_constraint_error_location (tree t)
    3120              : {
    3121         1286 :   if (location_t loc = cp_expr_location (t))
    3122              :     return loc;
    3123              : 
    3124              :   /* If we have a specific location give it.  */
    3125         1286 :   tree expr = CONSTR_EXPR (t);
    3126         1286 :   if (location_t loc = cp_expr_location (expr))
    3127              :     return loc;
    3128              : 
    3129              :   /* If the constraint is normalized from a requires-clause, give
    3130              :      the location as that of the constrained declaration.  */
    3131           80 :   tree cxt = CONSTR_CONTEXT (t);
    3132           80 :   tree src = cxt ? TREE_VALUE (cxt) : NULL_TREE;
    3133           75 :   if (!src)
    3134              :     /* TODO: This only happens for constrained non-template declarations.  */
    3135              :     ;
    3136           75 :   else if (DECL_P (src))
    3137           60 :     return DECL_SOURCE_LOCATION (src);
    3138              :   /* Otherwise, give the location as the defining concept.  */
    3139           15 :   else if (concept_check_p (src))
    3140              :     {
    3141           15 :       tree tmpl = TREE_OPERAND (src, 0);
    3142           15 :       return DECL_SOURCE_LOCATION (tmpl);
    3143              :     }
    3144              : 
    3145            5 :   return input_location;
    3146              : }
    3147              : 
    3148              : /* Emit a diagnostic for a failed trait.  */
    3149              : 
    3150              : void
    3151          812 : diagnose_trait_expr (location_t loc, tree expr, tree args)
    3152              : {
    3153              :   /* Build a "fake" version of the instantiated trait, so we can
    3154              :      get the instantiated types from result.  */
    3155          812 :   ++processing_template_decl;
    3156          812 :   expr = tsubst_expr (expr, args, tf_none, NULL_TREE);
    3157          812 :   --processing_template_decl;
    3158              : 
    3159          812 :   tree t1 = TRAIT_EXPR_TYPE1 (expr);
    3160          812 :   tree t2 = TRAIT_EXPR_TYPE2 (expr);
    3161          812 :   gcc_checking_assert (t1 != error_mark_node && t2 != error_mark_node);
    3162              : 
    3163          812 :   iloc_sentinel ils (loc);
    3164              : 
    3165              :   /* For traits intrinsically about the properties of user-defined types,
    3166              :      decl_loc will point to the declaration of that type.  */
    3167          812 :   location_t decl_loc = location_of (t1);
    3168          812 :   if (decl_loc == input_location)
    3169          523 :     decl_loc = loc;
    3170              : 
    3171          812 :   switch (TRAIT_EXPR_KIND (expr))
    3172              :     {
    3173            4 :     case CPTK_HAS_NOTHROW_ASSIGN:
    3174            4 :       inform (decl_loc, "%qT is not nothrow copy assignable", t1);
    3175            4 :       break;
    3176            4 :     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
    3177            4 :       inform (decl_loc, "%qT is not nothrow default constructible", t1);
    3178            4 :       break;
    3179            4 :     case CPTK_HAS_NOTHROW_COPY:
    3180            4 :       inform (decl_loc, "%qT is not nothrow copy constructible", t1);
    3181            4 :       break;
    3182            4 :     case CPTK_HAS_TRIVIAL_ASSIGN:
    3183            4 :       inform (decl_loc, "%qT is not trivially copy assignable", t1);
    3184            4 :       break;
    3185            4 :     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
    3186            4 :       inform (decl_loc, "%qT is not trivially default constructible", t1);
    3187            4 :       break;
    3188            4 :     case CPTK_HAS_TRIVIAL_COPY:
    3189            4 :       inform (decl_loc, "%qT is not trivially copy constructible", t1);
    3190            4 :       break;
    3191            4 :     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
    3192            4 :       inform (decl_loc, "%qT is not trivially destructible", t1);
    3193            4 :       break;
    3194           33 :     case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
    3195           33 :       inform (decl_loc, "%qT does not have unique object "
    3196              :               "representations, because", t1);
    3197           33 :       type_has_unique_obj_representations (t1, /*explain=*/true);
    3198           33 :       break;
    3199           19 :     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
    3200           19 :       {
    3201           19 :         location_t dtor_loc = decl_loc;
    3202           19 :         if (NON_UNION_CLASS_TYPE_P (t1))
    3203            6 :           if (tree dtor = CLASSTYPE_DESTRUCTOR (t1))
    3204            3 :             dtor_loc = DECL_SOURCE_LOCATION (dtor);
    3205           19 :         inform (dtor_loc, "%qT does not have a virtual destructor", t1);
    3206              :       }
    3207           19 :       break;
    3208            4 :     case CPTK_IS_ABSTRACT:
    3209            4 :       inform (decl_loc, "%qT is not an abstract class", t1);
    3210            4 :       break;
    3211            3 :     case CPTK_IS_AGGREGATE:
    3212            3 :       inform (decl_loc, "%qT is not an aggregate", t1);
    3213            3 :       break;
    3214            0 :     case CPTK_IS_ARRAY:
    3215            0 :       inform (loc, "%qT is not an array", t1);
    3216            0 :       break;
    3217           15 :     case CPTK_IS_ASSIGNABLE:
    3218           15 :       inform (loc, "%qT is not assignable from %qT, because", t1, t2);
    3219           15 :       is_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3220           15 :       break;
    3221            1 :     case CPTK_IS_BASE_OF:
    3222            1 :       inform (location_of (t2), "%qT is not a base of %qT", t1, t2);
    3223            1 :       break;
    3224            0 :     case CPTK_IS_BOUNDED_ARRAY:
    3225            0 :       inform (loc, "%qT is not a bounded array", t1);
    3226            0 :       break;
    3227          103 :     case CPTK_IS_CLASS:
    3228          103 :       inform (decl_loc, "%qT is not a class", t1);
    3229          103 :       break;
    3230            0 :     case CPTK_IS_CONST:
    3231            0 :       inform (loc, "%qT is not a const type", t1);
    3232            0 :       break;
    3233          141 :     case CPTK_IS_CONSTRUCTIBLE:
    3234          141 :       if (!TREE_VEC_LENGTH (t2))
    3235           76 :         inform (loc, "%qT is not default constructible, because", t1);
    3236              :       else
    3237           65 :         inform (loc, "%qT is not constructible from %qT, because", t1, t2);
    3238          141 :       is_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3239          141 :       break;
    3240           17 :     case CPTK_IS_CONVERTIBLE:
    3241              :       /* The errors produced here all seem to mention "convertible" in the
    3242              :          diagnostic, so an extra inform here appears redundant.  */
    3243           17 :       is_convertible (t1, t2, /*explain=*/true);
    3244           17 :       break;
    3245           12 :     case CPTK_IS_DESTRUCTIBLE:
    3246           12 :       inform (loc, "%qT is not destructible, because", t1);
    3247           12 :       is_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3248           12 :       break;
    3249            4 :     case CPTK_IS_EMPTY:
    3250            4 :       inform (decl_loc, "%qT is not an empty class", t1);
    3251            4 :       break;
    3252            0 :     case CPTK_IS_ENUM:
    3253            0 :       inform (decl_loc, "%qT is not an enum", t1);
    3254            0 :       break;
    3255            4 :     case CPTK_IS_FINAL:
    3256            4 :       inform (decl_loc, "%qT is not a final class", t1);
    3257            4 :       break;
    3258            0 :     case CPTK_IS_FUNCTION:
    3259            0 :       inform (loc, "%qT is not a function", t1);
    3260            0 :       break;
    3261            8 :     case CPTK_IS_IMPLICIT_LIFETIME:
    3262            8 :       inform (decl_loc, "%qT is not an implicit-lifetime type", t1);
    3263            8 :       break;
    3264           20 :     case CPTK_IS_INVOCABLE:
    3265           20 :       {
    3266           20 :         if (!TREE_VEC_LENGTH (t2))
    3267           11 :           inform (loc, "%qT is not invocable, because", t1);
    3268              :         else
    3269            9 :           inform (loc, "%qT is not invocable by %qT, because", t1, t2);
    3270           20 :         build_invoke (t1, t2, tf_error);
    3271              :       }
    3272           20 :       break;
    3273           24 :     case CPTK_IS_LAYOUT_COMPATIBLE:
    3274           24 :       inform (loc, "%qT is not layout compatible with %qT, because", t1, t2);
    3275           24 :       layout_compatible_type_p (t1, t2, /*explain=*/true);
    3276           24 :       break;
    3277            0 :     case CPTK_IS_LITERAL_TYPE:
    3278            0 :       inform (decl_loc, "%qT is not a literal type", t1);
    3279            0 :       break;
    3280            0 :     case CPTK_IS_MEMBER_FUNCTION_POINTER:
    3281            0 :       inform (loc, "%qT is not a member function pointer", t1);
    3282            0 :       break;
    3283            0 :     case CPTK_IS_MEMBER_OBJECT_POINTER:
    3284            0 :       inform (loc, "%qT is not a member object pointer", t1);
    3285            0 :       break;
    3286            0 :     case CPTK_IS_MEMBER_POINTER:
    3287            0 :       inform (loc, "%qT is not a member pointer", t1);
    3288            0 :       break;
    3289            6 :     case CPTK_IS_NOTHROW_ASSIGNABLE:
    3290            6 :       inform (loc, "%qT is not nothrow assignable from %qT, because", t1, t2);
    3291            6 :       is_nothrow_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3292            6 :       break;
    3293           15 :     case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
    3294           15 :       if (!TREE_VEC_LENGTH (t2))
    3295            6 :         inform (loc, "%qT is not nothrow default constructible, because", t1);
    3296              :       else
    3297            9 :         inform (loc, "%qT is not nothrow constructible from %qT, because",
    3298              :                 t1, t2);
    3299           15 :       is_nothrow_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3300           15 :       break;
    3301            6 :     case CPTK_IS_NOTHROW_CONVERTIBLE:
    3302            6 :       inform (loc, "%qT is not nothrow convertible from %qT, because", t1, t2);
    3303            6 :       is_nothrow_convertible (t1, t2, /*explain=*/true);
    3304            6 :       break;
    3305            8 :     case CPTK_IS_NOTHROW_DESTRUCTIBLE:
    3306            8 :       inform (loc, "%qT is not nothrow destructible, because", t1);
    3307            8 :       is_nothrow_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3308            8 :       break;
    3309            9 :     case CPTK_IS_NOTHROW_INVOCABLE:
    3310            9 :       {
    3311            9 :         if (!TREE_VEC_LENGTH (t2))
    3312            6 :           inform (loc, "%qT is not nothrow invocable, because", t1);
    3313              :         else
    3314            3 :           inform (loc, "%qT is not nothrow invocable by %qT, because", t1, t2);
    3315            9 :         tree call = build_invoke (t1, t2, tf_error);
    3316            9 :         if (call != error_mark_node)
    3317            9 :           explain_not_noexcept (call);
    3318              :       }
    3319              :       break;
    3320           48 :     case CPTK_IS_OBJECT:
    3321           48 :       inform (loc, "%qT is not an object type", t1);
    3322           48 :       break;
    3323           15 :     case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
    3324           15 :       inform (location_of (t2),
    3325              :               "%qT is not a pointer-interconvertible base of %qT, because",
    3326              :               t1, t2);
    3327           15 :       pointer_interconvertible_base_of_p (t1, t2, /*explain=*/true);
    3328           15 :       break;
    3329            4 :     case CPTK_IS_POD:
    3330            4 :       inform (loc, "%qT is not a POD type", t1);
    3331            4 :       break;
    3332            0 :     case CPTK_IS_POINTER:
    3333            0 :       inform (loc, "%qT is not a pointer", t1);
    3334            0 :       break;
    3335            4 :     case CPTK_IS_POLYMORPHIC:
    3336            4 :       inform (decl_loc, "%qT is not a polymorphic type", t1);
    3337            4 :       break;
    3338            0 :     case CPTK_IS_REFERENCE:
    3339            0 :       inform (loc, "%qT is not a reference", t1);
    3340            0 :       break;
    3341          188 :     case CPTK_IS_SAME:
    3342          188 :       inform (loc, "%q#T is not the same as %q#T", t1, t2);
    3343          188 :       break;
    3344            0 :     case CPTK_IS_SCOPED_ENUM:
    3345            0 :       inform (decl_loc, "%qT is not a scoped enum", t1);
    3346            0 :       break;
    3347            4 :     case CPTK_IS_STD_LAYOUT:
    3348            4 :       inform (decl_loc, "%qT is not a standard layout type", t1);
    3349            4 :       break;
    3350            4 :     case CPTK_IS_TRIVIAL:
    3351            4 :       inform (decl_loc, "%qT is not a trivial type", t1);
    3352            4 :       break;
    3353            6 :     case CPTK_IS_TRIVIALLY_ASSIGNABLE:
    3354            6 :       inform (loc, "%qT is not trivially assignable from %qT, because", t1, t2);
    3355            6 :       is_trivially_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3356            6 :       break;
    3357           15 :     case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
    3358           15 :       if (!TREE_VEC_LENGTH (t2))
    3359            6 :         inform (loc, "%qT is not trivially default constructible, because", t1);
    3360              :       else
    3361            9 :         inform (loc, "%qT is not trivially constructible from %qT, because",
    3362              :                 t1, t2);
    3363           15 :       is_trivially_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3364           15 :       break;
    3365            7 :     case CPTK_IS_TRIVIALLY_COPYABLE:
    3366            7 :       inform (decl_loc, "%qT is not trivially copyable", t1);
    3367            7 :       break;
    3368            6 :     case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
    3369            6 :       inform (loc, "%qT is not trivially destructible, because", t1);
    3370            6 :       is_trivially_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3371            6 :       break;
    3372            0 :     case CPTK_IS_UNBOUNDED_ARRAY:
    3373            0 :       inform (loc, "%qT is not an unbounded array", t1);
    3374            0 :       break;
    3375            4 :     case CPTK_IS_UNION:
    3376            4 :       inform (decl_loc, "%qT is not a union", t1);
    3377            4 :       break;
    3378            6 :     case CPTK_IS_VIRTUAL_BASE_OF:
    3379            6 :       inform (location_of (t2), "%qT is not a virtual base of %qT", t1, t2);
    3380            6 :       break;
    3381            0 :     case CPTK_IS_VOLATILE:
    3382            0 :       inform (loc, "%qT is not a volatile type", t1);
    3383            0 :       break;
    3384            0 :     case CPTK_IS_STRUCTURAL:
    3385            0 :       inform (decl_loc, "%qT is not a structural type", t1);
    3386            0 :       structural_type_p (t1, /*explain=*/true);
    3387            0 :       break;
    3388            0 :     case CPTK_RANK:
    3389            0 :       inform (loc, "%qT cannot yield a rank", t1);
    3390            0 :       break;
    3391            0 :     case CPTK_TYPE_ORDER:
    3392            0 :       inform (loc, "%qT and %qT cannot be ordered", t1, t2);
    3393            0 :       break;
    3394            0 :     case CPTK_STRUCTURED_BINDING_SIZE:
    3395            0 :       inform (loc, "%qT is not destructurable", t1);
    3396            0 :       break;
    3397            0 :     case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
    3398            0 :       inform (loc, "%qT is not a reference that binds to a temporary "
    3399              :               "object of type %qT (direct-initialization)", t1, t2);
    3400            0 :       break;
    3401            0 :     case CPTK_REF_CONVERTS_FROM_TEMPORARY:
    3402            0 :       inform (loc, "%qT is not a reference that binds to a temporary "
    3403              :               "object of type %qT (copy-initialization)", t1, t2);
    3404            0 :       break;
    3405           21 :     case CPTK_IS_DEDUCIBLE:
    3406           21 :       inform (loc, "%qD is not deducible from %qT", t1, t2);
    3407           21 :       break;
    3408              : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
    3409              :     case CPTK_##CODE:
    3410              : #include "cp-trait.def"
    3411              : #undef DEFTRAIT_TYPE
    3412              :       /* Type-yielding traits aren't expressions.  */
    3413            0 :       gcc_unreachable ();
    3414              :     /* We deliberately omit the default case so that when adding a new
    3415              :        trait we'll get reminded (by way of a warning) to handle it here.  */
    3416              :     }
    3417          812 : }
    3418              : 
    3419              : /* Attempt to detect if this is a standard type trait, defined in terms
    3420              :    of a compiler builtin (above).  If so, this will allow us to provide
    3421              :    more helpful diagnostics.   */
    3422              : 
    3423              : bool
    3424         2222 : maybe_diagnose_standard_trait (location_t loc, tree expr)
    3425              : {
    3426         2222 :   gcc_assert (TREE_CODE (expr) != TRAIT_EXPR);
    3427         2222 :   expr = tree_strip_nop_conversions (expr);
    3428              : 
    3429              :   /* TODO: in some cases it would be possible to provide more helpful
    3430              :      diagnostics for negations of traits, e.g. '!is_same_v<T1, T2>'.  */
    3431              : 
    3432         2222 :   tree args = NULL_TREE;
    3433         2222 :   if (VAR_P (expr) && DECL_LANG_SPECIFIC (expr) && DECL_USE_TEMPLATE (expr))
    3434              :     {
    3435          917 :       tree tinfo = DECL_TEMPLATE_INFO (expr);
    3436          917 :       if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) && TI_PARTIAL_INFO (tinfo))
    3437           12 :         tinfo = TI_PARTIAL_INFO (tinfo);
    3438          905 :       else if (DECL_TEMPLATE_SPECIALIZATION (expr))
    3439              :         /* In an explicit specialisation we no longer know what the original
    3440              :            initializer looked like.  */
    3441              :         tinfo = NULL_TREE;
    3442              : 
    3443          908 :       if (tinfo)
    3444              :         {
    3445          908 :           expr = DECL_INITIAL (DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)));
    3446          908 :           args = TI_ARGS (tinfo);
    3447              :         }
    3448              :     }
    3449              : 
    3450         2222 :   if (expr && TREE_CODE (expr) == TRAIT_EXPR)
    3451              :     {
    3452          439 :       diagnose_trait_expr (loc, expr, args);
    3453          439 :       return true;
    3454              :     }
    3455              : 
    3456              :   return false;
    3457              : }
    3458              : 
    3459              : /* Diagnose a substitution failure in the atomic constraint T using ARGS.  */
    3460              : 
    3461              : static void
    3462         1286 : diagnose_atomic_constraint (tree t, tree args, tree substituted, sat_info info)
    3463              : {
    3464              :   /* If the constraint is already ill-formed, we've previously diagnosed
    3465              :      the reason.  We should still say why the constraints aren't satisfied.  */
    3466         1286 :   if (t == error_mark_node)
    3467              :     {
    3468            0 :       location_t loc;
    3469            0 :       if (info.in_decl)
    3470            0 :         loc = DECL_SOURCE_LOCATION (info.in_decl);
    3471              :       else
    3472            0 :         loc = input_location;
    3473            0 :       inform (loc, "invalid constraints");
    3474            0 :       return;
    3475              :     }
    3476              : 
    3477         1286 :   location_t loc = get_constraint_error_location (t);
    3478         1286 :   iloc_sentinel loc_s (loc);
    3479              : 
    3480              :   /* Generate better diagnostics for certain kinds of expressions.  */
    3481         1286 :   tree expr = ATOMIC_CONSTR_EXPR (t);
    3482         1286 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    3483              : 
    3484         1286 :   if (TREE_CODE (expr) == REQUIRES_EXPR)
    3485              :     {
    3486          309 :       gcc_checking_assert (info.diagnose_unsatisfaction_p ());
    3487              :       /* Clear in_decl before replaying the substitution to avoid emitting
    3488              :          seemingly unhelpful "in declaration ..." notes that follow some
    3489              :          substitution failure error messages.  */
    3490          309 :       info.in_decl = NULL_TREE;
    3491          309 :       tsubst_requires_expr (expr, args, info);
    3492              :     }
    3493          977 :   else if (!same_type_p (TREE_TYPE (substituted), boolean_type_node))
    3494           32 :     error_at (loc, "constraint %qE has type %qT, not %<bool%>",
    3495           32 :               t, TREE_TYPE (substituted));
    3496              :   else
    3497              :     {
    3498          945 :       inform (loc, "the expression %qE evaluated to %<false%>", t);
    3499          945 :       if (TREE_CODE (expr) == TRAIT_EXPR)
    3500          373 :         diagnose_trait_expr (loc, expr, args);
    3501              :       else
    3502          572 :         maybe_diagnose_standard_trait (loc, substituted);
    3503              :     }
    3504         1286 : }
    3505              : 
    3506              : GTY(()) tree current_failed_constraint;
    3507              : 
    3508    476312717 : diagnosing_failed_constraint::
    3509              : diagnosing_failed_constraint (tree t, tree args, bool diag)
    3510    476312717 :   : diagnosing_error (diag)
    3511              : {
    3512    476312717 :   if (diagnosing_error)
    3513              :     {
    3514         3842 :       current_failed_constraint
    3515         3842 :         = tree_cons (args, t, current_failed_constraint);
    3516         3842 :       ++current_constraint_diagnosis_depth;
    3517              :     }
    3518    476312717 : }
    3519              : 
    3520    476310017 : diagnosing_failed_constraint::
    3521              : ~diagnosing_failed_constraint ()
    3522              : {
    3523    476310017 :   if (diagnosing_error)
    3524              :     {
    3525         3842 :       --current_constraint_diagnosis_depth;
    3526         3842 :       if (current_failed_constraint)
    3527         2399 :         current_failed_constraint = TREE_CHAIN (current_failed_constraint);
    3528              :     }
    3529              : 
    3530    476310017 : }
    3531              : 
    3532              : /* Whether we are allowed to replay an error that underlies a constraint failure
    3533              :    at the current diagnosis depth.  */
    3534              : 
    3535              : bool
    3536          414 : diagnosing_failed_constraint::replay_errors_p ()
    3537              : {
    3538          414 :   if (current_constraint_diagnosis_depth >= concepts_diagnostics_max_depth)
    3539              :     {
    3540          353 :       concepts_diagnostics_max_depth_exceeded_p = true;
    3541          353 :       return false;
    3542              :     }
    3543              :   else
    3544              :     return true;
    3545              : }
    3546              : 
    3547              : /* Emit diagnostics detailing the failure ARGS to satisfy the constraints
    3548              :    of T.  Here, T and ARGS are as in constraints_satisfied_p.  */
    3549              : 
    3550              : void
    3551         1382 : diagnose_constraints (location_t loc, tree t, tree args)
    3552              : {
    3553         1382 :   inform (loc, "constraints not satisfied");
    3554              : 
    3555         1382 :   if (concepts_diagnostics_max_depth == 0)
    3556            0 :     return;
    3557              : 
    3558         1382 :   auto_diagnostic_nesting_level sentinel;
    3559              : 
    3560              :   /* Replay satisfaction, but diagnose unsatisfaction.  */
    3561         1382 :   sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
    3562         1382 :   constraint_satisfaction_value (t, args, noisy);
    3563              : 
    3564         1382 :   static bool suggested_p;
    3565         1382 :   if (concepts_diagnostics_max_depth_exceeded_p
    3566          362 :       && current_constraint_diagnosis_depth == 0
    3567          359 :       && !suggested_p)
    3568              :     {
    3569          143 :       inform (UNKNOWN_LOCATION,
    3570              :               "set %qs to at least %d for more detail",
    3571              :               "-fconcepts-diagnostics-depth=",
    3572          143 :               concepts_diagnostics_max_depth + 1);
    3573          143 :       suggested_p = true;
    3574              :     }
    3575         1382 : }
    3576              : 
    3577              : #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.