LCOV - code coverage report
Current view: top level - gcc/cp - constraint.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.1 % 1537 1415
Test Date: 2026-03-28 14:25:54 Functions: 98.4 % 122 120
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    201641918 : processing_constraint_expression_sentinel::
      56              : processing_constraint_expression_sentinel ()
      57              : {
      58    201641918 :   ++scope_chain->x_processing_constraint;
      59    201641918 : }
      60              : 
      61    201641918 : processing_constraint_expression_sentinel::
      62              : ~processing_constraint_expression_sentinel ()
      63              : {
      64    201641918 :   --scope_chain->x_processing_constraint;
      65    201641918 : }
      66              : 
      67              : bool
      68      8522167 : processing_constraint_expression_p ()
      69              : {
      70      8522167 :   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   1457298550 :   subst_info (tsubst_flags_t cmp, tree in)
      82   1457298550 :     : complain (cmp), in_decl (in)
      83              :   { }
      84              : 
      85              :   /* True if we should not diagnose errors.  */
      86   4042518352 :   bool quiet () const
      87              :   {
      88   4042518352 :     return !(complain & tf_warning_or_error);
      89              :   }
      90              : 
      91              :   /* True if we should diagnose errors.  */
      92   3087355679 :   bool noisy () const
      93              :   {
      94   3120429963 :     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   1355044448 :   sat_info (tsubst_flags_t cmp, tree in, bool diag_unsat = false)
     132   1355044448 :     : subst_info (cmp, in), diagnose_unsatisfaction (diag_unsat)
     133              :   {
     134   1355044448 :     if (diagnose_unsatisfaction_p ())
     135            0 :       gcc_checking_assert (noisy ());
     136     15513060 :   }
     137              : 
     138              :   /* True if we should diagnose the cause of satisfaction failure.
     139              :      Implies noisy().  */
     140              :   bool
     141   1365900109 :   diagnose_unsatisfaction_p () const
     142              :   {
     143     15513060 :     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     28872677 : known_non_bool_p (tree t)
     156              : {
     157     28872677 :   return (t && !WILDCARD_TYPE_P (t) && TREE_CODE (t) != BOOLEAN_TYPE);
     158              : }
     159              : 
     160              : static bool
     161     28872677 : check_constraint_atom (cp_expr expr)
     162              : {
     163     28872677 :   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      8518572 : check_constraint_operands (location_t, cp_expr lhs, cp_expr rhs)
     175              : {
     176      8518572 :   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      8518578 : finish_constraint_binary_op (location_t loc,
     183              :                              tree_code code,
     184              :                              cp_expr lhs,
     185              :                              cp_expr rhs)
     186              : {
     187      8518578 :   gcc_assert (processing_constraint_expression_p ());
     188      8518578 :   if (lhs == error_mark_node || rhs == error_mark_node)
     189            6 :     return error_mark_node;
     190      8518572 :   if (!check_constraint_operands (loc, lhs, rhs))
     191            0 :     return error_mark_node;
     192      8518572 :   cp_expr expr
     193      8518572 :     = build_min_nt_loc (loc, code, lhs.get_value (), rhs.get_value ());
     194      8518572 :   expr.set_range (lhs.get_start (), rhs.get_finish ());
     195      8518572 :   return expr;
     196              : }
     197              : 
     198              : cp_expr
     199       430747 : finish_constraint_or_expr (location_t loc, cp_expr lhs, cp_expr rhs)
     200              : {
     201       430747 :   return finish_constraint_binary_op (loc, TRUTH_ORIF_EXPR, lhs, rhs);
     202              : }
     203              : 
     204              : cp_expr
     205      8087831 : finish_constraint_and_expr (location_t loc, cp_expr lhs, cp_expr rhs)
     206              : {
     207      8087831 :   return finish_constraint_binary_op (loc, TRUTH_ANDIF_EXPR, lhs, rhs);
     208              : }
     209              : 
     210              : cp_expr
     211     11835564 : finish_constraint_primary_expr (cp_expr expr)
     212              : {
     213     11835564 :   if (expr == error_mark_node)
     214           31 :     return error_mark_node;
     215     11835533 :   if (!check_constraint_atom (expr))
     216           10 :     return cp_expr (error_mark_node, expr.get_location ());
     217     11835523 :   return expr;
     218              : }
     219              : 
     220              : /* Combine two constraint-expressions with a logical-and.  */
     221              : 
     222              : tree
     223    185923683 : combine_constraint_expressions (tree lhs, tree rhs)
     224              : {
     225    185923683 :   processing_constraint_expression_sentinel pce;
     226    185923683 :   if (!lhs)
     227              :     return rhs;
     228     25199760 :   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      5179299 :   return finish_constraint_and_expr (UNKNOWN_LOCATION, lhs, rhs);
     233    185923683 : }
     234              : 
     235              : /* Extract the TEMPLATE_DECL from a concept check.  */
     236              : 
     237              : tree
     238     23007560 : get_concept_check_template (tree t)
     239              : {
     240     23007560 :   gcc_assert (concept_check_p (t));
     241     23007560 :   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     19525412 : get_concept_definition (tree decl)
     252              : {
     253     19525412 :   gcc_assert (TREE_CODE (decl) == CONCEPT_DECL);
     254     19525412 :   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     22085303 : map_arguments (tree parms, tree args)
     298              : {
     299     60617837 :   for (tree p = parms; p; p = TREE_CHAIN (p))
     300     38532534 :     if (args)
     301              :       {
     302     32760914 :         int level;
     303     32760914 :         int index;
     304     32760914 :         template_parm_level_and_index (TREE_VALUE (p), &level, &index);
     305     32760914 :         TREE_PURPOSE (p) = TMPL_ARG (args, level, index);
     306              :       }
     307              :     else
     308      5771620 :       TREE_PURPOSE (p) = template_parm_to_arg (p);
     309              : 
     310     22085303 :   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     22085303 : build_parameter_mapping (tree expr, tree args, tree ctx_parms)
     318              : {
     319     22085303 :   tree parms = find_template_parameters (expr, ctx_parms);
     320     22085303 :   tree map = map_arguments (parms, args);
     321     22085303 :   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     75441518 : parameter_mapping_equivalent_p (tree t1, tree t2)
     329              : {
     330     75441518 :   tree map1 = ATOMIC_CONSTR_MAP (t1);
     331     75441518 :   tree map2 = ATOMIC_CONSTR_MAP (t2);
     332    173570768 :   while (map1 && map2)
     333              :     {
     334    121130636 :       gcc_checking_assert (TREE_VALUE (map1) == TREE_VALUE (map2));
     335    121130636 :       tree arg1 = TREE_PURPOSE (map1);
     336    121130636 :       tree arg2 = TREE_PURPOSE (map2);
     337    121130636 :       if (!template_args_equal (arg1, arg2))
     338              :         return false;
     339     98129250 :       map1 = TREE_CHAIN (map1);
     340     98129250 :       map2 = TREE_CHAIN (map2);
     341              :     }
     342     52440132 :   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     11425883 :   explicit norm_info (bool diag)
     351     11425883 :     : norm_info (NULL_TREE, diag)
     352              :   {}
     353              : 
     354              :   /* Construct a top-level context for DECL.  */
     355              : 
     356     14934327 :   norm_info (tree in_decl, bool diag)
     357     14934327 :     : subst_info (tf_warning_or_error|tf_partial, in_decl),
     358     14934327 :       generate_diagnostics (diag)
     359              :   {
     360      3508444 :     if (in_decl)
     361              :       {
     362      2873183 :         initial_parms = DECL_TEMPLATE_PARMS (in_decl);
     363      2873183 :         if (generate_diagnostics)
     364         1280 :           context = build_tree_list (NULL_TREE, in_decl);
     365              :       }
     366              :     else
     367       635261 :       initial_parms = current_template_parms;
     368      3508444 :   }
     369              : 
     370     19215371 :   void update_context (tree expr, tree args)
     371              :   {
     372     19215371 :     if (generate_diagnostics)
     373              :       {
     374         3406 :         tree map = build_parameter_mapping (expr, args, ctx_parms ());
     375         3406 :         context = tree_cons (map, expr, context);
     376              :       }
     377     19215371 :     in_decl = get_concept_check_template (expr);
     378     19215371 :   }
     379              : 
     380              :   /* Returns the template parameters that are in scope for the current
     381              :      normalization context.  */
     382              : 
     383     22085303 :   tree ctx_parms ()
     384              :   {
     385     22085303 :     if (in_decl)
     386     21646414 :       return DECL_TEMPLATE_PARMS (in_decl);
     387              :     else
     388       438889 :       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     21909353 : normalize_logical_operation (tree t, tree args, tree_code c, norm_info info)
     416              : {
     417     21909353 :   tree t0 = normalize_expression (TREE_OPERAND (t, 0), args, info);
     418     21909353 :   tree t1 = normalize_expression (TREE_OPERAND (t, 1), args, info);
     419              : 
     420              :   /* Build a new info object for the constraint.  */
     421     21909353 :   tree ci = (info.generate_diagnostics
     422     21909353 :              ? build_tree_list (t, info.context) : NULL_TREE);
     423              : 
     424     21909353 :   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    187408202 :   static hashval_t hash (norm_entry *e)
     443              :   {
     444    187408202 :     ++comparing_specializations;
     445    187408202 :     hashval_t val = iterative_hash_template_arg (e->tmpl, 0);
     446    187408202 :     val = iterative_hash_template_arg (e->args, val);
     447    187408202 :     --comparing_specializations;
     448    187408202 :     return val;
     449              :   }
     450              : 
     451    210883019 :   static bool equal (norm_entry *e1, norm_entry *e2)
     452              :   {
     453    210883019 :     ++comparing_specializations;
     454    210883019 :     bool eq = e1->tmpl == e2->tmpl
     455    210883019 :       && template_args_equal (e1->args, e2->args);
     456    210883019 :     --comparing_specializations;
     457    210883019 :     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     24152045 : normalize_concept_check (tree check, tree args, norm_info info)
     468              : {
     469     24152045 :   gcc_assert (concept_check_p (check));
     470     24152045 :   tree tmpl = TREE_OPERAND (check, 0);
     471     24152045 :   tree targs = TREE_OPERAND (check, 1);
     472              : 
     473              :   /* Substitute through the arguments of the concept check.  */
     474     24152045 :   if (args)
     475     17300228 :     targs = tsubst_template_args (targs, args, info.complain, info.in_decl);
     476     24152045 :   if (targs == error_mark_node)
     477              :     return error_mark_node;
     478     24152045 :   if (template_args_equal (targs, generic_targs_for (tmpl)))
     479              :     /* Canonicalize generic arguments as NULL_TREE, as an optimization.  */
     480      3279400 :     targs = NULL_TREE;
     481              : 
     482              :   /* Build the substitution for the concept definition.  */
     483     24152045 :   tree parms = TREE_VALUE (DECL_TEMPLATE_PARMS (tmpl));
     484     24152045 :   if (targs && args)
     485              :     /* As an optimization, coerce the arguments only if necessary
     486              :        (i.e. if they were substituted).  */
     487     16925624 :     targs = coerce_template_parms (parms, targs, tmpl, tf_none);
     488     24152045 :   if (targs == error_mark_node)
     489              :     return error_mark_node;
     490              : 
     491     24152045 :   if (!norm_cache)
     492        77721 :     norm_cache = hash_table<norm_hasher>::create_ggc (31);
     493     24152045 :   norm_entry *entry = nullptr;
     494     24152045 :   if (!info.generate_diagnostics)
     495              :     {
     496              :       /* Cache the normal form of the substituted concept-id (when not
     497              :          diagnosing).  */
     498     24148639 :       norm_entry elt = {tmpl, targs, NULL_TREE};
     499     24148639 :       norm_entry **slot = norm_cache->find_slot (&elt, INSERT);
     500     24148639 :       if (*slot)
     501      4936674 :         return (*slot)->norm;
     502     19211965 :       entry = ggc_alloc<norm_entry> ();
     503     19211965 :       *entry = elt;
     504     19211965 :       *slot = entry;
     505              :     }
     506              : 
     507     19215371 :   tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
     508     19215371 :   info.update_context (check, args);
     509     19215371 :   tree norm = normalize_expression (def, targs, info);
     510     19215371 :   if (entry)
     511     19211965 :     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    165316461 :   static hashval_t hash (tree t)
     520              :   {
     521    165316461 :     ++comparing_specializations;
     522    165316461 :     hashval_t val = hash_atomic_constraint (t);
     523    165316461 :     --comparing_specializations;
     524    165316461 :     return val;
     525              :   }
     526              : 
     527    150416886 :   static bool equal (tree t1, tree t2)
     528              :   {
     529    150416886 :     ++comparing_specializations;
     530    150416886 :     bool eq = atomic_constraints_identical_p (t1, t2);
     531    150416886 :     --comparing_specializations;
     532    150416886 :     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     46233942 : normalize_atom (tree t, tree args, norm_info info)
     544              : {
     545              :   /* Concept checks are not atomic.  */
     546     46233942 :   if (concept_check_p (t))
     547     24152045 :     return normalize_concept_check (t, args, info);
     548              : 
     549              :   /* Build the parameter mapping for the atom.  */
     550     22081897 :   tree map = build_parameter_mapping (t, args, info.ctx_parms ());
     551              : 
     552              :   /* Build a new info object for the atom.  */
     553     22081897 :   tree ci = build_tree_list (t, info.context);
     554              : 
     555     22081897 :   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     43725036 :   if (info.in_decl && concept_definition_p (info.in_decl))
     563     19572416 :     ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (atom) = true;
     564              : 
     565     22081897 :   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     22077476 :       if (!atom_cache)
     570        85639 :         atom_cache = hash_table<atom_hasher>::create_ggc (31);
     571     22077476 :       tree *slot = atom_cache->find_slot (atom, INSERT);
     572     22077476 :       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     21491537 :       if (map)
     581              :         {
     582     21490837 :           tree targets = make_tree_vec (list_length (map));
     583     21490837 :           int i = 0;
     584     59375009 :           for (tree node = map; node; node = TREE_CHAIN (node))
     585              :             {
     586     37884172 :               tree target = TREE_PURPOSE (node);
     587     37884172 :               TREE_VEC_ELT (targets, i++) = target;
     588              :             }
     589     21490837 :           tree target_parms = find_template_parameters (targets,
     590              :                                                         info.initial_parms);
     591     21490837 :           TREE_TYPE (map) = target_parms;
     592              :         }
     593              : 
     594     21491537 :       *slot = atom;
     595              :     }
     596              :   return atom;
     597              : }
     598              : 
     599              : /* Returns the normal form of an expression.  */
     600              : 
     601              : static tree
     602     68143414 : normalize_expression (tree t, tree args, norm_info info)
     603              : {
     604     68143414 :   if (!t)
     605              :     return NULL_TREE;
     606              : 
     607     68143414 :   if (t == error_mark_node)
     608              :     return error_mark_node;
     609              : 
     610     68143295 :   switch (TREE_CODE (t))
     611              :     {
     612     21170478 :     case TRUTH_ANDIF_EXPR:
     613     21170478 :       return normalize_logical_operation (t, args, CONJ_CONSTR, info);
     614       738875 :     case TRUTH_ORIF_EXPR:
     615       738875 :       return normalize_logical_operation (t, args, DISJ_CONSTR, info);
     616     46233942 :     default:
     617     46233942 :       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      5109337 : get_normalized_constraints (tree t, norm_info info)
     627              : {
     628      5109337 :   auto_timevar time (TV_CONSTRAINT_NORM);
     629      5109337 :   return normalize_expression (t, NULL_TREE, info);
     630      5109337 : }
     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      3198411 : get_normalized_constraints_from_info (tree ci, tree in_decl, bool diag = false)
     638              : {
     639      3198411 :   if (ci == NULL_TREE)
     640              :     return NULL_TREE;
     641              : 
     642              :   /* Substitution errors during normalization are fatal.  */
     643      3198403 :   ++processing_template_decl;
     644      3198403 :   norm_info info (in_decl, diag);
     645      6396806 :   tree t = get_normalized_constraints (CI_ASSOCIATED_CONSTRAINTS (ci), info);
     646      3198403 :   --processing_template_decl;
     647              : 
     648      3198403 :   return t;
     649              : }
     650              : 
     651              : /* Returns the normalized constraints for the declaration D.  */
     652              : 
     653              : static tree
     654    499141480 : get_normalized_constraints_from_decl (tree d, bool diag = false)
     655              : {
     656    499141480 :   tree tmpl;
     657    499141480 :   tree decl;
     658              : 
     659              :   /* For inherited constructors, consider the original declaration;
     660              :      it has the correct template information attached.  */
     661    499141480 :   d = strip_inheriting_ctors (d);
     662              : 
     663    499141480 :   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      1637152 :       tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (d));
     669      1637152 :       lambda = most_general_lambda (lambda);
     670      1637152 :       d = lambda_function (lambda);
     671              :     }
     672              : 
     673    499141480 :   if (TREE_CODE (d) == TEMPLATE_DECL)
     674              :     {
     675    368120499 :       tmpl = d;
     676    368120499 :       decl = DECL_TEMPLATE_RESULT (tmpl);
     677              :     }
     678              :   else
     679              :     {
     680    131020981 :       if (tree ti = DECL_TEMPLATE_INFO (d))
     681     91199963 :         tmpl = TI_TEMPLATE (ti);
     682              :       else
     683              :         tmpl = NULL_TREE;
     684     91199963 :       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    459320462 :   if (tmpl && DECL_LANG_SPECIFIC (tmpl)
     705    550520410 :       && (!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     31833846 :           || (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl))
     715     15916923 :               < TMPL_ARGS_DEPTH (DECL_TI_ARGS (tmpl)))))
     716    443404708 :     tmpl = most_general_template (tmpl);
     717              : 
     718    499141480 :   d = tmpl ? tmpl : decl;
     719              : 
     720              :   /* If we're not diagnosing errors, use cached constraints, if any.  */
     721    499141480 :   if (!diag)
     722    998137337 :     if (tree *p = hash_map_safe_get (normalized_map, d))
     723    416647468 :       return *p;
     724              : 
     725     82494012 :   tree norm = NULL_TREE;
     726     82494012 :   if (tree ci = get_constraints (d))
     727              :     {
     728      2563055 :       push_access_scope_guard pas (decl);
     729      2563055 :       norm = get_normalized_constraints_from_info (ci, tmpl, diag);
     730      2563055 :     }
     731              : 
     732     82494012 :   if (!diag)
     733     82493005 :     hash_map_safe_put<hm_ggc> (normalized_map, d, norm);
     734              : 
     735     82494012 :   return norm;
     736              : }
     737              : 
     738              : /* Returns the normal form of TMPL's definition.  */
     739              : 
     740              : static tree
     741      3582821 : normalize_concept_definition (tree tmpl, bool diag)
     742              : {
     743      3582821 :   if (!norm_cache)
     744         1646 :     norm_cache = hash_table<norm_hasher>::create_ggc (31);
     745      3582821 :   norm_entry entry = {tmpl, NULL_TREE, NULL_TREE};
     746              : 
     747      3582821 :   if (!diag)
     748      3582548 :     if (norm_entry *found = norm_cache->find (&entry))
     749      3272780 :       return found->norm;
     750              : 
     751       310041 :   gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
     752       310041 :   tree def = get_concept_definition (DECL_TEMPLATE_RESULT (tmpl));
     753       310041 :   ++processing_template_decl;
     754       310041 :   norm_info info (tmpl, diag);
     755       310041 :   tree norm = get_normalized_constraints (def, info);
     756       310041 :   --processing_template_decl;
     757              : 
     758       310041 :   if (!diag)
     759              :     {
     760       309768 :       norm_entry **slot = norm_cache->find_slot (&entry, INSERT);
     761       309768 :       entry.norm = norm;
     762       309768 :       *slot = ggc_alloc<norm_entry> ();
     763       309768 :       **slot = entry;
     764              :     }
     765              : 
     766              :   return norm;
     767              : }
     768              : 
     769              : /* Normalize an EXPR as a constraint.  */
     770              : 
     771              : static tree
     772     11425883 : normalize_constraint_expression (tree expr, norm_info info)
     773              : {
     774     11425883 :   if (!expr || expr == error_mark_node)
     775              :     return expr;
     776              : 
     777     11425883 :   if (!info.generate_diagnostics)
     778     22851371 :     if (tree *p = hash_map_safe_get (normalized_map, expr))
     779      9824990 :       return *p;
     780              : 
     781      1600893 :   ++processing_template_decl;
     782      1600893 :   tree norm = get_normalized_constraints (expr, info);
     783      1600893 :   --processing_template_decl;
     784              : 
     785      1600893 :   if (!info.generate_diagnostics)
     786      1600741 :     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    368706606 : atomic_constraints_identical_p (tree t1, tree t2)
     797              : {
     798    368706606 :   gcc_assert (TREE_CODE (t1) == ATOMIC_CONSTR);
     799    368706606 :   gcc_assert (TREE_CODE (t2) == ATOMIC_CONSTR);
     800              : 
     801    368706606 :   if (ATOMIC_CONSTR_EXPR (t1) != ATOMIC_CONSTR_EXPR (t2))
     802              :     return false;
     803              : 
     804     75441518 :   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     17173018 : constraints_equivalent_p (tree t1, tree t2)
     815              : {
     816     17173018 :   gcc_assert (CONSTR_P (t1));
     817     17173018 :   gcc_assert (CONSTR_P (t2));
     818              : 
     819     17173018 :   if (TREE_CODE (t1) != TREE_CODE (t2))
     820              :     return false;
     821              : 
     822     16966627 :   switch (TREE_CODE (t1))
     823              :     {
     824      8528995 :     case CONJ_CONSTR:
     825      8528995 :     case DISJ_CONSTR:
     826      8528995 :       if (!constraints_equivalent_p (TREE_OPERAND (t1, 0),
     827      8528995 :                                      TREE_OPERAND (t2, 0)))
     828              :         return false;
     829      8283887 :       if (!constraints_equivalent_p (TREE_OPERAND (t1, 1),
     830      8283887 :                                      TREE_OPERAND (t2, 1)))
     831              :         return false;
     832              :       break;
     833      8437632 :     case ATOMIC_CONSTR:
     834      8437632 :       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   1896736537 : hash_atomic_constraint (tree t)
     847              : {
     848   1896736537 :   gcc_assert (TREE_CODE (t) == ATOMIC_CONSTR);
     849              : 
     850              :   /* Hash the identity of the expression.  */
     851   1896736537 :   hashval_t val = htab_hash_pointer (ATOMIC_CONSTR_EXPR (t));
     852              : 
     853              :   /* Hash the targets of the parameter map.  */
     854   1896736537 :   tree p = ATOMIC_CONSTR_MAP (t);
     855   4918876149 :   while (p)
     856              :     {
     857   3022139612 :       val = iterative_hash_template_arg (TREE_PURPOSE (p), val);
     858   3022139612 :       p = TREE_CHAIN (p);
     859              :     }
     860              : 
     861   1896736537 :   return val;
     862              : }
     863              : 
     864              : namespace inchash
     865              : {
     866              : 
     867              : static void
     868     77205766 : add_constraint (tree t, hash& h)
     869              : {
     870    153500110 :   h.add_int (TREE_CODE (t));
     871    153500110 :   switch (TREE_CODE (t))
     872              :     {
     873     76294344 :     case CONJ_CONSTR:
     874     76294344 :     case DISJ_CONSTR:
     875     76294344 :       add_constraint (TREE_OPERAND (t, 0), h);
     876     76294344 :       add_constraint (TREE_OPERAND (t, 1), h);
     877     76294344 :       break;
     878     77205766 :     case ATOMIC_CONSTR:
     879     77205766 :       h.merge_hash (hash_atomic_constraint (t));
     880     77205766 :       break;
     881            0 :     default:
     882            0 :       gcc_unreachable ();
     883              :     }
     884     77205766 : }
     885              : 
     886              : }
     887              : 
     888              : /* Computes a hash code for the constraint T.  */
     889              : 
     890              : hashval_t
     891       911422 : iterative_hash_constraint (tree t, hashval_t val)
     892              : {
     893       911422 :   gcc_assert (CONSTR_P (t));
     894       911422 :   inchash::hash h (val);
     895       911422 :   inchash::add_constraint (t, h);
     896       911422 :   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    101070220 : current_template_constraints (void)
     908              : {
     909    101070220 :   if (!current_template_parms)
     910              :     return NULL_TREE;
     911    101070217 :   tree tmpl_constr = TEMPLATE_PARMS_CONSTRAINTS (current_template_parms);
     912    101070217 :   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     37753755 : associate_classtype_constraints (tree type)
     921              : {
     922     37753755 :   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     37752985 :   if (!current_template_parms)
     927              :     return type;
     928              : 
     929     27590696 :   if (CLASSTYPE_IS_TEMPLATE (type) || CLASSTYPE_TEMPLATE_SPECIALIZATION (type))
     930              :     {
     931     26451771 :       tree decl = TYPE_STUB_DECL (type);
     932     26451771 :       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     26451771 :       if (tree orig_ci = get_constraints (decl))
     939              :         {
     940      1195273 :           if (int extra_levels = (TMPL_PARMS_DEPTH (current_template_parms)
     941      7369298 :                                   - 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      1195273 :           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      1195273 :           return type;
     963              :         }
     964     25256498 :       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     20377980 : build_constraint_info ()
     973              : {
     974     20377980 :   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    297816056 : build_constraints (tree tr, tree dr)
     987              : {
     988    297816056 :   if (!tr && !dr)
     989              :     return NULL_TREE;
     990              : 
     991     20377980 :   tree_constraint_info* ci = build_constraint_info ();
     992     20377980 :   ci->template_reqs = tr;
     993     20377980 :   ci->declarator_reqs = dr;
     994     20377980 :   ci->associated_constr = combine_constraint_expressions (tr, dr);
     995              : 
     996     20377980 :   return (tree)ci;
     997              : }
     998              : 
     999              : /* Add constraint RHS to the end of CONSTRAINT_INFO ci.  */
    1000              : 
    1001              : tree
    1002           70 : append_constraint (tree ci, tree rhs)
    1003              : {
    1004           70 :   tree tr = ci ? CI_TEMPLATE_REQS (ci) : NULL_TREE;
    1005           24 :   tree dr = ci ? CI_DECLARATOR_REQS (ci) : NULL_TREE;
    1006           70 :   dr = combine_constraint_expressions (dr, rhs);
    1007           70 :   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           58 :     ci = build_constraints (tr, dr);
    1015           70 :   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   1060038019 : get_constraints (const_tree t)
    1027              : {
    1028   1060038019 :   if (!flag_concepts)
    1029              :     return NULL_TREE;
    1030   1052330476 :   if (!decl_constraints)
    1031              :     return NULL_TREE;
    1032              : 
    1033   1039833416 :   gcc_assert (DECL_P (t));
    1034   1039833416 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1035    189256326 :     t = DECL_TEMPLATE_RESULT (t);
    1036   1039833416 :   tree* found = decl_constraints->get (const_cast<tree> (t));
    1037   1039833416 :   if (found)
    1038    113264102 :     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    288586782 : set_constraints (tree t, tree ci)
    1050              : {
    1051    288586782 :   if (!ci)
    1052              :     return;
    1053     38221155 :   gcc_assert (t && flag_concepts);
    1054     38221155 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1055       141043 :     t = DECL_TEMPLATE_RESULT (t);
    1056     38221155 :   bool found = hash_map_safe_put<hm_ggc> (decl_constraints, t, ci);
    1057     38221155 :   gcc_assert (!found);
    1058              : }
    1059              : 
    1060              : /* Remove the associated constraints of the declaration T.  */
    1061              : 
    1062              : void
    1063     14911827 : remove_constraints (tree t)
    1064              : {
    1065     14911827 :   gcc_checking_assert (DECL_P (t));
    1066     14911827 :   if (TREE_CODE (t) == TEMPLATE_DECL)
    1067          177 :     t = DECL_TEMPLATE_RESULT (t);
    1068              : 
    1069     14911827 :   if (decl_constraints)
    1070     14298898 :     decl_constraints->remove (t);
    1071     14911827 : }
    1072              : 
    1073              : /* If DECL is a friend, substitute into REQS to produce requirements suitable
    1074              :    for declaration matching.  */
    1075              : 
    1076              : tree
    1077    205944865 : maybe_substitute_reqs_for (tree reqs, const_tree decl)
    1078              : {
    1079    205944865 :   if (reqs == NULL_TREE)
    1080              :     return NULL_TREE;
    1081              : 
    1082     16374779 :   decl = STRIP_TEMPLATE (decl);
    1083     16374779 :   if (DECL_UNIQUE_FRIEND_P (decl) && DECL_TEMPLATE_INFO (decl))
    1084              :     {
    1085       175221 :       tree tmpl = DECL_TI_TEMPLATE (decl);
    1086       175221 :       tree outer_args = outer_template_args (decl);
    1087       175221 :       processing_template_decl_sentinel s;
    1088       175221 :       if (PRIMARY_TEMPLATE_P (tmpl)
    1089       175221 :           || uses_template_parms (outer_args))
    1090       175221 :         ++processing_template_decl;
    1091       175221 :       reqs = tsubst_constraint (reqs, outer_args,
    1092              :                                 tf_warning_or_error, NULL_TREE);
    1093       175221 :     }
    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    399066383 : get_trailing_function_requirements (tree t)
    1102              : {
    1103    399066383 :   tree ci = get_constraints (t);
    1104    399066383 :   if (!ci)
    1105              :     return NULL_TREE;
    1106    101109160 :   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     40476359 : build_concept_check_arguments (tree arg, tree rest)
    1114              : {
    1115     40476359 :   gcc_assert (!rest || TREE_CODE (rest) == TREE_VEC);
    1116     40476359 :   tree args;
    1117     40476359 :   if (arg)
    1118              :     {
    1119     30489621 :       int n = rest ? TREE_VEC_LENGTH (rest) : 0;
    1120     20768305 :       args = make_tree_vec (n + 1);
    1121     20768305 :       TREE_VEC_ELT (args, 0) = arg;
    1122     20768305 :       if (rest)
    1123     20999247 :         for (int i = 0; i < n; ++i)
    1124     11277931 :           TREE_VEC_ELT (args, i + 1) = TREE_VEC_ELT (rest, i);
    1125      9721316 :       int def = rest ? GET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (rest) : 0;
    1126     20768305 :       SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, def + 1);
    1127              :     }
    1128              :   else
    1129              :     args = rest;
    1130     40476359 :   return args;
    1131              : }
    1132              : 
    1133              : /* Construct an expression that checks TMPL using ARGS.  */
    1134              : 
    1135              : tree
    1136     19708054 : build_concept_check (tree tmpl, tree args, tsubst_flags_t complain)
    1137              : {
    1138     19708054 :   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     40476359 : build_concept_check (tree tmpl, tree arg, tree rest, tsubst_flags_t complain)
    1145              : {
    1146     40476359 :   if (TREE_DEPRECATED (DECL_TEMPLATE_RESULT (tmpl)))
    1147            9 :     warn_deprecated_use (DECL_TEMPLATE_RESULT (tmpl), NULL_TREE);
    1148              : 
    1149     40476359 :   tree parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl);
    1150     40476359 :   tree args = build_concept_check_arguments (arg, rest);
    1151     40476359 :   args = coerce_template_parms (parms, args, tmpl, complain);
    1152     40476359 :   if (args == error_mark_node)
    1153              :     return error_mark_node;
    1154     38112293 :   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     15469021 : 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     15469021 : build_concept_id (tree expr)
    1170              : {
    1171     15469021 :   gcc_assert (TREE_CODE (expr) == TEMPLATE_ID_EXPR);
    1172     15469021 :   tree id = build_concept_id (TREE_OPERAND (expr, 0), TREE_OPERAND (expr, 1));
    1173     15469021 :   protected_set_expr_location (id, cp_expr_location (expr));
    1174     15469021 :   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     11600962 : build_type_constraint (tree decl, tree args, tsubst_flags_t complain)
    1185              : {
    1186     11600962 :   tree proto = template_parm_to_arg (concept_prototype_parameter (decl));
    1187     11600962 :   ++processing_template_decl;
    1188     11600962 :   tree check = build_concept_check (decl, proto, args, complain);
    1189     11600962 :   --processing_template_decl;
    1190     11600962 :   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      7760992 : build_constrained_parameter (tree cnc, tree proto, tree args)
    1202              : {
    1203      7760992 :   tree name = DECL_NAME (cnc);
    1204      7760992 :   tree type = TREE_TYPE (proto);
    1205      7760992 :   tree decl = build_decl (input_location, TYPE_DECL, name, type);
    1206      7760992 :   CONSTRAINED_PARM_PROTOTYPE (decl) = proto;
    1207      7760992 :   CONSTRAINED_PARM_CONCEPT (decl) = cnc;
    1208      7760992 :   CONSTRAINED_PARM_EXTRA_ARGS (decl) = args;
    1209      7760992 :   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    163701652 : finish_shorthand_constraint (tree decl, tree constr, bool is_non_type)
    1222              : {
    1223              :   /* No requirements means no constraints.  */
    1224    163701652 :   if (!constr)
    1225              :     return NULL_TREE;
    1226              : 
    1227      7761076 :   if (error_operand_p (constr))
    1228              :     return NULL_TREE;
    1229              : 
    1230      7761076 :   tree proto, con, args;
    1231      7761076 :   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          108 :       gcc_checking_assert (is_auto (TREE_TYPE (decl))
    1237              :                            && !is_constrained_auto (TREE_TYPE (decl)));
    1238          108 :       gcc_checking_assert (TREE_CODE (constr) == TEMPLATE_ID_EXPR);
    1239          108 :       tree tmpl = TREE_OPERAND (constr, 0);
    1240          108 :       proto = concept_prototype_parameter (tmpl);
    1241          108 :       con = DECL_TEMPLATE_RESULT (tmpl);
    1242          108 :       args = TREE_OPERAND (constr, 1);
    1243              :     }
    1244              :   else
    1245              :     {
    1246      7760968 :       proto = CONSTRAINED_PARM_PROTOTYPE (constr);
    1247      7760968 :       con = CONSTRAINED_PARM_CONCEPT (constr);
    1248      7760968 :       args = CONSTRAINED_PARM_EXTRA_ARGS (constr);
    1249              :     }
    1250              : 
    1251      7761076 :   bool variadic_concept_p = template_parameter_pack_p (proto);
    1252      7761076 :   bool declared_pack_p = template_parameter_pack_p (decl);
    1253      7761076 :   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      7761076 :   tree arg = template_parm_to_arg (decl);
    1258      7761076 :   if (apply_to_each_p && declared_pack_p)
    1259        18423 :     arg = PACK_EXPANSION_PATTERN (TREE_VEC_ELT (ARGUMENT_PACK_ARGS (arg), 0));
    1260              : 
    1261              :   /* Build the concept constraint-expression.  */
    1262      7761076 :   tree tmpl = DECL_TI_TEMPLATE (con);
    1263      7761076 :   tree check;
    1264      7761076 :   if (is_non_type)
    1265              :     {
    1266          108 :       arg = finish_decltype_type (arg, /*id_expr=*/true, tf_warning_or_error);
    1267          108 :       if (ARGUMENT_PACK_P (TREE_VEC_ELT (args, 0)))
    1268            4 :         args = expand_template_argument_pack (args);
    1269              :       else
    1270          104 :         args = copy_template_args (args);
    1271          108 :       TREE_VEC_ELT (args, 0) = arg;
    1272          108 :       check = build_concept_check (tmpl, args, tf_warning_or_error);
    1273              :     }
    1274              :   else
    1275      7760968 :     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      7761076 :   if (apply_to_each_p && declared_pack_p)
    1281        18423 :     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     86246331 : get_shorthand_constraints (tree parms)
    1293              : {
    1294     86246331 :   tree result = NULL_TREE;
    1295     86246331 :   parms = INNERMOST_TEMPLATE_PARMS (parms);
    1296    246653072 :   for (int i = 0; i < TREE_VEC_LENGTH (parms); ++i)
    1297              :     {
    1298    160406741 :       tree parm = TREE_VEC_ELT (parms, i);
    1299    160406741 :       tree constr = TEMPLATE_PARM_CONSTRAINTS (parm);
    1300    160406741 :       result = combine_constraint_expressions (result, constr);
    1301              :     }
    1302     86246331 :   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    643653455 : equivalent_placeholder_constraints (tree c1, tree c2)
    1310              : {
    1311    643653455 :   if (c1 && TREE_CODE (c1) == TEMPLATE_TYPE_PARM)
    1312              :     /* A constrained auto.  */
    1313    643653455 :     c1 = PLACEHOLDER_TYPE_CONSTRAINTS (c1);
    1314    643653455 :   if (c2 && TREE_CODE (c2) == TEMPLATE_TYPE_PARM)
    1315    643653455 :     c2 = PLACEHOLDER_TYPE_CONSTRAINTS (c2);
    1316              : 
    1317    643653455 :   if (c1 == c2)
    1318              :     return true;
    1319      5089735 :   if (!c1 || !c2)
    1320              :     return false;
    1321      4771079 :   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      4771079 :   gcc_assert (concept_check_p (c1) && concept_check_p (c2));
    1328      4771079 :   tree t1 = TREE_OPERAND (c1, 0);
    1329      4771079 :   tree a1 = TREE_OPERAND (c1, 1);
    1330      4771079 :   tree t2 = TREE_OPERAND (c2, 0);
    1331      4771079 :   tree a2 = TREE_OPERAND (c2, 1);
    1332              : 
    1333      4771079 :   if (t1 != t2)
    1334              :     return false;
    1335              : 
    1336      2598167 :   int len1 = TREE_VEC_LENGTH (a1);
    1337      2598167 :   int len2 = TREE_VEC_LENGTH (a2);
    1338      2598167 :   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      3690629 :   for (int i = 1; i < len1; ++i)
    1344      1479010 :     if (!template_args_equal (TREE_VEC_ELT (a1, i),
    1345      1479010 :                               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    160758598 : iterative_hash_placeholder_constraint (tree c, hashval_t val)
    1354              : {
    1355    160758598 :   gcc_assert (concept_check_p (c));
    1356    160758598 :   tree t = TREE_OPERAND (c, 0);
    1357    160758598 :   tree a = TREE_OPERAND (c, 1);
    1358              : 
    1359              :   /* Like hash_tmpl_and_args, but skip the first argument.  */
    1360    160758598 :   val = iterative_hash_object (DECL_UID (t), val);
    1361              : 
    1362    305698324 :   for (int i = TREE_VEC_LENGTH (a)-1; i > 0; --i)
    1363    144939726 :     val = iterative_hash_template_arg (TREE_VEC_ELT (a, i), val);
    1364              : 
    1365    160758598 :   return val;
    1366              : }
    1367              : 
    1368              : /* Substitute through the expression of a simple requirement or
    1369              :    compound requirement.  */
    1370              : 
    1371              : static tree
    1372     16692804 : tsubst_valid_expression_requirement (tree t, tree args, sat_info info)
    1373              : {
    1374     16692804 :   tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
    1375     16692804 :   tree r = tsubst_expr (t, args, quiet, info.in_decl);
    1376     16690104 :   if (r != error_mark_node
    1377     16690104 :       && (processing_template_decl
    1378     15906396 :           || convert_to_void (r, ICV_STATEMENT, quiet) != error_mark_node))
    1379     15909962 :     return r;
    1380              : 
    1381       780142 :   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       779947 :   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       780142 :   return error_mark_node;
    1403              : }
    1404              : 
    1405              : 
    1406              : /* Substitute through the simple requirement.  */
    1407              : 
    1408              : static tree
    1409      5759152 : tsubst_simple_requirement (tree t, tree args, sat_info info)
    1410              : {
    1411      5759152 :   tree t0 = TREE_OPERAND (t, 0);
    1412      5759152 :   tree expr = tsubst_valid_expression_requirement (t0, args, info);
    1413      5756452 :   if (expr == error_mark_node)
    1414              :     return error_mark_node;
    1415      5103619 :   if (processing_template_decl)
    1416          266 :     return finish_simple_requirement (EXPR_LOCATION (t), expr);
    1417      5103353 :   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     16108935 : tsubst_type_requirement_1 (tree t, tree args, sat_info info, location_t loc)
    1425              : {
    1426     16108935 :   tsubst_flags_t quiet = info.complain & ~tf_warning_or_error;
    1427     16108935 :   tree r = tsubst (t, args, quiet, info.in_decl);
    1428     16108935 :   if (r != error_mark_node)
    1429              :     return r;
    1430              : 
    1431       596800 :   if (info.diagnose_unsatisfaction_p ())
    1432              :     {
    1433           23 :       if (diagnosing_failed_constraint::replay_errors_p ())
    1434              :         {
    1435              :           /* Replay the substitution error.  */
    1436            2 :           inform (loc, "the required type %qT is invalid, because", t);
    1437            2 :           tsubst (t, args, info.complain, info.in_decl);
    1438              :         }
    1439              :       else
    1440           21 :         inform (loc, "the required type %qT is invalid", t);
    1441              :     }
    1442       596777 :   else if (info.noisy ())
    1443            0 :     tsubst (t, args, info.complain, info.in_decl);
    1444              : 
    1445       596800 :   return error_mark_node;
    1446              : }
    1447              : 
    1448              : 
    1449              : /* Substitute through the type requirement.  */
    1450              : 
    1451              : static tree
    1452      5302607 : tsubst_type_requirement (tree t, tree args, sat_info info)
    1453              : {
    1454      5302607 :   tree t0 = TREE_OPERAND (t, 0);
    1455      5302607 :   tree type = tsubst_type_requirement_1 (t0, args, info, EXPR_LOCATION (t));
    1456      5302607 :   if (type == error_mark_node)
    1457              :     return error_mark_node;
    1458      4705807 :   if (processing_template_decl)
    1459            4 :     return finish_type_requirement (EXPR_LOCATION (t), type);
    1460      4705803 :   return boolean_true_node;
    1461              : }
    1462              : 
    1463              : /* True if TYPE can be deduced from EXPR.  */
    1464              : 
    1465              : static bool
    1466     10455321 : 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     10455321 :   expr = force_paren_expr_uneval (expr);
    1472              : 
    1473     10455321 :   tree deduced_type = do_auto_deduction (type, expr, placeholder,
    1474              :                                          info.complain, adc_requirement,
    1475              :                                          /*outer_targs=*/args);
    1476              : 
    1477     10455321 :   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            0 :       return false;
    1498              :     }
    1499              :   return true;
    1500              : }
    1501              : 
    1502              : 
    1503              : /* Substitute through the compound requirement.  */
    1504              : 
    1505              : static tree
    1506     10933652 : tsubst_compound_requirement (tree t, tree args, sat_info info)
    1507              : {
    1508     10933652 :   tree t0 = TREE_OPERAND (t, 0);
    1509     10933652 :   tree t1 = TREE_OPERAND (t, 1);
    1510     10933652 :   tree expr = tsubst_valid_expression_requirement (t0, args, info);
    1511     10933652 :   if (expr == error_mark_node)
    1512              :     return error_mark_node;
    1513              : 
    1514     10806343 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    1515              : 
    1516     10806343 :   subst_info quiet (info.complain & ~tf_warning_or_error, info.in_decl);
    1517              : 
    1518              :   /* Check the noexcept condition.  */
    1519     10806343 :   bool noexcept_p = COMPOUND_REQ_NOEXCEPT_P (t);
    1520       347692 :   if (noexcept_p && !processing_template_decl
    1521     11154032 :       && !expr_noexcept_p (expr, quiet.complain))
    1522              :     {
    1523           20 :       if (info.diagnose_unsatisfaction_p ())
    1524            5 :         inform (loc, "%qE is not %<noexcept%>", expr);
    1525              :       else
    1526           15 :         return error_mark_node;
    1527              :     }
    1528              : 
    1529              :   /* Substitute through the type expression, if any.  */
    1530     10806328 :   tree type = tsubst_type_requirement_1 (t1, args, info, EXPR_LOCATION (t));
    1531     10806328 :   if (type == error_mark_node)
    1532              :     return error_mark_node;
    1533              : 
    1534              :   /* Check expression against the result type.  */
    1535     10806328 :   if (type && !processing_template_decl)
    1536              :     {
    1537     10455314 :       if (tree placeholder = type_uses_auto (type))
    1538              :         {
    1539     10455309 :           if (!type_deducible_p (expr, type, placeholder, args, quiet))
    1540              :             {
    1541        21312 :               if (info.diagnose_unsatisfaction_p ())
    1542              :                 {
    1543           40 :                   if (diagnosing_failed_constraint::replay_errors_p ())
    1544              :                     {
    1545           12 :                       inform (loc,
    1546              :                               "%qE does not satisfy return-type-requirement, "
    1547              :                               "because", t0);
    1548              :                       /* Further explain the reason for the error.  */
    1549           12 :                       type_deducible_p (expr, type, placeholder, args, info);
    1550              :                     }
    1551              :                   else
    1552           28 :                     inform (loc,
    1553              :                             "%qE does not satisfy return-type-requirement", t0);
    1554              :                 }
    1555        21312 :               return error_mark_node;
    1556              :             }
    1557              :         }
    1558            5 :       else if (!expression_convertible_p (expr, type, quiet))
    1559              :         {
    1560            5 :           if (info.diagnose_unsatisfaction_p ())
    1561              :             {
    1562            0 :               if (diagnosing_failed_constraint::replay_errors_p ())
    1563              :                 {
    1564            0 :                   inform (loc, "cannot convert %qE to %qT because", t0, type);
    1565              :                   /* Further explain the reason for the error.  */
    1566            0 :                   expression_convertible_p (expr, type, info);
    1567              :                 }
    1568              :               else
    1569            0 :                 inform (loc, "cannot convert %qE to %qT", t0, type);
    1570              :             }
    1571            5 :           return error_mark_node;
    1572              :         }
    1573              :     }
    1574              : 
    1575     10785011 :   if (processing_template_decl)
    1576         3314 :     return finish_compound_requirement (EXPR_LOCATION (t),
    1577         3314 :                                         expr, type, noexcept_p);
    1578     10781697 :   return boolean_true_node;
    1579              : }
    1580              : 
    1581              : /* Substitute through the nested requirement.  */
    1582              : 
    1583              : static tree
    1584       970082 : tsubst_nested_requirement (tree t, tree args, sat_info info)
    1585              : {
    1586       970082 :   if (processing_template_decl)
    1587              :     {
    1588            0 :       tree req = TREE_OPERAND (t, 0);
    1589            0 :       req = tsubst_constraint (req, args, info.complain, info.in_decl);
    1590            0 :       if (req == error_mark_node)
    1591              :         return error_mark_node;
    1592            0 :       return finish_nested_requirement (EXPR_LOCATION (t), req);
    1593              :     }
    1594              : 
    1595       970082 :   sat_info quiet (info.complain & ~tf_warning_or_error, info.in_decl);
    1596       970082 :   tree result = constraint_satisfaction_value (t, args, quiet);
    1597       970082 :   if (result == boolean_true_node)
    1598              :     return boolean_true_node;
    1599              : 
    1600        38969 :   if (result == boolean_false_node
    1601        38969 :       && info.diagnose_unsatisfaction_p ())
    1602              :     {
    1603           77 :       tree expr = TREE_OPERAND (t, 0);
    1604           77 :       location_t loc = cp_expr_location (t);
    1605           77 :       if (diagnosing_failed_constraint::replay_errors_p ())
    1606              :         {
    1607              :           /* Replay the substitution error.  */
    1608           27 :           inform (loc, "nested requirement %qE is not satisfied, because", expr);
    1609           27 :           constraint_satisfaction_value (t, args, info);
    1610              :         }
    1611              :       else
    1612           50 :         inform (loc, "nested requirement %qE is not satisfied", expr);
    1613              :     }
    1614              : 
    1615        38969 :   return error_mark_node;
    1616              : }
    1617              : 
    1618              : /* Substitute ARGS into the requirement T.  */
    1619              : 
    1620              : static tree
    1621     22965493 : tsubst_requirement (tree t, tree args, sat_info info)
    1622              : {
    1623     22965493 :   iloc_sentinel loc_s (cp_expr_location (t));
    1624     22965493 :   switch (TREE_CODE (t))
    1625              :     {
    1626      5759152 :     case SIMPLE_REQ:
    1627      5759152 :       return tsubst_simple_requirement (t, args, info);
    1628      5302607 :     case TYPE_REQ:
    1629      5302607 :       return tsubst_type_requirement (t, args, info);
    1630     10933652 :     case COMPOUND_REQ:
    1631     10933652 :       return tsubst_compound_requirement (t, args, info);
    1632       970082 :     case NESTED_REQ:
    1633       970082 :       return tsubst_nested_requirement (t, args, info);
    1634            0 :     default:
    1635            0 :       break;
    1636              :     }
    1637            0 :   gcc_unreachable ();
    1638     22962793 : }
    1639              : 
    1640              : static tree
    1641      6956123 : declare_constraint_vars (tree parms, tree vars)
    1642              : {
    1643      6956123 :   tree s = vars;
    1644     17968517 :   for (tree t = parms; t; t = DECL_CHAIN (t))
    1645              :     {
    1646     11012394 :       if (DECL_PACK_P (t))
    1647              :         {
    1648         3082 :           tree pack = extract_fnparm_pack (t, &s);
    1649         3082 :           register_local_specialization (pack, t);
    1650              :         }
    1651              :       else
    1652              :         {
    1653     11009312 :           register_local_specialization (s, t);
    1654     11009312 :           s = DECL_CHAIN (s);
    1655              :         }
    1656              :     }
    1657      6956123 :   return vars;
    1658              : }
    1659              : 
    1660              : /* Substitute through as if checking function parameter types.  This
    1661              :    will diagnose common parameter type errors.  Returns error_mark_node
    1662              :    if an error occurred.  */
    1663              : 
    1664              : static tree
    1665      6956165 : check_constraint_variables (tree t, tree args, subst_info info)
    1666              : {
    1667      6956165 :   tree types = NULL_TREE;
    1668      6956165 :   tree p = t;
    1669     17968608 :   while (p && !VOID_TYPE_P (p))
    1670              :     {
    1671     11012443 :       types = tree_cons (NULL_TREE, TREE_TYPE (p), types);
    1672     11012443 :       p = TREE_CHAIN (p);
    1673              :     }
    1674      6956165 :   types = chainon (nreverse (types), void_list_node);
    1675      6956165 :   return tsubst_function_parms (types, args, info.complain, info.in_decl);
    1676              : }
    1677              : 
    1678              : /* A subroutine of tsubst_parameterized_constraint.  Substitute ARGS
    1679              :    into the parameter list T, producing a sequence of constraint
    1680              :    variables, declared in the current scope.
    1681              : 
    1682              :    Note that the caller must establish a local specialization stack
    1683              :    prior to calling this function since this substitution will
    1684              :    declare the substituted parameters.  */
    1685              : 
    1686              : static tree
    1687      6956165 : tsubst_constraint_variables (tree t, tree args, subst_info info)
    1688              : {
    1689              :   /* Perform a trial substitution to check for type errors.  */
    1690      6956165 :   tree parms = check_constraint_variables (t, args, info);
    1691      6956165 :   if (parms == error_mark_node)
    1692              :     return error_mark_node;
    1693              : 
    1694              :   /* Clear cp_unevaluated_operand across tsubst so that we get a proper chain
    1695              :      of PARM_DECLs.  */
    1696      6956123 :   int saved_unevaluated_operand = cp_unevaluated_operand;
    1697      6956123 :   cp_unevaluated_operand = 0;
    1698      6956123 :   tree vars = tsubst (t, args, info.complain, info.in_decl);
    1699      6956123 :   cp_unevaluated_operand = saved_unevaluated_operand;
    1700      6956123 :   if (vars == error_mark_node)
    1701              :     return error_mark_node;
    1702      6956123 :   return declare_constraint_vars (t, vars);
    1703              : }
    1704              : 
    1705              : /* Substitute ARGS into the requires-expression T. [8.4.7]p6.  The
    1706              :    substitution of template arguments into a requires-expression
    1707              :    may result in the formation of invalid types or expressions
    1708              :    in its requirements ...  In such cases, the expression evaluates
    1709              :    to false; it does not cause the program to be ill-formed.
    1710              : 
    1711              :    When substituting through a REQUIRES_EXPR as part of template
    1712              :    instantiation, we call this routine with info.quiet() true.
    1713              : 
    1714              :    When evaluating a REQUIRES_EXPR that appears outside a template in
    1715              :    cp_parser_requires_expression, we call this routine with
    1716              :    info.noisy() true.
    1717              : 
    1718              :    Finally, when diagnosing unsatisfaction from diagnose_atomic_constraint
    1719              :    and when diagnosing a false REQUIRES_EXPR via diagnose_constraints,
    1720              :    we call this routine with info.diagnose_unsatisfaction_p() true.  */
    1721              : 
    1722              : static tree
    1723     14543431 : tsubst_requires_expr (tree t, tree args, sat_info info)
    1724              : {
    1725     14543431 :   local_specialization_stack stack (lss_copy);
    1726              : 
    1727              :   /* We need to check access during the substitution.  */
    1728     14543431 :   deferring_access_check_sentinel acs (dk_no_deferred);
    1729              : 
    1730              :   /* A requires-expression is an unevaluated context.  */
    1731     14543431 :   cp_unevaluated u;
    1732              : 
    1733     14543431 :   args = add_extra_args (REQUIRES_EXPR_EXTRA_ARGS (t), args,
    1734              :                          info.complain, info.in_decl);
    1735     14543431 :   if (processing_template_decl
    1736     14543431 :       && !processing_constraint_expression_p ())
    1737              :     {
    1738              :       /* We're partially instantiating a generic lambda.  Substituting into
    1739              :          this requires-expression now may cause its requirements to get
    1740              :          checked out of order, so instead just remember the template
    1741              :          arguments and wait until we can substitute them all at once.
    1742              : 
    1743              :          Except if this requires-expr is part of associated constraints
    1744              :          that we're substituting into directly (for e.g. declaration
    1745              :          matching or dguide constraint rewriting), in which case we need
    1746              :          to partially substitute.  */
    1747          762 :       t = copy_node (t);
    1748          762 :       REQUIRES_EXPR_EXTRA_ARGS (t) = NULL_TREE;
    1749          762 :       REQUIRES_EXPR_EXTRA_ARGS (t) = build_extra_args (t, args, info.complain);
    1750          762 :       return t;
    1751              :     }
    1752              : 
    1753     14542669 :   tree parms = REQUIRES_EXPR_PARMS (t);
    1754     14542669 :   if (parms)
    1755              :     {
    1756      6956165 :       parms = tsubst_constraint_variables (parms, args, info);
    1757      6956165 :       if (parms == error_mark_node)
    1758           42 :         return boolean_false_node;
    1759              :     }
    1760              : 
    1761     14542627 :   tree result = boolean_true_node;
    1762     14542627 :   if (processing_template_decl)
    1763         2827 :     result = NULL_TREE;
    1764     36068512 :   for (tree reqs = REQUIRES_EXPR_REQS (t); reqs; reqs = TREE_CHAIN (reqs))
    1765              :     {
    1766     22965493 :       tree req = TREE_VALUE (reqs);
    1767     22965493 :       req = tsubst_requirement (req, args, info);
    1768     22962793 :       if (req == error_mark_node)
    1769              :         {
    1770      1437243 :           result = boolean_false_node;
    1771      1437243 :           if (info.diagnose_unsatisfaction_p ())
    1772              :             /* Keep going so that we diagnose all failed requirements.  */;
    1773              :           else
    1774              :             break;
    1775              :         }
    1776     21525550 :       else if (processing_template_decl)
    1777         3584 :         result = tree_cons (NULL_TREE, req, result);
    1778              :     }
    1779     14539927 :   if (processing_template_decl && result != boolean_false_node)
    1780         2827 :     result = finish_requires_expr (EXPR_LOCATION (t), parms, nreverse (result));
    1781              :   return result;
    1782     14540731 : }
    1783              : 
    1784              : /* Public wrapper for the above.  */
    1785              : 
    1786              : tree
    1787     14542978 : tsubst_requires_expr (tree t, tree args,
    1788              :                       tsubst_flags_t complain, tree in_decl)
    1789              : {
    1790     14542978 :   sat_info info (complain, in_decl);
    1791     14542978 :   return tsubst_requires_expr (t, args, info);
    1792              : }
    1793              : 
    1794              : /* Substitute ARGS into the constraint information CI, producing a new
    1795              :    constraint record.  */
    1796              : 
    1797              : tree
    1798       770444 : tsubst_constraint_info (tree t, tree args,
    1799              :                         tsubst_flags_t complain, tree in_decl)
    1800              : {
    1801       770444 :   if (!t || t == error_mark_node || !check_constraint_info (t))
    1802              :     return NULL_TREE;
    1803              : 
    1804       160593 :   tree tr = tsubst_constraint (CI_TEMPLATE_REQS (t), args, complain, in_decl);
    1805       321186 :   tree dr = tsubst_constraint (CI_DECLARATOR_REQS (t), args, complain, in_decl);
    1806       160593 :   return build_constraints (tr, dr);
    1807              : }
    1808              : 
    1809              : /* Substitute through a parameter mapping, in order to get the actual
    1810              :    arguments used to instantiate an atomic constraint.  This may fail
    1811              :    if the substitution into arguments produces something ill-formed.  */
    1812              : 
    1813              : static tree
    1814     76513440 : tsubst_parameter_mapping (tree map, tree args, subst_info info)
    1815              : {
    1816     76513440 :   if (!map)
    1817              :     return NULL_TREE;
    1818              : 
    1819     76512680 :   tsubst_flags_t complain = info.complain;
    1820     76512680 :   tree in_decl = info.in_decl;
    1821              : 
    1822     76512680 :   tree result = NULL_TREE;
    1823    208136870 :   for (tree p = map; p; p = TREE_CHAIN (p))
    1824              :     {
    1825    131627429 :       if (p == error_mark_node)
    1826              :         return error_mark_node;
    1827    131627429 :       tree parm = TREE_VALUE (p);
    1828    131627429 :       tree arg = TREE_PURPOSE (p);
    1829    131627429 :       tree new_arg;
    1830    131627429 :       if (ARGUMENT_PACK_P (arg))
    1831      4397740 :         new_arg = tsubst_argument_pack (arg, args, complain, in_decl);
    1832              :       else
    1833              :         {
    1834    127229689 :           new_arg = tsubst_template_arg (arg, args, complain, in_decl);
    1835    127229689 :           if (TYPE_P (new_arg))
    1836    126941262 :             new_arg = canonicalize_type_argument (new_arg, complain);
    1837              :         }
    1838    131627429 :       if (TREE_CODE (new_arg) == TYPE_ARGUMENT_PACK)
    1839              :         {
    1840      4391330 :           tree pack_args = ARGUMENT_PACK_ARGS (new_arg);
    1841      8646446 :           for (tree& pack_arg : tree_vec_range (pack_args))
    1842      4255116 :             if (TYPE_P (pack_arg))
    1843      4255116 :               pack_arg = canonicalize_type_argument (pack_arg, complain);
    1844              :         }
    1845    131627429 :       if (new_arg == error_mark_node)
    1846              :         return error_mark_node;
    1847              : 
    1848    131624190 :       result = tree_cons (new_arg, parm, result);
    1849              :     }
    1850     76509441 :   return nreverse (result);
    1851              : }
    1852              : 
    1853              : tree
    1854         1091 : tsubst_parameter_mapping (tree map, tree args, tsubst_flags_t complain, tree in_decl)
    1855              : {
    1856         1091 :   return tsubst_parameter_mapping (map, args, subst_info (complain, in_decl));
    1857              : }
    1858              : 
    1859              : /*---------------------------------------------------------------------------
    1860              :                         Constraint satisfaction
    1861              : ---------------------------------------------------------------------------*/
    1862              : 
    1863              : /* True if we are currently satisfying a constraint.  */
    1864              : 
    1865              : static bool satisfying_constraint;
    1866              : 
    1867              : /* A vector of incomplete types (and of declarations with undeduced return type),
    1868              :    appended to by note_failed_type_completion.  The
    1869              :    satisfaction caches use this in order to keep track of "potentially unstable"
    1870              :    satisfaction results.
    1871              : 
    1872              :    Since references to entries in this vector are stored only in the
    1873              :    GC-deletable sat_cache, it's safe to make this deletable as well.  */
    1874              : 
    1875              : static GTY((deletable)) vec<tree, va_gc> *failed_type_completions;
    1876              : 
    1877              : /* A map of where types were found to be incomplete in SFINAE context, for
    1878              :    warning if they are later completed.  */
    1879              : 
    1880              : static GTY((cache)) hash_map<tree, location_t, decl_location_traits> *failed_completions_map;
    1881              : 
    1882              : /* Called whenever a type completion (or return type deduction) failure occurs
    1883              :    that definitely affects the meaning of the program, by e.g. inducing
    1884              :    substitution failure.  */
    1885              : 
    1886              : void
    1887         4642 : note_failed_type_completion (tree t, tsubst_flags_t complain)
    1888              : {
    1889         4642 :   if (dependent_template_arg_p (t))
    1890              :     return;
    1891              : 
    1892         4605 :   gcc_checking_assert ((TYPE_P (t) && !COMPLETE_TYPE_P (t))
    1893              :                        || (DECL_P (t) && undeduced_auto_decl (t)));
    1894              : 
    1895         4605 :   if (satisfying_constraint)
    1896          183 :     vec_safe_push (failed_type_completions, t);
    1897              : 
    1898         4605 :   if (TYPE_P (t))
    1899              :     {
    1900         3980 :       if (!CLASS_TYPE_P (t))
    1901              :         return;
    1902         3667 :       t = TYPE_MAIN_DECL (t);
    1903              :     }
    1904         4292 :   if (!(complain & tf_error)
    1905         7990 :       && warning_enabled_at (DECL_SOURCE_LOCATION (t),
    1906         3698 :                              OPT_Wsfinae_incomplete_))
    1907              :     {
    1908         3696 :       if (warn_sfinae_incomplete > 1)
    1909              :         {
    1910            0 :           if (TREE_CODE (t) == TYPE_DECL)
    1911            0 :             warning (OPT_Wsfinae_incomplete_,
    1912            0 :                      "failed to complete %qT in SFINAE context", TREE_TYPE (t));
    1913              :           else
    1914            0 :             warning (OPT_Wsfinae_incomplete_,
    1915              :                      "failed to deduce %qD in SFINAE context", t);
    1916              :         }
    1917         3696 :       if (!failed_completions_map)
    1918          103 :         failed_completions_map
    1919          103 :           = hash_map<tree, location_t, decl_location_traits>::create_ggc ();
    1920         3696 :       failed_completions_map->put (t, input_location);
    1921              :     }
    1922              : }
    1923              : 
    1924              : /* If T was previously found to be incomplete in SFINAE context, return the
    1925              :    location where that happened, otherwise UNKNOWN_LOCATION.  */
    1926              : 
    1927              : location_t
    1928     57741151 : failed_completion_location (tree t)
    1929              : {
    1930     57741151 :   if (failed_completions_map)
    1931              :     {
    1932       113654 :       if (TYPE_P (t))
    1933        95091 :         t = TYPE_MAIN_DECL (t);
    1934       113654 :       if (location_t *p = failed_completions_map->get (t))
    1935           17 :         return *p;
    1936              :     }
    1937              :   return UNKNOWN_LOCATION;
    1938              : }
    1939              : 
    1940              : /* Returns true if the range [BEGIN, END) of elements within the
    1941              :    failed_type_completions vector contains a complete type (or a
    1942              :    declaration with a non-placeholder return type).  */
    1943              : 
    1944              : static bool
    1945    890397899 : some_type_complete_p (int begin, int end)
    1946              : {
    1947    890398484 :   for (int i = begin; i < end; i++)
    1948              :     {
    1949          648 :       tree t = (*failed_type_completions)[i];
    1950          648 :       if (TYPE_P (t) && COMPLETE_TYPE_P (t))
    1951              :         return true;
    1952          603 :       if (DECL_P (t) && !undeduced_auto_decl (t))
    1953              :         return true;
    1954              :     }
    1955              :   return false;
    1956              : }
    1957              : 
    1958              : /* Hash functions and data types for satisfaction cache entries.  */
    1959              : 
    1960              : struct GTY((for_user)) sat_entry
    1961              : {
    1962              :   /* The relevant ATOMIC_CONSTR.  */
    1963              :   tree atom;
    1964              : 
    1965              :   /* The relevant template arguments.  */
    1966              :   tree args;
    1967              : 
    1968              :   /* The result of satisfaction of ATOM+ARGS.
    1969              :      This is either boolean_true_node, boolean_false_node or error_mark_node,
    1970              :      where error_mark_node indicates ill-formed satisfaction.
    1971              :      It's set to NULL_TREE while computing satisfaction of ATOM+ARGS for
    1972              :      the first time.  */
    1973              :   tree result;
    1974              : 
    1975              :   /* For a !ATOMIC_CONSTR_MAP_INSTANTIATED_P atom, this conveniently points to
    1976              :      the entry for the corresponding atom after instantiating its mapping.  */
    1977              :   sat_entry *inst_entry;
    1978              : 
    1979              :   /* The value of input_location when satisfaction of ATOM+ARGS was first
    1980              :      performed.  */
    1981              :   location_t location;
    1982              : 
    1983              :   /* The range of elements appended to the failed_type_completions vector
    1984              :      during computation of this satisfaction result, encoded as a begin/end
    1985              :      pair of offsets.  */
    1986              :   int ftc_begin, ftc_end;
    1987              : 
    1988              :   /* True if we want to diagnose the above instability when it's detected.
    1989              :      We don't always want to do so, in order to avoid emitting duplicate
    1990              :      diagnostics in some cases.  */
    1991              :   bool diagnose_instability;
    1992              : 
    1993              :   /* True if we're in the middle of computing this satisfaction result.
    1994              :      Used during both quiet and noisy satisfaction to detect self-recursive
    1995              :      satisfaction.  */
    1996              :   bool evaluating;
    1997              : };
    1998              : 
    1999              : struct sat_hasher : ggc_ptr_hash<sat_entry>
    2000              : {
    2001   5818812104 :   static hashval_t hash (sat_entry *e)
    2002              :   {
    2003   5818812104 :     auto cso = make_temp_override (comparing_specializations);
    2004   5818812104 :     ++comparing_specializations;
    2005              : 
    2006   5818812104 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e->atom))
    2007              :       {
    2008              :         /* Atoms with instantiated mappings are built during satisfaction.
    2009              :            They live only inside the sat_cache, and we build one to query
    2010              :            the cache with each time we instantiate a mapping.  */
    2011   1654214310 :         gcc_assert (!e->args);
    2012   1654214310 :         return hash_atomic_constraint (e->atom);
    2013              :       }
    2014              : 
    2015              :     /* Atoms with uninstantiated mappings are built during normalization.
    2016              :        Since normalize_atom caches the atoms it returns, we can assume
    2017              :        pointer-based identity for fast hashing and comparison.  Even if this
    2018              :        assumption is violated, that's okay, we'll just get a cache miss.  */
    2019   4164597794 :     hashval_t value = htab_hash_pointer (e->atom);
    2020              : 
    2021   4164597794 :     if (tree map = ATOMIC_CONSTR_MAP (e->atom))
    2022              :       /* Only the parameters that are used in the targets of the mapping
    2023              :          affect the satisfaction value of the atom.  So we consider only
    2024              :          the arguments for these parameters, and ignore the rest.  */
    2025   4164586450 :       for (tree target_parms = TREE_TYPE (map);
    2026   9179397683 :            target_parms;
    2027   5014811233 :            target_parms = TREE_CHAIN (target_parms))
    2028              :         {
    2029   5014811233 :           int level, index;
    2030   5014811233 :           tree parm = TREE_VALUE (target_parms);
    2031   5014811233 :           template_parm_level_and_index (parm, &level, &index);
    2032   5014811233 :           tree arg = TMPL_ARG (e->args, level, index);
    2033   5014811233 :           value = iterative_hash_template_arg (arg, value);
    2034              :         }
    2035              :     return value;
    2036   5818812104 :   }
    2037              : 
    2038   6268490320 :   static bool equal (sat_entry *e1, sat_entry *e2)
    2039              :   {
    2040   6268490320 :     auto cso = make_temp_override (comparing_specializations);
    2041   6268490320 :     ++comparing_specializations;
    2042              : 
    2043   6268490320 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom)
    2044   6268490320 :         != ATOMIC_CONSTR_MAP_INSTANTIATED_P (e2->atom))
    2045              :       return false;
    2046              : 
    2047              :     /* See sat_hasher::hash.  */
    2048   4362623841 :     if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (e1->atom))
    2049              :       {
    2050    209852088 :         gcc_assert (!e1->args && !e2->args);
    2051    209852088 :         return atomic_constraints_identical_p (e1->atom, e2->atom);
    2052              :       }
    2053              : 
    2054   4152771753 :     if (e1->atom != e2->atom)
    2055              :       return false;
    2056              : 
    2057    745975041 :     if (tree map = ATOMIC_CONSTR_MAP (e1->atom))
    2058    745973669 :       for (tree target_parms = TREE_TYPE (map);
    2059   1518819321 :            target_parms;
    2060    772845652 :            target_parms = TREE_CHAIN (target_parms))
    2061              :         {
    2062    781440543 :           int level, index;
    2063    781440543 :           tree parm = TREE_VALUE (target_parms);
    2064    781440543 :           template_parm_level_and_index (parm, &level, &index);
    2065    781440543 :           tree arg1 = TMPL_ARG (e1->args, level, index);
    2066    781440543 :           tree arg2 = TMPL_ARG (e2->args, level, index);
    2067    781440543 :           if (!template_args_equal (arg1, arg2))
    2068      8594891 :             return false;
    2069              :         }
    2070              :     return true;
    2071   6268490320 :   }
    2072              : };
    2073              : 
    2074              : /* Cache the result of satisfy_atom.  */
    2075              : static GTY((deletable)) hash_table<sat_hasher> *sat_cache;
    2076              : 
    2077              : /* Cache the result of satisfy_declaration_constraints.  */
    2078              : static GTY((deletable)) hash_map<tree, tree> *decl_satisfied_cache;
    2079              : 
    2080              : /* A tool used by satisfy_atom to help manage satisfaction caching and to
    2081              :    diagnose "unstable" satisfaction values.  We insert into the cache only
    2082              :    when performing satisfaction quietly.  */
    2083              : 
    2084              : struct satisfaction_cache
    2085              : {
    2086              :   satisfaction_cache (tree, tree, sat_info);
    2087              :   tree get ();
    2088              :   tree save (tree);
    2089              : 
    2090              :   sat_entry *entry;
    2091              :   sat_info info;
    2092              :   int ftc_begin;
    2093              : };
    2094              : 
    2095              : /* Constructor for the satisfaction_cache class.  We're performing satisfaction
    2096              :    of ATOM+ARGS according to INFO.  */
    2097              : 
    2098    890397941 : satisfaction_cache
    2099    890397941 : ::satisfaction_cache (tree atom, tree args, sat_info info)
    2100    890397941 :   : entry(nullptr), info(info), ftc_begin(-1)
    2101              : {
    2102    890397941 :   if (!sat_cache)
    2103        69333 :     sat_cache = hash_table<sat_hasher>::create_ggc (31);
    2104              : 
    2105              :   /* When noisy, we query the satisfaction cache in order to diagnose
    2106              :      "unstable" satisfaction values.  */
    2107    890397941 :   if (info.noisy ())
    2108              :     {
    2109              :       /* When noisy, constraints have been re-normalized, and that breaks the
    2110              :          pointer-based identity assumption of sat_cache (for atoms with
    2111              :          uninstantiated mappings).  So undo this re-normalization by looking in
    2112              :          the atom_cache for the corresponding atom that was used during quiet
    2113              :          satisfaction.  */
    2114         7296 :       if (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
    2115              :         {
    2116         3661 :           if (tree found = atom_cache->find (atom))
    2117         3661 :             atom = found;
    2118              :           else
    2119              :             /* The lookup should always succeed, but if it fails then let's
    2120              :                just leave 'entry' empty, effectively disabling the cache.  */
    2121            0 :             return;
    2122              :         }
    2123              :     }
    2124              : 
    2125              :   /* Look up or create the corresponding satisfaction entry.  */
    2126    890397941 :   sat_entry elt;
    2127    890397941 :   elt.atom = atom;
    2128    890397941 :   elt.args = args;
    2129    890397941 :   sat_entry **slot = sat_cache->find_slot (&elt, INSERT);
    2130    890397941 :   if (*slot)
    2131    780809790 :     entry = *slot;
    2132    109588151 :   else if (info.quiet ())
    2133              :     {
    2134    109588145 :       entry = ggc_alloc<sat_entry> ();
    2135    109588145 :       entry->atom = atom;
    2136    109588145 :       entry->args = args;
    2137    109588145 :       entry->result = NULL_TREE;
    2138    109588145 :       entry->inst_entry = nullptr;
    2139    109588145 :       entry->location = input_location;
    2140    109588145 :       entry->ftc_begin = entry->ftc_end = -1;
    2141    109588145 :       entry->diagnose_instability = false;
    2142    109588145 :       if (ATOMIC_CONSTR_MAP_INSTANTIATED_P (atom))
    2143              :         /* We always want to diagnose instability of an atom with an
    2144              :            instantiated parameter mapping.  For atoms with an uninstantiated
    2145              :            mapping, we set this flag (in satisfy_atom) only if substitution
    2146              :            into its mapping previously failed.  */
    2147     33079471 :         entry->diagnose_instability = true;
    2148    109588145 :       entry->evaluating = false;
    2149    109588145 :       *slot = entry;
    2150              :     }
    2151              :   else
    2152              :     {
    2153              :       /* We're evaluating this atom for the first time, and doing so noisily.
    2154              :          This shouldn't happen outside of error recovery situations involving
    2155              :          unstable satisfaction.  Let's just leave 'entry' empty, effectively
    2156              :          disabling the cache, and remove the empty slot.  */
    2157            6 :       gcc_checking_assert (seen_error ());
    2158              :       /* Appease hash_table::check_complete_insertion.  */
    2159            6 :       *slot = ggc_alloc<sat_entry> ();
    2160            6 :       sat_cache->clear_slot (slot);
    2161              :     }
    2162              : }
    2163              : 
    2164              : /* Returns the cached satisfaction result if we have one and we're not
    2165              :    recomputing the satisfaction result from scratch.  Otherwise returns
    2166              :    NULL_TREE.  */
    2167              : 
    2168              : tree
    2169    890397941 : satisfaction_cache::get ()
    2170              : {
    2171    890397941 :   if (!entry)
    2172              :     return NULL_TREE;
    2173              : 
    2174    890397935 :   if (entry->evaluating)
    2175              :     {
    2176              :       /* If we get here, it means satisfaction is self-recursive.  */
    2177           36 :       gcc_checking_assert (!entry->result || seen_error ());
    2178              :       /* Prefer printing the instantiated mapping.  */
    2179           36 :       tree atom = entry->inst_entry ? entry->inst_entry->atom : entry->atom;
    2180           36 :       if (info.noisy ())
    2181           18 :         error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (atom)),
    2182              :                   "satisfaction of atomic constraint %qE depends on itself",
    2183              :                   atom);
    2184           36 :       return error_mark_node;
    2185              :     }
    2186              : 
    2187              :   /* This satisfaction result is "potentially unstable" if a type for which
    2188              :      type completion failed during its earlier computation is now complete.  */
    2189    890397899 :   bool maybe_unstable = some_type_complete_p (entry->ftc_begin,
    2190              :                                               entry->ftc_end);
    2191              : 
    2192    890397899 :   if (info.noisy () || maybe_unstable || !entry->result)
    2193              :     {
    2194              :       /* We're computing the satisfaction result from scratch.  */
    2195    109595459 :       entry->evaluating = true;
    2196    109595459 :       ftc_begin = vec_safe_length (failed_type_completions);
    2197    109595459 :       return NULL_TREE;
    2198              :     }
    2199              :   else
    2200              :     return entry->result;
    2201              : }
    2202              : 
    2203              : /* RESULT is the computed satisfaction result.  If RESULT differs from the
    2204              :    previously cached result, this routine issues an appropriate error.
    2205              :    Otherwise, when evaluating quietly, updates the cache appropriately.  */
    2206              : 
    2207              : tree
    2208    109590065 : satisfaction_cache::save (tree result)
    2209              : {
    2210    109590065 :   if (!entry)
    2211              :     return result;
    2212              : 
    2213    109590059 :   gcc_checking_assert (entry->evaluating);
    2214    109590059 :   entry->evaluating = false;
    2215              : 
    2216    109590059 :   if (entry->result && result != entry->result)
    2217              :     {
    2218           42 :       if (info.quiet ())
    2219              :         /* Return error_mark_node to force satisfaction to get replayed
    2220              :            noisily.  */
    2221           21 :         return error_mark_node;
    2222              :       else
    2223              :         {
    2224           21 :           if (entry->diagnose_instability)
    2225              :             {
    2226           12 :               auto_diagnostic_group d;
    2227           12 :               error_at (EXPR_LOCATION (ATOMIC_CONSTR_EXPR (entry->atom)),
    2228              :                         "satisfaction value of atomic constraint %qE changed "
    2229           12 :                         "from %qE to %qE", entry->atom, entry->result, result);
    2230           12 :               inform (entry->location,
    2231              :                       "satisfaction value first evaluated to %qE from here",
    2232           12 :                       entry->result);
    2233           12 :             }
    2234              :           /* For sake of error recovery, allow this latest satisfaction result
    2235              :              to prevail.  */
    2236           21 :           entry->result = result;
    2237           21 :           return result;
    2238              :         }
    2239              :     }
    2240              : 
    2241    109590017 :   if (info.quiet ())
    2242              :     {
    2243    109582766 :       entry->result = result;
    2244              :       /* Store into this entry the list of relevant failed type completions
    2245              :          that occurred during (re)computation of the satisfaction result.  */
    2246    109582766 :       gcc_checking_assert (ftc_begin != -1);
    2247    109582766 :       entry->ftc_begin = ftc_begin;
    2248    109822311 :       entry->ftc_end = vec_safe_length (failed_type_completions);
    2249              :     }
    2250              : 
    2251              :   return result;
    2252              : }
    2253              : 
    2254              : /* Substitute ARGS into constraint-expression T during instantiation of
    2255              :    a member of a class template.  */
    2256              : 
    2257              : tree
    2258      1891924 : tsubst_constraint (tree t, tree args, tsubst_flags_t complain, tree in_decl)
    2259              : {
    2260              :   /* We also don't want to evaluate concept-checks when substituting the
    2261              :      constraint-expressions of a declaration.  */
    2262      1891924 :   processing_constraint_expression_sentinel s;
    2263      1891924 :   cp_unevaluated u;
    2264      1891924 :   tree expr = tsubst_expr (t, args, complain, in_decl);
    2265      3783848 :   return expr;
    2266      1891924 : }
    2267              : 
    2268              : static tree satisfy_constraint_r (tree, tree, sat_info info);
    2269              : 
    2270              : /* Compute the satisfaction of a conjunction.  */
    2271              : 
    2272              : static tree
    2273    705100610 : satisfy_conjunction (tree t, tree args, sat_info info)
    2274              : {
    2275    705100610 :   tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, info);
    2276    705100610 :   if (lhs == error_mark_node || lhs == boolean_false_node)
    2277              :     return lhs;
    2278    696297497 :   return satisfy_constraint_r (TREE_OPERAND (t, 1), args, info);
    2279              : }
    2280              : 
    2281              : /* The current depth at which we're replaying an error during recursive
    2282              :    diagnosis of a constraint satisfaction failure.  */
    2283              : 
    2284              : static int current_constraint_diagnosis_depth;
    2285              : 
    2286              : /* Whether CURRENT_CONSTRAINT_DIAGNOSIS_DEPTH has ever exceeded
    2287              :    CONCEPTS_DIAGNOSTICS_MAX_DEPTH during recursive diagnosis of a constraint
    2288              :    satisfaction error.  */
    2289              : 
    2290              : static bool concepts_diagnostics_max_depth_exceeded_p;
    2291              : 
    2292              : /* Recursive subroutine of collect_operands_of_disjunction.  T is a normalized
    2293              :    subexpression of a constraint (composed of CONJ_CONSTRs and DISJ_CONSTRs)
    2294              :    and E is the corresponding unnormalized subexpression (composed of
    2295              :    TRUTH_ANDIF_EXPRs and TRUTH_ORIF_EXPRs).  */
    2296              : 
    2297              : static void
    2298           22 : collect_operands_of_disjunction_r (tree t, tree e,
    2299              :                                    auto_vec<tree_pair> *operands)
    2300              : {
    2301           36 :   if (TREE_CODE (e) == TRUTH_ORIF_EXPR)
    2302              :     {
    2303           14 :       collect_operands_of_disjunction_r (TREE_OPERAND (t, 0),
    2304           14 :                                          TREE_OPERAND (e, 0), operands);
    2305           14 :       collect_operands_of_disjunction_r (TREE_OPERAND (t, 1),
    2306           14 :                                          TREE_OPERAND (e, 1), operands);
    2307              :     }
    2308              :   else
    2309              :     {
    2310           22 :       tree_pair p = std::make_pair (t, e);
    2311           22 :       operands->safe_push (p);
    2312              :     }
    2313           22 : }
    2314              : 
    2315              : /* Recursively collect the normalized and unnormalized operands of the
    2316              :    disjunction T and append them to OPERANDS in order.  */
    2317              : 
    2318              : static void
    2319            8 : collect_operands_of_disjunction (tree t, auto_vec<tree_pair> *operands)
    2320              : {
    2321            8 :   collect_operands_of_disjunction_r (t, CONSTR_EXPR (t), operands);
    2322            8 : }
    2323              : 
    2324              : /* Compute the satisfaction of a disjunction.  */
    2325              : 
    2326              : static tree
    2327     67441741 : satisfy_disjunction (tree t, tree args, sat_info info)
    2328              : {
    2329              :   /* Evaluate each operand with unsatisfaction diagnostics disabled.  */
    2330     67441741 :   sat_info sub = info;
    2331     67441741 :   sub.diagnose_unsatisfaction = false;
    2332              : 
    2333     67441741 :   tree lhs = satisfy_constraint_r (TREE_OPERAND (t, 0), args, sub);
    2334     67441741 :   if (lhs == boolean_true_node || lhs == error_mark_node)
    2335              :     return lhs;
    2336              : 
    2337     32486038 :   tree rhs = satisfy_constraint_r (TREE_OPERAND (t, 1), args, sub);
    2338     32486038 :   if (rhs == boolean_true_node || rhs == error_mark_node)
    2339              :     return rhs;
    2340              : 
    2341              :   /* Both branches evaluated to false.  Explain the satisfaction failure in
    2342              :      each branch.  */
    2343      3498472 :   if (info.diagnose_unsatisfaction_p ())
    2344              :     {
    2345           62 :       diagnosing_failed_constraint failure (t, args, info.noisy ());
    2346           62 :       cp_expr disj_expr = CONSTR_EXPR (t);
    2347           62 :       inform (disj_expr.get_location (),
    2348              :               "no operand of the disjunction is satisfied");
    2349           62 :       if (diagnosing_failed_constraint::replay_errors_p ())
    2350              :         {
    2351            8 :           auto_diagnostic_nesting_level sentinel;
    2352              :           /* Replay the error in each branch of the disjunction.  */
    2353            8 :           auto_vec<tree_pair> operands;
    2354            8 :           collect_operands_of_disjunction (t, &operands);
    2355           30 :           for (unsigned i = 0; i < operands.length (); i++)
    2356              :             {
    2357           22 :               tree norm_op = operands[i].first;
    2358           22 :               tree op = operands[i].second;
    2359           22 :               location_t loc = make_location (cp_expr_location (op),
    2360              :                                               disj_expr.get_start (),
    2361              :                                               disj_expr.get_finish ());
    2362           22 :               inform (loc, "the operand %qE is unsatisfied because", op);
    2363           22 :               auto_diagnostic_nesting_level sentinel;
    2364           22 :               satisfy_constraint_r (norm_op, args, info);
    2365           22 :             }
    2366            8 :         }
    2367           62 :     }
    2368              : 
    2369      3498472 :   return boolean_false_node;
    2370              : }
    2371              : 
    2372              : /* Ensures that T is a truth value and not (accidentally, as sometimes
    2373              :    happens) an integer value.  */
    2374              : 
    2375              : tree
    2376     33074229 : satisfaction_value (tree t)
    2377              : {
    2378     33074229 :   if (t == error_mark_node || t == boolean_true_node || t == boolean_false_node)
    2379              :     return t;
    2380              : 
    2381            2 :   gcc_assert (TREE_CODE (t) == INTEGER_CST
    2382              :               && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t),
    2383              :                                                             boolean_type_node));
    2384            2 :   if (integer_zerop (t))
    2385            0 :     return boolean_false_node;
    2386              :   else
    2387            2 :     return boolean_true_node;
    2388              : }
    2389              : 
    2390              : /* Build a new template argument vector corresponding to the parameter
    2391              :    mapping of the atomic constraint T, using arguments from ARGS.  */
    2392              : 
    2393              : static tree
    2394     33083124 : get_mapped_args (tree t, tree args)
    2395              : {
    2396     33083124 :   tree map = ATOMIC_CONSTR_MAP (t);
    2397              : 
    2398              :   /* No map, no arguments.  */
    2399     33083124 :   if (!map)
    2400              :     return NULL_TREE;
    2401              : 
    2402              :   /* Determine the depth of the resulting argument vector.  */
    2403     33082364 :   int depth;
    2404     33082364 :   if (ATOMIC_CONSTR_EXPR_FROM_CONCEPT_P (t))
    2405              :     /* The expression of this atomic constraint comes from a concept
    2406              :        definition, whose template depth is always one, so the resulting
    2407              :        argument vector will also have depth one.  */
    2408              :     depth = 1;
    2409              :   else
    2410              :     /* Otherwise, the expression of this atomic constraint comes from
    2411              :        the context of the constrained entity, whose template depth is that
    2412              :        of ARGS.  */
    2413     24069660 :     depth = TMPL_ARGS_DEPTH (args);
    2414              : 
    2415              :   /* Place each argument at its corresponding position in the argument
    2416              :      list.  Note that the list will be sparse (not all arguments supplied),
    2417              :      but instantiation is guaranteed to only use the parameters in the
    2418              :      mapping, so null arguments would never be used.  */
    2419     33082364 :   auto_vec< vec<tree> > lists (depth);
    2420     33082364 :   lists.quick_grow_cleared (depth);
    2421     83993126 :   for (tree p = map; p; p = TREE_CHAIN (p))
    2422              :     {
    2423     50910762 :       int level;
    2424     50910762 :       int index;
    2425     50910762 :       template_parm_level_and_index (TREE_VALUE (p), &level, &index);
    2426              : 
    2427              :       /* Insert the argument into its corresponding position.  */
    2428     50910762 :       vec<tree> &list = lists[level - 1];
    2429     67828403 :       if (index >= (int)list.length ())
    2430     47031225 :         list.safe_grow_cleared (index + 1, /*exact=*/false);
    2431     50910762 :       list[index] = TREE_PURPOSE (p);
    2432              :     }
    2433              : 
    2434              :   /* Build the new argument list.  */
    2435     33082364 :   args = make_tree_vec (lists.length ());
    2436    135696234 :   for (unsigned i = 0; i != lists.length (); ++i)
    2437              :     {
    2438     34765753 :       vec<tree> &list = lists[i];
    2439     34765753 :       tree level = make_tree_vec (list.length ());
    2440     86815049 :       for (unsigned j = 0; j < list.length (); ++j)
    2441     52049296 :         TREE_VEC_ELT (level, j) = list[j];
    2442     34765753 :       SET_TMPL_ARGS_LEVEL (args, i + 1, level);
    2443     34765753 :       list.release ();
    2444              :     }
    2445     33082364 :   SET_NON_DEFAULT_TEMPLATE_ARGS_COUNT (args, 0);
    2446              : 
    2447     33082364 :   if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)
    2448     33082364 :       && TMPL_ARGS_DEPTH (args) == 1)
    2449              :     {
    2450              :       /* Get rid of the redundant outer TREE_VEC.  */
    2451     31405519 :       tree level = TMPL_ARGS_LEVEL (args, 1);
    2452     31405519 :       ggc_free (args);
    2453     31405519 :       args = level;
    2454              :     }
    2455              : 
    2456     33082364 :   return args;
    2457     33082364 : }
    2458              : 
    2459              : static void diagnose_atomic_constraint (tree, tree, tree, sat_info);
    2460              : 
    2461              : /* Compute the satisfaction of an atomic constraint.  */
    2462              : 
    2463              : static tree
    2464    813888827 : satisfy_atom (tree t, tree args, sat_info info)
    2465              : {
    2466              :   /* In case there is a diagnostic, we want to establish the context
    2467              :      prior to printing errors.  If no errors occur, this context is
    2468              :      removed before returning.  */
    2469    813888827 :   diagnosing_failed_constraint failure (t, args, info.noisy ());
    2470              : 
    2471    813888827 :   satisfaction_cache cache (t, args, info);
    2472    813888827 :   if (tree r = cache.get ())
    2473              :     return r;
    2474              : 
    2475              :   /* Perform substitution quietly.  */
    2476     76512341 :   subst_info quiet (tf_none, NULL_TREE);
    2477              : 
    2478              :   /* Instantiate the parameter mapping.  */
    2479     76512341 :   tree map = tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, quiet);
    2480     76512341 :   if (map == error_mark_node)
    2481              :     {
    2482              :       /* If instantiation of the parameter mapping fails, the constraint is
    2483              :          not satisfied.  Replay the substitution.  */
    2484         3227 :       if (info.diagnose_unsatisfaction_p ())
    2485            8 :         tsubst_parameter_mapping (ATOMIC_CONSTR_MAP (t), args, info);
    2486         3227 :       if (info.quiet ())
    2487              :         /* Since instantiation of the parameter mapping failed, we
    2488              :            want to diagnose potential instability of this satisfaction
    2489              :            result.  */
    2490         3219 :         cache.entry->diagnose_instability = true;
    2491         3227 :       return cache.save (boolean_false_node);
    2492              :     }
    2493              : 
    2494              :   /* Now build a new atom using the instantiated mapping.  We use
    2495              :      this atom as a second key to the satisfaction cache, and we
    2496              :      also pass it to diagnose_atomic_constraint so that diagnostics
    2497              :      which refer to the atom display the instantiated mapping.  */
    2498     76509114 :   t = copy_node (t);
    2499     76509114 :   ATOMIC_CONSTR_MAP (t) = map;
    2500     76509114 :   gcc_assert (!ATOMIC_CONSTR_MAP_INSTANTIATED_P (t));
    2501     76509114 :   ATOMIC_CONSTR_MAP_INSTANTIATED_P (t) = true;
    2502     76509114 :   satisfaction_cache inst_cache (t, /*args=*/NULL_TREE, info);
    2503     76509114 :   if (cache.entry && inst_cache.entry)
    2504     76509111 :     cache.entry->inst_entry = inst_cache.entry;
    2505     76509114 :   if (tree r = inst_cache.get ())
    2506              :     {
    2507     43425990 :       cache.entry->location = inst_cache.entry->location;
    2508     43425990 :       return cache.save (r);
    2509              :     }
    2510              : 
    2511              :   /* Rebuild the argument vector from the parameter mapping.  */
    2512     33083124 :   args = get_mapped_args (t, args);
    2513              : 
    2514              :   /* Apply the parameter mapping (i.e., just substitute).  */
    2515     33083124 :   tree expr = ATOMIC_CONSTR_EXPR (t);
    2516     33083124 :   tree result = tsubst_expr (expr, args, quiet.complain, quiet.in_decl);
    2517     33080424 :   if (result == error_mark_node)
    2518              :     {
    2519              :       /* If substitution results in an invalid type or expression, the
    2520              :          constraint is not satisfied.  Replay the substitution.  */
    2521         6140 :       if (info.diagnose_unsatisfaction_p ())
    2522           20 :         tsubst_expr (expr, args, info.complain, info.in_decl);
    2523         6140 :       return cache.save (inst_cache.save (boolean_false_node));
    2524              :     }
    2525              : 
    2526              :   /* [17.4.1.2] ... lvalue-to-rvalue conversion is performed as necessary,
    2527              :      and EXPR shall be a constant expression of type bool.  */
    2528     33074284 :   result = force_rvalue (result, info.complain);
    2529     33074284 :   if (result == error_mark_node)
    2530            0 :     return cache.save (inst_cache.save (error_mark_node));
    2531     33074284 :   tree substituted = result;
    2532     33074284 :   if (!same_type_p (TREE_TYPE (result), boolean_type_node))
    2533              :     {
    2534           55 :       if (info.noisy ())
    2535           30 :         diagnose_atomic_constraint (t, args, substituted, info);
    2536           55 :       return cache.save (inst_cache.save (error_mark_node));
    2537              :     }
    2538              : 
    2539              :   /* Compute the value of the constraint.  */
    2540     33074229 :   if (info.noisy ())
    2541              :     {
    2542         3576 :       iloc_sentinel ils (EXPR_LOCATION (result));
    2543         3576 :       result = cxx_constant_value (result);
    2544         3576 :     }
    2545              :   else
    2546              :     {
    2547     33070653 :       result = maybe_constant_value (result, NULL_TREE, mce_true);
    2548     33070653 :       if (!TREE_CONSTANT (result))
    2549           22 :         result = error_mark_node;
    2550              :     }
    2551     33074229 :   result = satisfaction_value (result);
    2552     33074229 :   if (result == boolean_false_node && info.diagnose_unsatisfaction_p ())
    2553         1173 :     diagnose_atomic_constraint (t, args, substituted, info);
    2554              : 
    2555     33074229 :   return cache.save (inst_cache.save (result));
    2556    813886127 : }
    2557              : 
    2558              : /* Determine if the normalized constraint T is satisfied.
    2559              :    Returns boolean_true_node if the expression/constraint is
    2560              :    satisfied, boolean_false_node if not, and error_mark_node
    2561              :    if there was an error evaluating the constraint.
    2562              : 
    2563              :    The parameter mapping of atomic constraints is simply the
    2564              :    set of template arguments that will be substituted into
    2565              :    the expression, regardless of template parameters appearing
    2566              :    within.  Whether a template argument is used in the atomic
    2567              :    constraint only matters for subsumption.  */
    2568              : 
    2569              : static tree
    2570   1586431320 : satisfy_constraint_r (tree t, tree args, sat_info info)
    2571              : {
    2572   1586431320 :   if (t == error_mark_node)
    2573              :     return error_mark_node;
    2574              : 
    2575   1586431178 :   switch (TREE_CODE (t))
    2576              :     {
    2577    705100610 :     case CONJ_CONSTR:
    2578    705100610 :       return satisfy_conjunction (t, args, info);
    2579     67441741 :     case DISJ_CONSTR:
    2580     67441741 :       return satisfy_disjunction (t, args, info);
    2581    813888827 :     case ATOMIC_CONSTR:
    2582    813888827 :       return satisfy_atom (t, args, info);
    2583            0 :     default:
    2584            0 :       gcc_unreachable ();
    2585              :     }
    2586              : }
    2587              : 
    2588              : /* Check that the normalized constraint T is satisfied for ARGS.  */
    2589              : 
    2590              : static tree
    2591     85105412 : satisfy_normalized_constraints (tree t, tree args, sat_info info)
    2592              : {
    2593     85105412 :   auto_timevar time (TV_CONSTRAINT_SAT);
    2594              : 
    2595     85105412 :   auto ovr = make_temp_override (satisfying_constraint, true);
    2596              : 
    2597              :   /* Turn off template processing.  Constraint satisfaction only applies
    2598              :      to non-dependent terms, so we want to ensure full checking here.  */
    2599     85105412 :   processing_template_decl_sentinel proc (true);
    2600              : 
    2601              :   /* We need to check access during satisfaction.  */
    2602     85105412 :   deferring_access_check_sentinel acs (dk_no_deferred);
    2603              : 
    2604              :   /* Constraints are unevaluated operands.  */
    2605     85105412 :   cp_unevaluated u;
    2606              : 
    2607     85105412 :   return satisfy_constraint_r (t, args, info);
    2608     85102712 : }
    2609              : 
    2610              : /* Return the normal form of the constraints on the placeholder 'auto'
    2611              :    type T.  */
    2612              : 
    2613              : static tree
    2614     10455762 : normalize_placeholder_type_constraints (tree t, bool diag)
    2615              : {
    2616     10455762 :   gcc_assert (is_auto (t));
    2617     10455762 :   tree ci = PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t);
    2618     10455762 :   if (!ci)
    2619              :     return NULL_TREE;
    2620              : 
    2621     10455762 :   tree constr = TREE_VALUE (ci);
    2622              :   /* The TREE_PURPOSE contains the set of template parameters that were in
    2623              :      scope for this placeholder type; use them as the initial template
    2624              :      parameters for normalization.  */
    2625     10455762 :   tree initial_parms = TREE_PURPOSE (ci);
    2626              : 
    2627              :   /* The 'auto' itself is used as the first argument in its own constraints,
    2628              :      and its level is one greater than its template depth.  So in order to
    2629              :      capture all used template parameters, we need to add an extra level of
    2630              :      template parameters to the context; a dummy level suffices.  */
    2631     10455762 :   initial_parms
    2632     20911283 :     = tree_cons (size_int (initial_parms
    2633              :                            ? TMPL_PARMS_DEPTH (initial_parms) + 1 : 1),
    2634              :                  make_tree_vec (0), initial_parms);
    2635              : 
    2636     10455762 :   norm_info info (diag);
    2637     10455762 :   info.initial_parms = initial_parms;
    2638     10455762 :   return normalize_constraint_expression (constr, info);
    2639              : }
    2640              : 
    2641              : /* Evaluate the constraints of T using ARGS, returning a satisfaction value.
    2642              :    Here, T can be a concept-id, nested-requirement, placeholder 'auto', or
    2643              :    requires-expression.  */
    2644              : 
    2645              : static tree
    2646     15008873 : satisfy_nondeclaration_constraints (tree t, tree args, sat_info info)
    2647              : {
    2648     15008873 :   if (t == error_mark_node)
    2649              :     return error_mark_node;
    2650              : 
    2651              :   /* Handle REQUIRES_EXPR directly, bypassing satisfaction.  */
    2652     15008869 :   if (TREE_CODE (t) == REQUIRES_EXPR)
    2653              :     {
    2654          165 :       auto ovr = make_temp_override (current_constraint_diagnosis_depth);
    2655          165 :       if (info.noisy ())
    2656           35 :         ++current_constraint_diagnosis_depth;
    2657          165 :       return tsubst_requires_expr (t, args, info);
    2658          165 :     }
    2659              : 
    2660              :   /* Get the normalized constraints.  */
    2661     15008704 :   tree norm;
    2662     15008704 :   if (concept_check_p (t))
    2663              :     {
    2664      3582821 :       gcc_assert (!args);
    2665      3582821 :       args = TREE_OPERAND (t, 1);
    2666      3582821 :       tree tmpl = get_concept_check_template (t);
    2667      3582821 :       norm = normalize_concept_definition (tmpl, info.noisy ());
    2668              :     }
    2669     11425883 :   else if (TREE_CODE (t) == NESTED_REQ)
    2670              :     {
    2671       970121 :       norm_info ninfo (info.noisy ());
    2672              :       /* The TREE_TYPE contains the set of template parameters that were in
    2673              :          scope for this nested requirement; use them as the initial template
    2674              :          parameters for normalization.  */
    2675       970121 :       ninfo.initial_parms = TREE_TYPE (t);
    2676       970121 :       norm = normalize_constraint_expression (TREE_OPERAND (t, 0), ninfo);
    2677              :     }
    2678     10455762 :   else if (is_auto (t))
    2679              :     {
    2680     10455762 :       norm = normalize_placeholder_type_constraints (t, info.noisy ());
    2681     10455762 :       if (!norm)
    2682            0 :         return boolean_true_node;
    2683              :     }
    2684              :   else
    2685            0 :     gcc_unreachable ();
    2686              : 
    2687              :   /* Perform satisfaction.  */
    2688     15008704 :   return satisfy_normalized_constraints (norm, args, info);
    2689              : }
    2690              : 
    2691              : /* Evaluate the associated constraints of the template specialization T
    2692              :    according to INFO, returning a satisfaction value.  */
    2693              : 
    2694              : static tree
    2695    859341976 : satisfy_declaration_constraints (tree t, sat_info info)
    2696              : {
    2697    859341976 :   gcc_assert (DECL_P (t) && TREE_CODE (t) != TEMPLATE_DECL);
    2698    859341976 :   const tree saved_t = t;
    2699              : 
    2700              :   /* For inherited constructors, consider the original declaration;
    2701              :      it has the correct template information attached.  */
    2702    859341976 :   t = strip_inheriting_ctors (t);
    2703    859341976 :   tree inh_ctor_targs = NULL_TREE;
    2704    859341976 :   if (t != saved_t)
    2705       370530 :     if (tree ti = DECL_TEMPLATE_INFO (saved_t))
    2706              :       /* The inherited constructor points to an instantiation of a constructor
    2707              :          template; remember its template arguments.  */
    2708        29898 :       inh_ctor_targs = TI_ARGS (ti);
    2709              : 
    2710              :   /* Update the declaration for diagnostics.  */
    2711    859341976 :   info.in_decl = t;
    2712              : 
    2713    859341976 :   if (info.quiet ())
    2714   1718546177 :     if (tree *result = hash_map_safe_get (decl_satisfied_cache, saved_t))
    2715    735961057 :       return *result;
    2716              : 
    2717    123380919 :   tree args = NULL_TREE;
    2718    123380919 :   if (tree ti = DECL_TEMPLATE_INFO (t))
    2719              :     {
    2720              :       /* The initial parameter mapping is the complete set of
    2721              :          template arguments substituted into the declaration.  */
    2722     83835443 :       args = TI_ARGS (ti);
    2723     83835443 :       if (inh_ctor_targs)
    2724        12462 :         args = add_outermost_template_args (args, inh_ctor_targs);
    2725              :     }
    2726              : 
    2727    123380919 :   if (regenerated_lambda_fn_p (t))
    2728              :     {
    2729              :       /* The TI_ARGS of a regenerated lambda contains only the innermost
    2730              :          set of template arguments.  Augment this with the outer template
    2731              :          arguments that were used to regenerate the lambda.  */
    2732      1623646 :       gcc_assert (!args || TMPL_ARGS_DEPTH (args) == 1);
    2733      1040972 :       tree regen_args = lambda_regenerating_args (t);
    2734      1040972 :       if (args)
    2735       582674 :         args = add_to_template_args (regen_args, args);
    2736              :       else
    2737              :         args = regen_args;
    2738              :     }
    2739              : 
    2740              :   /* If the innermost arguments are dependent, or if the outer arguments
    2741              :      are dependent and are needed by the constraints, we can't check
    2742              :      satisfaction yet so pretend they're satisfied for now.  */
    2743    123380919 :   if (uses_template_parms (args)
    2744    123380919 :       && ((DECL_TEMPLATE_INFO (t)
    2745       282095 :            && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))
    2746        94340 :            && (TMPL_ARGS_DEPTH (args) == 1
    2747        22816 :                || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args))))
    2748       257795 :           || uses_outer_template_parms_in_constraints (t)))
    2749        24378 :     return boolean_true_node;
    2750              : 
    2751              :   /* Get the normalized constraints.  */
    2752    123356541 :   tree norm = get_normalized_constraints_from_decl (t, info.noisy ());
    2753              : 
    2754    123356541 :   unsigned ftc_count = vec_safe_length (failed_type_completions);
    2755              : 
    2756    123356541 :   tree result = boolean_true_node;
    2757    123356541 :   if (norm)
    2758              :     {
    2759      3368211 :       if (!push_tinst_level (t))
    2760              :         return result;
    2761      3367753 :       push_to_top_level ();
    2762      3367753 :       push_access_scope (t);
    2763      3367753 :       result = satisfy_normalized_constraints (norm, args, info);
    2764      3367753 :       pop_access_scope (t);
    2765      3367753 :       pop_from_top_level ();
    2766      3367753 :       pop_tinst_level ();
    2767              :     }
    2768              : 
    2769              :   /* True if this satisfaction is (heuristically) potentially unstable, i.e.
    2770              :      if its result may depend on where in the program it was performed.  */
    2771    123356083 :   bool maybe_unstable_satisfaction = false;
    2772    123463626 :   if (ftc_count != vec_safe_length (failed_type_completions))
    2773              :     /* Type completion failure occurred during satisfaction.  The satisfaction
    2774              :        result may (or may not) materially depend on the completeness of a type,
    2775              :        so we consider it potentially unstable.   */
    2776              :     maybe_unstable_satisfaction = true;
    2777              : 
    2778    123356083 :   if (maybe_unstable_satisfaction)
    2779              :     /* Don't cache potentially unstable satisfaction, to allow satisfy_atom
    2780              :        to check the stability the next time around.  */;
    2781    123356083 :   else if (info.quiet ())
    2782    123355993 :     hash_map_safe_put<hm_ggc> (decl_satisfied_cache, saved_t, result);
    2783              : 
    2784    123356083 :   return result;
    2785              : }
    2786              : 
    2787              : /* Evaluate the associated constraints of the template T using ARGS as the
    2788              :    innermost set of template arguments and according to INFO, returning a
    2789              :    satisfaction value.  */
    2790              : 
    2791              : static tree
    2792    466150648 : satisfy_declaration_constraints (tree t, tree args, sat_info info)
    2793              : {
    2794    466150648 :   tree orig_args = args;
    2795              : 
    2796              :   /* Update the declaration for diagnostics.  */
    2797    466150648 :   info.in_decl = t;
    2798              : 
    2799    466150648 :   gcc_assert (TREE_CODE (t) == TEMPLATE_DECL);
    2800              : 
    2801    466150648 :   if (regenerated_lambda_fn_p (t))
    2802              :     {
    2803              :       /* As in the two-parameter version of this function.  */
    2804      1192392 :       gcc_assert (TMPL_ARGS_DEPTH (args) == 1);
    2805       596196 :       tree lambda = CLASSTYPE_LAMBDA_EXPR (DECL_CONTEXT (t));
    2806       596196 :       tree outer_args = TI_ARGS (LAMBDA_EXPR_REGEN_INFO (lambda));
    2807       596196 :       args = add_to_template_args (outer_args, args);
    2808              :     }
    2809              :   else
    2810    465554452 :     args = add_outermost_template_args (t, args);
    2811              : 
    2812              :   /* If the innermost arguments are dependent, or if the outer arguments
    2813              :      are dependent and are needed by the constraints, we can't check
    2814              :      satisfaction yet so pretend they're satisfied for now.  */
    2815    466150648 :   if (uses_template_parms (args)
    2816    579677991 :       && (TMPL_ARGS_DEPTH (args) == 1
    2817      7393308 :           || uses_template_parms (INNERMOST_TEMPLATE_ARGS (args))
    2818       304182 :           || uses_outer_template_parms_in_constraints (t)))
    2819    113223161 :     return boolean_true_node;
    2820              : 
    2821    352927487 :   tree result = boolean_true_node;
    2822    352927487 :   if (tree norm = get_normalized_constraints_from_decl (t, info.noisy ()))
    2823              :     {
    2824     66728955 :       if (!push_tinst_level (t, orig_args))
    2825              :         return result;
    2826     66728955 :       tree pattern = DECL_TEMPLATE_RESULT (t);
    2827     66728955 :       push_to_top_level ();
    2828     66728955 :       push_access_scope (pattern);
    2829     66728955 :       result = satisfy_normalized_constraints (norm, args, info);
    2830     66726255 :       pop_access_scope (pattern);
    2831     66726255 :       pop_from_top_level ();
    2832     66726255 :       pop_tinst_level ();
    2833              :     }
    2834              : 
    2835              :   return result;
    2836              : }
    2837              : 
    2838              : /* A wrapper around satisfy_declaration_constraints and
    2839              :    satisfy_nondeclaration_constraints which additionally replays
    2840              :    quiet ill-formed satisfaction noisily, so that ill-formed
    2841              :    satisfaction always gets diagnosed.  */
    2842              : 
    2843              : static tree
    2844   1340501497 : constraint_satisfaction_value (tree t, tree args, sat_info info)
    2845              : {
    2846   1340501497 :   tree r;
    2847   1340501497 :   if (DECL_P (t))
    2848              :     {
    2849   1325492624 :       if (args)
    2850    466150648 :         r = satisfy_declaration_constraints (t, args, info);
    2851              :       else
    2852    859341976 :         r = satisfy_declaration_constraints (t, info);
    2853              :     }
    2854              :   else
    2855     15008873 :     r = satisfy_nondeclaration_constraints (t, args, info);
    2856          321 :   if (r == error_mark_node && info.quiet ()
    2857   1340498946 :       && !(DECL_P (t) && warning_suppressed_p (t)))
    2858              :     {
    2859              :       /* Replay the error noisily.  */
    2860          149 :       sat_info noisy (tf_warning_or_error, info.in_decl);
    2861          149 :       constraint_satisfaction_value (t, args, noisy);
    2862          149 :       if (DECL_P (t) && !args)
    2863              :         /* Avoid giving these errors again.  */
    2864            0 :         suppress_warning (t);
    2865              :     }
    2866   1340498797 :   return r;
    2867              : }
    2868              : 
    2869              : /* True iff the result of satisfying T using ARGS is BOOLEAN_TRUE_NODE
    2870              :    and false otherwise, even in the case of errors.
    2871              : 
    2872              :    Here, T can be:
    2873              :      - a template declaration
    2874              :      - a template specialization (in which case ARGS must be empty)
    2875              :      - a concept-id (in which case ARGS must be empty)
    2876              :      - a nested-requirement
    2877              :      - a placeholder 'auto'
    2878              :      - a requires-expression.  */
    2879              : 
    2880              : bool
    2881   1337622480 : constraints_satisfied_p (tree t, tree args/*= NULL_TREE */)
    2882              : {
    2883   1337622480 :   if (!flag_concepts)
    2884              :     return true;
    2885              : 
    2886   1335947268 :   sat_info quiet (tf_none, NULL_TREE);
    2887   1335947268 :   return constraint_satisfaction_value (t, args, quiet) == boolean_true_node;
    2888              : }
    2889              : 
    2890              : /* Evaluate a concept check of the form C<ARGS>.  This is only used for the
    2891              :    evaluation of template-ids as id-expressions.  */
    2892              : 
    2893              : tree
    2894      3582548 : evaluate_concept_check (tree check)
    2895              : {
    2896      3582548 :   if (check == error_mark_node)
    2897              :     return error_mark_node;
    2898              : 
    2899      3582548 :   gcc_assert (concept_check_p (check));
    2900              : 
    2901              :   /* We don't want any declarations instantiated from a concept evaluation
    2902              :      to enter the binding table for the current scope, such as lambdas, so
    2903              :      leave that scope.  But maintain the access context (PR104111).  */
    2904      3582548 :   tree scope = current_scope ();
    2905      3582548 :   if (CLASS_TYPE_P (scope))
    2906       745264 :     scope = TYPE_MAIN_DECL (scope);
    2907      2837284 :   else if (TREE_CODE (scope) != FUNCTION_DECL)
    2908       179869 :     scope = NULL_TREE;
    2909              : 
    2910       745264 :   push_to_top_level ();
    2911      3582548 :   if (scope)
    2912      3402679 :     push_access_scope (scope);
    2913              : 
    2914              :   /* Check for satisfaction without diagnostics.  */
    2915      3582548 :   sat_info quiet (tf_none, NULL_TREE);
    2916      3582548 :   tree r = constraint_satisfaction_value (check, /*args=*/NULL_TREE, quiet);
    2917              : 
    2918      3582548 :   if (scope)
    2919      3402679 :     pop_access_scope (scope);
    2920      3582548 :   pop_from_top_level ();
    2921      3582548 :   return r;
    2922              : }
    2923              : 
    2924              : /* Evaluate the requires-expression T, returning either boolean_true_node
    2925              :    or boolean_false_node.  This is used during folding and constexpr
    2926              :    evaluation.  */
    2927              : 
    2928              : tree
    2929          130 : evaluate_requires_expr (tree t)
    2930              : {
    2931          130 :   gcc_assert (TREE_CODE (t) == REQUIRES_EXPR);
    2932          130 :   sat_info quiet (tf_none, NULL_TREE);
    2933          130 :   return constraint_satisfaction_value (t, /*args=*/NULL_TREE, quiet);
    2934              : }
    2935              : 
    2936              : /*---------------------------------------------------------------------------
    2937              :                 Semantic analysis of requires-expressions
    2938              : ---------------------------------------------------------------------------*/
    2939              : 
    2940              : /* Finish a requires expression for the given PARMS (possibly
    2941              :    null) and the non-empty sequence of requirements.  */
    2942              : 
    2943              : tree
    2944      2764521 : finish_requires_expr (location_t loc, tree parms, tree reqs)
    2945              : {
    2946              :   /* Build the node.  */
    2947      2764521 :   tree r = build_min (REQUIRES_EXPR, boolean_type_node, parms, reqs, NULL_TREE);
    2948      2764521 :   TREE_SIDE_EFFECTS (r) = false;
    2949      2764521 :   TREE_CONSTANT (r) = true;
    2950      2764521 :   SET_EXPR_LOCATION (r, loc);
    2951      2764521 :   return r;
    2952              : }
    2953              : 
    2954              : /* Construct a requirement for the validity of EXPR.   */
    2955              : 
    2956              : tree
    2957      1471028 : finish_simple_requirement (location_t loc, tree expr)
    2958              : {
    2959      1471028 :   tree r = build_nt (SIMPLE_REQ, expr);
    2960      1471028 :   SET_EXPR_LOCATION (r, loc);
    2961      1471028 :   return r;
    2962              : }
    2963              : 
    2964              : /* Construct a requirement for the validity of TYPE.  */
    2965              : 
    2966              : tree
    2967       728473 : finish_type_requirement (location_t loc, tree type)
    2968              : {
    2969       728473 :   tree r = build_nt (TYPE_REQ, type);
    2970       728473 :   SET_EXPR_LOCATION (r, loc);
    2971       728473 :   return r;
    2972              : }
    2973              : 
    2974              : /* Construct a requirement for the validity of EXPR, along with
    2975              :    its properties.  If TYPE is non-null, then it specifies either
    2976              :    an implicit conversion or argument deduction constraint,
    2977              :    depending on whether any placeholders occur in the type name.
    2978              :    NOEXCEPT_P is true iff the noexcept keyword was specified.  */
    2979              : 
    2980              : tree
    2981      1398714 : finish_compound_requirement (location_t loc, tree expr, tree type, bool noexcept_p)
    2982              : {
    2983      1398714 :   tree req = build_nt (COMPOUND_REQ, expr, type);
    2984      1398714 :   SET_EXPR_LOCATION (req, loc);
    2985      1398714 :   COMPOUND_REQ_NOEXCEPT_P (req) = noexcept_p;
    2986      1398714 :   return req;
    2987              : }
    2988              : 
    2989              : /* Finish a nested requirement.  */
    2990              : 
    2991              : tree
    2992       231279 : finish_nested_requirement (location_t loc, tree expr)
    2993              : {
    2994              :   /* Build the requirement, saving the set of in-scope template
    2995              :      parameters as its type.  */
    2996       231279 :   tree r = build1 (NESTED_REQ, current_template_parms, expr);
    2997       231279 :   SET_EXPR_LOCATION (r, loc);
    2998       231279 :   return r;
    2999              : }
    3000              : 
    3001              : /*---------------------------------------------------------------------------
    3002              :                         Equivalence of constraints
    3003              : ---------------------------------------------------------------------------*/
    3004              : 
    3005              : /* Returns true when A and B are equivalent constraints.  */
    3006              : bool
    3007     28278076 : equivalent_constraints (tree a, tree b)
    3008              : {
    3009     28278076 :   gcc_assert (!a || TREE_CODE (a) == CONSTRAINT_INFO);
    3010     28278076 :   gcc_assert (!b || TREE_CODE (b) == CONSTRAINT_INFO);
    3011     28278076 :   return cp_tree_equal (a, b);
    3012              : }
    3013              : 
    3014              : /* Returns true if the template declarations A and B have equivalent
    3015              :    constraints.  This is the case when A's constraints subsume B's and
    3016              :    when B's also constrain A's.  */
    3017              : bool
    3018          146 : equivalently_constrained (tree d1, tree d2)
    3019              : {
    3020          146 :   gcc_assert (TREE_CODE (d1) == TREE_CODE (d2));
    3021          146 :   return equivalent_constraints (get_constraints (d1), get_constraints (d2));
    3022              : }
    3023              : 
    3024              : /*---------------------------------------------------------------------------
    3025              :                      Partial ordering of constraints
    3026              : ---------------------------------------------------------------------------*/
    3027              : 
    3028              : /* Returns true when the constraints in CI strictly subsume
    3029              :    the associated constraints of TMPL.  */
    3030              : 
    3031              : bool
    3032       635269 : strictly_subsumes (tree ci, tree tmpl)
    3033              : {
    3034       635269 :   tree n1 = get_normalized_constraints_from_info (ci, NULL_TREE);
    3035       635269 :   tree n2 = get_normalized_constraints_from_decl (tmpl);
    3036              : 
    3037       635269 :   return subsumes (n1, n2) && !subsumes (n2, n1);
    3038              : }
    3039              : 
    3040              : /* Returns true when the template template parameter constraints in CI
    3041              :    subsume the associated constraints of the template template argument
    3042              :    TMPL.  */
    3043              : 
    3044              : bool
    3045           87 : ttp_subsumes (tree ci, tree tmpl)
    3046              : {
    3047           87 :   tree n1 = get_normalized_constraints_from_info (ci, tmpl);
    3048           87 :   tree n2 = get_normalized_constraints_from_decl (tmpl);
    3049              : 
    3050           87 :   return subsumes (n1, n2);
    3051              : }
    3052              : 
    3053              : /* Determines which of the declarations, A or B, is more constrained.
    3054              :    That is, which declaration's constraints subsume but are not subsumed
    3055              :    by the other's?
    3056              : 
    3057              :    Returns 1 if D1 is more constrained than D2, -1 if D2 is more constrained
    3058              :    than D1, and 0 otherwise.  */
    3059              : 
    3060              : int
    3061      3572566 : more_constrained (tree d1, tree d2)
    3062              : {
    3063      3572566 :   tree n1 = get_normalized_constraints_from_decl (d1);
    3064      3572566 :   tree n2 = get_normalized_constraints_from_decl (d2);
    3065              : 
    3066      3572566 :   int winner = 0;
    3067      3572566 :   if (subsumes (n1, n2))
    3068      3275706 :     ++winner;
    3069      3572566 :   if (subsumes (n2, n1))
    3070      2466570 :     --winner;
    3071      3572566 :   return winner;
    3072              : }
    3073              : 
    3074              : /* Return whether D1 is at least as constrained as D2.  */
    3075              : 
    3076              : bool
    3077      7538482 : at_least_as_constrained (tree d1, tree d2)
    3078              : {
    3079      7538482 :   tree n1 = get_normalized_constraints_from_decl (d1);
    3080      7538482 :   tree n2 = get_normalized_constraints_from_decl (d2);
    3081              : 
    3082      7538482 :   return subsumes (n1, n2);
    3083              : }
    3084              : 
    3085              : /*---------------------------------------------------------------------------
    3086              :                         Constraint diagnostics
    3087              : ---------------------------------------------------------------------------*/
    3088              : 
    3089              : /* Returns the best location to diagnose a constraint error.  */
    3090              : 
    3091              : static location_t
    3092         1203 : get_constraint_error_location (tree t)
    3093              : {
    3094         1203 :   if (location_t loc = cp_expr_location (t))
    3095              :     return loc;
    3096              : 
    3097              :   /* If we have a specific location give it.  */
    3098         1203 :   tree expr = CONSTR_EXPR (t);
    3099         1203 :   if (location_t loc = cp_expr_location (expr))
    3100              :     return loc;
    3101              : 
    3102              :   /* If the constraint is normalized from a requires-clause, give
    3103              :      the location as that of the constrained declaration.  */
    3104           80 :   tree cxt = CONSTR_CONTEXT (t);
    3105           80 :   tree src = cxt ? TREE_VALUE (cxt) : NULL_TREE;
    3106           78 :   if (!src)
    3107              :     /* TODO: This only happens for constrained non-template declarations.  */
    3108              :     ;
    3109           78 :   else if (DECL_P (src))
    3110           63 :     return DECL_SOURCE_LOCATION (src);
    3111              :   /* Otherwise, give the location as the defining concept.  */
    3112           15 :   else if (concept_check_p (src))
    3113              :     {
    3114           15 :       tree tmpl = TREE_OPERAND (src, 0);
    3115           15 :       return DECL_SOURCE_LOCATION (tmpl);
    3116              :     }
    3117              : 
    3118            2 :   return input_location;
    3119              : }
    3120              : 
    3121              : /* Emit a diagnostic for a failed trait.  */
    3122              : 
    3123              : void
    3124          783 : diagnose_trait_expr (location_t loc, tree expr, tree args)
    3125              : {
    3126              :   /* Build a "fake" version of the instantiated trait, so we can
    3127              :      get the instantiated types from result.  */
    3128          783 :   ++processing_template_decl;
    3129          783 :   expr = tsubst_expr (expr, args, tf_none, NULL_TREE);
    3130          783 :   --processing_template_decl;
    3131              : 
    3132          783 :   tree t1 = TRAIT_EXPR_TYPE1 (expr);
    3133          783 :   tree t2 = TRAIT_EXPR_TYPE2 (expr);
    3134          783 :   gcc_checking_assert (t1 != error_mark_node && t2 != error_mark_node);
    3135              : 
    3136          783 :   iloc_sentinel ils (loc);
    3137              : 
    3138              :   /* For traits intrinsically about the properties of user-defined types,
    3139              :      decl_loc will point to the declaration of that type.  */
    3140          783 :   location_t decl_loc = location_of (t1);
    3141          783 :   if (decl_loc == input_location)
    3142          511 :     decl_loc = loc;
    3143              : 
    3144          783 :   switch (TRAIT_EXPR_KIND (expr))
    3145              :     {
    3146            4 :     case CPTK_HAS_NOTHROW_ASSIGN:
    3147            4 :       inform (decl_loc, "%qT is not nothrow copy assignable", t1);
    3148            4 :       break;
    3149            4 :     case CPTK_HAS_NOTHROW_CONSTRUCTOR:
    3150            4 :       inform (decl_loc, "%qT is not nothrow default constructible", t1);
    3151            4 :       break;
    3152            4 :     case CPTK_HAS_NOTHROW_COPY:
    3153            4 :       inform (decl_loc, "%qT is not nothrow copy constructible", t1);
    3154            4 :       break;
    3155            4 :     case CPTK_HAS_TRIVIAL_ASSIGN:
    3156            4 :       inform (decl_loc, "%qT is not trivially copy assignable", t1);
    3157            4 :       break;
    3158            4 :     case CPTK_HAS_TRIVIAL_CONSTRUCTOR:
    3159            4 :       inform (decl_loc, "%qT is not trivially default constructible", t1);
    3160            4 :       break;
    3161            4 :     case CPTK_HAS_TRIVIAL_COPY:
    3162            4 :       inform (decl_loc, "%qT is not trivially copy constructible", t1);
    3163            4 :       break;
    3164            4 :     case CPTK_HAS_TRIVIAL_DESTRUCTOR:
    3165            4 :       inform (decl_loc, "%qT is not trivially destructible", t1);
    3166            4 :       break;
    3167           30 :     case CPTK_HAS_UNIQUE_OBJ_REPRESENTATIONS:
    3168           30 :       inform (decl_loc, "%qT does not have unique object "
    3169              :               "representations, because", t1);
    3170           30 :       type_has_unique_obj_representations (t1, /*explain=*/true);
    3171           30 :       break;
    3172           19 :     case CPTK_HAS_VIRTUAL_DESTRUCTOR:
    3173           19 :       {
    3174           19 :         location_t dtor_loc = decl_loc;
    3175           19 :         if (NON_UNION_CLASS_TYPE_P (t1))
    3176            6 :           if (tree dtor = CLASSTYPE_DESTRUCTOR (t1))
    3177            3 :             dtor_loc = DECL_SOURCE_LOCATION (dtor);
    3178           19 :         inform (dtor_loc, "%qT does not have a virtual destructor", t1);
    3179              :       }
    3180           19 :       break;
    3181            4 :     case CPTK_IS_ABSTRACT:
    3182            4 :       inform (decl_loc, "%qT is not an abstract class", t1);
    3183            4 :       break;
    3184            3 :     case CPTK_IS_AGGREGATE:
    3185            3 :       inform (decl_loc, "%qT is not an aggregate", t1);
    3186            3 :       break;
    3187            0 :     case CPTK_IS_ARRAY:
    3188            0 :       inform (loc, "%qT is not an array", t1);
    3189            0 :       break;
    3190           15 :     case CPTK_IS_ASSIGNABLE:
    3191           15 :       inform (loc, "%qT is not assignable from %qT, because", t1, t2);
    3192           15 :       is_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3193           15 :       break;
    3194            1 :     case CPTK_IS_BASE_OF:
    3195            1 :       inform (location_of (t2), "%qT is not a base of %qT", t1, t2);
    3196            1 :       break;
    3197            0 :     case CPTK_IS_BOUNDED_ARRAY:
    3198            0 :       inform (loc, "%qT is not a bounded array", t1);
    3199            0 :       break;
    3200          103 :     case CPTK_IS_CLASS:
    3201          103 :       inform (decl_loc, "%qT is not a class", t1);
    3202          103 :       break;
    3203            0 :     case CPTK_IS_CONST:
    3204            0 :       inform (loc, "%qT is not a const type", t1);
    3205            0 :       break;
    3206          135 :     case CPTK_IS_CONSTRUCTIBLE:
    3207          135 :       if (!TREE_VEC_LENGTH (t2))
    3208           76 :         inform (loc, "%qT is not default constructible, because", t1);
    3209              :       else
    3210           59 :         inform (loc, "%qT is not constructible from %qT, because", t1, t2);
    3211          135 :       is_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3212          135 :       break;
    3213           17 :     case CPTK_IS_CONVERTIBLE:
    3214              :       /* The errors produced here all seem to mention "convertible" in the
    3215              :          diagnostic, so an extra inform here appears redundant.  */
    3216           17 :       is_convertible (t1, t2, /*explain=*/true);
    3217           17 :       break;
    3218           12 :     case CPTK_IS_DESTRUCTIBLE:
    3219           12 :       inform (loc, "%qT is not destructible, because", t1);
    3220           12 :       is_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3221           12 :       break;
    3222            4 :     case CPTK_IS_EMPTY:
    3223            4 :       inform (decl_loc, "%qT is not an empty class", t1);
    3224            4 :       break;
    3225            0 :     case CPTK_IS_ENUM:
    3226            0 :       inform (decl_loc, "%qT is not an enum", t1);
    3227            0 :       break;
    3228            4 :     case CPTK_IS_FINAL:
    3229            4 :       inform (decl_loc, "%qT is not a final class", t1);
    3230            4 :       break;
    3231            0 :     case CPTK_IS_FUNCTION:
    3232            0 :       inform (loc, "%qT is not a function", t1);
    3233            0 :       break;
    3234            0 :     case CPTK_IS_IMPLICIT_LIFETIME:
    3235            0 :       inform (decl_loc, "%qT is not an implicit-lifetime type", t1);
    3236            0 :       break;
    3237           20 :     case CPTK_IS_INVOCABLE:
    3238           20 :       {
    3239           20 :         if (!TREE_VEC_LENGTH (t2))
    3240           11 :           inform (loc, "%qT is not invocable, because", t1);
    3241              :         else
    3242            9 :           inform (loc, "%qT is not invocable by %qT, because", t1, t2);
    3243           20 :         build_invoke (t1, t2, tf_error);
    3244              :       }
    3245           20 :       break;
    3246           24 :     case CPTK_IS_LAYOUT_COMPATIBLE:
    3247           24 :       inform (loc, "%qT is not layout compatible with %qT, because", t1, t2);
    3248           24 :       layout_compatible_type_p (t1, t2, /*explain=*/true);
    3249           24 :       break;
    3250            0 :     case CPTK_IS_LITERAL_TYPE:
    3251            0 :       inform (decl_loc, "%qT is not a literal type", t1);
    3252            0 :       break;
    3253            0 :     case CPTK_IS_MEMBER_FUNCTION_POINTER:
    3254            0 :       inform (loc, "%qT is not a member function pointer", t1);
    3255            0 :       break;
    3256            0 :     case CPTK_IS_MEMBER_OBJECT_POINTER:
    3257            0 :       inform (loc, "%qT is not a member object pointer", t1);
    3258            0 :       break;
    3259            0 :     case CPTK_IS_MEMBER_POINTER:
    3260            0 :       inform (loc, "%qT is not a member pointer", t1);
    3261            0 :       break;
    3262            6 :     case CPTK_IS_NOTHROW_ASSIGNABLE:
    3263            6 :       inform (loc, "%qT is not nothrow assignable from %qT, because", t1, t2);
    3264            6 :       is_nothrow_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3265            6 :       break;
    3266           15 :     case CPTK_IS_NOTHROW_CONSTRUCTIBLE:
    3267           15 :       if (!TREE_VEC_LENGTH (t2))
    3268            6 :         inform (loc, "%qT is not nothrow default constructible, because", t1);
    3269              :       else
    3270            9 :         inform (loc, "%qT is not nothrow constructible from %qT, because",
    3271              :                 t1, t2);
    3272           15 :       is_nothrow_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3273           15 :       break;
    3274            6 :     case CPTK_IS_NOTHROW_CONVERTIBLE:
    3275            6 :       inform (loc, "%qT is not nothrow convertible from %qT, because", t1, t2);
    3276            6 :       is_nothrow_convertible (t1, t2, /*explain=*/true);
    3277            6 :       break;
    3278            8 :     case CPTK_IS_NOTHROW_DESTRUCTIBLE:
    3279            8 :       inform (loc, "%qT is not nothrow destructible, because", t1);
    3280            8 :       is_nothrow_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3281            8 :       break;
    3282            9 :     case CPTK_IS_NOTHROW_INVOCABLE:
    3283            9 :       {
    3284            9 :         if (!TREE_VEC_LENGTH (t2))
    3285            6 :           inform (loc, "%qT is not nothrow invocable, because", t1);
    3286              :         else
    3287            3 :           inform (loc, "%qT is not nothrow invocable by %qT, because", t1, t2);
    3288            9 :         tree call = build_invoke (t1, t2, tf_error);
    3289            9 :         if (call != error_mark_node)
    3290            9 :           explain_not_noexcept (call);
    3291              :       }
    3292              :       break;
    3293           46 :     case CPTK_IS_OBJECT:
    3294           46 :       inform (loc, "%qT is not an object type", t1);
    3295           46 :       break;
    3296           15 :     case CPTK_IS_POINTER_INTERCONVERTIBLE_BASE_OF:
    3297           15 :       inform (location_of (t2),
    3298              :               "%qT is not a pointer-interconvertible base of %qT, because",
    3299              :               t1, t2);
    3300           15 :       pointer_interconvertible_base_of_p (t1, t2, /*explain=*/true);
    3301           15 :       break;
    3302            4 :     case CPTK_IS_POD:
    3303            4 :       inform (loc, "%qT is not a POD type", t1);
    3304            4 :       break;
    3305            0 :     case CPTK_IS_POINTER:
    3306            0 :       inform (loc, "%qT is not a pointer", t1);
    3307            0 :       break;
    3308            4 :     case CPTK_IS_POLYMORPHIC:
    3309            4 :       inform (decl_loc, "%qT is not a polymorphic type", t1);
    3310            4 :       break;
    3311            0 :     case CPTK_IS_REFERENCE:
    3312            0 :       inform (loc, "%qT is not a reference", t1);
    3313            0 :       break;
    3314          178 :     case CPTK_IS_SAME:
    3315          178 :       inform (loc, "%q#T is not the same as %q#T", t1, t2);
    3316          178 :       break;
    3317            0 :     case CPTK_IS_SCOPED_ENUM:
    3318            0 :       inform (decl_loc, "%qT is not a scoped enum", t1);
    3319            0 :       break;
    3320            4 :     case CPTK_IS_STD_LAYOUT:
    3321            4 :       inform (decl_loc, "%qT is not a standard layout type", t1);
    3322            4 :       break;
    3323            4 :     case CPTK_IS_TRIVIAL:
    3324            4 :       inform (decl_loc, "%qT is not a trivial type", t1);
    3325            4 :       break;
    3326            6 :     case CPTK_IS_TRIVIALLY_ASSIGNABLE:
    3327            6 :       inform (loc, "%qT is not trivially assignable from %qT, because", t1, t2);
    3328            6 :       is_trivially_xible (MODIFY_EXPR, t1, t2, /*explain=*/true);
    3329            6 :       break;
    3330           15 :     case CPTK_IS_TRIVIALLY_CONSTRUCTIBLE:
    3331           15 :       if (!TREE_VEC_LENGTH (t2))
    3332            6 :         inform (loc, "%qT is not trivially default constructible, because", t1);
    3333              :       else
    3334            9 :         inform (loc, "%qT is not trivially constructible from %qT, because",
    3335              :                 t1, t2);
    3336           15 :       is_trivially_xible (INIT_EXPR, t1, t2, /*explain=*/true);
    3337           15 :       break;
    3338            7 :     case CPTK_IS_TRIVIALLY_COPYABLE:
    3339            7 :       inform (decl_loc, "%qT is not trivially copyable", t1);
    3340            7 :       break;
    3341            6 :     case CPTK_IS_TRIVIALLY_DESTRUCTIBLE:
    3342            6 :       inform (loc, "%qT is not trivially destructible, because", t1);
    3343            6 :       is_trivially_xible (BIT_NOT_EXPR, t1, NULL_TREE, /*explain=*/true);
    3344            6 :       break;
    3345            0 :     case CPTK_IS_UNBOUNDED_ARRAY:
    3346            0 :       inform (loc, "%qT is not an unbounded array", t1);
    3347            0 :       break;
    3348            4 :     case CPTK_IS_UNION:
    3349            4 :       inform (decl_loc, "%qT is not a union", t1);
    3350            4 :       break;
    3351            6 :     case CPTK_IS_VIRTUAL_BASE_OF:
    3352            6 :       inform (location_of (t2), "%qT is not a virtual base of %qT", t1, t2);
    3353            6 :       break;
    3354            0 :     case CPTK_IS_VOLATILE:
    3355            0 :       inform (loc, "%qT is not a volatile type", t1);
    3356            0 :       break;
    3357            0 :     case CPTK_IS_CONSTEVAL_ONLY:
    3358            0 :       inform (decl_loc, "%qT is not consteval-only", t1);
    3359            0 :       break;
    3360            0 :     case CPTK_RANK:
    3361            0 :       inform (loc, "%qT cannot yield a rank", t1);
    3362            0 :       break;
    3363            0 :     case CPTK_TYPE_ORDER:
    3364            0 :       inform (loc, "%qT and %qT cannot be ordered", t1, t2);
    3365            0 :       break;
    3366            0 :     case CPTK_STRUCTURED_BINDING_SIZE:
    3367            0 :       inform (loc, "%qT is not destructurable", t1);
    3368            0 :       break;
    3369            0 :     case CPTK_REF_CONSTRUCTS_FROM_TEMPORARY:
    3370            0 :       inform (loc, "%qT is not a reference that binds to a temporary "
    3371              :               "object of type %qT (direct-initialization)", t1, t2);
    3372            0 :       break;
    3373            0 :     case CPTK_REF_CONVERTS_FROM_TEMPORARY:
    3374            0 :       inform (loc, "%qT is not a reference that binds to a temporary "
    3375              :               "object of type %qT (copy-initialization)", t1, t2);
    3376            0 :       break;
    3377           21 :     case CPTK_IS_DEDUCIBLE:
    3378           21 :       inform (loc, "%qD is not deducible from %qT", t1, t2);
    3379           21 :       break;
    3380              : #define DEFTRAIT_TYPE(CODE, NAME, ARITY) \
    3381              :     case CPTK_##CODE:
    3382              : #include "cp-trait.def"
    3383              : #undef DEFTRAIT_TYPE
    3384              :       /* Type-yielding traits aren't expressions.  */
    3385            0 :       gcc_unreachable ();
    3386              :     /* We deliberately omit the default case so that when adding a new
    3387              :        trait we'll get reminded (by way of a warning) to handle it here.  */
    3388              :     }
    3389          783 : }
    3390              : 
    3391              : /* Attempt to detect if this is a standard type trait, defined in terms
    3392              :    of a compiler builtin (above).  If so, this will allow us to provide
    3393              :    more helpful diagnostics.   */
    3394              : 
    3395              : bool
    3396         1811 : maybe_diagnose_standard_trait (location_t loc, tree expr)
    3397              : {
    3398         1811 :   gcc_assert (TREE_CODE (expr) != TRAIT_EXPR);
    3399         1811 :   expr = tree_strip_nop_conversions (expr);
    3400              : 
    3401              :   /* TODO: in some cases it would be possible to provide more helpful
    3402              :      diagnostics for negations of traits, e.g. '!is_same_v<T1, T2>'.  */
    3403              : 
    3404         1811 :   tree args = NULL_TREE;
    3405         1811 :   if (VAR_P (expr) && DECL_LANG_SPECIFIC (expr) && DECL_USE_TEMPLATE (expr))
    3406              :     {
    3407          801 :       tree tinfo = DECL_TEMPLATE_INFO (expr);
    3408          801 :       if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (tinfo)) && TI_PARTIAL_INFO (tinfo))
    3409           12 :         tinfo = TI_PARTIAL_INFO (tinfo);
    3410          789 :       else if (DECL_TEMPLATE_SPECIALIZATION (expr))
    3411              :         /* In an explicit specialisation we no longer know what the original
    3412              :            initializer looked like.  */
    3413              :         tinfo = NULL_TREE;
    3414              : 
    3415          792 :       if (tinfo)
    3416              :         {
    3417          792 :           expr = DECL_INITIAL (DECL_TEMPLATE_RESULT (TI_TEMPLATE (tinfo)));
    3418          792 :           args = TI_ARGS (tinfo);
    3419              :         }
    3420              :     }
    3421              : 
    3422         1811 :   if (expr && TREE_CODE (expr) == TRAIT_EXPR)
    3423              :     {
    3424          410 :       diagnose_trait_expr (loc, expr, args);
    3425          410 :       return true;
    3426              :     }
    3427              : 
    3428              :   return false;
    3429              : }
    3430              : 
    3431              : /* Diagnose a substitution failure in the atomic constraint T using ARGS.  */
    3432              : 
    3433              : static void
    3434         1203 : diagnose_atomic_constraint (tree t, tree args, tree substituted, sat_info info)
    3435              : {
    3436              :   /* If the constraint is already ill-formed, we've previously diagnosed
    3437              :      the reason.  We should still say why the constraints aren't satisfied.  */
    3438         1203 :   if (t == error_mark_node)
    3439              :     {
    3440            0 :       location_t loc;
    3441            0 :       if (info.in_decl)
    3442            0 :         loc = DECL_SOURCE_LOCATION (info.in_decl);
    3443              :       else
    3444            0 :         loc = input_location;
    3445            0 :       inform (loc, "invalid constraints");
    3446            0 :       return;
    3447              :     }
    3448              : 
    3449         1203 :   location_t loc = get_constraint_error_location (t);
    3450         1203 :   iloc_sentinel loc_s (loc);
    3451              : 
    3452              :   /* Generate better diagnostics for certain kinds of expressions.  */
    3453         1203 :   tree expr = ATOMIC_CONSTR_EXPR (t);
    3454         1203 :   STRIP_ANY_LOCATION_WRAPPER (expr);
    3455              : 
    3456         1203 :   if (TREE_CODE (expr) == REQUIRES_EXPR)
    3457              :     {
    3458          288 :       gcc_checking_assert (info.diagnose_unsatisfaction_p ());
    3459              :       /* Clear in_decl before replaying the substitution to avoid emitting
    3460              :          seemingly unhelpful "in declaration ..." notes that follow some
    3461              :          substitution failure error messages.  */
    3462          288 :       info.in_decl = NULL_TREE;
    3463          288 :       tsubst_requires_expr (expr, args, info);
    3464              :     }
    3465          915 :   else if (!same_type_p (TREE_TYPE (substituted), boolean_type_node))
    3466           30 :     error_at (loc, "constraint %qE has type %qT, not %<bool%>",
    3467           30 :               t, TREE_TYPE (substituted));
    3468              :   else
    3469              :     {
    3470          885 :       inform (loc, "the expression %qE evaluated to %<false%>", t);
    3471          885 :       if (TREE_CODE (expr) == TRAIT_EXPR)
    3472          373 :         diagnose_trait_expr (loc, expr, args);
    3473              :       else
    3474          512 :         maybe_diagnose_standard_trait (loc, substituted);
    3475              :     }
    3476         1203 : }
    3477              : 
    3478              : GTY(()) tree current_failed_constraint;
    3479              : 
    3480    813888889 : diagnosing_failed_constraint::
    3481    813888889 : diagnosing_failed_constraint (tree t, tree args, bool diag)
    3482    813888889 :   : diagnosing_error (diag)
    3483              : {
    3484    813888889 :   if (diagnosing_error)
    3485              :     {
    3486         3723 :       current_failed_constraint
    3487         3723 :         = tree_cons (args, t, current_failed_constraint);
    3488         3723 :       ++current_constraint_diagnosis_depth;
    3489              :     }
    3490    813888889 : }
    3491              : 
    3492    813886189 : diagnosing_failed_constraint::
    3493              : ~diagnosing_failed_constraint ()
    3494              : {
    3495    813886189 :   if (diagnosing_error)
    3496              :     {
    3497         3723 :       --current_constraint_diagnosis_depth;
    3498         3723 :       if (current_failed_constraint)
    3499         2372 :         current_failed_constraint = TREE_CHAIN (current_failed_constraint);
    3500              :     }
    3501              : 
    3502    813886189 : }
    3503              : 
    3504              : /* Whether we are allowed to replay an error that underlies a constraint failure
    3505              :    at the current diagnosis depth.  */
    3506              : 
    3507              : bool
    3508          397 : diagnosing_failed_constraint::replay_errors_p ()
    3509              : {
    3510          397 :   if (current_constraint_diagnosis_depth >= concepts_diagnostics_max_depth)
    3511              :     {
    3512          338 :       concepts_diagnostics_max_depth_exceeded_p = true;
    3513          338 :       return false;
    3514              :     }
    3515              :   else
    3516              :     return true;
    3517              : }
    3518              : 
    3519              : /* Emit diagnostics detailing the failure ARGS to satisfy the constraints
    3520              :    of T.  Here, T and ARGS are as in constraints_satisfied_p.  */
    3521              : 
    3522              : void
    3523         1293 : diagnose_constraints (location_t loc, tree t, tree args)
    3524              : {
    3525         1293 :   inform (loc, "constraints not satisfied");
    3526              : 
    3527         1293 :   if (concepts_diagnostics_max_depth == 0)
    3528            0 :     return;
    3529              : 
    3530         1293 :   auto_diagnostic_nesting_level sentinel;
    3531              : 
    3532              :   /* Replay satisfaction, but diagnose unsatisfaction.  */
    3533         1293 :   sat_info noisy (tf_warning_or_error, NULL_TREE, /*diag_unsat=*/true);
    3534         1293 :   constraint_satisfaction_value (t, args, noisy);
    3535              : 
    3536         1293 :   static bool suggested_p;
    3537         1293 :   if (concepts_diagnostics_max_depth_exceeded_p
    3538          347 :       && current_constraint_diagnosis_depth == 0
    3539          344 :       && !suggested_p)
    3540              :     {
    3541          140 :       inform (UNKNOWN_LOCATION,
    3542              :               "set %qs to at least %d for more detail",
    3543              :               "-fconcepts-diagnostics-depth=",
    3544          140 :               concepts_diagnostics_max_depth + 1);
    3545          140 :       suggested_p = true;
    3546              :     }
    3547         1293 : }
    3548              : 
    3549              : #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.