LCOV - code coverage report
Current view: top level - gcc/cp - cp-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.2 % 2305 2172
Test Date: 2026-08-22 16:33:35 Functions: 100.0 % 82 82
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* C++-specific tree lowering bits; see also c-gimplify.cc and gimple.cc.
       2              : 
       3              :    Copyright (C) 2002-2026 Free Software Foundation, Inc.
       4              :    Contributed by Jason Merrill <jason@redhat.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify it under
       9              : the terms of the GNU General Public License as published by the Free
      10              : Software Foundation; either version 3, or (at your option) any later
      11              : version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      14              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      15              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      16              : for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #include "config.h"
      23              : #include "system.h"
      24              : #include "coretypes.h"
      25              : #include "target.h"
      26              : #include "basic-block.h"
      27              : #include "cp-tree.h"
      28              : #include "gimple.h"
      29              : #include "predict.h"
      30              : #include "stor-layout.h"
      31              : #include "tree-iterator.h"
      32              : #include "gimplify.h"
      33              : #include "c-family/c-ubsan.h"
      34              : #include "stringpool.h"
      35              : #include "attribs.h"
      36              : #include "asan.h"
      37              : #include "gcc-rich-location.h"
      38              : #include "memmodel.h"
      39              : #include "tm_p.h"
      40              : #include "output.h"
      41              : #include "file-prefix-map.h"
      42              : #include "cgraph.h"
      43              : #include "omp-general.h"
      44              : #include "opts.h"
      45              : #include "gcc-urlifier.h"
      46              : #include "contracts.h" // build_contract_check ()
      47              : #include "builtins.h"
      48              : 
      49              : /* Keep track of forward references to immediate-escalating functions in
      50              :    case they become consteval.  This vector contains ADDR_EXPRs and
      51              :    PTRMEM_CSTs; it also stores FUNCTION_DECLs that had an escalating
      52              :    function call in them, to check that they can be evaluated to a constant,
      53              :    and immediate-escalating functions that may become consteval.  */
      54              : static GTY(()) hash_set<tree> *deferred_escalating_exprs;
      55              : 
      56              : static void
      57     26506937 : remember_escalating_expr (tree t)
      58              : {
      59     26506937 :   if (uses_template_parms (t))
      60              :     /* Templates don't escalate, and cp_fold_immediate can get confused by
      61              :        other template trees in the function body (c++/115986).  */
      62              :     return;
      63     26506937 :   if (!deferred_escalating_exprs)
      64        19920 :     deferred_escalating_exprs = hash_set<tree>::create_ggc (37);
      65     26506937 :   deferred_escalating_exprs->add (t);
      66              : }
      67              : 
      68              : /* Flags for cp_fold and cp_fold_r.  */
      69              : 
      70              : enum fold_flags {
      71              :   ff_none = 0,
      72              :   /* Whether we're being called from cp_fold_function.  */
      73              :   ff_genericize = 1 << 0,
      74              :   /* Whether we're folding a point where we know we're
      75              :      definitely not in a manifestly constant-evaluated
      76              :      context.  */
      77              :   ff_mce_false = 1 << 1,
      78              :   /* Whether we're only folding non-ODR usages of constants.
      79              :      This happens before saving the constexpr funcdef, so
      80              :      we should do as little other folding as possible.
      81              :      Mutually exclusive with ff_mce_false.  */
      82              :   ff_only_non_odr = 1 << 2,
      83              : };
      84              : 
      85              : using fold_flags_t = int;
      86              : 
      87     85056474 : struct cp_fold_data
      88              : {
      89              :   hash_set<tree> pset;
      90              :   fold_flags_t flags;
      91    200604169 :   cp_fold_data (fold_flags_t flags): flags (flags)
      92              :   {
      93    200604169 :     gcc_checking_assert (!(flags & ff_mce_false)
      94              :                          || !(flags & ff_only_non_odr));
      95    200604169 :   }
      96              : };
      97              : 
      98              : /* Forward declarations.  */
      99              : 
     100              : static tree cp_genericize_r (tree *, int *, void *);
     101              : static tree cp_fold_r (tree *, int *, void *);
     102              : static void cp_genericize_tree (tree*, bool);
     103              : static tree cp_fold (tree, fold_flags_t);
     104              : static tree cp_fold_immediate_r (tree *, int *, void *);
     105              : 
     106              : /* Genericize a TRY_BLOCK.  */
     107              : 
     108              : static void
     109        18369 : genericize_try_block (tree *stmt_p)
     110              : {
     111        18369 :   tree body = TRY_STMTS (*stmt_p);
     112        18369 :   tree cleanup = TRY_HANDLERS (*stmt_p);
     113              : 
     114        18369 :   *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
     115        18369 : }
     116              : 
     117              : /* Genericize a HANDLER by converting to a CATCH_EXPR.  */
     118              : 
     119              : static void
     120        21477 : genericize_catch_block (tree *stmt_p)
     121              : {
     122        21477 :   tree type = HANDLER_TYPE (*stmt_p);
     123        21477 :   tree body = HANDLER_BODY (*stmt_p);
     124              : 
     125              :   /* FIXME should the caught type go in TREE_TYPE?  */
     126        21477 :   *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
     127        21477 : }
     128              : 
     129              : /* A terser interface for building a representation of an exception
     130              :    specification.  */
     131              : 
     132              : static tree
     133         5891 : build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
     134              : {
     135         5891 :   tree t;
     136              : 
     137              :   /* FIXME should the allowed types go in TREE_TYPE?  */
     138         5891 :   t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
     139         5891 :   append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
     140              : 
     141         5891 :   t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
     142         5891 :   append_to_statement_list (body, &TREE_OPERAND (t, 0));
     143              : 
     144         5891 :   return t;
     145              : }
     146              : 
     147              : /* Genericize an EH_SPEC_BLOCK by converting it to a
     148              :    TRY_CATCH_EXPR/EH_FILTER_EXPR pair.  */
     149              : 
     150              : static void
     151         5891 : genericize_eh_spec_block (tree *stmt_p)
     152              : {
     153         5891 :   tree body = EH_SPEC_STMTS (*stmt_p);
     154         5891 :   tree allowed = EH_SPEC_RAISES (*stmt_p);
     155         5891 :   tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
     156              : 
     157         5891 :   *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
     158         5891 :   suppress_warning (*stmt_p);
     159         5891 :   suppress_warning (TREE_OPERAND (*stmt_p, 1));
     160         5891 : }
     161              : 
     162              : /* Return the first non-compound statement in STMT.  */
     163              : 
     164              : tree
     165     15104508 : first_stmt (tree stmt)
     166              : {
     167     22883302 :   switch (TREE_CODE (stmt))
     168              :     {
     169      6044282 :     case STATEMENT_LIST:
     170      6044282 :       if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt))
     171      4096903 :         return first_stmt (p->stmt);
     172      1947379 :       return void_node;
     173              : 
     174      3681891 :     case BIND_EXPR:
     175      3681891 :       return first_stmt (BIND_EXPR_BODY (stmt));
     176              : 
     177              :     default:
     178              :       return stmt;
     179              :     }
     180              : }
     181              : 
     182              : /* Genericize an IF_STMT by turning it into a COND_EXPR.  */
     183              : 
     184              : static void
     185     22270888 : genericize_if_stmt (tree *stmt_p)
     186              : {
     187     22270888 :   tree stmt, cond, then_, else_;
     188     22270888 :   location_t locus = EXPR_LOCATION (*stmt_p);
     189              : 
     190     22270888 :   stmt = *stmt_p;
     191     22270888 :   cond = IF_COND (stmt);
     192     22270888 :   then_ = THEN_CLAUSE (stmt);
     193     22270888 :   else_ = ELSE_CLAUSE (stmt);
     194              : 
     195     22270888 :   if (then_ && else_)
     196              :     {
     197      7552254 :       tree ft = first_stmt (then_);
     198      7552254 :       tree fe = first_stmt (else_);
     199      7552254 :       br_predictor pr;
     200      7552254 :       if (TREE_CODE (ft) == PREDICT_EXPR
     201        43165 :           && TREE_CODE (fe) == PREDICT_EXPR
     202           48 :           && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe)
     203      7552293 :           && (pr == PRED_HOT_LABEL || pr == PRED_COLD_LABEL))
     204              :         {
     205            3 :           gcc_rich_location richloc (EXPR_LOC_OR_LOC (ft, locus));
     206            3 :           richloc.add_range (EXPR_LOC_OR_LOC (fe, locus));
     207            3 :           warning_at (&richloc, OPT_Wattributes,
     208              :                       "both branches of %<if%> statement marked as %qs",
     209              :                       pr == PRED_HOT_LABEL ? "likely" : "unlikely");
     210            3 :         }
     211              :     }
     212              : 
     213     22270888 :   if (IF_STMT_VACUOUS_INIT_P (stmt))
     214              :     {
     215           56 :       gcc_checking_assert (integer_zerop (cond));
     216           56 :       gcc_checking_assert (!else_ || !TREE_SIDE_EFFECTS (else_));
     217           56 :       tree lab = create_artificial_label (UNKNOWN_LOCATION);
     218           56 :       VACUOUS_INIT_LABEL_P (lab) = 1;
     219           56 :       tree goto_expr = build_stmt (UNKNOWN_LOCATION, GOTO_EXPR, lab);
     220           56 :       tree label_expr = build_stmt (UNKNOWN_LOCATION, LABEL_EXPR, lab);
     221           56 :       if (TREE_CODE (then_) == STATEMENT_LIST)
     222              :         {
     223           56 :           tree_stmt_iterator i = tsi_start (then_);
     224           56 :           tsi_link_before (&i, goto_expr, TSI_CONTINUE_LINKING);
     225           56 :           i = tsi_last (then_);
     226           56 :           tsi_link_after (&i, label_expr, TSI_CONTINUE_LINKING);
     227           56 :           stmt = then_;
     228              :         }
     229              :       else
     230              :         {
     231            0 :           stmt = NULL_TREE;
     232            0 :           append_to_statement_list (goto_expr, &stmt);
     233            0 :           append_to_statement_list (then_, &stmt);
     234            0 :           append_to_statement_list (label_expr, &stmt);
     235              :         }
     236           56 :       *stmt_p = stmt;
     237           56 :       return;
     238              :     }
     239              : 
     240     22270832 :   if (!then_)
     241         2008 :     then_ = build_empty_stmt (locus);
     242     22270832 :   if (!else_)
     243     14716677 :     else_ = build_empty_stmt (locus);
     244              : 
     245              :   /* consteval if has been verified not to have the then_/else_ blocks
     246              :      entered by gotos/case labels from elsewhere, and as then_ block
     247              :      can contain unfolded immediate function calls, we have to discard
     248              :      the then_ block regardless of whether else_ has side-effects or not.  */
     249     22270832 :   if (IF_STMT_CONSTEVAL_P (stmt))
     250              :     {
     251        76373 :       if (block_may_fallthru (then_))
     252        24713 :         stmt = build3 (COND_EXPR, void_type_node, boolean_false_node,
     253              :                        void_node, else_);
     254              :       else
     255        51660 :         stmt = else_;
     256              :     }
     257     22194459 :   else if (IF_STMT_CONSTEXPR_P (stmt))
     258      6982619 :     stmt = integer_nonzerop (cond) ? then_ : else_;
     259              :   /* ??? This optimization doesn't seem to belong here, but removing it
     260              :      causes -Wreturn-type regressions (e.g. 107310).  */
     261     17455542 :   else if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
     262        99258 :     stmt = then_;
     263     17356284 :   else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
     264        35449 :     stmt = else_;
     265              :   else
     266     17320835 :     stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
     267     22270832 :   protected_set_expr_location_if_unset (stmt, locus);
     268     22270832 :   *stmt_p = stmt;
     269              : }
     270              : 
     271              : /* Hook into the middle of gimplifying an OMP_FOR node.  */
     272              : 
     273              : static enum gimplify_status
     274        45533 : cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
     275              : {
     276        45533 :   tree for_stmt = *expr_p;
     277        45533 :   gimple_seq seq = NULL;
     278              : 
     279              :   /* Protect ourselves from recursion.  */
     280        45533 :   if (OMP_FOR_GIMPLIFYING_P (for_stmt))
     281              :     return GS_UNHANDLED;
     282        21160 :   OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
     283              : 
     284        21160 :   gimplify_and_add (for_stmt, &seq);
     285        21160 :   gimple_seq_add_seq (pre_p, seq);
     286              : 
     287        21160 :   OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
     288              : 
     289        21160 :   return GS_ALL_DONE;
     290              : }
     291              : 
     292              : /*  Gimplify an EXPR_STMT node.  */
     293              : 
     294              : static void
     295      4091710 : gimplify_expr_stmt (tree *stmt_p)
     296              : {
     297      4091710 :   tree stmt = EXPR_STMT_EXPR (*stmt_p);
     298              : 
     299      4091710 :   if (stmt == error_mark_node)
     300              :     stmt = NULL;
     301              : 
     302              :   /* Gimplification of a statement expression will nullify the
     303              :      statement if all its side effects are moved to *PRE_P and *POST_P.
     304              : 
     305              :      In this case we will not want to emit the gimplified statement.
     306              :      However, we may still want to emit a warning, so we do that before
     307              :      gimplification.  */
     308      4087705 :   if (stmt && warn_unused_value)
     309              :     {
     310       308305 :       if (!TREE_SIDE_EFFECTS (stmt))
     311              :         {
     312            0 :           if (!IS_EMPTY_STMT (stmt)
     313         6846 :               && !VOID_TYPE_P (TREE_TYPE (stmt))
     314         6846 :               && !warning_suppressed_p (stmt, OPT_Wunused_value))
     315            0 :             warning (OPT_Wunused_value, "statement with no effect");
     316              :         }
     317              :       else
     318       301459 :         warn_if_unused_value (stmt, input_location);
     319              :     }
     320              : 
     321      4091710 :   if (stmt == NULL_TREE)
     322         4005 :     stmt = alloc_stmt_list ();
     323              : 
     324      4091710 :   *stmt_p = stmt;
     325      4091710 : }
     326              : 
     327              : /* Gimplify initialization from an AGGR_INIT_EXPR.  */
     328              : 
     329              : static void
     330     12006694 : cp_gimplify_init_expr (tree *expr_p)
     331              : {
     332     12006694 :   tree from = TREE_OPERAND (*expr_p, 1);
     333     12006694 :   tree to = TREE_OPERAND (*expr_p, 0);
     334     12006694 :   tree t;
     335              : 
     336     12006694 :   if (TREE_CODE (from) == TARGET_EXPR)
     337       208842 :     if (tree init = TARGET_EXPR_INITIAL (from))
     338              :       {
     339              :         /* Make sure that we expected to elide this temporary.  But also allow
     340              :            gimplify_modify_expr_rhs to elide temporaries of trivial type.  */
     341       208842 :         gcc_checking_assert (TARGET_EXPR_ELIDING_P (from)
     342              :                              || !TREE_ADDRESSABLE (TREE_TYPE (from)));
     343       208842 :         if (target_expr_needs_replace (from))
     344              :           {
     345              :             /* If this was changed by cp_genericize_target_expr, we need to
     346              :                walk into it to replace uses of the slot.  */
     347           90 :             replace_decl (&init, TARGET_EXPR_SLOT (from), to);
     348           90 :             *expr_p = init;
     349           90 :             return;
     350              :           }
     351              :         else
     352              :           from = init;
     353              :       }
     354              : 
     355              :   /* Look through any COMPOUND_EXPRs, since build_compound_expr pushes them
     356              :      inside the TARGET_EXPR.  */
     357     12094688 :   for (t = from; t; )
     358              :     {
     359     12094688 :       tree sub = TREE_CODE (t) == COMPOUND_EXPR ? TREE_OPERAND (t, 0) : t;
     360              : 
     361              :       /* If we are initializing from an AGGR_INIT_EXPR, drop the INIT_EXPR and
     362              :          replace the slot operand with our target.
     363              : 
     364              :          Should we add a target parm to gimplify_expr instead?  No, as in this
     365              :          case we want to replace the INIT_EXPR.  */
     366     12094688 :       if (TREE_CODE (sub) == AGGR_INIT_EXPR
     367     12094688 :           || TREE_CODE (sub) == VEC_INIT_EXPR)
     368              :         {
     369       112277 :           if (TREE_CODE (sub) == AGGR_INIT_EXPR)
     370       112277 :             AGGR_INIT_EXPR_SLOT (sub) = to;
     371              :           else
     372            0 :             VEC_INIT_EXPR_SLOT (sub) = to;
     373       112277 :           *expr_p = from;
     374              : 
     375              :           /* The initialization is now a side-effect, so the container can
     376              :              become void.  */
     377       112277 :           if (from != sub)
     378           73 :             TREE_TYPE (from) = void_type_node;
     379              :         }
     380              : 
     381              :       /* Handle aggregate NSDMI.  */
     382     12094688 :       replace_placeholders (sub, to);
     383              : 
     384     12094688 :       if (t == sub)
     385              :         break;
     386              :       else
     387        88084 :         t = TREE_OPERAND (t, 1);
     388              :     }
     389              : 
     390              : }
     391              : 
     392              : /* Gimplify a MUST_NOT_THROW_EXPR.  */
     393              : 
     394              : static enum gimplify_status
     395       585521 : gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
     396              : {
     397       585521 :   tree stmt = *expr_p;
     398       585521 :   tree temp = voidify_wrapper_expr (stmt, NULL);
     399       585521 :   tree body = TREE_OPERAND (stmt, 0);
     400       585521 :   gimple_seq try_ = NULL;
     401       585521 :   gimple_seq catch_ = NULL;
     402       585521 :   gimple *mnt;
     403              : 
     404       585521 :   gimplify_and_add (body, &try_);
     405       585521 :   mnt = gimple_build_eh_must_not_throw (call_terminate_fn);
     406       585521 :   gimple_seq_add_stmt_without_update (&catch_, mnt);
     407       585521 :   mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
     408              : 
     409       585521 :   gimple_seq_add_stmt_without_update (pre_p, mnt);
     410       585521 :   if (temp)
     411              :     {
     412           33 :       *expr_p = temp;
     413           33 :       return GS_OK;
     414              :     }
     415              : 
     416              :   *expr_p = NULL;
     417              :   return GS_ALL_DONE;
     418              : }
     419              : 
     420              : /* Return TRUE if an operand (OP) of a given TYPE being copied is
     421              :    really just an empty class copy.
     422              : 
     423              :    Check that the operand has a simple form so that TARGET_EXPRs and
     424              :    non-empty CONSTRUCTORs get reduced properly, and we leave the
     425              :    return slot optimization alone because it isn't a copy.  */
     426              : 
     427              : bool
     428     20117863 : simple_empty_class_p (tree type, tree op, tree_code code)
     429              : {
     430     23542723 :   if (TREE_CODE (op) == COMPOUND_EXPR)
     431       185289 :     return simple_empty_class_p (type, TREE_OPERAND (op, 1), code);
     432      4320167 :   if (SIMPLE_TARGET_EXPR_P (op)
     433     26598559 :       && TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
     434              :     /* The TARGET_EXPR is itself a simple copy, look through it.  */
     435      3239571 :     return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
     436              : 
     437     20117863 :   if (TREE_CODE (op) == PARM_DECL
     438     20117863 :       && TREE_ADDRESSABLE (TREE_TYPE (op)))
     439              :     {
     440            9 :       tree fn = DECL_CONTEXT (op);
     441            9 :       if (DECL_THUNK_P (fn)
     442           12 :           || lambda_static_thunk_p (fn))
     443              :         /* In a thunk, we pass through invisible reference parms, so this isn't
     444              :            actually a copy.  */
     445              :         return false;
     446              :     }
     447              : 
     448     20117854 :   return
     449     20117854 :     (TREE_CODE (op) == EMPTY_CLASS_EXPR
     450     20117824 :      || code == MODIFY_EXPR
     451     17065967 :      || is_gimple_lvalue (op)
     452     13504926 :      || INDIRECT_REF_P (op)
     453     13072415 :      || (TREE_CODE (op) == CONSTRUCTOR
     454      2901359 :          && CONSTRUCTOR_NELTS (op) == 0)
     455     10465673 :      || (TREE_CODE (op) == CALL_EXPR
     456      2733548 :          && !CALL_EXPR_RETURN_SLOT_OPT (op)))
     457     12278793 :     && !TREE_CLOBBER_P (op)
     458     31777853 :     && is_really_empty_class (type, /*ignore_vptr*/true);
     459              : }
     460              : 
     461              : /* Returns true if evaluating E as an lvalue has side-effects;
     462              :    specifically, a volatile lvalue has TREE_SIDE_EFFECTS, but it doesn't really
     463              :    have side-effects until there is a read or write through it.  */
     464              : 
     465              : static bool
     466      2709432 : lvalue_has_side_effects (tree e)
     467              : {
     468      2709432 :   if (!TREE_SIDE_EFFECTS (e))
     469              :     return false;
     470        58204 :   while (handled_component_p (e))
     471              :     {
     472         5027 :       if (TREE_CODE (e) == ARRAY_REF
     473         5027 :           && TREE_SIDE_EFFECTS (TREE_OPERAND (e, 1)))
     474              :         return true;
     475         3228 :       e = TREE_OPERAND (e, 0);
     476              :     }
     477        53177 :   if (DECL_P (e))
     478              :     /* Just naming a variable has no side-effects.  */
     479              :     return false;
     480        36176 :   else if (INDIRECT_REF_P (e))
     481              :     /* Similarly, indirection has no side-effects.  */
     482        36042 :     return TREE_SIDE_EFFECTS (TREE_OPERAND (e, 0));
     483              :   else
     484              :     /* For anything else, trust TREE_SIDE_EFFECTS.  */
     485          134 :     return TREE_SIDE_EFFECTS (e);
     486              : }
     487              : 
     488              : /* Return true if FN is an immediate-escalating function.  */
     489              : 
     490              : bool
     491    205207328 : immediate_escalating_function_p (tree fn)
     492              : {
     493    205207328 :   if (!fn || !flag_immediate_escalation)
     494              :     return false;
     495              : 
     496    205206961 :   gcc_checking_assert (TREE_CODE (fn) == FUNCTION_DECL);
     497              : 
     498    205206961 :   if (DECL_IMMEDIATE_FUNCTION_P (fn))
     499              :     return false;
     500              : 
     501              :   /* An immediate-escalating function is
     502              :       -- the call operator of a lambda that is not declared with the consteval
     503              :          specifier  */
     504    208922653 :   if (LAMBDA_FUNCTION_P (fn))
     505              :     return true;
     506              :   /* -- a defaulted function that is not declared with the
     507              :         consteval specifier  */
     508    203111509 :   if (DECL_DEFAULTED_FN (fn))
     509              :     return true;
     510              :   /* -- a function that results from the instantiation of a templated entity
     511              :         defined with the constexpr specifier.  */
     512    195251811 :   return is_instantiation_of_constexpr (fn);
     513              : }
     514              : 
     515              : /* Return true if FN is an immediate-escalating function that has not been
     516              :    checked for escalating expressions..  */
     517              : 
     518              : static bool
     519    205163215 : unchecked_immediate_escalating_function_p (tree fn)
     520              : {
     521    205163215 :   return (immediate_escalating_function_p (fn)
     522    205163215 :           && !DECL_ESCALATION_CHECKED_P (fn));
     523              : }
     524              : 
     525              : /* Promote FN to an immediate function, including its clones.  */
     526              : 
     527              : void
     528        41458 : promote_function_to_consteval (tree fn)
     529              : {
     530        41458 :   SET_DECL_IMMEDIATE_FUNCTION_P (fn);
     531        41458 :   DECL_ESCALATION_CHECKED_P (fn) = true;
     532        41458 :   tree clone;
     533        67196 :   FOR_EACH_CLONE (clone, fn)
     534              :     {
     535        25738 :       SET_DECL_IMMEDIATE_FUNCTION_P (clone);
     536        25738 :       DECL_ESCALATION_CHECKED_P (clone) = true;
     537              :     }
     538        41458 : }
     539              : 
     540              : /* A wrapper around cp_fold_immediate_r.  Return a non-null tree if
     541              :    we found a non-constant immediate function, or taking the address
     542              :    of an immediate function.  */
     543              : 
     544              : tree
     545     16483726 : cp_fold_immediate (tree *tp, mce_value manifestly_const_eval,
     546              :                    tree decl /*= current_function_decl*/)
     547              : {
     548     16483726 :   if (cxx_dialect <= cxx17)
     549              :     return NULL_TREE;
     550              : 
     551     16476348 :   temp_override<tree> cfd (current_function_decl, decl);
     552              : 
     553     16476348 :   fold_flags_t flags = ff_none;
     554     16476348 :   if (manifestly_const_eval == mce_false)
     555      9675099 :     flags |= ff_mce_false;
     556              : 
     557     16476348 :   cp_fold_data data (flags);
     558     16476348 :   int save_errorcount = errorcount;
     559     16476348 :   tree r = cp_walk_tree (tp, cp_fold_immediate_r, &data, NULL);
     560     16476348 :   if (errorcount > save_errorcount)
     561           49 :     return integer_one_node;
     562              :   return r;
     563     16476348 : }
     564              : 
     565              : /* Maybe say that FN (a function decl with DECL_IMMEDIATE_FUNCTION_P set)
     566              :    was initially not an immediate function, but was promoted to one because
     567              :    its body contained an immediate-escalating expression or conversion.  */
     568              : 
     569              : static void
     570          469 : maybe_explain_promoted_consteval (location_t loc, tree fn)
     571              : {
     572          469 :   if (DECL_ESCALATION_CHECKED_P (fn))
     573              :     {
     574              :       /* See if we can figure out what made the function consteval.  */
     575          126 :       tree x = cp_fold_immediate (&DECL_SAVED_TREE (fn), mce_unknown, NULL_TREE);
     576          126 :       if (x)
     577           99 :         inform (cp_expr_loc_or_loc (x, loc),
     578              :                 "%qD was promoted to an immediate function because its "
     579              :                 "body contains an immediate-escalating expression %qE", fn, x);
     580              :       else
     581           27 :         inform (loc, "%qD was promoted to an immediate function", fn);
     582              :     }
     583          469 : }
     584              : 
     585              : /* Gimplify *EXPR_P as rvalue into an expression that can't be modified
     586              :    by expressions with side-effects in other operands.  */
     587              : 
     588              : static enum gimplify_status
     589        37335 : gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
     590              :                     bool (*gimple_test_f) (tree))
     591              : {
     592        37335 :   enum gimplify_status t
     593        37335 :     = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
     594        37335 :   if (t == GS_ERROR)
     595              :     return GS_ERROR;
     596        37332 :   else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
     597         3089 :     *expr_p = get_initialized_tmp_var (*expr_p, pre_p);
     598              :   return t;
     599              : }
     600              : 
     601              : /* Like gimplify_arg, but if ORDERED is set (which should be set if
     602              :    any of the arguments this argument is sequenced before has
     603              :    TREE_SIDE_EFFECTS set, make sure expressions with is_gimple_reg_type type
     604              :    are gimplified into SSA_NAME or a fresh temporary and for
     605              :    non-is_gimple_reg_type we don't optimize away TARGET_EXPRs.  */
     606              : 
     607              : static enum gimplify_status
     608      4339348 : cp_gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
     609              :                  bool ordered)
     610              : {
     611      4339348 :   enum gimplify_status t;
     612      4339348 :   if (ordered
     613       441699 :       && !is_gimple_reg_type (TREE_TYPE (*arg_p))
     614      4341231 :       && TREE_CODE (*arg_p) == TARGET_EXPR)
     615              :     {
     616              :       /* gimplify_arg would strip away the TARGET_EXPR, but
     617              :          that can mean we don't copy the argument and some following
     618              :          argument with side-effect could modify it.  */
     619         1744 :       protected_set_expr_location (*arg_p, call_location);
     620         1744 :       return gimplify_expr (arg_p, pre_p, NULL, is_gimple_lvalue, fb_either);
     621              :     }
     622              :   else
     623              :     {
     624      4337604 :       t = gimplify_arg (arg_p, pre_p, call_location);
     625      4337604 :       if (t == GS_ERROR)
     626              :         return GS_ERROR;
     627      4337604 :       else if (ordered
     628       439955 :                && is_gimple_reg_type (TREE_TYPE (*arg_p))
     629       439816 :                && is_gimple_variable (*arg_p)
     630       222549 :                && TREE_CODE (*arg_p) != SSA_NAME
     631              :                /* No need to force references into register, references
     632              :                   can't be modified.  */
     633       135238 :                && !TYPE_REF_P (TREE_TYPE (*arg_p))
     634              :                /* And this can't be modified either.  */
     635      4427677 :                && *arg_p != current_class_ptr)
     636         8203 :         *arg_p = get_initialized_tmp_var (*arg_p, pre_p);
     637              :       return t;
     638              :     }
     639              : 
     640              : }
     641              : 
     642              : /* Emit a decl = {CLOBBER(bob)}; stmt before DECL_EXPR or first
     643              :    TARGET_EXPR gimplification for -flifetime-dse=2.  */
     644              : 
     645              : static void
     646      1487768 : maybe_emit_clobber_object_begin (tree decl, gimple_seq *pre_p)
     647              : {
     648      1487768 :   if (VAR_P (decl)
     649      1487092 :       && auto_var_p (decl)
     650      1452646 :       && TREE_TYPE (decl) != error_mark_node
     651      1452628 :       && DECL_NONTRIVIALLY_INITIALIZED_P (decl)
     652              :       /* Don't do it if it is fully initialized.  */
     653       896622 :       && DECL_INITIAL (decl) == NULL_TREE
     654       449615 :       && !DECL_HAS_VALUE_EXPR_P (decl)
     655       449298 :       && !OPAQUE_TYPE_P (TREE_TYPE (decl))
     656              :       /* Nor going to have decl = .DEFERRED_INIT (...); added.  */
     657      1937066 :       && (flag_auto_var_init == AUTO_INIT_UNINITIALIZED
     658        86636 :           || lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))
     659        86636 :           || lookup_attribute ("indeterminate", DECL_ATTRIBUTES (decl))))
     660              :     {
     661       362663 :       tree eltype = strip_array_types (TREE_TYPE (decl));
     662       362663 :       if (RECORD_OR_UNION_TYPE_P (eltype)
     663       362663 :           && !is_empty_class (eltype))
     664              :         {
     665       151150 :           tree clobber
     666       151150 :             = build_clobber (TREE_TYPE (decl), CLOBBER_OBJECT_BEGIN);
     667       151150 :           gimple *g = gimple_build_assign (decl, clobber);
     668       151150 :           gimple_set_location (g, DECL_SOURCE_LOCATION (decl));
     669       151150 :           gimple_seq_add_stmt_without_update (pre_p, g);
     670              :         }
     671              :     }
     672      1487768 : }
     673              : 
     674              : /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
     675              : 
     676              : int
     677    177258251 : cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
     678              : {
     679    177258251 :   int saved_stmts_are_full_exprs_p = 0;
     680    177258251 :   location_t loc = cp_expr_loc_or_input_loc (*expr_p);
     681    177258251 :   enum tree_code code = TREE_CODE (*expr_p);
     682    177258251 :   enum gimplify_status ret;
     683              : 
     684    177258251 :   if (STATEMENT_CODE_P (code))
     685              :     {
     686      4137447 :       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
     687      8274894 :       current_stmt_tree ()->stmts_are_full_exprs_p
     688      4137447 :         = STMT_IS_FULL_EXPR_P (*expr_p);
     689              :     }
     690              : 
     691    177258251 :   switch (code)
     692              :     {
     693       365496 :     case AGGR_INIT_EXPR:
     694       365496 :       simplify_aggr_init_expr (expr_p);
     695       365496 :       ret = GS_OK;
     696       365496 :       break;
     697              : 
     698            0 :     case VEC_INIT_EXPR:
     699            0 :       {
     700            0 :         *expr_p = expand_vec_init_expr (NULL_TREE, *expr_p,
     701              :                                         tf_warning_or_error);
     702              : 
     703            0 :         cp_fold_data data (ff_genericize | ff_mce_false);
     704            0 :         cp_walk_tree (expr_p, cp_fold_r, &data, NULL);
     705            0 :         cp_genericize_tree (expr_p, false);
     706            0 :         copy_if_shared (expr_p);
     707            0 :         ret = GS_OK;
     708            0 :       }
     709            0 :       break;
     710              : 
     711        20062 :     case THROW_EXPR:
     712              :       /* FIXME communicate throw type to back end, probably by moving
     713              :          THROW_EXPR into ../tree.def.  */
     714        20062 :       *expr_p = TREE_OPERAND (*expr_p, 0);
     715        20062 :       ret = GS_OK;
     716        20062 :       break;
     717              : 
     718       585521 :     case MUST_NOT_THROW_EXPR:
     719       585521 :       ret = gimplify_must_not_throw_expr (expr_p, pre_p);
     720       585521 :       break;
     721              : 
     722              :       /* We used to do this for MODIFY_EXPR as well, but that's unsafe; the
     723              :          LHS of an assignment might also be involved in the RHS, as in bug
     724              :          25979.  */
     725     12006694 :     case INIT_EXPR:
     726     12006694 :       cp_gimplify_init_expr (expr_p);
     727     12006694 :       if (TREE_CODE (*expr_p) != INIT_EXPR)
     728              :         return GS_OK;
     729              :       /* Fall through.  */
     730     16121048 :     case MODIFY_EXPR:
     731     11894327 :     modify_expr_case:
     732     16121048 :       {
     733              :         /* If the back end isn't clever enough to know that the lhs and rhs
     734              :            types are the same, add an explicit conversion.  */
     735     16121048 :         tree op0 = TREE_OPERAND (*expr_p, 0);
     736     16121048 :         tree op1 = TREE_OPERAND (*expr_p, 1);
     737              : 
     738     16121048 :         if (!error_operand_p (op0)
     739     16121048 :             && !error_operand_p (op1)
     740     16121029 :             && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
     741     16117834 :                 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
     742     16124252 :             && !useless_type_conversion_p (TREE_TYPE (op1), TREE_TYPE (op0)))
     743            9 :           TREE_OPERAND (*expr_p, 1) = build1 (VIEW_CONVERT_EXPR,
     744            9 :                                               TREE_TYPE (op0), op1);
     745              : 
     746     16121039 :         else if (simple_empty_class_p (TREE_TYPE (op0), op1, code))
     747              :           {
     748       219094 :             while (TREE_CODE (op1) == TARGET_EXPR)
     749              :               /* We're disconnecting the initializer from its target,
     750              :                  don't create a temporary.  */
     751         6824 :               op1 = TARGET_EXPR_INITIAL (op1);
     752              : 
     753              :             /* Remove any copies of empty classes.  Also drop volatile
     754              :                variables on the RHS to avoid infinite recursion from
     755              :                gimplify_expr trying to load the value.  */
     756       212270 :             if (TREE_SIDE_EFFECTS (op1))
     757              :               {
     758        16039 :                 if (TREE_THIS_VOLATILE (op1)
     759            0 :                     && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
     760            0 :                   op1 = build_fold_addr_expr (op1);
     761              : 
     762        16039 :                 suppress_warning (op1, OPT_Wunused_result);
     763        16039 :                 gimplify_and_add (op1, pre_p);
     764              :               }
     765       212270 :             gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
     766              :                            is_gimple_lvalue, fb_lvalue);
     767       212270 :             *expr_p = TREE_OPERAND (*expr_p, 0);
     768       212270 :             if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p))
     769              :               /* Avoid 'return *<retval>;'  */
     770         1267 :               *expr_p = TREE_OPERAND (*expr_p, 0);
     771              :           }
     772              :         /* P0145 says that the RHS is sequenced before the LHS.
     773              :            gimplify_modify_expr gimplifies the RHS before the LHS, but that
     774              :            isn't quite strong enough in two cases:
     775              : 
     776              :            1) gimplify.cc wants to leave a CALL_EXPR on the RHS, which would
     777              :            mean it's evaluated after the LHS.
     778              : 
     779              :            2) the value calculation of the RHS is also sequenced before the
     780              :            LHS, so for scalar assignment we need to preevaluate if the
     781              :            RHS could be affected by LHS side-effects even if it has no
     782              :            side-effects of its own.  We don't need this for classes because
     783              :            class assignment takes its RHS by reference.  */
     784     15908769 :        else if (flag_strong_eval_order > 1
     785     14534185 :                 && TREE_CODE (*expr_p) == MODIFY_EXPR
     786      2709432 :                 && lvalue_has_side_effects (op0)
     787     15946600 :                 && (TREE_CODE (op1) == CALL_EXPR
     788        30827 :                     || (SCALAR_TYPE_P (TREE_TYPE (op1))
     789        24603 :                         && !TREE_CONSTANT (op1))))
     790        21271 :          TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);
     791              :       }
     792              :       ret = GS_OK;
     793              :       break;
     794              : 
     795        98836 :     case EMPTY_CLASS_EXPR:
     796              :       /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
     797        98836 :       *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
     798        98836 :       ret = GS_OK;
     799        98836 :       break;
     800              : 
     801            0 :     case BASELINK:
     802            0 :       *expr_p = BASELINK_FUNCTIONS (*expr_p);
     803            0 :       ret = GS_OK;
     804            0 :       break;
     805              : 
     806        18369 :     case TRY_BLOCK:
     807        18369 :       genericize_try_block (expr_p);
     808        18369 :       ret = GS_OK;
     809        18369 :       break;
     810              : 
     811        21477 :     case HANDLER:
     812        21477 :       genericize_catch_block (expr_p);
     813        21477 :       ret = GS_OK;
     814        21477 :       break;
     815              : 
     816         5891 :     case EH_SPEC_BLOCK:
     817         5891 :       genericize_eh_spec_block (expr_p);
     818         5891 :       ret = GS_OK;
     819         5891 :       break;
     820              : 
     821            0 :     case USING_STMT:
     822            0 :       gcc_unreachable ();
     823              : 
     824            0 :     case FOR_STMT:
     825            0 :     case WHILE_STMT:
     826            0 :     case DO_STMT:
     827            0 :     case SWITCH_STMT:
     828            0 :     case CONTINUE_STMT:
     829            0 :     case BREAK_STMT:
     830            0 :       gcc_unreachable ();
     831              : 
     832        45533 :     case OMP_FOR:
     833        45533 :     case OMP_SIMD:
     834        45533 :     case OMP_DISTRIBUTE:
     835        45533 :     case OMP_LOOP:
     836        45533 :     case OMP_TASKLOOP:
     837        45533 :     case OMP_TILE:
     838        45533 :     case OMP_UNROLL:
     839        45533 :       ret = cp_gimplify_omp_for (expr_p, pre_p);
     840        45533 :       break;
     841              : 
     842      4091710 :     case EXPR_STMT:
     843      4091710 :       gimplify_expr_stmt (expr_p);
     844      4091710 :       ret = GS_OK;
     845      4091710 :       break;
     846              : 
     847            0 :     case UNARY_PLUS_EXPR:
     848            0 :       {
     849            0 :         tree arg = TREE_OPERAND (*expr_p, 0);
     850            0 :         tree type = TREE_TYPE (*expr_p);
     851            0 :         *expr_p = (TREE_TYPE (arg) != type) ? fold_convert (type, arg)
     852              :                                             : arg;
     853            0 :         ret = GS_OK;
     854              :       }
     855            0 :       break;
     856              : 
     857              :     case CALL_EXPR:
     858              :       ret = GS_OK;
     859              :       /* At this point any function that takes/returns a consteval-only
     860              :          expression is a problem.  */
     861     22894286 :       for (int i = 0; i < call_expr_nargs (*expr_p); ++i)
     862     14046599 :         if (check_out_of_consteval_use (CALL_EXPR_ARG (*expr_p, i)))
     863           10 :           ret = GS_ERROR;
     864      8847687 :       if (consteval_only_p (TREE_TYPE (*expr_p)))
     865            2 :         ret = GS_ERROR;
     866      8847687 :       if (flag_strong_eval_order == 2
     867      8339606 :           && CALL_EXPR_FN (*expr_p)
     868      7964018 :           && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)
     869     15976324 :           && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
     870              :         {
     871        37335 :           tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
     872        37335 :           enum gimplify_status t
     873        37335 :             = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
     874              :                                   is_gimple_call_addr);
     875        37335 :           if (t == GS_ERROR)
     876              :             ret = GS_ERROR;
     877              :           /* GIMPLE considers most pointer conversion useless, but for
     878              :              calls we actually care about the exact function pointer type.  */
     879        37332 :           else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
     880         9103 :             CALL_EXPR_FN (*expr_p)
     881        18206 :               = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
     882              :         }
     883      8847687 :       if (!CALL_EXPR_FN (*expr_p))
     884              :         /* Internal function call.  */
     885       398173 :         switch (CALL_EXPR_IFN (*expr_p))
     886              :           {
     887           36 :           case IFN_BSWAP:
     888           36 :           case IFN_BITREVERSE:
     889           36 :             if (ret == GS_OK)
     890              :               {
     891           36 :                 location_t loc = EXPR_LOCATION (*expr_p);
     892           36 :                 internal_fn ifn = CALL_EXPR_IFN (*expr_p);
     893           36 :                 tree arg = CALL_EXPR_ARG (*expr_p, 0);
     894           36 :                 tree r = fold_build_builtin_bswapg_bitreverseg (loc, ifn,
     895              :                                                                 arg);
     896           36 :                 if (TREE_CODE (r) == CALL_EXPR
     897           27 :                     && !CALL_EXPR_FN (r)
     898           36 :                     && CALL_EXPR_IFN (r) == ifn)
     899              :                   break;
     900           36 :                 *expr_p = r;
     901           36 :                 return ret;
     902              :               }
     903              :             break;
     904              :           default:
     905              :             break;
     906              :           }
     907      8449514 :       else if (CALL_EXPR_REVERSE_ARGS (*expr_p))
     908              :         {
     909              :           /* This is a call to a (compound) assignment operator that used
     910              :              the operator syntax; gimplify the RHS first.  */
     911        50070 :           gcc_assert (call_expr_nargs (*expr_p) == 2);
     912        50070 :           gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
     913        50070 :           enum gimplify_status t
     914        50070 :             = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc,
     915        50070 :                                TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, 0)));
     916        50070 :           if (t == GS_ERROR)
     917              :             ret = GS_ERROR;
     918              :         }
     919      8399444 :       else if (CALL_EXPR_ORDERED_ARGS (*expr_p))
     920              :         {
     921              :           /* Leave the last argument for gimplify_call_expr, to avoid problems
     922              :              with __builtin_va_arg_pack().  */
     923       257645 :           int nargs = call_expr_nargs (*expr_p) - 1;
     924       257645 :           int last_side_effects_arg = -1;
     925       506857 :           for (int i = nargs; i > 0; --i)
     926       276130 :             if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
     927              :               {
     928              :                 last_side_effects_arg = i;
     929              :                 break;
     930              :               }
     931       544906 :           for (int i = 0; i < nargs; ++i)
     932              :             {
     933       287261 :               enum gimplify_status t
     934       287261 :                 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc,
     935              :                                    i < last_side_effects_arg);
     936       287261 :               if (t == GS_ERROR)
     937            0 :                 ret = GS_ERROR;
     938              :             }
     939              :         }
     940      8141799 :       else if (flag_strong_eval_order
     941      8141799 :                && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
     942              :         {
     943              :           /* If flag_strong_eval_order, evaluate the object argument first.  */
     944      7547474 :           tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
     945      7547474 :           if (INDIRECT_TYPE_P (fntype))
     946      7547471 :             fntype = TREE_TYPE (fntype);
     947      7547474 :           tree decl = cp_get_callee_fndecl_nofold (*expr_p);
     948              :           /* We can't just rely on 'decl' because virtual function callees
     949              :              are expressed as OBJ_TYPE_REF.  Note that the xobj memfn check
     950              :              will also hold for calls of the form (&A::f)(a, ...) which does
     951              :              not require such sequencing, though it's allowed under
     952              :              "indeterminately sequenced".  */
     953      7547474 :           if (TREE_CODE (fntype) == METHOD_TYPE
     954      7547474 :               || (decl && DECL_LANG_SPECIFIC (decl)
     955      3534723 :                   && DECL_XOBJ_MEMBER_FUNCTION_P (decl)))
     956              :             {
     957      4002017 :               int nargs = call_expr_nargs (*expr_p);
     958      4002017 :               bool side_effects = false;
     959      5617967 :               for (int i = 1; i < nargs; ++i)
     960      2013936 :                 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
     961              :                   {
     962              :                     side_effects = true;
     963              :                     break;
     964              :                   }
     965      4002017 :               enum gimplify_status t
     966      4002017 :                 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc,
     967              :                                    side_effects);
     968      4002017 :               if (t == GS_ERROR)
     969              :                 ret = GS_ERROR;
     970              :             }
     971              :         }
     972      8847651 :       if (ret != GS_ERROR)
     973              :         {
     974      8847636 :           tree decl = cp_get_callee_fndecl_nofold (*expr_p);
     975      8847636 :           if (!decl)
     976              :             break;
     977      8407208 :           if (fndecl_built_in_p (decl, BUILT_IN_FRONTEND))
     978            9 :             switch (DECL_FE_FUNCTION_CODE (decl))
     979              :               {
     980            0 :               case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
     981            0 :                 *expr_p = boolean_false_node;
     982            0 :                 break;
     983            0 :               case CP_BUILT_IN_SOURCE_LOCATION:
     984            0 :                 *expr_p
     985            0 :                   = fold_builtin_source_location (*expr_p);
     986            0 :                 break;
     987            0 :               case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
     988            0 :                 *expr_p
     989            0 :                   = fold_builtin_is_corresponding_member
     990            0 :                         (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
     991              :                          &CALL_EXPR_ARG (*expr_p, 0));
     992            0 :                 break;
     993            0 :               case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
     994            0 :                 *expr_p
     995            0 :                   = fold_builtin_is_pointer_inverconvertible_with_class
     996            0 :                         (EXPR_LOCATION (*expr_p), call_expr_nargs (*expr_p),
     997              :                          &CALL_EXPR_ARG (*expr_p, 0));
     998            0 :                 break;
     999            0 :               case CP_BUILT_IN_EH_PTR_ADJUST_REF:
    1000            0 :                 error_at (EXPR_LOCATION (*expr_p),
    1001              :                           "%qs used outside of constant expressions",
    1002              :                           "__builtin_eh_ptr_adjust_ref");
    1003            0 :                 *expr_p = void_node;
    1004            0 :                 break;
    1005            9 :               case CP_BUILT_IN_CURRENT_EXCEPTION:
    1006            9 :               case CP_BUILT_IN_UNCAUGHT_EXCEPTIONS:
    1007            9 :                 {
    1008            9 :                   const char *name
    1009              :                     = (DECL_FE_FUNCTION_CODE (decl)
    1010              :                        == CP_BUILT_IN_CURRENT_EXCEPTION
    1011            9 :                        ? "current_exception" : "uncaught_exceptions");
    1012            9 :                   tree newdecl = lookup_qualified_name (std_node, name);
    1013            9 :                   if (error_operand_p (newdecl))
    1014            0 :                     *expr_p = build_zero_cst (TREE_TYPE (*expr_p));
    1015            9 :                   else if (TREE_CODE (newdecl) != FUNCTION_DECL
    1016            9 :                            || !same_type_p (TREE_TYPE (TREE_TYPE (newdecl)),
    1017              :                                             TREE_TYPE (TREE_TYPE (decl)))
    1018           18 :                            || (TYPE_ARG_TYPES (TREE_TYPE (newdecl))
    1019            9 :                                != void_list_node))
    1020              :                     {
    1021            0 :                       error_at (EXPR_LOCATION (*expr_p),
    1022              :                                 "unexpected %<std::%s%> declaration",
    1023              :                                 name);
    1024            0 :                       *expr_p = build_zero_cst (TREE_TYPE (*expr_p));
    1025              :                     }
    1026              :                   else
    1027            9 :                     *expr_p = build_call_expr_loc (EXPR_LOCATION (*expr_p),
    1028              :                                                    newdecl, 0);
    1029              :                   break;
    1030              :                 }
    1031            0 :               case CP_BUILT_IN_IS_STRING_LITERAL:
    1032            0 :                 *expr_p
    1033            0 :                   = fold_builtin_is_string_literal (EXPR_LOCATION (*expr_p),
    1034            0 :                                                     call_expr_nargs (*expr_p),
    1035              :                                                     &CALL_EXPR_ARG (*expr_p,
    1036              :                                                                     0));
    1037            0 :                 break;
    1038            0 :               case CP_BUILT_IN_CONSTEXPR_DIAG:
    1039            0 :                 *expr_p = void_node;
    1040            0 :                 break;
    1041              :               default:
    1042              :                 break;
    1043              :               }
    1044      8407199 :           else if (fndecl_built_in_p (decl, BUILT_IN_CLZG, BUILT_IN_CTZG))
    1045           33 :             ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p,
    1046              :                                                           post_p);
    1047              :           else
    1048              :             /* All consteval functions should have been processed by now.  */
    1049      8407166 :             gcc_checking_assert (!immediate_invocation_p (decl));
    1050              :         }
    1051              :       break;
    1052              : 
    1053       696047 :     case TARGET_EXPR:
    1054              :       /* A TARGET_EXPR that expresses direct-initialization should have been
    1055              :          elided by cp_gimplify_init_expr.  */
    1056       696047 :       gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
    1057              :       /* Likewise, but allow extra temps of trivial type so that
    1058              :          gimplify_init_ctor_preeval can materialize subobjects of a CONSTRUCTOR
    1059              :          on the rhs of an assignment, as in constexpr-aggr1.C.  */
    1060       696047 :       gcc_checking_assert (!TARGET_EXPR_ELIDING_P (*expr_p)
    1061              :                            || !TREE_ADDRESSABLE (TREE_TYPE (*expr_p)));
    1062       696047 :       if (flag_lifetime_dse > 1
    1063       695919 :           && TARGET_EXPR_INITIAL (*expr_p)
    1064      1382983 :           && VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (*expr_p))))
    1065       254885 :         maybe_emit_clobber_object_begin (TARGET_EXPR_SLOT (*expr_p), pre_p);
    1066              :       ret = GS_UNHANDLED;
    1067              :       break;
    1068              : 
    1069            3 :     case PTRMEM_CST:
    1070            3 :       *expr_p = cplus_expand_constant (*expr_p);
    1071            3 :       if (TREE_CODE (*expr_p) == PTRMEM_CST)
    1072              :         ret = GS_ERROR;
    1073              :       else
    1074    177145848 :         ret = GS_OK;
    1075              :       break;
    1076              : 
    1077      1233111 :     case DECL_EXPR:
    1078      1233111 :       if (flag_lifetime_dse > 1)
    1079      1232883 :         maybe_emit_clobber_object_begin (DECL_EXPR_DECL (*expr_p), pre_p);
    1080              :       ret = GS_UNHANDLED;
    1081              :       break;
    1082              : 
    1083      1243305 :     case RETURN_EXPR:
    1084      1243305 :       if (TREE_OPERAND (*expr_p, 0)
    1085      1243305 :           && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
    1086        13185 :               || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
    1087              :         {
    1088      1174864 :           expr_p = &TREE_OPERAND (*expr_p, 0);
    1089              :           /* Avoid going through the INIT_EXPR case, which can
    1090              :              degrade INIT_EXPRs into AGGR_INIT_EXPRs.  */
    1091      1174864 :           goto modify_expr_case;
    1092              :         }
    1093              :       /* Fall through.  */
    1094              : 
    1095    144995093 :     default:
    1096    144995093 :       ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
    1097    144995093 :       break;
    1098              :     }
    1099              : 
    1100              :   /* Restore saved state.  */
    1101    177145848 :   if (STATEMENT_CODE_P (code))
    1102      4137447 :     current_stmt_tree ()->stmts_are_full_exprs_p
    1103      4137447 :       = saved_stmts_are_full_exprs_p;
    1104              : 
    1105              :   return ret;
    1106              : }
    1107              : 
    1108              : bool
    1109   2056873220 : is_invisiref_parm (const_tree t)
    1110              : {
    1111   1927848290 :   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
    1112   2102185216 :           && DECL_BY_REFERENCE (t));
    1113              : }
    1114              : 
    1115              : /* A stable comparison routine for use with splay trees and DECLs.  */
    1116              : 
    1117              : static int
    1118        62362 : splay_tree_compare_decl_uid (splay_tree_key xa, splay_tree_key xb)
    1119              : {
    1120        62362 :   tree a = (tree) xa;
    1121        62362 :   tree b = (tree) xb;
    1122              : 
    1123        62362 :   return DECL_UID (a) - DECL_UID (b);
    1124              : }
    1125              : 
    1126              : /* OpenMP context during genericization.  */
    1127              : 
    1128              : struct cp_genericize_omp_taskreg
    1129              : {
    1130              :   bool is_parallel;
    1131              :   bool default_shared;
    1132              :   struct cp_genericize_omp_taskreg *outer;
    1133              :   splay_tree variables;
    1134              : };
    1135              : 
    1136              : /* Return true if genericization should try to determine if
    1137              :    DECL is firstprivate or shared within task regions.  */
    1138              : 
    1139              : static bool
    1140       119550 : omp_var_to_track (tree decl)
    1141              : {
    1142       119550 :   tree type = TREE_TYPE (decl);
    1143       119550 :   if (is_invisiref_parm (decl))
    1144          537 :     type = TREE_TYPE (type);
    1145       119013 :   else if (TYPE_REF_P (type))
    1146         4249 :     type = TREE_TYPE (type);
    1147       144559 :   while (TREE_CODE (type) == ARRAY_TYPE)
    1148        25009 :     type = TREE_TYPE (type);
    1149       119550 :   if (type == error_mark_node || !CLASS_TYPE_P (type))
    1150              :     return false;
    1151        14084 :   if (VAR_P (decl) && CP_DECL_THREAD_LOCAL_P (decl))
    1152              :     return false;
    1153        14081 :   if (cxx_omp_predetermined_sharing (decl) != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    1154           57 :     return false;
    1155              :   return true;
    1156              : }
    1157              : 
    1158              : /* Note DECL use in OpenMP region OMP_CTX during genericization.  */
    1159              : 
    1160              : static void
    1161        14267 : omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
    1162              : {
    1163        14267 :   splay_tree_node n = splay_tree_lookup (omp_ctx->variables,
    1164              :                                          (splay_tree_key) decl);
    1165        14267 :   if (n == NULL)
    1166              :     {
    1167         4319 :       int flags = OMP_CLAUSE_DEFAULT_SHARED;
    1168         4319 :       if (omp_ctx->outer)
    1169         1257 :         omp_cxx_notice_variable (omp_ctx->outer, decl);
    1170         4319 :       if (!omp_ctx->default_shared)
    1171              :         {
    1172          948 :           struct cp_genericize_omp_taskreg *octx;
    1173              : 
    1174         1065 :           for (octx = omp_ctx->outer; octx; octx = octx->outer)
    1175              :             {
    1176          902 :               n = splay_tree_lookup (octx->variables, (splay_tree_key) decl);
    1177          902 :               if (n && n->value != OMP_CLAUSE_DEFAULT_SHARED)
    1178              :                 {
    1179              :                   flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
    1180              :                   break;
    1181              :                 }
    1182          859 :               if (octx->is_parallel)
    1183              :                 break;
    1184              :             }
    1185          948 :           if (octx == NULL
    1186          948 :               && (TREE_CODE (decl) == PARM_DECL
    1187          120 :                   || (!(TREE_STATIC (decl) || DECL_EXTERNAL (decl))
    1188           41 :                       && DECL_CONTEXT (decl) == current_function_decl)))
    1189              :             flags = OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
    1190          864 :           if (flags == OMP_CLAUSE_DEFAULT_FIRSTPRIVATE)
    1191              :             {
    1192              :               /* DECL is implicitly determined firstprivate in
    1193              :                  the current task construct.  Ensure copy ctor and
    1194              :                  dtor are instantiated, because during gimplification
    1195              :                  it will be already too late.  */
    1196          127 :               tree type = TREE_TYPE (decl);
    1197          127 :               if (is_invisiref_parm (decl))
    1198            2 :                 type = TREE_TYPE (type);
    1199          125 :               else if (TYPE_REF_P (type))
    1200           52 :                 type = TREE_TYPE (type);
    1201          177 :               while (TREE_CODE (type) == ARRAY_TYPE)
    1202           50 :                 type = TREE_TYPE (type);
    1203          127 :               get_copy_ctor (type, tf_none);
    1204          127 :               get_dtor (type, tf_none);
    1205              :             }
    1206              :         }
    1207         4319 :       splay_tree_insert (omp_ctx->variables, (splay_tree_key) decl, flags);
    1208              :     }
    1209        14267 : }
    1210              : 
    1211              : /* True if any of the element initializers in CTOR are TARGET_EXPRs that are
    1212              :    not expected to elide, e.g. because unsafe_copy_elision_p is true.  */
    1213              : 
    1214              : static bool
    1215       132918 : any_non_eliding_target_exprs (tree ctor)
    1216              : {
    1217       619356 :   for (const constructor_elt &e : *CONSTRUCTOR_ELTS (ctor))
    1218              :     {
    1219       486441 :       if (TREE_CODE (e.value) == TARGET_EXPR
    1220       486441 :           && !TARGET_EXPR_ELIDING_P (e.value))
    1221              :         return true;
    1222              :     }
    1223              :   return false;
    1224              : }
    1225              : 
    1226              : /* If we might need to clean up a partially constructed object, break down the
    1227              :    CONSTRUCTOR with split_nonconstant_init.  Also expand VEC_INIT_EXPR at this
    1228              :    point.  If initializing TO with FROM is non-trivial, overwrite *REPLACE with
    1229              :    the result.  */
    1230              : 
    1231              : static void
    1232     84147701 : cp_genericize_init (tree *replace, tree from, tree to, vec<tree,va_gc>** flags)
    1233              : {
    1234     84147701 :   tree init = NULL_TREE;
    1235     84147701 :   if (TREE_CODE (from) == VEC_INIT_EXPR)
    1236          987 :     init = expand_vec_init_expr (to, from, tf_warning_or_error, flags);
    1237     84146714 :   else if (TREE_CODE (from) == CONSTRUCTOR
    1238      4829143 :            && TREE_SIDE_EFFECTS (from)
    1239     84281049 :            && ((flag_exceptions
    1240       134248 :                 && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (from)))
    1241       132918 :                || any_non_eliding_target_exprs (from)))
    1242              :     {
    1243         1420 :       to = cp_stabilize_reference (to);
    1244         1420 :       replace_placeholders (from, to);
    1245         1420 :       init = split_nonconstant_init (to, from);
    1246              :     }
    1247              : 
    1248         2407 :   if (init)
    1249              :     {
    1250         2407 :       if (*replace == from)
    1251              :         /* Make cp_gimplify_init_expr call replace_decl on this
    1252              :            TARGET_EXPR_INITIAL.  */
    1253          713 :         init = fold_convert (void_type_node, init);
    1254         2407 :       *replace = init;
    1255              :     }
    1256     84147701 : }
    1257              : 
    1258              : /* For an INIT_EXPR, replace the INIT_EXPR itself.  */
    1259              : 
    1260              : static void
    1261     63310385 : cp_genericize_init_expr (tree *stmt_p)
    1262              : {
    1263     63310385 :   iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
    1264     63310385 :   tree to = TREE_OPERAND (*stmt_p, 0);
    1265     63310385 :   tree from = TREE_OPERAND (*stmt_p, 1);
    1266      6604914 :   if (SIMPLE_TARGET_EXPR_P (from)
    1267              :       /* Return gets confused if we clobber its INIT_EXPR this soon.  */
    1268     68228067 :       && TREE_CODE (to) != RESULT_DECL)
    1269       175467 :     from = TARGET_EXPR_INITIAL (from);
    1270     63310385 :   cp_genericize_init (stmt_p, from, to, nullptr);
    1271     63310385 : }
    1272              : 
    1273              : /* For a TARGET_EXPR, change the TARGET_EXPR_INITIAL.  We will need to use
    1274              :    replace_decl later when we know what we're initializing.  */
    1275              : 
    1276              : static void
    1277     20837316 : cp_genericize_target_expr (tree *stmt_p)
    1278              : {
    1279     20837316 :   iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
    1280     20837316 :   tree slot = TARGET_EXPR_SLOT (*stmt_p);
    1281     20837316 :   vec<tree, va_gc> *flags = make_tree_vector ();
    1282     20837316 :   cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p),
    1283     20837316 :                       TARGET_EXPR_INITIAL (*stmt_p), slot, &flags);
    1284     20837316 :   gcc_assert (!DECL_INITIAL (slot));
    1285     62511980 :   for (tree f : flags)
    1286              :     {
    1287              :       /* Once initialization is complete TARGET_EXPR_CLEANUP becomes active, so
    1288              :          disable any subobject cleanups.  */
    1289           32 :       tree d = build_disable_temp_cleanup (f);
    1290           32 :       auto &r = TARGET_EXPR_INITIAL (*stmt_p);
    1291           32 :       r = add_stmt_to_compound (r, d);
    1292              :     }
    1293     20837316 :   release_tree_vector (flags);
    1294     20837316 : }
    1295              : 
    1296              : /* Similar to if (target_expr_needs_replace) replace_decl, but TP is the
    1297              :    TARGET_EXPR_INITIAL, and this also updates *_SLOT.  We need this extra
    1298              :    replacement when cp_folding TARGET_EXPR to preserve the invariant that
    1299              :    AGGR_INIT_EXPR_SLOT agrees with the enclosing TARGET_EXPR_SLOT.  */
    1300              : 
    1301              : static bool
    1302          130 : maybe_replace_decl (tree *tp, tree decl, tree replacement)
    1303              : {
    1304          130 :   if (!*tp || !VOID_TYPE_P (TREE_TYPE (*tp)))
    1305              :     return false;
    1306           50 :   tree t = *tp;
    1307           50 :   while (TREE_CODE (t) == COMPOUND_EXPR)
    1308            0 :     t = TREE_OPERAND (t, 1);
    1309           50 :   if (TREE_CODE (t) == AGGR_INIT_EXPR)
    1310           50 :     replace_decl (&AGGR_INIT_EXPR_SLOT (t), decl, replacement);
    1311            0 :   else if (TREE_CODE (t) == VEC_INIT_EXPR)
    1312            0 :     replace_decl (&VEC_INIT_EXPR_SLOT (t), decl, replacement);
    1313              :   else
    1314            0 :     replace_decl (tp, decl, replacement);
    1315              :   return true;
    1316              : }
    1317              : 
    1318              : /* Genericization context.  */
    1319              : 
    1320     51927537 : struct cp_genericize_data
    1321              : {
    1322              :   hash_set<tree> *p_set;
    1323              :   auto_vec<tree> bind_expr_stack;
    1324              :   struct cp_genericize_omp_taskreg *omp_ctx;
    1325              :   tree try_block;
    1326              :   bool no_sanitize_p;
    1327              :   bool handle_invisiref_parm_p;
    1328              : };
    1329              : 
    1330              : /* Emit an error about taking the address of an immediate function.
    1331              :    EXPR is the whole expression; DECL is the immediate function.  */
    1332              : 
    1333              : static void
    1334           63 : taking_address_of_imm_fn_error (tree expr, tree decl)
    1335              : {
    1336           63 :   auto_diagnostic_group d;
    1337           63 :   const location_t loc = (TREE_CODE (expr) == PTRMEM_CST
    1338           63 :                           ? PTRMEM_CST_LOCATION (expr)
    1339           63 :                           : EXPR_LOCATION (expr));
    1340           63 :   error_at (loc, "taking address of an immediate function %qD", decl);
    1341           63 :   maybe_explain_promoted_consteval (loc, decl);
    1342           63 : }
    1343              : 
    1344              : /* Build up an INIT_EXPR to initialize the object of a constructor call that
    1345              :    has been folded to a constant value.  CALL is the CALL_EXPR for the
    1346              :    constructor call; INIT is the value.  */
    1347              : 
    1348              : static tree
    1349          433 : cp_build_init_expr_for_ctor (tree call, tree init)
    1350              : {
    1351          433 :   tree a = CALL_EXPR_ARG (call, 0);
    1352          433 :   if (is_dummy_object (a))
    1353              :     return init;
    1354          433 :   const bool return_this = targetm.cxx.cdtor_returns_this ();
    1355          433 :   const location_t loc = EXPR_LOCATION (call);
    1356          433 :   if (return_this)
    1357            0 :     a = cp_save_expr (a);
    1358          433 :   tree s = build_fold_indirect_ref_loc (loc, a);
    1359          433 :   init = cp_build_init_expr (s, init);
    1360          433 :   if (return_this)
    1361              :     {
    1362            0 :       init = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (call), init,
    1363            0 :                          fold_convert_loc (loc, TREE_TYPE (call), a));
    1364            0 :       suppress_warning (init);
    1365              :     }
    1366              :   return init;
    1367              : }
    1368              : 
    1369              : /* For every DECL_EXPR check if it declares a consteval-only variable and
    1370              :    if so, overwrite it with a no-op.  The point here is not to leak
    1371              :    consteval-only variables into the middle end.  */
    1372              : 
    1373              : static tree
    1374      1025262 : wipe_consteval_only_r (tree *stmt_p, int *, void *)
    1375              : {
    1376      1025262 :   if (TREE_CODE (*stmt_p) == DECL_EXPR)
    1377              :     {
    1378         1678 :       tree d = DECL_EXPR_DECL (*stmt_p);
    1379         1678 :       if (VAR_P (d) && consteval_only_p (d))
    1380              :         /* Wipe the DECL_EXPR so that it doesn't get into gimple.  */
    1381            6 :         *stmt_p = void_node;
    1382              :     }
    1383      1025262 :   return NULL_TREE;
    1384              : }
    1385              : 
    1386              : /* A walk_tree callback for cp_fold_function and cp_fully_fold_init to handle
    1387              :    immediate functions.  */
    1388              : 
    1389              : static tree
    1390   3254551165 : cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_)
    1391              : {
    1392   3254551165 :   auto data = static_cast<cp_fold_data *>(data_);
    1393   3254551165 :   tree stmt = *stmt_p;
    1394              :   /* The purpose of this is not to emit errors for mce_unknown.  */
    1395   3254551165 :   const tsubst_flags_t complain = (data->flags & ff_mce_false
    1396   3254551165 :                                    ? tf_error : tf_none);
    1397   3254551165 :   const tree_code code = TREE_CODE (stmt);
    1398              : 
    1399              :   /* No need to look into types or unevaluated operands.
    1400              :      NB: This affects cp_fold_r as well.  */
    1401   3254551165 :   if (TYPE_P (stmt)
    1402   3252129245 :       || unevaluated_p (code)
    1403              :       /* We do not use in_immediate_context here because it checks
    1404              :          more than is desirable, e.g., sk_template_parms.  */
    1405   3251776667 :       || cp_unevaluated_operand
    1406   6506327832 :       || (current_function_decl
    1407   6323703606 :           && DECL_IMMEDIATE_FUNCTION_P (current_function_decl)))
    1408              :     {
    1409      2800096 :       *walk_subtrees = 0;
    1410      2800096 :       return NULL_TREE;
    1411              :     }
    1412              : 
    1413              :   /* Most invalid uses of consteval-only types should have been already
    1414              :      detected at this point.  And the valid ones won't be needed
    1415              :      anymore.  */
    1416   3251751069 :   if (flag_reflection
    1417     74508773 :       && complain
    1418     61699427 :       && (data->flags & ff_genericize)
    1419     47173502 :       && TREE_CODE (stmt) == STATEMENT_LIST)
    1420      3952032 :     for (tree s : tsi_range (stmt))
    1421      2670172 :       if (check_out_of_consteval_use (s))
    1422           16 :         *stmt_p = void_node;
    1423              : 
    1424   3251751069 :   tree decl = NULL_TREE;
    1425   3251751069 :   bool call_p = false;
    1426              : 
    1427              :   /* We are looking for &fn or fn().  */
    1428   3251751069 :   switch (code)
    1429              :     {
    1430     36968758 :     case DECL_EXPR:
    1431              :       /* Clear consteval-only DECL_EXPRs.  */
    1432     36968758 :       if (flag_reflection)
    1433              :         {
    1434       736081 :           tree d = DECL_EXPR_DECL (stmt);
    1435       736081 :           if (VAR_P (d) && consteval_only_p (d))
    1436          824 :             *stmt_p = void_node;
    1437              :         }
    1438              :       break;
    1439    156955934 :     case CALL_EXPR:
    1440    156955934 :     case AGGR_INIT_EXPR:
    1441    156955934 :       if (tree fn = cp_get_callee (stmt))
    1442    156643071 :         if (TREE_CODE (fn) != ADDR_EXPR || ADDR_EXPR_DENOTES_CALL_P (fn))
    1443    149862451 :           decl = cp_get_fndecl_from_callee (fn, /*fold*/false);
    1444              :       call_p = true;
    1445              :       break;
    1446        33110 :     case PTRMEM_CST:
    1447        33110 :       decl = PTRMEM_CST_MEMBER (stmt);
    1448        33110 :       break;
    1449    237348247 :     case ADDR_EXPR:
    1450    237348247 :       if (!ADDR_EXPR_DENOTES_CALL_P (stmt))
    1451     89217580 :         decl = TREE_OPERAND (stmt, 0);
    1452              :       break;
    1453     21797771 :     case IF_STMT:
    1454     21797771 :       if (IF_STMT_CONSTEVAL_P (stmt))
    1455              :         {
    1456        76388 :           if (!data->pset.add (stmt))
    1457              :             {
    1458        76388 :               cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_immediate_r, data_,
    1459              :                             nullptr);
    1460        76388 :               if (flag_reflection)
    1461              :                 /* Check & clear consteval-only DECL_EXPRs even here,
    1462              :                    because we wouldn't be walking this subtree otherwise.  */
    1463        27054 :                 cp_walk_tree (&THEN_CLAUSE (stmt), wipe_consteval_only_r,
    1464              :                               data_, nullptr);
    1465              :             }
    1466        76388 :           *walk_subtrees = 0;
    1467        76388 :           return NULL_TREE;
    1468              :         }
    1469              :       /* FALLTHRU */
    1470   2820368632 :     default:
    1471   2820368632 :       if (data->pset.add (stmt))
    1472    481248877 :         *walk_subtrees = 0;
    1473              :       return NULL_TREE;
    1474              :     }
    1475              : 
    1476    239113965 :   if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
    1477              :     return NULL_TREE;
    1478              : 
    1479              :   /* Fully escalate once all templates have been instantiated.  What we're
    1480              :      calling is not a consteval function but it may become one.  This
    1481              :      requires recursing; DECL may be promoted to consteval because it
    1482              :      contains an escalating expression E, but E itself may have to be
    1483              :      promoted first, etc.  */
    1484    156393555 :   if (at_eof > 1 && unchecked_immediate_escalating_function_p (decl))
    1485              :     {
    1486              :       /* Set before the actual walk to avoid endless recursion.  */
    1487      6013674 :       DECL_ESCALATION_CHECKED_P (decl) = true;
    1488              :       /* We're only looking for the first escalating expression.  Let us not
    1489              :          walk more trees than necessary, hence mce_unknown.  */
    1490      6013674 :       cp_fold_immediate (&DECL_SAVED_TREE (decl), mce_unknown, decl);
    1491              :     }
    1492              : 
    1493              :   /* [expr.const]p16 "An expression or conversion is immediate-escalating if
    1494              :      it is not initially in an immediate function context and it is either
    1495              :      -- an immediate invocation that is not a constant expression and is not
    1496              :      a subexpression of an immediate invocation."
    1497              : 
    1498              :      If we are in an immediate-escalating function, the immediate-escalating
    1499              :      expression or conversion makes it an immediate function.  So STMT does
    1500              :      not need to produce a constant expression.  */
    1501    312787110 :   if (DECL_IMMEDIATE_FUNCTION_P (decl))
    1502              :     {
    1503       477482 :       tree e = cxx_constant_value (stmt, tf_none);
    1504       477482 :       if (e == error_mark_node)
    1505              :         {
    1506              :           /* This takes care of, e.g.,
    1507              :               template <typename T>
    1508              :               constexpr int f(T t)
    1509              :               {
    1510              :                 return id(t);
    1511              :               }
    1512              :             where id (consteval) causes f<int> to be promoted.  */
    1513         2535 :           if (immediate_escalating_function_p (current_function_decl))
    1514         1970 :             promote_function_to_consteval (current_function_decl);
    1515          565 :           else if (complain & tf_error)
    1516              :             {
    1517          457 :               if (call_p)
    1518              :                 {
    1519          406 :                   auto_diagnostic_group d;
    1520          406 :                   location_t loc = cp_expr_loc_or_input_loc (stmt);
    1521          406 :                   error_at (loc, "call to consteval function %qE is "
    1522              :                             "not a constant expression", stmt);
    1523              :                   /* Explain why it's not a constant expression.  */
    1524          406 :                   *stmt_p = cxx_constant_value (stmt, complain);
    1525          406 :                   maybe_explain_promoted_consteval (loc, decl);
    1526          406 :                 }
    1527           51 :               else if (!data->pset.add (stmt))
    1528              :                 {
    1529           51 :                   taking_address_of_imm_fn_error (stmt, decl);
    1530           51 :                   *stmt_p = build_zero_cst (TREE_TYPE (stmt));
    1531              :                 }
    1532              :               /* If we're giving hard errors, continue the walk rather than
    1533              :                  bailing out after the first error.  */
    1534              :               return NULL_TREE;
    1535              :             }
    1536         2078 :           *walk_subtrees = 0;
    1537         2078 :           return stmt;
    1538              :         }
    1539              :       /* If we called a consteval function and it evaluated to a consteval-only
    1540              :          expression, it could be a problem if we are outside a manifestly
    1541              :          constant-evaluated context.  */
    1542       474947 :       else if ((data->flags & ff_genericize)
    1543       474947 :                && check_out_of_consteval_use (e, complain))
    1544              :         {
    1545            4 :           *stmt_p = void_node;
    1546            4 :           if (complain & tf_error)
    1547              :             return NULL_TREE;
    1548              :           else
    1549              :             {
    1550            0 :               *walk_subtrees = 0;
    1551            0 :               return stmt;
    1552              :             }
    1553              :         }
    1554              : 
    1555              :       /* We've evaluated the consteval function call.  */
    1556       474943 :       if (call_p)
    1557              :         {
    1558       571179 :           if (code == CALL_EXPR && DECL_CONSTRUCTOR_P (decl))
    1559            0 :             *stmt_p = cp_build_init_expr_for_ctor (stmt, e);
    1560              :           else
    1561       474943 :             *stmt_p = e;
    1562              :         }
    1563              :     }
    1564              :   /* We've encountered a function call that may turn out to be consteval
    1565              :      later.  Store its caller so that we can ensure that the call is
    1566              :      a constant expression.  */
    1567    155916073 :   else if (unchecked_immediate_escalating_function_p (decl))
    1568              :     {
    1569              :       /* Make sure we're not inserting new elements while walking
    1570              :          the deferred_escalating_exprs hash table; if we are, it's
    1571              :          likely that a function wasn't properly marked checked for
    1572              :          i-e expressions.  */
    1573     26507318 :       gcc_checking_assert (at_eof <= 1);
    1574     26507318 :       if (current_function_decl)
    1575     26506794 :         remember_escalating_expr (current_function_decl);
    1576              :       /* auto p = &f<int>; in the global scope won't be ensconced in
    1577              :          a function we could store for later at this point.  (If there's
    1578              :          no c_f_d at this point and we're dealing with a call, we should
    1579              :          see the call when cp_fold_function __static_i_and_d.)  */
    1580          524 :       else if (!call_p)
    1581          143 :         remember_escalating_expr (stmt);
    1582              :     }
    1583              : 
    1584              :   return NULL_TREE;
    1585              : }
    1586              : 
    1587              : /* A walk_tree helper to replace constant-initialized references in an
    1588              :    OMP_CLAUSE with the the declaration that they refer to.  Such refs
    1589              :    will have been folded out in the body by cp_fold_non_odr_use_1 and
    1590              :    so we need to follow suit to prevent confusion.  */
    1591              : 
    1592              : static tree
    1593        97784 : cp_fold_omp_clause_refs_r (tree *expr_p, int *walk_subtrees, void */*data*/)
    1594              : {
    1595        97784 :   tree expr = *expr_p;
    1596              : 
    1597        97784 :   if (TYPE_P (expr))
    1598              :     {
    1599            0 :       *walk_subtrees = 0;
    1600            0 :       return NULL_TREE;
    1601              :     }
    1602              : 
    1603        97784 :   if (DECL_P (expr))
    1604              :     {
    1605        53667 :       *walk_subtrees = 0;
    1606              : 
    1607        53667 :       if (decl_constant_var_p (expr)
    1608        53667 :           && TYPE_REF_P (TREE_TYPE (expr)))
    1609              :         {
    1610          532 :           tree init = maybe_constant_value (expr);
    1611          532 :           if (TREE_CONSTANT (init))
    1612          532 :             *expr_p = tree_strip_nop_conversions (init);
    1613              :         }
    1614              :     }
    1615              : 
    1616              :   return NULL_TREE;
    1617              : }
    1618              : 
    1619              : /* Perform any pre-gimplification folding of C++ front end trees to
    1620              :    GENERIC.
    1621              :    Note:  The folding of non-omp cases is something to move into
    1622              :      the middle-end.  As for now we have most foldings only on GENERIC
    1623              :      in fold-const, we need to perform this before transformation to
    1624              :      GIMPLE-form.
    1625              : 
    1626              :    ??? This is algorithmically weird because walk_tree works in pre-order, so
    1627              :    we see outer expressions before inner expressions.  This isn't as much of an
    1628              :    issue because cp_fold recurses into subexpressions in many cases, but then
    1629              :    walk_tree walks back into those subexpressions again.  We avoid the
    1630              :    resulting complexity problem by caching the result of cp_fold, but it's
    1631              :    inelegant.  */
    1632              : 
    1633              : static tree
    1634   4477972238 : cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
    1635              : {
    1636   4477972238 :   cp_fold_data *data = (cp_fold_data*)data_;
    1637   4477972238 :   tree stmt = *stmt_p;
    1638   4477972238 :   enum tree_code code = TREE_CODE (stmt);
    1639              : 
    1640   4477972238 :   *stmt_p = stmt = cp_fold (*stmt_p, data->flags);
    1641              : 
    1642   4477972238 :   if (data->pset.add (stmt))
    1643              :     {
    1644              :       /* Don't walk subtrees of stmts we've already walked once, otherwise
    1645              :          we can have exponential complexity with e.g. lots of nested
    1646              :          SAVE_EXPRs or TARGET_EXPRs.  cp_fold uses a cache and will return
    1647              :          always the same tree, which the first time cp_fold_r has been
    1648              :          called on it had the subtrees walked.  */
    1649    637237755 :       *walk_subtrees = 0;
    1650    637237755 :       return NULL_TREE;
    1651              :     }
    1652              : 
    1653   3840734483 :   code = TREE_CODE (stmt);
    1654   3840734483 :   switch (code)
    1655              :     {
    1656        51963 :       tree x;
    1657        51963 :       int i, n;
    1658        51963 :     case OMP_FOR:
    1659        51963 :     case OMP_SIMD:
    1660        51963 :     case OMP_DISTRIBUTE:
    1661        51963 :     case OMP_LOOP:
    1662        51963 :     case OMP_TASKLOOP:
    1663        51963 :     case OMP_TILE:
    1664        51963 :     case OMP_UNROLL:
    1665        51963 :     case OACC_LOOP:
    1666        51963 :       cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
    1667        51963 :       cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
    1668        51963 :       cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
    1669        51963 :       x = OMP_FOR_COND (stmt);
    1670        51963 :       if (x && TREE_CODE_CLASS (TREE_CODE (x)) == tcc_comparison)
    1671              :         {
    1672            0 :           cp_walk_tree (&TREE_OPERAND (x, 0), cp_fold_r, data, NULL);
    1673            0 :           cp_walk_tree (&TREE_OPERAND (x, 1), cp_fold_r, data, NULL);
    1674              :         }
    1675        38311 :       else if (x && TREE_CODE (x) == TREE_VEC)
    1676              :         {
    1677        38311 :           n = TREE_VEC_LENGTH (x);
    1678        87964 :           for (i = 0; i < n; i++)
    1679              :             {
    1680        49653 :               tree o = TREE_VEC_ELT (x, i);
    1681        49653 :               if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
    1682        47827 :                 cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
    1683              :             }
    1684              :         }
    1685        51963 :       x = OMP_FOR_INCR (stmt);
    1686        51963 :       if (x && TREE_CODE (x) == TREE_VEC)
    1687              :         {
    1688        38311 :           n = TREE_VEC_LENGTH (x);
    1689        87964 :           for (i = 0; i < n; i++)
    1690              :             {
    1691        49653 :               tree o = TREE_VEC_ELT (x, i);
    1692        49653 :               if (o && TREE_CODE (o) == MODIFY_EXPR)
    1693        12044 :                 o = TREE_OPERAND (o, 1);
    1694        47827 :               if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
    1695        38683 :                         || TREE_CODE (o) == POINTER_PLUS_EXPR))
    1696              :                 {
    1697        12044 :                   cp_walk_tree (&TREE_OPERAND (o, 0), cp_fold_r, data, NULL);
    1698        12044 :                   cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
    1699              :                 }
    1700              :             }
    1701              :         }
    1702        51963 :       cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
    1703        51963 :       *walk_subtrees = 0;
    1704        51963 :       return NULL_TREE;
    1705              : 
    1706       167028 :     case OMP_CLAUSE:
    1707       167028 :       if ((data->flags & ff_only_non_odr)
    1708        83525 :           && omp_clause_num_ops[OMP_CLAUSE_CODE (stmt)] >= 1
    1709        70097 :           && OMP_CLAUSE_CODE (stmt) >= OMP_CLAUSE_PRIVATE
    1710        70097 :           && OMP_CLAUSE_CODE (stmt) <= OMP_CLAUSE__SCANTEMP_
    1711       213720 :           && OMP_CLAUSE_DECL (stmt))
    1712              :         {
    1713        45510 :           tree *decl = &OMP_CLAUSE_DECL (stmt);
    1714        45510 :           cp_walk_tree (decl, cp_fold_omp_clause_refs_r, NULL, NULL);
    1715        45510 :           if (TREE_CODE (*decl) == ADDR_EXPR
    1716        45510 :               && DECL_P (TREE_OPERAND (*decl, 0)))
    1717          148 :             *decl = TREE_OPERAND (*decl, 0);
    1718        45510 :           data->pset.add (*decl);
    1719              :         }
    1720              :       break;
    1721              : 
    1722     45957555 :     case IF_STMT:
    1723     45957555 :       if (IF_STMT_CONSTEVAL_P (stmt))
    1724              :         {
    1725              :           /* Don't walk THEN_CLAUSE (stmt) for consteval if.  IF_COND is always
    1726              :              boolean_false_node.  */
    1727       154058 :           cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL);
    1728       154058 :           cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL);
    1729       154058 :           *walk_subtrees = 0;
    1730       154058 :           return NULL_TREE;
    1731              :         }
    1732              :       break;
    1733              : 
    1734              :       /* cp_genericize_{init,target}_expr are only for genericize time; they're
    1735              :          here rather than in cp_genericize to avoid problems with the invisible
    1736              :          reference transition.  */
    1737    127789837 :     case INIT_EXPR:
    1738    127789837 :       if (!flag_no_inline
    1739    120789420 :           && (data->flags & ff_genericize))
    1740              :         {
    1741     59864518 :           tree to = TREE_OPERAND (*stmt_p, 0);
    1742     59864518 :           tree &from = TREE_OPERAND (*stmt_p, 1);
    1743     59864518 :           tree folded = maybe_constant_init (from, to,
    1744     59864518 :                                              (data->flags & ff_mce_false
    1745              :                                               ? mce_false : mce_unknown));
    1746     59864518 :           if (folded != from && TREE_CONSTANT (folded))
    1747      1516959 :             from = folded;
    1748              :         }
    1749              : 
    1750    127789837 :       if (data->flags & ff_genericize)
    1751     63310385 :         cp_genericize_init_expr (stmt_p);
    1752              :       break;
    1753              : 
    1754     44389276 :     case TARGET_EXPR:
    1755     44389276 :       if (!flag_no_inline
    1756     41825434 :           && (data->flags & ff_genericize))
    1757     19589144 :         if (tree &init = TARGET_EXPR_INITIAL (stmt))
    1758              :           {
    1759     19589144 :             tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt),
    1760     19589144 :                                                (data->flags & ff_mce_false
    1761              :                                                 ? mce_false : mce_unknown));
    1762     19589144 :             if (folded != init && TREE_CONSTANT (folded))
    1763      1229327 :               init = folded;
    1764              :           }
    1765              : 
    1766              :       /* This needs to happen between the constexpr evaluation (which wants
    1767              :          pre-generic trees) and fold (which wants the cp_genericize_init
    1768              :          transformations).  */
    1769     44389276 :       if (data->flags & ff_genericize)
    1770     20837316 :         cp_genericize_target_expr (stmt_p);
    1771              : 
    1772     44389276 :       if (tree &init = TARGET_EXPR_INITIAL (stmt))
    1773              :         {
    1774     44389276 :           cp_walk_tree (&init, cp_fold_r, data, NULL);
    1775     44389276 :           cp_walk_tree (&TARGET_EXPR_CLEANUP (stmt), cp_fold_r, data, NULL);
    1776     44389276 :           *walk_subtrees = 0;
    1777              :           /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in
    1778              :              that case, strip it in favor of this one.  */
    1779     44389276 :           if (TREE_CODE (init) == TARGET_EXPR)
    1780              :             {
    1781          130 :               tree sub = TARGET_EXPR_INITIAL (init);
    1782          130 :               maybe_replace_decl (&sub, TARGET_EXPR_SLOT (init),
    1783          130 :                                   TARGET_EXPR_SLOT (stmt));
    1784          130 :               init = sub;
    1785              :             }
    1786              :         }
    1787              :       break;
    1788              : 
    1789              :     default:
    1790              :       break;
    1791              :     }
    1792              : 
    1793              :   return NULL_TREE;
    1794              : }
    1795              : 
    1796              : /* Fold ALL the trees!  FIXME we should be able to remove this, but
    1797              :    apparently that still causes optimization regressions.  */
    1798              : 
    1799              : void
    1800     68580126 : cp_fold_function (tree fndecl)
    1801              : {
    1802              :   /* By now all manifestly-constant-evaluated expressions will have
    1803              :      been constant-evaluated already if possible, so we can safely
    1804              :      pass ff_mce_false.  */
    1805     68580126 :   cp_fold_data data (ff_genericize | ff_mce_false);
    1806              :   /* Do cp_fold_immediate_r in separate whole IL walk instead of during
    1807              :      cp_fold_r, as otherwise expressions using results of immediate functions
    1808              :      might not be folded as cp_fold is called on those before cp_fold_r is
    1809              :      called on their argument.  */
    1810     68580126 :   if (cxx_dialect >= cxx20)
    1811              :     {
    1812     66597576 :       cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_immediate_r,
    1813              :                     &data, NULL);
    1814     66597576 :       data.pset.empty ();
    1815              :     }
    1816     68580126 :   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
    1817              : 
    1818              :   /* This is merely an optimization: if FNDECL has no i-e expressions,
    1819              :      we'll not save c_f_d, and we can safely say that FNDECL will not
    1820              :      be promoted to consteval.  */
    1821     68580126 :   if (deferred_escalating_exprs
    1822     68580126 :       && !deferred_escalating_exprs->contains (current_function_decl))
    1823     51132859 :     DECL_ESCALATION_CHECKED_P (fndecl) = true;
    1824     68580126 : }
    1825              : 
    1826              : /* Fold any non-ODR usages of constant variables in FNDECL.  This occurs
    1827              :    before saving the constexpr fundef, so do as little other folding
    1828              :    as possible.  */
    1829              : 
    1830              : void
    1831     69710442 : cp_fold_function_non_odr_use (tree fndecl)
    1832              : {
    1833     69710442 :   cp_fold_data data (ff_only_non_odr);
    1834     69710442 :   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
    1835     69710442 : }
    1836              : 
    1837              : /* We've stashed immediate-escalating functions.  Now see if they indeed
    1838              :    ought to be promoted to consteval.  */
    1839              : 
    1840              : void
    1841        99007 : process_and_check_pending_immediate_escalating_fns ()
    1842              : {
    1843              :   /* This will be null for -fno-immediate-escalation.  */
    1844        99007 :   if (!deferred_escalating_exprs)
    1845              :     return;
    1846              : 
    1847     14152419 :   for (auto e : *deferred_escalating_exprs)
    1848     14132507 :     if (TREE_CODE (e) == FUNCTION_DECL && !DECL_ESCALATION_CHECKED_P (e))
    1849      9662151 :       cp_fold_immediate (&DECL_SAVED_TREE (e), mce_false, e);
    1850              : 
    1851              :   /* We've escalated every function that could have been promoted to
    1852              :      consteval.  Check that we are not taking the address of a consteval
    1853              :      function.  */
    1854     14152419 :   for (auto e : *deferred_escalating_exprs)
    1855              :     {
    1856     14132507 :       if (TREE_CODE (e) == FUNCTION_DECL)
    1857     14132364 :         continue;
    1858          143 :       tree decl = (TREE_CODE (e) == PTRMEM_CST
    1859          143 :                    ? PTRMEM_CST_MEMBER (e)
    1860          143 :                    : TREE_OPERAND (e, 0));
    1861          286 :       if (DECL_IMMEDIATE_FUNCTION_P (decl))
    1862           12 :         taking_address_of_imm_fn_error (e, decl);
    1863              :     }
    1864              : 
    1865        19912 :   deferred_escalating_exprs = nullptr;
    1866              : }
    1867              : 
    1868              : /* Turn SPACESHIP_EXPR EXPR into GENERIC.  */
    1869              : 
    1870       236974 : static tree genericize_spaceship (tree expr)
    1871              : {
    1872       236974 :   iloc_sentinel s (cp_expr_location (expr));
    1873       236974 :   tree type = TREE_TYPE (expr);
    1874       236974 :   tree op0 = TREE_OPERAND (expr, 0);
    1875       236974 :   tree op1 = TREE_OPERAND (expr, 1);
    1876       236974 :   return genericize_spaceship (input_location, type, op0, op1);
    1877       236974 : }
    1878              : 
    1879              : /* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
    1880              :    to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
    1881              :    the middle-end (c++/88256).  If EXPR is a DECL, use add_stmt and return
    1882              :    NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR.  */
    1883              : 
    1884              : tree
    1885    144019297 : predeclare_vla (tree expr)
    1886              : {
    1887    144019297 :   tree type = TREE_TYPE (expr);
    1888    144019297 :   if (type == error_mark_node)
    1889              :     return expr;
    1890    144019177 :   if (is_typedef_decl (expr))
    1891    144019177 :     type = DECL_ORIGINAL_TYPE (expr);
    1892              : 
    1893              :   /* We need to strip pointers for gimplify_type_sizes.  */
    1894    144019177 :   tree vla = type;
    1895    219550196 :   while (POINTER_TYPE_P (vla))
    1896              :     {
    1897     78063582 :       if (TYPE_NAME (vla))
    1898              :         return expr;
    1899     75531019 :       vla = TREE_TYPE (vla);
    1900              :     }
    1901     73585893 :   if (vla == type || TYPE_NAME (vla)
    1902    142065249 :       || !variably_modified_type_p (vla, NULL_TREE))
    1903              :     return expr;
    1904              : 
    1905          315 :   tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
    1906          315 :   DECL_ARTIFICIAL (decl) = 1;
    1907          315 :   TYPE_NAME (vla) = decl;
    1908          315 :   tree dexp = build_stmt (input_location, DECL_EXPR, decl);
    1909          315 :   if (DECL_P (expr))
    1910              :     {
    1911            5 :       add_stmt (dexp);
    1912            5 :       return NULL_TREE;
    1913              :     }
    1914              :   else
    1915              :     {
    1916          310 :       expr = build2 (COMPOUND_EXPR, type, dexp, expr);
    1917          310 :       return expr;
    1918              :     }
    1919              : }
    1920              : 
    1921              : /* Perform any pre-gimplification lowering of C++ front end trees to
    1922              :    GENERIC.  */
    1923              : 
    1924              : static tree
    1925   1866881350 : cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
    1926              : {
    1927   1889153216 :   tree stmt = *stmt_p;
    1928   1889153216 :   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
    1929   1889153216 :   hash_set<tree> *p_set = wtd->p_set;
    1930              : 
    1931              :   /* If in an OpenMP context, note var uses.  */
    1932   1889153216 :   if (UNLIKELY (wtd->omp_ctx != NULL)
    1933       600147 :       && (VAR_P (stmt)
    1934              :           || TREE_CODE (stmt) == PARM_DECL
    1935              :           || TREE_CODE (stmt) == RESULT_DECL)
    1936   1889261292 :       && omp_var_to_track (stmt))
    1937        12507 :     omp_cxx_notice_variable (wtd->omp_ctx, stmt);
    1938              : 
    1939              :   /* Don't dereference parms in a thunk, pass the references through. */
    1940     76153705 :   if ((TREE_CODE (stmt) == CALL_EXPR && call_from_lambda_thunk_p (stmt))
    1941   1965238402 :       || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
    1942              :     {
    1943        68733 :       *walk_subtrees = 0;
    1944        68733 :       return NULL;
    1945              :     }
    1946              : 
    1947              :   /* Dereference invisible reference parms.  */
    1948   1889084483 :   if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
    1949              :     {
    1950      1319282 :       *stmt_p = convert_from_reference (stmt);
    1951      1319282 :       p_set->add (*stmt_p);
    1952      1319282 :       *walk_subtrees = 0;
    1953      1319282 :       return NULL;
    1954              :     }
    1955              : 
    1956              :   /* Map block scope extern declarations to visible declarations with the
    1957              :      same name and type in outer scopes if any.  */
    1958   1887765201 :   if (VAR_OR_FUNCTION_DECL_P (stmt) && DECL_LOCAL_DECL_P (stmt))
    1959        21989 :     if (tree alias = DECL_LOCAL_DECL_ALIAS (stmt))
    1960              :       {
    1961        21989 :         if (alias != error_mark_node)
    1962              :           {
    1963        21986 :             *stmt_p = alias;
    1964        21986 :             TREE_USED (alias) |= TREE_USED (stmt);
    1965              :           }
    1966        21989 :         *walk_subtrees = 0;
    1967        21989 :         return NULL;
    1968              :       }
    1969              : 
    1970   1887743212 :   if (TREE_CODE (stmt) == INTEGER_CST
    1971    216899766 :       && TYPE_REF_P (TREE_TYPE (stmt))
    1972          168 :       && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
    1973   1887743213 :       && !wtd->no_sanitize_p)
    1974              :     {
    1975            1 :       ubsan_maybe_instrument_reference (stmt_p);
    1976            1 :       if (*stmt_p != stmt)
    1977              :         {
    1978            1 :           *walk_subtrees = 0;
    1979            1 :           return NULL_TREE;
    1980              :         }
    1981              :     }
    1982              : 
    1983              :   /* Other than invisiref parms, don't walk the same tree twice.  */
    1984   1887743211 :   if (p_set->contains (stmt))
    1985              :     {
    1986    375415753 :       *walk_subtrees = 0;
    1987    375415753 :       return NULL_TREE;
    1988              :     }
    1989              : 
    1990   1512327458 :   if ((TREE_CODE (stmt) == VAR_DECL
    1991              :        || TREE_CODE (stmt) == PARM_DECL
    1992              :        || TREE_CODE (stmt) == RESULT_DECL)
    1993    161745842 :       && DECL_HAS_VALUE_EXPR_P (stmt))
    1994              :     {
    1995       852242 :       tree ve = DECL_VALUE_EXPR (stmt);
    1996       852242 :       cp_walk_tree (&ve, cp_genericize_r, data, NULL);
    1997       852242 :       SET_DECL_VALUE_EXPR (stmt, ve);
    1998              :     }
    1999              : 
    2000   1512327458 :   switch (TREE_CODE (stmt))
    2001              :     {
    2002    122100201 :     case ADDR_EXPR:
    2003    122100201 :       if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
    2004              :         {
    2005              :           /* If in an OpenMP context, note var uses.  */
    2006       571419 :           if (UNLIKELY (wtd->omp_ctx != NULL)
    2007       571419 :               && omp_var_to_track (TREE_OPERAND (stmt, 0)))
    2008          412 :             omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
    2009       571419 :           *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
    2010       571419 :           *walk_subtrees = 0;
    2011              :         }
    2012              :       break;
    2013              : 
    2014     45300487 :     case RETURN_EXPR:
    2015     45300487 :       if (TREE_OPERAND (stmt, 0))
    2016              :         {
    2017     44599379 :           if (error_operand_p (TREE_OPERAND (stmt, 0))
    2018     44599379 :               && warn_return_type)
    2019              :             /* Suppress -Wreturn-type for this function.  */
    2020           12 :             suppress_warning (current_function_decl, OPT_Wreturn_type);
    2021              : 
    2022     44599379 :           if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
    2023              :             /* Don't dereference an invisiref RESULT_DECL inside a
    2024              :                RETURN_EXPR.  */
    2025          657 :             *walk_subtrees = 0;
    2026     44599379 :           if (RETURN_EXPR_LOCAL_ADDR_P (stmt))
    2027              :             {
    2028              :               /* Don't return the address of a local variable.  */
    2029          175 :               tree *p = &TREE_OPERAND (stmt, 0);
    2030          350 :               while (TREE_CODE (*p) == COMPOUND_EXPR)
    2031            0 :                 p = &TREE_OPERAND (*p, 0);
    2032          175 :               if (TREE_CODE (*p) == INIT_EXPR)
    2033              :                 {
    2034          175 :                   tree op = TREE_OPERAND (*p, 1);
    2035          175 :                   tree new_op = build2 (COMPOUND_EXPR, TREE_TYPE (op), op,
    2036          175 :                                         build_zero_cst (TREE_TYPE (op)));
    2037          175 :                   TREE_OPERAND (*p, 1) = new_op;
    2038              :                 }
    2039              :             }
    2040              :         }
    2041              :       break;
    2042              : 
    2043        83412 :     case OMP_CLAUSE:
    2044        83412 :       switch (OMP_CLAUSE_CODE (stmt))
    2045              :         {
    2046         2590 :         case OMP_CLAUSE_LASTPRIVATE:
    2047              :           /* Don't dereference an invisiref in OpenMP clauses.  */
    2048         2590 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2049              :             {
    2050           53 :               *walk_subtrees = 0;
    2051           53 :               if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
    2052           48 :                 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
    2053              :                               cp_genericize_r, data, NULL);
    2054              :             }
    2055              :           break;
    2056         2094 :         case OMP_CLAUSE_PRIVATE:
    2057              :           /* Don't dereference an invisiref in OpenMP clauses.  */
    2058         2094 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2059            8 :             *walk_subtrees = 0;
    2060         2086 :           else if (wtd->omp_ctx != NULL)
    2061              :             {
    2062              :               /* Private clause doesn't cause any references to the
    2063              :                  var in outer contexts, avoid calling
    2064              :                  omp_cxx_notice_variable for it.  */
    2065          584 :               struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
    2066          584 :               wtd->omp_ctx = NULL;
    2067          584 :               cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
    2068              :                             data, NULL);
    2069          584 :               wtd->omp_ctx = old;
    2070          584 :               *walk_subtrees = 0;
    2071              :             }
    2072              :           break;
    2073         6077 :         case OMP_CLAUSE_SHARED:
    2074         6077 :         case OMP_CLAUSE_FIRSTPRIVATE:
    2075         6077 :         case OMP_CLAUSE_COPYIN:
    2076         6077 :         case OMP_CLAUSE_COPYPRIVATE:
    2077         6077 :         case OMP_CLAUSE_INCLUSIVE:
    2078         6077 :         case OMP_CLAUSE_EXCLUSIVE:
    2079              :           /* Don't dereference an invisiref in OpenMP clauses.  */
    2080         6077 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2081           87 :             *walk_subtrees = 0;
    2082              :           break;
    2083         8593 :         case OMP_CLAUSE_REDUCTION:
    2084         8593 :         case OMP_CLAUSE_IN_REDUCTION:
    2085         8593 :         case OMP_CLAUSE_TASK_REDUCTION:
    2086              :           /* Don't dereference an invisiref in reduction clause's
    2087              :              OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
    2088              :              still needs to be genericized.  */
    2089         8593 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2090              :             {
    2091           38 :               *walk_subtrees = 0;
    2092           38 :               if (OMP_CLAUSE_REDUCTION_INIT (stmt))
    2093           38 :                 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
    2094              :                               cp_genericize_r, data, NULL);
    2095           38 :               if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
    2096           38 :                 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
    2097              :                               cp_genericize_r, data, NULL);
    2098              :             }
    2099              :           break;
    2100              :         default:
    2101              :           break;
    2102              :         }
    2103              :       break;
    2104              : 
    2105              :     /* Due to the way voidify_wrapper_expr is written, we don't get a chance
    2106              :        to lower this construct before scanning it, so we need to lower these
    2107              :        before doing anything else.  */
    2108      5879880 :     case CLEANUP_STMT:
    2109      5879880 :       *stmt_p = build2_loc (EXPR_LOCATION (stmt),
    2110      5879880 :                             CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
    2111              :                                                    : TRY_FINALLY_EXPR,
    2112              :                             void_type_node,
    2113      5879880 :                             CLEANUP_BODY (stmt),
    2114      5879880 :                             CLEANUP_EXPR (stmt));
    2115      5879880 :       break;
    2116              : 
    2117     22270888 :     case IF_STMT:
    2118     22270888 :       genericize_if_stmt (stmt_p);
    2119              :       /* *stmt_p has changed, tail recurse to handle it again.  */
    2120     22270888 :       return cp_genericize_r (stmt_p, walk_subtrees, data);
    2121              : 
    2122              :     /* COND_EXPR might have incompatible types in branches if one or both
    2123              :        arms are bitfields.  Fix it up now.  */
    2124     20018447 :     case COND_EXPR:
    2125     20018447 :       {
    2126     20018447 :         tree type_left
    2127     20018447 :           = (TREE_OPERAND (stmt, 1)
    2128     20018447 :              ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
    2129              :              : NULL_TREE);
    2130     20018447 :         tree type_right
    2131     20018447 :           = (TREE_OPERAND (stmt, 2)
    2132     20018447 :              ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
    2133              :              : NULL_TREE);
    2134     20018447 :         if (type_left
    2135     20018480 :             && !useless_type_conversion_p (TREE_TYPE (stmt),
    2136           33 :                                            TREE_TYPE (TREE_OPERAND (stmt, 1))))
    2137              :           {
    2138           30 :             TREE_OPERAND (stmt, 1)
    2139           30 :               = fold_convert (type_left, TREE_OPERAND (stmt, 1));
    2140           30 :             gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
    2141              :                                                    type_left));
    2142              :           }
    2143     20018447 :         if (type_right
    2144     20018464 :             && !useless_type_conversion_p (TREE_TYPE (stmt),
    2145           17 :                                            TREE_TYPE (TREE_OPERAND (stmt, 2))))
    2146              :           {
    2147           17 :             TREE_OPERAND (stmt, 2)
    2148           17 :               = fold_convert (type_right, TREE_OPERAND (stmt, 2));
    2149           17 :             gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
    2150              :                                                    type_right));
    2151              :           }
    2152              :       }
    2153              :       break;
    2154              : 
    2155     26288779 :     case BIND_EXPR:
    2156     26288779 :       if (UNLIKELY (wtd->omp_ctx != NULL))
    2157              :         {
    2158        27441 :           tree decl;
    2159        33754 :           for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
    2160         6313 :             if (VAR_P (decl)
    2161         6265 :                 && !DECL_EXTERNAL (decl)
    2162        12578 :                 && omp_var_to_track (decl))
    2163              :               {
    2164          586 :                 splay_tree_node n
    2165          586 :                   = splay_tree_lookup (wtd->omp_ctx->variables,
    2166              :                                        (splay_tree_key) decl);
    2167          586 :                 if (n == NULL)
    2168          586 :                   splay_tree_insert (wtd->omp_ctx->variables,
    2169              :                                      (splay_tree_key) decl,
    2170          586 :                                      TREE_STATIC (decl)
    2171              :                                      ? OMP_CLAUSE_DEFAULT_SHARED
    2172              :                                      : OMP_CLAUSE_DEFAULT_PRIVATE);
    2173              :               }
    2174              :         }
    2175     26288779 :       if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
    2176              :         {
    2177              :           /* The point here is to not sanitize static initializers.  */
    2178         3552 :           bool no_sanitize_p = wtd->no_sanitize_p;
    2179         3552 :           wtd->no_sanitize_p = true;
    2180         3552 :           for (tree decl = BIND_EXPR_VARS (stmt);
    2181         6998 :                decl;
    2182         3446 :                decl = DECL_CHAIN (decl))
    2183         3446 :             if (VAR_P (decl)
    2184         3031 :                 && TREE_STATIC (decl)
    2185         3520 :                 && DECL_INITIAL (decl))
    2186           12 :               cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
    2187         3552 :           wtd->no_sanitize_p = no_sanitize_p;
    2188              :         }
    2189     26288779 :       if (flag_reflection)
    2190              :         /* Wipe consteval-only vars from BIND_EXPR_VARS and BLOCK_VARS.  */
    2191      1103496 :         for (tree *p = &BIND_EXPR_VARS (stmt); *p; )
    2192              :           {
    2193       537222 :             if (VAR_P (*p) && consteval_only_p (*p))
    2194              :               {
    2195          860 :                 if (BIND_EXPR_BLOCK (stmt)
    2196          860 :                     && *p == BLOCK_VARS (BIND_EXPR_BLOCK (stmt)))
    2197          458 :                   BLOCK_VARS (BIND_EXPR_BLOCK (stmt)) = DECL_CHAIN (*p);
    2198          860 :                 *p = DECL_CHAIN (*p);
    2199          860 :                 continue;
    2200              :               }
    2201       536362 :             p = &DECL_CHAIN (*p);
    2202              :           }
    2203     26288779 :       wtd->bind_expr_stack.safe_push (stmt);
    2204     26288779 :       cp_walk_tree (&BIND_EXPR_BODY (stmt),
    2205              :                     cp_genericize_r, data, NULL);
    2206     26288779 :       wtd->bind_expr_stack.pop ();
    2207     26288779 :       break;
    2208              : 
    2209          978 :     case ASSERTION_STMT:
    2210          978 :     case PRECONDITION_STMT:
    2211          978 :     case POSTCONDITION_STMT:
    2212          978 :       if (tree check = build_contract_check (stmt))
    2213              :         {
    2214          978 :           *stmt_p = check;
    2215          978 :           return cp_genericize_r (stmt_p, walk_subtrees, data);
    2216              :         }
    2217              :       /* If we didn't build a check, replace it with void_node so we don't
    2218              :          leak contracts into GENERIC.  */
    2219            0 :       *stmt_p = void_node;
    2220            0 :       *walk_subtrees = 0;
    2221            0 :       break;
    2222              : 
    2223        18515 :     case USING_STMT:
    2224        18515 :       {
    2225        18515 :         tree block = NULL_TREE;
    2226              : 
    2227              :         /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
    2228              :            BLOCK, and append an IMPORTED_DECL to its
    2229              :            BLOCK_VARS chained list.  */
    2230        18515 :         if (wtd->bind_expr_stack.exists ())
    2231              :           {
    2232        18515 :             int i;
    2233        18515 :             for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
    2234        18515 :               if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
    2235              :                 break;
    2236              :           }
    2237        18515 :         if (block)
    2238              :           {
    2239        18515 :             tree decl = TREE_OPERAND (stmt, 0);
    2240        18515 :             gcc_assert (decl);
    2241              : 
    2242        18515 :             if (undeduced_auto_decl (decl))
    2243              :               /* Omit from the GENERIC, the back-end can't handle it.  */;
    2244              :             else
    2245              :               {
    2246        18512 :                 tree using_directive = make_node (IMPORTED_DECL);
    2247        18512 :                 TREE_TYPE (using_directive) = void_type_node;
    2248        18512 :                 DECL_CONTEXT (using_directive) = current_function_decl;
    2249        37024 :                 DECL_SOURCE_LOCATION (using_directive)
    2250        18512 :                   = cp_expr_loc_or_input_loc (stmt);
    2251              : 
    2252        18512 :                 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
    2253        18512 :                 DECL_CHAIN (using_directive) = BLOCK_VARS (block);
    2254        18512 :                 BLOCK_VARS (block) = using_directive;
    2255              :               }
    2256              :           }
    2257              :         /* The USING_STMT won't appear in GENERIC.  */
    2258        18515 :         *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
    2259        18515 :         *walk_subtrees = 0;
    2260              :       }
    2261        18515 :       break;
    2262              : 
    2263     25999705 :     case DECL_EXPR:
    2264     25999705 :       if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
    2265              :         {
    2266              :           /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
    2267        20958 :           *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
    2268        20958 :           *walk_subtrees = 0;
    2269              :         }
    2270              :       else
    2271              :         {
    2272     25978747 :           tree d = DECL_EXPR_DECL (stmt);
    2273     25978747 :           if (VAR_P (d))
    2274     51955773 :             gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
    2275              :         }
    2276              :       break;
    2277              : 
    2278        11736 :     case OMP_PARALLEL:
    2279        11736 :     case OMP_TASK:
    2280        11736 :     case OMP_TASKLOOP:
    2281        11736 :       {
    2282        11736 :         struct cp_genericize_omp_taskreg omp_ctx;
    2283        11736 :         tree c, decl;
    2284        11736 :         splay_tree_node n;
    2285              : 
    2286        11736 :         *walk_subtrees = 0;
    2287        11736 :         cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
    2288        11736 :         omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
    2289        11736 :         omp_ctx.default_shared = omp_ctx.is_parallel;
    2290        11736 :         omp_ctx.outer = wtd->omp_ctx;
    2291        11736 :         omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
    2292        11736 :         wtd->omp_ctx = &omp_ctx;
    2293        27814 :         for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    2294        16078 :           switch (OMP_CLAUSE_CODE (c))
    2295              :             {
    2296         4797 :             case OMP_CLAUSE_SHARED:
    2297         4797 :             case OMP_CLAUSE_PRIVATE:
    2298         4797 :             case OMP_CLAUSE_FIRSTPRIVATE:
    2299         4797 :             case OMP_CLAUSE_LASTPRIVATE:
    2300         4797 :               decl = OMP_CLAUSE_DECL (c);
    2301         4797 :               if (decl == error_mark_node || !omp_var_to_track (decl))
    2302              :                 break;
    2303          519 :               n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
    2304          519 :               if (n != NULL)
    2305              :                 break;
    2306         1020 :               splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
    2307          510 :                                  OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
    2308              :                                  ? OMP_CLAUSE_DEFAULT_SHARED
    2309              :                                  : OMP_CLAUSE_DEFAULT_PRIVATE);
    2310          510 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
    2311           91 :                 omp_cxx_notice_variable (omp_ctx.outer, decl);
    2312              :               break;
    2313         1647 :             case OMP_CLAUSE_DEFAULT:
    2314         1647 :               if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
    2315          731 :                 omp_ctx.default_shared = true;
    2316              :             default:
    2317              :               break;
    2318              :             }
    2319        11736 :         if (TREE_CODE (stmt) == OMP_TASKLOOP)
    2320         1001 :           c_genericize_control_stmt (stmt_p, walk_subtrees, data,
    2321              :                                      cp_genericize_r, cp_walk_subtrees);
    2322              :         else
    2323        10735 :           cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
    2324        11736 :         wtd->omp_ctx = omp_ctx.outer;
    2325        11736 :         splay_tree_delete (omp_ctx.variables);
    2326              :       }
    2327        11736 :       break;
    2328              : 
    2329         6939 :     case OMP_TARGET:
    2330         6939 :       cfun->has_omp_target = true;
    2331         6939 :       break;
    2332              : 
    2333       140898 :     case TRY_BLOCK:
    2334       140898 :       {
    2335       140898 :         *walk_subtrees = 0;
    2336       140898 :         tree try_block = wtd->try_block;
    2337       140898 :         wtd->try_block = stmt;
    2338       140898 :         cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
    2339       140898 :         wtd->try_block = try_block;
    2340       140898 :         cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
    2341              :       }
    2342       140898 :       break;
    2343              : 
    2344     25789193 :     case MUST_NOT_THROW_EXPR:
    2345              :       /* MUST_NOT_THROW_COND might be something else with TM.  */
    2346     25789193 :       if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
    2347              :         {
    2348     25789175 :           *walk_subtrees = 0;
    2349     25789175 :           tree try_block = wtd->try_block;
    2350     25789175 :           wtd->try_block = stmt;
    2351     25789175 :           cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
    2352     25789175 :           wtd->try_block = try_block;
    2353              :         }
    2354              :       break;
    2355              : 
    2356       145524 :     case THROW_EXPR:
    2357       145524 :       {
    2358       145524 :         location_t loc = location_of (stmt);
    2359       145524 :         if (warning_suppressed_p (stmt /* What warning? */))
    2360              :           /* Never mind.  */;
    2361        45561 :         else if (wtd->try_block)
    2362              :           {
    2363        10633 :             if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
    2364              :               {
    2365           18 :                 auto_diagnostic_group d;
    2366           31 :                 if (warning_at (loc, OPT_Wterminate,
    2367              :                                 "%<throw%> will always call %<terminate%>")
    2368           10 :                     && cxx_dialect >= cxx11
    2369           36 :                     && DECL_DESTRUCTOR_P (current_function_decl))
    2370            5 :                   inform (loc, "in C++11 destructors default to %<noexcept%>");
    2371           18 :               }
    2372              :           }
    2373              :         else
    2374              :           {
    2375          103 :             if (warn_cxx11_compat && cxx_dialect < cxx11
    2376          206 :                 && DECL_DESTRUCTOR_P (current_function_decl)
    2377            1 :                 && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
    2378              :                     == NULL_TREE)
    2379        34929 :                 && (get_defaulted_eh_spec (current_function_decl)
    2380            1 :                     == empty_except_spec))
    2381            1 :               warning_at (loc, OPT_Wc__11_compat,
    2382              :                           "in C++11 this %<throw%> will call %<terminate%> "
    2383              :                           "because destructors default to %<noexcept%>");
    2384              :           }
    2385              :       }
    2386              :       break;
    2387              : 
    2388     42582697 :     case CONVERT_EXPR:
    2389     42582697 :       gcc_checking_assert (!AGGREGATE_TYPE_P (TREE_TYPE (stmt)));
    2390     42582697 :       gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
    2391              :       break;
    2392              : 
    2393       236974 :     case SPACESHIP_EXPR:
    2394       236974 :       *stmt_p = genericize_spaceship (*stmt_p);
    2395       236974 :       break;
    2396              : 
    2397        31961 :     case PTRMEM_CST:
    2398              :       /* By the time we get here we're handing off to the back end, so we don't
    2399              :          need or want to preserve PTRMEM_CST anymore.  */
    2400        31961 :       *stmt_p = cplus_expand_constant (stmt);
    2401        31961 :       *walk_subtrees = 0;
    2402        31961 :       break;
    2403              : 
    2404       282014 :     case MEM_REF:
    2405              :       /* For MEM_REF, make sure not to sanitize the second operand even
    2406              :          if it has reference type.  It is just an offset with a type
    2407              :          holding other information.  There is no other processing we
    2408              :          need to do for INTEGER_CSTs, so just ignore the second argument
    2409              :          unconditionally.  */
    2410       282014 :       cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
    2411       282014 :       *walk_subtrees = 0;
    2412       282014 :       break;
    2413              : 
    2414    120299057 :     case NOP_EXPR:
    2415    120299057 :       *stmt_p = predeclare_vla (*stmt_p);
    2416              : 
    2417              :       /* Warn of new allocations that are not big enough for the target
    2418              :          type.  */
    2419    120299057 :       if (warn_alloc_size
    2420      1085133 :           && TREE_CODE (TREE_OPERAND (stmt, 0)) == CALL_EXPR
    2421    120363835 :           && POINTER_TYPE_P (TREE_TYPE (stmt)))
    2422              :         {
    2423        23625 :           if (tree fndecl = get_callee_fndecl (TREE_OPERAND (stmt, 0)))
    2424        23611 :             if (DECL_IS_MALLOC (fndecl))
    2425              :               {
    2426         1165 :                 tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
    2427         1165 :                 tree alloc_size = lookup_attribute ("alloc_size", attrs);
    2428         1165 :                 if (alloc_size)
    2429         1163 :                   warn_for_alloc_size (EXPR_LOCATION (stmt),
    2430         1163 :                                        TREE_TYPE (TREE_TYPE (stmt)),
    2431         1163 :                                        TREE_OPERAND (stmt, 0), alloc_size);
    2432              :               }
    2433              :         }
    2434              : 
    2435    120299057 :       if (!wtd->no_sanitize_p
    2436    120299052 :           && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
    2437    120315031 :           && TYPE_REF_P (TREE_TYPE (stmt)))
    2438         2501 :         ubsan_maybe_instrument_reference (stmt_p);
    2439              :       break;
    2440              : 
    2441     76080846 :     case CALL_EXPR:
    2442     76080846 :       if (!wtd->no_sanitize_p
    2443     76080846 :           && sanitize_flags_p ((SANITIZE_NULL
    2444              :                                 | SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
    2445              :         {
    2446        16130 :           tree fn = CALL_EXPR_FN (stmt);
    2447        16130 :           if (fn != NULL_TREE
    2448        10009 :               && !error_operand_p (fn)
    2449        10009 :               && INDIRECT_TYPE_P (TREE_TYPE (fn))
    2450        26139 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
    2451              :             {
    2452         5669 :               bool is_ctor
    2453         5669 :                 = TREE_CODE (fn) == ADDR_EXPR
    2454         5546 :                   && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
    2455        16761 :                   && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
    2456         5669 :               if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
    2457         5058 :                 ubsan_maybe_instrument_member_call (stmt, is_ctor);
    2458         5669 :               if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
    2459         4825 :                 cp_ubsan_maybe_instrument_member_call (stmt);
    2460              :             }
    2461        10461 :           else if (fn == NULL_TREE
    2462         6121 :                    && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
    2463         5014 :                    && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
    2464        10467 :                    && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
    2465            6 :             *walk_subtrees = 0;
    2466              :         }
    2467              :       /* Fall through.  */
    2468     80946115 :     case AGGR_INIT_EXPR:
    2469              :       /* For calls to a multi-versioned function, overload resolution
    2470              :          returns the function with the highest target priority, that is,
    2471              :          the version that will checked for dispatching first.  If this
    2472              :          version is inlinable, a direct call to this version can be made
    2473              :          otherwise the call should go through the dispatcher.
    2474              :          This is done at multiple_target.cc for target_version semantics.  */
    2475     80946115 :       {
    2476     80946115 :         tree fn = cp_get_callee_fndecl_nofold (stmt);
    2477     80946115 :         if (TARGET_HAS_FMV_TARGET_ATTRIBUTE
    2478              :             && fn
    2479     79770067 :             && DECL_FUNCTION_VERSIONED (fn)
    2480     80946250 :             && (current_function_decl == NULL
    2481          135 :                 || !targetm.target_option.can_inline_p
    2482          135 :                       (current_function_decl, fn)))
    2483          123 :           if (tree dis = get_function_version_dispatcher (fn))
    2484              :             {
    2485          123 :               mark_versions_used (dis);
    2486          123 :               dis = build_address (dis);
    2487          123 :               if (TREE_CODE (stmt) == CALL_EXPR)
    2488          120 :                 CALL_EXPR_FN (stmt) = dis;
    2489              :               else
    2490            3 :                 AGGR_INIT_EXPR_FN (stmt) = dis;
    2491              :             }
    2492              :       }
    2493              :       break;
    2494              : 
    2495     19587634 :     case TARGET_EXPR:
    2496     19587634 :       if (TARGET_EXPR_INITIAL (stmt)
    2497     19587634 :           && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
    2498     22032714 :           && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
    2499          169 :         TARGET_EXPR_NO_ELIDE (stmt) = 1;
    2500              :       break;
    2501              : 
    2502          642 :     case TEMPLATE_ID_EXPR:
    2503          642 :       gcc_assert (concept_check_p (stmt));
    2504              :       /* Emit the value of the concept check.  */
    2505          642 :       *stmt_p = evaluate_concept_check (stmt);
    2506          642 :       walk_subtrees = 0;
    2507          642 :       break;
    2508              : 
    2509         4241 :     case OMP_DISTRIBUTE:
    2510              :       /* Need to explicitly instantiate copy ctors on class iterators of
    2511              :          composite distribute parallel for.  */
    2512         4241 :       if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
    2513              :         {
    2514         3742 :           tree *data[4] = { NULL, NULL, NULL, NULL };
    2515         3742 :           tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
    2516              :                                   find_combined_omp_for, data, NULL);
    2517         3742 :           if (inner != NULL_TREE
    2518         3708 :               && TREE_CODE (inner) == OMP_FOR)
    2519              :             {
    2520         4554 :               for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
    2521         2859 :                 if (TREE_VEC_ELT (OMP_FOR_INIT (inner), i)
    2522         2843 :                     && OMP_FOR_ORIG_DECLS (inner)
    2523         2843 :                     && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
    2524              :                                   i)) == TREE_LIST
    2525         2883 :                     && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
    2526              :                                      i)))
    2527              :                   {
    2528           12 :                     tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
    2529              :                     /* Class iterators aren't allowed on OMP_SIMD, so the only
    2530              :                        case we need to solve is distribute parallel for.  */
    2531           12 :                     gcc_assert (TREE_CODE (inner) == OMP_FOR
    2532              :                                 && data[1]);
    2533           12 :                     tree orig_decl = TREE_PURPOSE (orig);
    2534           12 :                     tree c, cl = NULL_TREE;
    2535           12 :                     for (c = OMP_FOR_CLAUSES (inner);
    2536           16 :                          c; c = OMP_CLAUSE_CHAIN (c))
    2537           12 :                       if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
    2538            5 :                            || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
    2539           13 :                           && OMP_CLAUSE_DECL (c) == orig_decl)
    2540              :                         {
    2541              :                           cl = c;
    2542              :                           break;
    2543              :                         }
    2544           12 :                     if (cl == NULL_TREE)
    2545              :                       {
    2546            4 :                         for (c = OMP_PARALLEL_CLAUSES (*data[1]);
    2547            4 :                              c; c = OMP_CLAUSE_CHAIN (c))
    2548            1 :                           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
    2549            1 :                               && OMP_CLAUSE_DECL (c) == orig_decl)
    2550              :                             {
    2551              :                               cl = c;
    2552              :                               break;
    2553              :                             }
    2554              :                       }
    2555            4 :                     if (cl)
    2556              :                       {
    2557            9 :                         orig_decl = require_complete_type (orig_decl);
    2558            9 :                         tree inner_type = TREE_TYPE (orig_decl);
    2559            9 :                         if (orig_decl == error_mark_node)
    2560            0 :                           continue;
    2561            9 :                         if (TYPE_REF_P (TREE_TYPE (orig_decl)))
    2562            0 :                           inner_type = TREE_TYPE (inner_type);
    2563              : 
    2564            9 :                         while (TREE_CODE (inner_type) == ARRAY_TYPE)
    2565            0 :                           inner_type = TREE_TYPE (inner_type);
    2566            9 :                         get_copy_ctor (inner_type, tf_warning_or_error);
    2567              :                       }
    2568              :                 }
    2569              :             }
    2570              :         }
    2571              :       /* FALLTHRU */
    2572              : 
    2573      5068860 :     case FOR_STMT:
    2574      5068860 :     case WHILE_STMT:
    2575      5068860 :     case DO_STMT:
    2576      5068860 :     case SWITCH_STMT:
    2577      5068860 :     case CONTINUE_STMT:
    2578      5068860 :     case BREAK_STMT:
    2579      5068860 :     case OMP_FOR:
    2580      5068860 :     case OMP_SIMD:
    2581      5068860 :     case OMP_LOOP:
    2582      5068860 :     case OMP_TILE:
    2583      5068860 :     case OMP_UNROLL:
    2584      5068860 :     case OACC_LOOP:
    2585              :       /* These cases are handled by shared code.  */
    2586      5068860 :       c_genericize_control_stmt (stmt_p, walk_subtrees, data,
    2587              :                                  cp_genericize_r, cp_walk_subtrees);
    2588      5068860 :       break;
    2589              : 
    2590     70770727 :     case STATEMENT_LIST:
    2591              :       /* As above, handled by shared code.  */
    2592     70770727 :       c_genericize_control_stmt (stmt_p, walk_subtrees, data,
    2593              :                                  cp_genericize_r, cp_walk_subtrees);
    2594              :       /* If a statement list is freed as part of genericisation it will be
    2595              :          pushed onto the top of a statement list cache stack.  A subsequent
    2596              :          action can cause a new statement list to be required - and the one
    2597              :          just pushed will be returned.  If that is marked as visited, it can
    2598              :          prevent a tail recursion from processing the 'new' statement list,
    2599              :          so we do not mark statement lists as visited.  */
    2600     70770727 :       return NULL_TREE;
    2601        76839 :       break;
    2602              : 
    2603        76839 :     case BIT_CAST_EXPR:
    2604        76839 :       *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
    2605        76839 :                             TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
    2606        76839 :       break;
    2607              : 
    2608     22184727 :     case MODIFY_EXPR:
    2609              :       /* Mark stores to parts of complex automatic non-addressable
    2610              :          variables as DECL_NOT_GIMPLE_REG_P for -O0.  This can't be
    2611              :          done during gimplification.  See PR119120.  */
    2612     22184727 :       if ((TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
    2613     22156288 :            || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR)
    2614        56889 :           && !optimize
    2615          552 :           && DECL_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0))
    2616     22184821 :           && is_gimple_reg (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)))
    2617           50 :         DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)) = 1;
    2618              :       break;
    2619              : 
    2620    856203629 :     default:
    2621    856203629 :       if (IS_TYPE_OR_DECL_P (stmt))
    2622    266550620 :         *walk_subtrees = 0;
    2623              :       break;
    2624              :     }
    2625              : 
    2626   1419284865 :   p_set->add (*stmt_p);
    2627              : 
    2628   1419284865 :   return NULL;
    2629              : }
    2630              : 
    2631              : /* Lower C++ front end trees to GENERIC in T_P.  */
    2632              : 
    2633              : static void
    2634     51927537 : cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
    2635              : {
    2636     51927537 :   struct cp_genericize_data wtd;
    2637              : 
    2638     51927537 :   wtd.p_set = new hash_set<tree>;
    2639     51927537 :   wtd.bind_expr_stack.create (0);
    2640     51927537 :   wtd.omp_ctx = NULL;
    2641     51927537 :   wtd.try_block = NULL_TREE;
    2642     51927537 :   wtd.no_sanitize_p = false;
    2643     51927537 :   wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
    2644     51927537 :   cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
    2645    103855074 :   delete wtd.p_set;
    2646     51927537 :   if (sanitize_flags_p (SANITIZE_VPTR))
    2647         5738 :     cp_ubsan_instrument_member_accesses (t_p);
    2648     51927537 : }
    2649              : 
    2650              : /* If a function that should end with a return in non-void
    2651              :    function doesn't obviously end with return, add ubsan
    2652              :    instrumentation code to verify it at runtime.  If -fsanitize=return
    2653              :    is not enabled, instrument __builtin_unreachable.  */
    2654              : 
    2655              : static void
    2656     51927537 : cp_maybe_instrument_return (tree fndecl)
    2657              : {
    2658     51927537 :   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
    2659     74493546 :       || DECL_CONSTRUCTOR_P (fndecl)
    2660     37246773 :       || DECL_DESTRUCTOR_P (fndecl)
    2661     89174310 :       || !targetm.warn_func_return (fndecl))
    2662              :     return;
    2663              : 
    2664     37246761 :   if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
    2665              :       /* Don't add __builtin_unreachable () if not optimizing, it will not
    2666              :          improve any optimizations in that case, just break UB code.
    2667              :          Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
    2668              :          UBSan covers this with ubsan_instrument_return above where sufficient
    2669              :          information is provided, while the __builtin_unreachable () below
    2670              :          if return sanitization is disabled will just result in hard to
    2671              :          understand runtime error without location.  */
    2672     37246761 :       && ((!optimize && !flag_unreachable_traps)
    2673     37242893 :           || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
    2674              :     return;
    2675              : 
    2676     37246731 :   tree t = DECL_SAVED_TREE (fndecl);
    2677     64299642 :   while (t)
    2678              :     {
    2679     64299642 :       switch (TREE_CODE (t))
    2680              :         {
    2681      4965827 :         case BIND_EXPR:
    2682      4965827 :           t = BIND_EXPR_BODY (t);
    2683      4965827 :           continue;
    2684      9018588 :         case TRY_FINALLY_EXPR:
    2685      9018588 :         case CLEANUP_POINT_EXPR:
    2686      9018588 :           t = TREE_OPERAND (t, 0);
    2687      9018588 :           continue;
    2688     13071315 :         case STATEMENT_LIST:
    2689     13071315 :           {
    2690     13071315 :             tree_stmt_iterator i = tsi_last (t);
    2691     13074940 :             while (!tsi_end_p (i))
    2692              :               {
    2693     13072121 :                 tree p = tsi_stmt (i);
    2694     13072121 :                 if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
    2695              :                   break;
    2696         3625 :                 tsi_prev (&i);
    2697              :               }
    2698     13071315 :             if (!tsi_end_p (i))
    2699              :               {
    2700     13068496 :                 t = tsi_stmt (i);
    2701     13068496 :                 continue;
    2702              :               }
    2703              :           }
    2704         2819 :           break;
    2705              :         case RETURN_EXPR:
    2706              :           return;
    2707              :         default:
    2708              :           break;
    2709     13984415 :         }
    2710              :       break;
    2711              :     }
    2712     20565000 :   if (t == NULL_TREE)
    2713              :     return;
    2714     20565000 :   tree *p = &DECL_SAVED_TREE (fndecl);
    2715     20565000 :   if (TREE_CODE (*p) == BIND_EXPR)
    2716       933222 :     p = &BIND_EXPR_BODY (*p);
    2717              : 
    2718     20565000 :   location_t loc = DECL_SOURCE_LOCATION (fndecl);
    2719     20565000 :   if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
    2720         1798 :     t = ubsan_instrument_return (loc);
    2721              :   else
    2722     20563202 :     t = build_builtin_unreachable (BUILTINS_LOCATION);
    2723              : 
    2724     20565000 :   append_to_statement_list (t, p);
    2725              : }
    2726              : 
    2727              : void
    2728     68575665 : cp_genericize (tree fndecl)
    2729              : {
    2730     68575665 :   tree t;
    2731              : 
    2732              :   /* Fix up the types of parms passed by invisible reference.  */
    2733    181753927 :   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
    2734    113178262 :     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
    2735              :       {
    2736              :         /* If a function's arguments are copied to create a thunk,
    2737              :            then DECL_BY_REFERENCE will be set -- but the type of the
    2738              :            argument will be a pointer type, so we will never get
    2739              :            here.  */
    2740       132446 :         gcc_assert (!DECL_BY_REFERENCE (t));
    2741       132446 :         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
    2742       132446 :         TREE_TYPE (t) = DECL_ARG_TYPE (t);
    2743       132446 :         DECL_BY_REFERENCE (t) = 1;
    2744       132446 :         TREE_ADDRESSABLE (t) = 0;
    2745       132446 :         relayout_decl (t);
    2746              :       }
    2747              : 
    2748              :   /* Do the same for the return value.  */
    2749     68575665 :   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
    2750              :     {
    2751      1169105 :       t = DECL_RESULT (fndecl);
    2752      1169105 :       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
    2753      1169105 :       DECL_BY_REFERENCE (t) = 1;
    2754      1169105 :       TREE_ADDRESSABLE (t) = 0;
    2755      1169105 :       relayout_decl (t);
    2756      1169105 :       if (DECL_NAME (t))
    2757              :         {
    2758              :           /* Adjust DECL_VALUE_EXPR of the original var.  */
    2759       130921 :           tree outer = outer_curly_brace_block (current_function_decl);
    2760       130921 :           tree var;
    2761              : 
    2762       130921 :           if (outer)
    2763       307709 :             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
    2764       306979 :               if (VAR_P (var)
    2765       296853 :                   && DECL_NAME (t) == DECL_NAME (var)
    2766       130191 :                   && DECL_HAS_VALUE_EXPR_P (var)
    2767       437170 :                   && DECL_VALUE_EXPR (var) == t)
    2768              :                 {
    2769       130191 :                   tree val = convert_from_reference (t);
    2770       130191 :                   SET_DECL_VALUE_EXPR (var, val);
    2771       130191 :                   break;
    2772              :                 }
    2773              :         }
    2774              :     }
    2775              : 
    2776              :   /* If we're a clone, the body is already GIMPLE.  */
    2777     68575665 :   if (DECL_CLONED_FUNCTION_P (fndecl))
    2778     16648128 :     return;
    2779              : 
    2780              :   /* Allow cp_genericize calls to be nested.  */
    2781     51927537 :   bc_state_t save_state;
    2782     51927537 :   save_bc_state (&save_state);
    2783              : 
    2784              :   /* We do want to see every occurrence of the parms, so we can't just use
    2785              :      walk_tree's hash functionality.  */
    2786     51927537 :   cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
    2787              : 
    2788     51927537 :   cp_maybe_instrument_return (fndecl);
    2789              : 
    2790              :   /* Do everything else.  */
    2791     51927537 :   c_genericize (fndecl);
    2792     51927537 :   restore_bc_state (&save_state);
    2793              : }
    2794              : 
    2795              : /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
    2796              :    NULL if there is in fact nothing to do.  ARG2 may be null if FN
    2797              :    actually only takes one argument.  */
    2798              : 
    2799              : static tree
    2800         3680 : cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
    2801              : {
    2802         3680 :   tree defparm, parm, t;
    2803         3680 :   int i = 0;
    2804         3680 :   int nargs;
    2805         3680 :   tree *argarray;
    2806              : 
    2807         3680 :   if (fn == NULL)
    2808              :     return NULL;
    2809              : 
    2810         2824 :   nargs = list_length (DECL_ARGUMENTS (fn));
    2811         2824 :   argarray = XALLOCAVEC (tree, nargs);
    2812              : 
    2813         2824 :   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
    2814         2824 :   if (arg2)
    2815          944 :     defparm = TREE_CHAIN (defparm);
    2816              : 
    2817         2824 :   bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
    2818         2824 :   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
    2819              :     {
    2820           27 :       tree inner_type = TREE_TYPE (arg1);
    2821           27 :       tree start1, end1, p1;
    2822           27 :       tree start2 = NULL, p2 = NULL;
    2823           27 :       tree ret = NULL, lab;
    2824              : 
    2825           27 :       start1 = arg1;
    2826           27 :       start2 = arg2;
    2827           27 :       do
    2828              :         {
    2829           27 :           inner_type = TREE_TYPE (inner_type);
    2830           27 :           start1 = build4 (ARRAY_REF, inner_type, start1,
    2831              :                            size_zero_node, NULL, NULL);
    2832           27 :           if (arg2)
    2833            9 :             start2 = build4 (ARRAY_REF, inner_type, start2,
    2834              :                              size_zero_node, NULL, NULL);
    2835              :         }
    2836           27 :       while (TREE_CODE (inner_type) == ARRAY_TYPE);
    2837           27 :       start1 = build_fold_addr_expr_loc (input_location, start1);
    2838           27 :       if (arg2)
    2839            9 :         start2 = build_fold_addr_expr_loc (input_location, start2);
    2840              : 
    2841           27 :       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
    2842           27 :       end1 = fold_build_pointer_plus (start1, end1);
    2843              : 
    2844           27 :       p1 = create_tmp_var (TREE_TYPE (start1));
    2845           27 :       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
    2846           27 :       append_to_statement_list (t, &ret);
    2847              : 
    2848           27 :       if (arg2)
    2849              :         {
    2850            9 :           p2 = create_tmp_var (TREE_TYPE (start2));
    2851            9 :           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
    2852            9 :           append_to_statement_list (t, &ret);
    2853              :         }
    2854              : 
    2855           27 :       lab = create_artificial_label (input_location);
    2856           27 :       t = build1 (LABEL_EXPR, void_type_node, lab);
    2857           27 :       append_to_statement_list (t, &ret);
    2858              : 
    2859           27 :       argarray[i++] = p1;
    2860           27 :       if (arg2)
    2861            9 :         argarray[i++] = p2;
    2862              :       /* Handle default arguments.  */
    2863           27 :       for (parm = defparm; parm && parm != void_list_node;
    2864            0 :            parm = TREE_CHAIN (parm), i++)
    2865            0 :         argarray[i] = convert_default_arg (TREE_VALUE (parm),
    2866            0 :                                            TREE_PURPOSE (parm), fn,
    2867              :                                            i - is_method, tf_warning_or_error);
    2868           27 :       t = build_call_a (fn, i, argarray);
    2869           27 :       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
    2870            0 :         t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
    2871           27 :       t = fold_convert (void_type_node, t);
    2872           27 :       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
    2873           27 :       append_to_statement_list (t, &ret);
    2874              : 
    2875           27 :       t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
    2876           27 :       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
    2877           27 :       append_to_statement_list (t, &ret);
    2878              : 
    2879           27 :       if (arg2)
    2880              :         {
    2881            9 :           t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
    2882            9 :           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
    2883            9 :           append_to_statement_list (t, &ret);
    2884              :         }
    2885              : 
    2886           27 :       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
    2887           27 :       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
    2888           27 :       append_to_statement_list (t, &ret);
    2889              : 
    2890           27 :       return ret;
    2891              :     }
    2892              :   else
    2893              :     {
    2894         2797 :       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
    2895         2797 :       if (arg2)
    2896          935 :         argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
    2897              :       /* Handle default arguments.  */
    2898         2802 :       for (parm = defparm; parm && parm != void_list_node;
    2899            5 :            parm = TREE_CHAIN (parm), i++)
    2900           10 :         argarray[i] = convert_default_arg (TREE_VALUE (parm),
    2901            5 :                                            TREE_PURPOSE (parm), fn,
    2902              :                                            i - is_method, tf_warning_or_error);
    2903         2797 :       t = build_call_a (fn, i, argarray);
    2904         2797 :       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
    2905            1 :         t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
    2906         2797 :       t = fold_convert (void_type_node, t);
    2907         2797 :       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
    2908              :     }
    2909              : }
    2910              : 
    2911              : /* Return code to initialize DECL with its default constructor, or
    2912              :    NULL if there's nothing to do.  */
    2913              : 
    2914              : tree
    2915        42656 : cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
    2916              : {
    2917        42656 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2918        42656 :   tree ret = NULL;
    2919              : 
    2920        42656 :   if (info)
    2921         1401 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
    2922              : 
    2923        42656 :   return ret;
    2924              : }
    2925              : 
    2926              : /* Return code to initialize DST with a copy constructor from SRC.  */
    2927              : 
    2928              : tree
    2929        12378 : cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
    2930              : {
    2931        12378 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2932        12378 :   tree ret = NULL;
    2933              : 
    2934        12378 :   if (info)
    2935          283 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
    2936          283 :   if (ret == NULL)
    2937        12160 :     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
    2938              : 
    2939        12378 :   return ret;
    2940              : }
    2941              : 
    2942              : /* Similarly, except use an assignment operator instead.  */
    2943              : 
    2944              : tree
    2945        12686 : cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
    2946              : {
    2947        12686 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2948        12686 :   tree ret = NULL;
    2949              : 
    2950        12686 :   if (info)
    2951          748 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
    2952          748 :   if (ret == NULL)
    2953        11960 :     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
    2954              : 
    2955        12686 :   return ret;
    2956              : }
    2957              : 
    2958              : /* Return code to destroy DECL.  */
    2959              : 
    2960              : tree
    2961        62712 : cxx_omp_clause_dtor (tree clause, tree decl)
    2962              : {
    2963        62712 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2964        62712 :   tree ret = NULL;
    2965              : 
    2966        62712 :   if (info)
    2967         1248 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
    2968              : 
    2969        62712 :   return ret;
    2970              : }
    2971              : 
    2972              : /* True if OpenMP should privatize what this DECL points to rather
    2973              :    than the DECL itself.  */
    2974              : 
    2975              : bool
    2976       978792 : cxx_omp_privatize_by_reference (const_tree decl)
    2977              : {
    2978       978792 :   return (TYPE_REF_P (TREE_TYPE (decl))
    2979       978792 :           || is_invisiref_parm (decl));
    2980              : }
    2981              : 
    2982              : /* Return true if DECL is const qualified var having no mutable member.  */
    2983              : bool
    2984        15435 : cxx_omp_const_qual_no_mutable (tree decl)
    2985              : {
    2986        15435 :   tree type = TREE_TYPE (decl);
    2987        15435 :   if (TYPE_REF_P (type))
    2988              :     {
    2989          864 :       if (!is_invisiref_parm (decl))
    2990              :         return false;
    2991            0 :       type = TREE_TYPE (type);
    2992              : 
    2993            0 :       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
    2994              :         {
    2995              :           /* NVR doesn't preserve const qualification of the
    2996              :              variable's type.  */
    2997            0 :           tree outer = outer_curly_brace_block (current_function_decl);
    2998            0 :           tree var;
    2999              : 
    3000            0 :           if (outer)
    3001            0 :             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
    3002            0 :               if (VAR_P (var)
    3003            0 :                   && DECL_NAME (decl) == DECL_NAME (var)
    3004            0 :                   && (TYPE_MAIN_VARIANT (type)
    3005            0 :                       == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
    3006              :                 {
    3007            0 :                   if (TYPE_READONLY (TREE_TYPE (var)))
    3008            0 :                     type = TREE_TYPE (var);
    3009              :                   break;
    3010              :                 }
    3011              :         }
    3012              :     }
    3013              : 
    3014        14571 :   if (type == error_mark_node)
    3015              :     return false;
    3016              : 
    3017              :   /* Variables with const-qualified type having no mutable member
    3018              :      are predetermined shared.  */
    3019        14556 :   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
    3020           69 :     return true;
    3021              : 
    3022              :   return false;
    3023              : }
    3024              : 
    3025              : /* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
    3026              :    of DECL is predetermined.  */
    3027              : 
    3028              : enum omp_clause_default_kind
    3029        55800 : cxx_omp_predetermined_sharing_1 (tree decl)
    3030              : {
    3031              :   /* Static data members are predetermined shared.  */
    3032        55800 :   if (TREE_STATIC (decl))
    3033              :     {
    3034        15173 :       tree ctx = CP_DECL_CONTEXT (decl);
    3035        15173 :       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
    3036              :         return OMP_CLAUSE_DEFAULT_SHARED;
    3037              : 
    3038        15067 :       if (c_omp_predefined_variable (decl))
    3039              :         return OMP_CLAUSE_DEFAULT_SHARED;
    3040              :     }
    3041              : 
    3042              :   /* this may not be specified in data-sharing clauses, still we need
    3043              :      to predetermined it firstprivate.  */
    3044        55649 :   if (decl == current_class_ptr)
    3045          113 :     return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
    3046              : 
    3047              :   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
    3048              : }
    3049              : 
    3050              : /* Likewise, but also include the artificial vars.  We don't want to
    3051              :    disallow the artificial vars being mentioned in explicit clauses,
    3052              :    as we use artificial vars e.g. for loop constructs with random
    3053              :    access iterators other than pointers, but during gimplification
    3054              :    we want to treat them as predetermined.  */
    3055              : 
    3056              : enum omp_clause_default_kind
    3057        35150 : cxx_omp_predetermined_sharing (tree decl)
    3058              : {
    3059        35150 :   enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
    3060        35150 :   if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    3061              :     return ret;
    3062              : 
    3063              :   /* Predetermine artificial variables holding integral values, those
    3064              :      are usually result of gimplify_one_sizepos or SAVE_EXPR
    3065              :      gimplification.  */
    3066        34933 :   if (VAR_P (decl)
    3067        23002 :       && DECL_ARTIFICIAL (decl)
    3068         7154 :       && INTEGRAL_TYPE_P (TREE_TYPE (decl))
    3069        35457 :       && !(DECL_LANG_SPECIFIC (decl)
    3070            2 :            && DECL_OMP_PRIVATIZED_MEMBER (decl)))
    3071              :     return OMP_CLAUSE_DEFAULT_SHARED;
    3072              : 
    3073              :   /* Similarly for typeinfo symbols.  */
    3074        34411 :   if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl))
    3075           60 :     return OMP_CLAUSE_DEFAULT_SHARED;
    3076              : 
    3077              :   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
    3078              : }
    3079              : 
    3080              : enum omp_clause_defaultmap_kind
    3081        17613 : cxx_omp_predetermined_mapping (tree decl)
    3082              : {
    3083              :   /* Predetermine artificial variables holding integral values, those
    3084              :      are usually result of gimplify_one_sizepos or SAVE_EXPR
    3085              :      gimplification.  */
    3086        17613 :   if (VAR_P (decl)
    3087         1676 :       && DECL_ARTIFICIAL (decl)
    3088          142 :       && INTEGRAL_TYPE_P (TREE_TYPE (decl))
    3089        17679 :       && !(DECL_LANG_SPECIFIC (decl)
    3090            6 :            && DECL_OMP_PRIVATIZED_MEMBER (decl)))
    3091              :     return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
    3092              : 
    3093        17547 :   if (c_omp_predefined_variable (decl))
    3094           12 :     return OMP_CLAUSE_DEFAULTMAP_TO;
    3095              : 
    3096              :   return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
    3097              : }
    3098              : 
    3099              : /* Finalize an implicitly determined clause.  */
    3100              : 
    3101              : void
    3102        64354 : cxx_omp_finish_clause (tree c, gimple_seq *, bool /* openacc */)
    3103              : {
    3104        64354 :   tree decl, inner_type;
    3105        64354 :   bool make_shared = false;
    3106              : 
    3107        64354 :   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
    3108        56857 :       && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
    3109        94422 :       && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
    3110         4752 :           || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
    3111              :     return;
    3112              : 
    3113        34301 :   decl = OMP_CLAUSE_DECL (c);
    3114        34301 :   decl = require_complete_type (decl);
    3115        34301 :   inner_type = TREE_TYPE (decl);
    3116        34301 :   if (decl == error_mark_node)
    3117        34301 :     make_shared = true;
    3118        34301 :   else if (TYPE_REF_P (TREE_TYPE (decl)))
    3119           86 :     inner_type = TREE_TYPE (inner_type);
    3120              : 
    3121              :   /* We're interested in the base element, not arrays.  */
    3122        34561 :   while (TREE_CODE (inner_type) == ARRAY_TYPE)
    3123          260 :     inner_type = TREE_TYPE (inner_type);
    3124              : 
    3125              :   /* Check for special function availability by building a call to one.
    3126              :      Save the results, because later we won't be in the right context
    3127              :      for making these queries.  */
    3128        34301 :   bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
    3129        34301 :   bool last = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE;
    3130        34301 :   if (!make_shared
    3131        34301 :       && CLASS_TYPE_P (inner_type)
    3132        34524 :       && cxx_omp_create_clause_info (c, inner_type, !first, first, last,
    3133              :                                      true))
    3134              :     make_shared = true;
    3135              : 
    3136        34295 :   if (make_shared)
    3137              :     {
    3138            6 :       OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
    3139            6 :       OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
    3140            6 :       OMP_CLAUSE_SHARED_READONLY (c) = 0;
    3141              :     }
    3142              : }
    3143              : 
    3144              : tree
    3145           38 : cxx_omp_finish_mapper_clauses (tree clauses)
    3146              : {
    3147           38 :   return finish_omp_clauses (clauses, C_ORT_OMP);
    3148              : }
    3149              : 
    3150              : /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
    3151              :    disregarded in OpenMP construct, because it is going to be
    3152              :    remapped during OpenMP lowering.  SHARED is true if DECL
    3153              :    is going to be shared, false if it is going to be privatized.  */
    3154              : 
    3155              : bool
    3156       669264 : cxx_omp_disregard_value_expr (tree decl, bool shared)
    3157              : {
    3158       669264 :   if (shared)
    3159              :     return false;
    3160       402492 :   if (VAR_P (decl)
    3161       380365 :       && DECL_HAS_VALUE_EXPR_P (decl)
    3162         9549 :       && DECL_ARTIFICIAL (decl)
    3163         9038 :       && DECL_LANG_SPECIFIC (decl)
    3164       410391 :       && DECL_OMP_PRIVATIZED_MEMBER (decl))
    3165              :     return true;
    3166       397079 :   if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
    3167              :     return true;
    3168              :   return false;
    3169              : }
    3170              : 
    3171              : /* Fold any non-ODR-usages of a constant variable in expression X.  */
    3172              : 
    3173              : static tree
    3174    591634534 : cp_fold_non_odr_use_1 (tree x)
    3175              : {
    3176    591634534 :   tree var = x;
    3177    892439259 :   while (!VAR_P (var))
    3178    816529767 :     switch (TREE_CODE (var))
    3179              :       {
    3180    288574124 :       case ARRAY_REF:
    3181    288574124 :       case BIT_FIELD_REF:
    3182    288574124 :       case COMPONENT_REF:
    3183    288574124 :       case VIEW_CONVERT_EXPR:
    3184    288574124 :       CASE_CONVERT:
    3185    288574124 :         var = TREE_OPERAND (var, 0);
    3186    288574124 :         break;
    3187              : 
    3188     28959254 :       case INDIRECT_REF:
    3189     28959254 :         if (REFERENCE_REF_P (var))
    3190     12230601 :           var = TREE_OPERAND (var, 0);
    3191              :         else
    3192              :           return x;
    3193     12230601 :         break;
    3194              : 
    3195              :       default:
    3196              :         return x;
    3197              :       }
    3198              : 
    3199     75909492 :   if (TREE_THIS_VOLATILE (var)
    3200     75909492 :       || !decl_constant_var_p (var))
    3201              :     return x;
    3202              : 
    3203              :   /* We mustn't fold std::hardware_destructive_interference_size here
    3204              :      so that maybe_warn_about_constant_value can complain if it's used
    3205              :      in a manifestly constant-evaluated context.  */
    3206      5870413 :   if (decl_in_std_namespace_p (var)
    3207      2800272 :       && DECL_NAME (var)
    3208      8670685 :       && id_equal (DECL_NAME (var), "hardware_destructive_interference_size"))
    3209              :     return x;
    3210              : 
    3211      5870413 :   tree t = maybe_constant_value (x);
    3212      5870413 :   return TREE_CONSTANT (t) ? t : x;
    3213              : }
    3214              : 
    3215              : /* Fold expression X which is used as an rvalue if RVAL is true.  */
    3216              : 
    3217              : static tree
    3218   2612382691 : cp_fold_maybe_rvalue (tree x, bool rval, fold_flags_t flags)
    3219              : {
    3220   2633478943 :   while (true)
    3221              :     {
    3222   2622930817 :       if (rval && (flags & ff_only_non_odr))
    3223    574642341 :         x = cp_fold_non_odr_use_1 (x);
    3224   2622930817 :       x = cp_fold (x, flags);
    3225   2622930817 :       if (rval)
    3226              :         {
    3227   1752580480 :           x = mark_rvalue_use (x);
    3228   1752580480 :           if (!(flags & ff_only_non_odr)
    3229   1752580480 :               && DECL_P (x) && !TYPE_REF_P (TREE_TYPE (x)))
    3230              :             {
    3231    263725750 :               tree v = decl_constant_value (x);
    3232    263725750 :               if (v != x && v != error_mark_node)
    3233              :                 {
    3234     10548126 :                   x = v;
    3235     10548126 :                   continue;
    3236              :                 }
    3237              :             }
    3238              :         }
    3239   2612382691 :       break;
    3240     10548126 :     }
    3241   2612382691 :   return x;
    3242              : }
    3243              : 
    3244              : tree
    3245     77301022 : cp_fold_maybe_rvalue (tree x, bool rval)
    3246              : {
    3247     77301022 :   return cp_fold_maybe_rvalue (x, rval, ff_none);
    3248              : }
    3249              : 
    3250              : /* Fold expression X which is used as an rvalue.  */
    3251              : 
    3252              : static tree
    3253    277021190 : cp_fold_rvalue (tree x, fold_flags_t flags)
    3254              : {
    3255     10256451 :   return cp_fold_maybe_rvalue (x, true, flags);
    3256              : }
    3257              : 
    3258              : tree
    3259      2175322 : cp_fold_rvalue (tree x)
    3260              : {
    3261      2175322 :   return cp_fold_rvalue (x, ff_none);
    3262              : }
    3263              : 
    3264              : /* Fold any non-ODR used constants in an expression X which
    3265              :    is used as an rvalue if RVAL is true.  */
    3266              : 
    3267              : tree
    3268       740370 : cp_fold_non_odr_use (tree x, bool rval)
    3269              : {
    3270       740370 :   return cp_fold_maybe_rvalue (x, rval, ff_only_non_odr);
    3271              : }
    3272              : 
    3273              : /* Perform folding on expression X.  */
    3274              : 
    3275              : static tree
    3276    290421555 : cp_fully_fold (tree x, mce_value manifestly_const_eval)
    3277              : {
    3278    290421555 :   if (processing_template_decl)
    3279              :     return x;
    3280              :   /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
    3281              :      have to call both.  */
    3282    264589417 :   if (cxx_dialect >= cxx11)
    3283              :     {
    3284    263461023 :       x = maybe_constant_value (x, /*decl=*/NULL_TREE, manifestly_const_eval);
    3285              :       /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
    3286              :          a TARGET_EXPR; undo that here.  */
    3287    263461023 :       if (TREE_CODE (x) == TARGET_EXPR)
    3288       681792 :         x = TARGET_EXPR_INITIAL (x);
    3289    262779231 :       else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
    3290     27993674 :                && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
    3291    262779417 :                && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
    3292          186 :         x = TREE_OPERAND (x, 0);
    3293              :     }
    3294    264589417 :   fold_flags_t flags = ff_none;
    3295    264589417 :   if (manifestly_const_eval == mce_false)
    3296     45837253 :     flags |= ff_mce_false;
    3297    264589417 :   return cp_fold_rvalue (x, flags);
    3298              : }
    3299              : 
    3300              : tree
    3301    244584302 : cp_fully_fold (tree x)
    3302              : {
    3303    244584302 :   return cp_fully_fold (x, mce_unknown);
    3304              : }
    3305              : 
    3306              : /* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
    3307              :    in some cases.  */
    3308              : 
    3309              : tree
    3310     48169408 : cp_fully_fold_init (tree x)
    3311              : {
    3312     48169408 :   if (processing_template_decl)
    3313      2332155 :     return x;
    3314     45837253 :   x = cp_fully_fold (x, mce_false);
    3315     45837253 :   cp_fold_data data (ff_mce_false);
    3316     45837253 :   if (cxx_dialect >= cxx20)
    3317              :     {
    3318     45197667 :       cp_walk_tree (&x, cp_fold_immediate_r, &data, NULL);
    3319     45197667 :       data.pset.empty ();
    3320              :     }
    3321     45837253 :   cp_walk_tree (&x, cp_fold_r, &data, NULL);
    3322     45837253 :   return x;
    3323     45837253 : }
    3324              : 
    3325              : /* c-common interface to cp_fold.  If IN_INIT, this is in a static initializer
    3326              :    and certain changes are made to the folding done.  Or should be (FIXME).  We
    3327              :    never touch maybe_const, as it is only used for the C front-end
    3328              :    C_MAYBE_CONST_EXPR.  */
    3329              : 
    3330              : tree
    3331     77301022 : c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
    3332              : {
    3333     77301022 :   return cp_fold_maybe_rvalue (x, !lval);
    3334              : }
    3335              : 
    3336              : static GTY((deletable)) hash_map<tree, tree> *fold_caches[3];
    3337              : 
    3338              : /* Subroutine of cp_fold.  Returns which fold cache to use according
    3339              :    to the given flags.  We need multiple caches since the result of
    3340              :    folding may depend on which flags are used.  */
    3341              : 
    3342              : static hash_map<tree, tree> *&
    3343   4830077029 : get_fold_cache (fold_flags_t flags)
    3344              : {
    3345            0 :   if (flags & ff_mce_false)
    3346   2173404775 :     return fold_caches[2];
    3347   2656672254 :   else if (flags & ff_only_non_odr)
    3348   2287924064 :     return fold_caches[1];
    3349              :   else
    3350    368748190 :     return fold_caches[0];
    3351              : }
    3352              : 
    3353              : /* Dispose of the whole FOLD_CACHE.  */
    3354              : 
    3355              : void
    3356     41217916 : clear_fold_cache (void)
    3357              : {
    3358    164871664 :   for (auto& fold_cache : fold_caches)
    3359    123653748 :     if (fold_cache != NULL)
    3360    148076006 :       fold_cache->empty ();
    3361     41217916 : }
    3362              : 
    3363              : /*  This function tries to fold an expression X.
    3364              :     To avoid combinatorial explosion, folding results are kept in fold_cache.
    3365              :     If X is invalid, we don't fold at all.
    3366              :     For performance reasons we don't cache expressions representing a
    3367              :     declaration or constant.
    3368              :     Function returns X or its folded variant.  */
    3369              : 
    3370              : static tree
    3371   7864247533 : cp_fold (tree x, fold_flags_t flags)
    3372              : {
    3373   7864247533 :   tree op0, op1, op2, op3;
    3374   7864247533 :   tree org_x = x, r = NULL_TREE;
    3375   7864247533 :   enum tree_code code;
    3376   7864247533 :   location_t loc;
    3377   7864247533 :   bool rval_ops = true;
    3378              : 
    3379   7864247533 :   if (!x || x == error_mark_node)
    3380              :     return x;
    3381              : 
    3382   7857724081 :   if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
    3383              :     return x;
    3384              : 
    3385              :   /* Don't bother to cache DECLs or constants.  */
    3386   7857421899 :   if (DECL_P (x) || CONSTANT_CLASS_P (x))
    3387              :     return x;
    3388              : 
    3389   4830077029 :   auto& fold_cache = get_fold_cache (flags);
    3390   4830077029 :   if (fold_cache == NULL)
    3391       521235 :     fold_cache = hash_map<tree, tree>::create_ggc (101);
    3392              : 
    3393   4830077029 :   if (tree *cached = fold_cache->get (x))
    3394              :     {
    3395              :       /* unshare_expr doesn't recurse into SAVE_EXPRs.  If SAVE_EXPR's
    3396              :          argument has been folded into a tree invariant, make sure it is
    3397              :          unshared.  See PR112727.  */
    3398   1108520218 :       if (TREE_CODE (x) == SAVE_EXPR && *cached != x)
    3399           85 :         return unshare_expr (*cached);
    3400   1108520133 :       return *cached;
    3401              :     }
    3402              : 
    3403   3721556811 :   uid_sensitive_constexpr_evaluation_checker c;
    3404              : 
    3405   3721556811 :   code = TREE_CODE (x);
    3406   3721556811 :   switch (code)
    3407              :     {
    3408    211431900 :     case CLEANUP_POINT_EXPR:
    3409              :       /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
    3410              :          effects.  */
    3411    211431900 :       r = cp_fold (TREE_OPERAND (x, 0), flags);
    3412    211431900 :       if (!TREE_SIDE_EFFECTS (r) && !(flags & ff_only_non_odr))
    3413      2418726 :         x = r;
    3414              :       break;
    3415              : 
    3416      1728890 :     case SIZEOF_EXPR:
    3417      1728890 :       x = fold_sizeof_expr (x);
    3418      1728890 :       break;
    3419              : 
    3420    331843353 :     case VIEW_CONVERT_EXPR:
    3421    331843353 :       rval_ops = false;
    3422              :       /* FALLTHRU */
    3423   1021546901 :     case NON_LVALUE_EXPR:
    3424   1021546901 :     CASE_CONVERT:
    3425              : 
    3426   1021546901 :       if (VOID_TYPE_P (TREE_TYPE (x)))
    3427              :         {
    3428              :           /* This is just to make sure we don't end up with casts to
    3429              :              void from error_mark_node.  If we just return x, then
    3430              :              cp_fold_r might fold the operand into error_mark_node and
    3431              :              leave the conversion in the IR.  STRIP_USELESS_TYPE_CONVERSION
    3432              :              during gimplification doesn't like such casts.
    3433              :              Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
    3434              :              folding of the operand should be in the caches and if in cp_fold_r
    3435              :              it will modify it in place.  */
    3436     93296548 :           op0 = cp_fold (TREE_OPERAND (x, 0), flags);
    3437     93296548 :           if (op0 == error_mark_node)
    3438          107 :             x = error_mark_node;
    3439              :           break;
    3440              :         }
    3441              : 
    3442    928250353 :       loc = EXPR_LOCATION (x);
    3443    928250353 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3444              : 
    3445    928250353 :       if (op0 == error_mark_node)
    3446            0 :         x = error_mark_node;
    3447    928250353 :       else if (flags & ff_only_non_odr)
    3448              :         {
    3449    345470257 :           if (op0 != TREE_OPERAND (x, 0))
    3450      2114914 :             x = build1_loc (loc, code, TREE_TYPE (x), op0);
    3451    345470257 :           if (code == NOP_EXPR)
    3452    176416481 :             REINTERPRET_CAST_P (x) = REINTERPRET_CAST_P (org_x);
    3453              :         }
    3454    582780096 :       else if (code == CONVERT_EXPR
    3455     46098115 :           && SCALAR_TYPE_P (TREE_TYPE (x))
    3456    628877183 :           && op0 != void_node)
    3457              :         /* During parsing we used convert_to_*_nofold; re-convert now using the
    3458              :            folding variants, since fold() doesn't do those transformations.  */
    3459     41672249 :         x = fold (convert (TREE_TYPE (x), op0));
    3460    541107847 :       else if (op0 != TREE_OPERAND (x, 0))
    3461    143965629 :         x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
    3462              :       else
    3463    397142218 :         x = fold (x);
    3464              : 
    3465              :       /* Conversion of an out-of-range value has implementation-defined
    3466              :          behavior; the language considers it different from arithmetic
    3467              :          overflow, which is undefined.  */
    3468    928250353 :       if (TREE_CODE (op0) == INTEGER_CST
    3469    928250353 :           && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
    3470           44 :         TREE_OVERFLOW (x) = false;
    3471              : 
    3472              :       break;
    3473              : 
    3474          261 :     case EXCESS_PRECISION_EXPR:
    3475          261 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3476          261 :       if (op0 == error_mark_node)
    3477            0 :         x = error_mark_node;
    3478          261 :       else if (flags & ff_only_non_odr)
    3479              :         {
    3480           67 :           if (op0 != TREE_OPERAND (x, 0))
    3481            0 :             x = build1_loc (EXPR_LOCATION (x), code, TREE_TYPE (x), op0);
    3482              :         }
    3483              :       else
    3484          194 :         x = fold_convert_loc (EXPR_LOCATION (x), TREE_TYPE (x), op0);
    3485              :       break;
    3486              : 
    3487    127938520 :     case INDIRECT_REF:
    3488              :       /* We don't need the decltype(auto) obfuscation anymore.  */
    3489    127938520 :       if (REF_PARENTHESIZED_P (x))
    3490              :         {
    3491          776 :           tree p = maybe_undo_parenthesized_ref (x);
    3492          776 :           if (p != x)
    3493            0 :             return cp_fold (p, flags);
    3494              :         }
    3495              :       /* When folding non-ODR usages of constants, we also want to
    3496              :          remove any constant-initialized references, even when
    3497              :          used as lvalues.  */
    3498    127938520 :       if ((flags & ff_only_non_odr) && REFERENCE_REF_P (x))
    3499              :         {
    3500     16992193 :           op0 = cp_fold_non_odr_use_1 (TREE_OPERAND (x, 0));
    3501     16992193 :           if (op0 != TREE_OPERAND (x, 0))
    3502         1518 :             return convert_from_reference (cp_fold (op0, flags));
    3503              :         }
    3504    127937002 :       goto unary;
    3505              : 
    3506    319587886 :     case ADDR_EXPR:
    3507    319587886 :       loc = EXPR_LOCATION (x);
    3508    319587886 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false, flags);
    3509              : 
    3510              :       /* Cope with user tricks that amount to offsetof.  */
    3511    319587886 :       if (op0 != error_mark_node
    3512    319587886 :           && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0))
    3513    438450424 :           && !(flags & ff_only_non_odr))
    3514              :         {
    3515     65905122 :           tree val = get_base_address (op0);
    3516     65905122 :           if (val
    3517     65905122 :               && INDIRECT_REF_P (val)
    3518     25577594 :               && COMPLETE_TYPE_P (TREE_TYPE (val))
    3519     91482626 :               && TREE_CONSTANT (TREE_OPERAND (val, 0)))
    3520              :             {
    3521          261 :               val = TREE_OPERAND (val, 0);
    3522          261 :               STRIP_NOPS (val);
    3523          261 :               val = maybe_constant_value (val);
    3524          261 :               if (TREE_CODE (val) == INTEGER_CST)
    3525          127 :                 return fold_offsetof (op0, TREE_TYPE (x));
    3526              :             }
    3527              :         }
    3528    319587759 :       goto finish_unary;
    3529              : 
    3530              :     case REALPART_EXPR:
    3531              :     case IMAGPART_EXPR:
    3532    171036521 :       rval_ops = false;
    3533              :       /* FALLTHRU */
    3534    171036521 :     case CONJ_EXPR:
    3535    171036521 :     case FIX_TRUNC_EXPR:
    3536    171036521 :     case FLOAT_EXPR:
    3537    171036521 :     case NEGATE_EXPR:
    3538    171036521 :     case ABS_EXPR:
    3539    171036521 :     case ABSU_EXPR:
    3540    171036521 :     case BIT_NOT_EXPR:
    3541    171036521 :     case TRUTH_NOT_EXPR:
    3542    171036521 :     case FIXED_CONVERT_EXPR:
    3543    171036521 :     unary:
    3544              : 
    3545    171036521 :       loc = EXPR_LOCATION (x);
    3546    171036521 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3547              : 
    3548    490624280 :     finish_unary:
    3549    490624280 :       if (op0 == error_mark_node)
    3550            0 :         x = error_mark_node;
    3551    490624280 :       else if (op0 != TREE_OPERAND (x, 0))
    3552              :         {
    3553     31791739 :           if (flags & ff_only_non_odr)
    3554       426533 :             x = build1_loc (loc, code, TREE_TYPE (x), op0);
    3555              :           else
    3556     31365206 :             x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
    3557     31791739 :           if (code == INDIRECT_REF
    3558      9720138 :               && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
    3559              :             {
    3560      9719933 :               TREE_READONLY (x) = TREE_READONLY (org_x);
    3561      9719933 :               TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
    3562      9719933 :               TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
    3563              :             }
    3564              :         }
    3565    458832541 :       else if (!(flags & ff_only_non_odr))
    3566    226646105 :         x = fold (x);
    3567              : 
    3568    490624280 :       gcc_assert (TREE_CODE (x) != COND_EXPR
    3569              :                   || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
    3570              :       break;
    3571              : 
    3572       319676 :     case UNARY_PLUS_EXPR:
    3573       319676 :       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
    3574       319676 :       if (op0 == error_mark_node)
    3575            0 :         x = error_mark_node;
    3576       319676 :       else if (flags & ff_only_non_odr)
    3577              :         {
    3578       126317 :           if (op0 != TREE_OPERAND (x, 0))
    3579           12 :             x = build1_loc (EXPR_LOCATION (x), code, TREE_TYPE (x), op0);
    3580              :         }
    3581              :       else
    3582       193359 :         x = fold_convert (TREE_TYPE (x), op0);
    3583              :       break;
    3584              : 
    3585    201867517 :     case POSTDECREMENT_EXPR:
    3586    201867517 :     case POSTINCREMENT_EXPR:
    3587    201867517 :     case INIT_EXPR:
    3588    201867517 :     case PREDECREMENT_EXPR:
    3589    201867517 :     case PREINCREMENT_EXPR:
    3590    201867517 :     case COMPOUND_EXPR:
    3591    201867517 :     case MODIFY_EXPR:
    3592    201867517 :       rval_ops = false;
    3593              :       /* FALLTHRU */
    3594    419222544 :     case POINTER_PLUS_EXPR:
    3595    419222544 :     case PLUS_EXPR:
    3596    419222544 :     case POINTER_DIFF_EXPR:
    3597    419222544 :     case MINUS_EXPR:
    3598    419222544 :     case MULT_EXPR:
    3599    419222544 :     case TRUNC_DIV_EXPR:
    3600    419222544 :     case CEIL_DIV_EXPR:
    3601    419222544 :     case FLOOR_DIV_EXPR:
    3602    419222544 :     case ROUND_DIV_EXPR:
    3603    419222544 :     case TRUNC_MOD_EXPR:
    3604    419222544 :     case CEIL_MOD_EXPR:
    3605    419222544 :     case ROUND_MOD_EXPR:
    3606    419222544 :     case RDIV_EXPR:
    3607    419222544 :     case EXACT_DIV_EXPR:
    3608    419222544 :     case MIN_EXPR:
    3609    419222544 :     case MAX_EXPR:
    3610    419222544 :     case LSHIFT_EXPR:
    3611    419222544 :     case RSHIFT_EXPR:
    3612    419222544 :     case LROTATE_EXPR:
    3613    419222544 :     case RROTATE_EXPR:
    3614    419222544 :     case BIT_AND_EXPR:
    3615    419222544 :     case BIT_IOR_EXPR:
    3616    419222544 :     case BIT_XOR_EXPR:
    3617    419222544 :     case TRUTH_AND_EXPR:
    3618    419222544 :     case TRUTH_ANDIF_EXPR:
    3619    419222544 :     case TRUTH_OR_EXPR:
    3620    419222544 :     case TRUTH_ORIF_EXPR:
    3621    419222544 :     case TRUTH_XOR_EXPR:
    3622    419222544 :     case LT_EXPR: case LE_EXPR:
    3623    419222544 :     case GT_EXPR: case GE_EXPR:
    3624    419222544 :     case EQ_EXPR: case NE_EXPR:
    3625    419222544 :     case UNORDERED_EXPR: case ORDERED_EXPR:
    3626    419222544 :     case UNLT_EXPR: case UNLE_EXPR:
    3627    419222544 :     case UNGT_EXPR: case UNGE_EXPR:
    3628    419222544 :     case UNEQ_EXPR: case LTGT_EXPR:
    3629    419222544 :     case RANGE_EXPR: case COMPLEX_EXPR:
    3630              : 
    3631    419222544 :       loc = EXPR_LOCATION (x);
    3632    419222544 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3633    419222544 :       bool clear_decl_read;
    3634    419222544 :       clear_decl_read = false;
    3635    419222544 :       if (code == MODIFY_EXPR
    3636     52752603 :           && (VAR_P (op0) || TREE_CODE (op0) == PARM_DECL)
    3637    434007711 :           && !DECL_READ_P (op0))
    3638              :         clear_decl_read = true;
    3639    419222544 :       op1 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 1),
    3640              :                                   code != COMPOUND_EXPR, flags);
    3641    419222544 :       if (clear_decl_read)
    3642       779125 :         DECL_READ_P (op0) = 0;
    3643              : 
    3644    419222544 :       if (flags & ff_only_non_odr)
    3645              :         {
    3646    182539435 :           if (op0 == error_mark_node || op1 == error_mark_node)
    3647           24 :             x = error_mark_node;
    3648    182539411 :           else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
    3649              :             {
    3650      8091810 :               if (code == INIT_EXPR && op1 != TREE_OPERAND (x, 1))
    3651      2534075 :                 set_target_expr_eliding (op1);
    3652      8091810 :               x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
    3653              :             }
    3654              :           break;
    3655              :         }
    3656              : 
    3657              :       /* decltype(nullptr) has only one value, so optimize away all comparisons
    3658              :          with that type right away, keeping them in the IL causes troubles for
    3659              :          various optimizations.  */
    3660    236683109 :       if (COMPARISON_CLASS_P (org_x)
    3661     39333517 :           && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
    3662    236683136 :           && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
    3663              :         {
    3664           27 :           switch (code)
    3665              :             {
    3666           12 :             case EQ_EXPR:
    3667           12 :               x = constant_boolean_node (true, TREE_TYPE (x));
    3668           12 :               break;
    3669           15 :             case NE_EXPR:
    3670           15 :               x = constant_boolean_node (false, TREE_TYPE (x));
    3671           15 :               break;
    3672            0 :             default:
    3673            0 :               gcc_unreachable ();
    3674              :             }
    3675           27 :           return omit_two_operands_loc (loc, TREE_TYPE (x), x,
    3676           27 :                                         op0, op1);
    3677              :         }
    3678              : 
    3679    236683082 :       if (op0 == error_mark_node || op1 == error_mark_node)
    3680          102 :         x = error_mark_node;
    3681    236682980 :       else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
    3682    162872196 :         x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
    3683              :       else
    3684     73810784 :         x = fold (x);
    3685              : 
    3686              :       /* This is only needed for -Wnonnull-compare and only if
    3687              :          TREE_NO_WARNING (org_x), but to avoid that option affecting code
    3688              :          generation, we do it always.  */
    3689    236683082 :       if (COMPARISON_CLASS_P (org_x))
    3690              :         {
    3691     39333490 :           if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
    3692              :             ;
    3693     38191962 :           else if (COMPARISON_CLASS_P (x))
    3694              :             {
    3695     37173194 :               if (warn_nonnull_compare
    3696     37173194 :                   && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
    3697       122805 :                 suppress_warning (x, OPT_Wnonnull_compare);
    3698              :             }
    3699              :           /* Otherwise give up on optimizing these, let GIMPLE folders
    3700              :              optimize those later on.  */
    3701      1018768 :           else if (op0 != TREE_OPERAND (org_x, 0)
    3702      1018768 :                    || op1 != TREE_OPERAND (org_x, 1))
    3703              :             {
    3704      1016687 :               x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
    3705      1016687 :               if (warn_nonnull_compare
    3706      1016687 :                   && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
    3707           16 :                 suppress_warning (x, OPT_Wnonnull_compare);
    3708              :             }
    3709              :           else
    3710         2081 :             x = org_x;
    3711              :         }
    3712              : 
    3713              :       break;
    3714              : 
    3715      9936775 :     case VEC_COND_EXPR:
    3716      9936775 :     case COND_EXPR:
    3717      9936775 :       loc = EXPR_LOCATION (x);
    3718      9936775 :       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
    3719      9936775 :       op1 = cp_fold (TREE_OPERAND (x, 1), flags);
    3720      9936775 :       op2 = cp_fold (TREE_OPERAND (x, 2), flags);
    3721              : 
    3722      9936775 :       if (flags & ff_only_non_odr)
    3723              :         {
    3724      4179648 :           if (op0 == error_mark_node
    3725      4179642 :               || op1 == error_mark_node
    3726      4179642 :               || op2 == error_mark_node)
    3727            6 :             x = error_mark_node;
    3728      4179642 :           else if (op0 != TREE_OPERAND (x, 0)
    3729      4102159 :                    || op1 != TREE_OPERAND (x, 1)
    3730      8052432 :                    || op2 != TREE_OPERAND (x, 2))
    3731       321743 :             x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
    3732              :           break;
    3733              :         }
    3734              : 
    3735      5757127 :       if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
    3736              :         {
    3737        21102 :           warning_sentinel s (warn_int_in_bool_context);
    3738        21102 :           if (!VOID_TYPE_P (TREE_TYPE (op1)))
    3739        21102 :             op1 = cp_truthvalue_conversion (op1, tf_warning_or_error);
    3740        21102 :           if (!VOID_TYPE_P (TREE_TYPE (op2)))
    3741        21081 :             op2 = cp_truthvalue_conversion (op2, tf_warning_or_error);
    3742        21102 :         }
    3743      5736025 :       else if (VOID_TYPE_P (TREE_TYPE (x)))
    3744              :         {
    3745      1851228 :           if (TREE_CODE (op0) == INTEGER_CST)
    3746              :             {
    3747              :               /* If the condition is constant, fold can fold away
    3748              :                  the COND_EXPR.  If some statement-level uses of COND_EXPR
    3749              :                  have one of the branches NULL, avoid folding crash.  */
    3750       305906 :               if (!op1)
    3751            0 :                 op1 = build_empty_stmt (loc);
    3752       305906 :               if (!op2)
    3753           12 :                 op2 = build_empty_stmt (loc);
    3754              :             }
    3755              :           else
    3756              :             {
    3757              :               /* Otherwise, don't bother folding a void condition, since
    3758              :                  it can't produce a constant value.  */
    3759      1545322 :               if (op0 != TREE_OPERAND (x, 0)
    3760      1455081 :                   || op1 != TREE_OPERAND (x, 1)
    3761      2643663 :                   || op2 != TREE_OPERAND (x, 2))
    3762       449252 :                 x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
    3763              :               break;
    3764              :             }
    3765              :         }
    3766              : 
    3767      4211805 :       if (op0 == error_mark_node
    3768      4211805 :           || op1 == error_mark_node
    3769      4211791 :           || op2 == error_mark_node)
    3770           62 :         x = error_mark_node;
    3771      4211743 :       else if (op0 != TREE_OPERAND (x, 0)
    3772      1677809 :                || op1 != TREE_OPERAND (x, 1)
    3773      5522732 :                || op2 != TREE_OPERAND (x, 2))
    3774      3008600 :         x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
    3775              :       else
    3776      1203143 :         x = fold (x);
    3777              : 
    3778              :       /* A COND_EXPR might have incompatible types in branches if one or both
    3779              :          arms are bitfields.  If folding exposed such a branch, fix it up.  */
    3780      4211805 :       if (TREE_CODE (x) != code
    3781       944817 :           && x != error_mark_node
    3782      5156560 :           && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
    3783        17769 :         x = fold_convert (TREE_TYPE (org_x), x);
    3784              : 
    3785              :       break;
    3786              : 
    3787    232402619 :     case CALL_EXPR:
    3788    232402619 :       {
    3789    232402619 :         tree callee = get_callee_fndecl (x);
    3790              : 
    3791              :         /* "Inline" calls to std::move/forward and other cast-like functions
    3792              :            by simply folding them into a corresponding cast to their return
    3793              :            type.  This is cheaper than relying on the middle end to do so, and
    3794              :            also means we avoid generating useless debug info for them at all.
    3795              : 
    3796              :            At this point the argument has already been converted into a
    3797              :            reference, so it suffices to use a NOP_EXPR to express the
    3798              :            cast.  */
    3799    232402619 :         if ((OPTION_SET_P (flag_fold_simple_inlines)
    3800    232402619 :              ? flag_fold_simple_inlines
    3801    232402304 :              : !flag_no_inline)
    3802    219978458 :             && !(flags & ff_only_non_odr)
    3803    127097763 :             && call_expr_nargs (x) == 1
    3804     66910280 :             && decl_in_std_namespace_p (callee)
    3805     42842753 :             && DECL_NAME (callee) != NULL_TREE
    3806    275245372 :             && (id_equal (DECL_NAME (callee), "move")
    3807     41520500 :                 || id_equal (DECL_NAME (callee), "forward")
    3808     39901181 :                 || id_equal (DECL_NAME (callee), "forward_like")
    3809     39901035 :                 || id_equal (DECL_NAME (callee), "addressof")
    3810              :                 /* This addressof equivalent is used heavily in libstdc++.  */
    3811     39560055 :                 || id_equal (DECL_NAME (callee), "__addressof")
    3812     39172947 :                 || id_equal (DECL_NAME (callee), "to_underlying")
    3813     39172941 :                 || id_equal (DECL_NAME (callee), "as_const")))
    3814              :           {
    3815      3672409 :             r = CALL_EXPR_ARG (x, 0);
    3816              :             /* These type-checks must be performed here, because invalid
    3817              :                definitions of these functions could fail to ensure those and
    3818              :                build_nop could misbehave.  See PR122185.  */
    3819      3672409 :             if (id_equal (DECL_NAME (callee), "to_underlying")
    3820      3672409 :                 ? TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
    3821            6 :                   && INTEGRAL_TYPE_P (TREE_TYPE (x))
    3822      6616718 :                 : INDIRECT_TYPE_P (TREE_TYPE (x))
    3823      6616706 :                   && INDIRECT_TYPE_P (TREE_TYPE (r)))
    3824              :               {
    3825      3672394 :                 r = build_nop (TREE_TYPE (x), r);
    3826      3672394 :                 x = cp_fold (r, flags);
    3827              :               }
    3828              :             break;
    3829              :           }
    3830              : 
    3831    228730210 :         int sv = optimize, nw = sv;
    3832              : 
    3833              :         /* Some built-in function calls will be evaluated at compile-time in
    3834              :            fold ().  Set optimize to 1 when folding __builtin_constant_p inside
    3835              :            a constexpr function so that fold_builtin_1 doesn't fold it to 0.  */
    3836    226295783 :         if (callee && fndecl_built_in_p (callee) && !optimize
    3837      2112547 :             && DECL_IS_BUILTIN_CONSTANT_P (callee)
    3838        48797 :             && current_function_decl
    3839    228778991 :             && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
    3840              :           nw = 1;
    3841              : 
    3842    226295783 :         if (callee && !(flags & ff_only_non_odr)
    3843    357767793 :             && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
    3844              :           {
    3845        60457 :             iloc_sentinel ils (EXPR_LOCATION (x));
    3846        60457 :             switch (DECL_FE_FUNCTION_CODE (callee))
    3847              :               {
    3848        55342 :               case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
    3849              :                 /* Defer folding __builtin_is_constant_evaluated unless
    3850              :                    we know this isn't a manifestly constant-evaluated
    3851              :                    context.  */
    3852        55342 :                 if (flags & ff_mce_false)
    3853        28051 :                   x = boolean_false_node;
    3854              :                 break;
    3855            3 :               case CP_BUILT_IN_SOURCE_LOCATION:
    3856            3 :                 x = fold_builtin_source_location (x);
    3857            3 :                 break;
    3858          456 :               case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
    3859          912 :                 x = fold_builtin_is_corresponding_member
    3860          456 :                         (EXPR_LOCATION (x), call_expr_nargs (x),
    3861              :                          &CALL_EXPR_ARG (x, 0));
    3862          456 :                 break;
    3863          400 :               case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
    3864          800 :                 x = fold_builtin_is_pointer_inverconvertible_with_class
    3865          400 :                         (EXPR_LOCATION (x), call_expr_nargs (x),
    3866              :                          &CALL_EXPR_ARG (x, 0));
    3867          400 :                 break;
    3868              :               default:
    3869              :                 break;
    3870              :               }
    3871        60457 :             break;
    3872        60457 :           }
    3873              : 
    3874    228669753 :         bool changed = false;
    3875    228669753 :         int m = call_expr_nargs (x);
    3876    563777951 :         for (int i = 0; i < m; i++)
    3877              :           {
    3878    335108198 :             r = cp_fold (CALL_EXPR_ARG (x, i), flags);
    3879    335108198 :             if (r != CALL_EXPR_ARG (x, i))
    3880              :               {
    3881    110303138 :                 if (r == error_mark_node)
    3882              :                   {
    3883            0 :                     x = error_mark_node;
    3884            0 :                     break;
    3885              :                   }
    3886    110303138 :                 if (!changed)
    3887     70329838 :                   x = copy_node (x);
    3888    110303138 :                 CALL_EXPR_ARG (x, i) = r;
    3889    110303138 :                 changed = true;
    3890              :               }
    3891              :           }
    3892              :         /* Don't fold away the function entirely if we're just folding
    3893              :            non-ODR-used variables.  */
    3894    228669753 :         if (x == error_mark_node || (flags & ff_only_non_odr))
    3895              :           break;
    3896              : 
    3897    130384144 :         optimize = nw;
    3898    130384144 :         r = fold (x);
    3899    130384144 :         optimize = sv;
    3900              : 
    3901    130384144 :         if (TREE_CODE (r) != CALL_EXPR)
    3902              :           {
    3903      2961940 :             x = cp_fold (r, flags);
    3904      2961940 :             break;
    3905              :           }
    3906              : 
    3907    127422204 :         optimize = nw;
    3908              : 
    3909              :         /* Invoke maybe_constant_value for functions declared
    3910              :            constexpr and not called with AGGR_INIT_EXPRs.
    3911              :            TODO:
    3912              :            Do constexpr expansion of expressions where the call itself is not
    3913              :            constant, but the call followed by an INDIRECT_REF is.  */
    3914    126015186 :         if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
    3915              :             && !(flags & ff_only_non_odr)
    3916    190391221 :             && (!flag_no_inline
    3917      3611625 :                 || lookup_attribute ("always_inline",
    3918      3611625 :                                      DECL_ATTRIBUTES (callee))))
    3919              :           {
    3920     60151602 :             mce_value manifestly_const_eval = mce_unknown;
    3921     60151602 :             if (flags & ff_mce_false)
    3922              :               /* Allow folding __builtin_is_constant_evaluated to false during
    3923              :                  constexpr evaluation of this call.  */
    3924     46653981 :               manifestly_const_eval = mce_false;
    3925     60151602 :             r = maybe_constant_value (x, /*decl=*/NULL_TREE,
    3926              :                                       manifestly_const_eval);
    3927              :           }
    3928    127422204 :         optimize = sv;
    3929              : 
    3930    127422204 :         if (TREE_CODE (r) != CALL_EXPR)
    3931              :           {
    3932      9167140 :             if (DECL_CONSTRUCTOR_P (callee))
    3933          433 :               r = cp_build_init_expr_for_ctor (x, r);
    3934      4583570 :             x = r;
    3935      4583570 :             break;
    3936              :           }
    3937              : 
    3938              :         break;
    3939              :       }
    3940              : 
    3941     24355769 :     case CONSTRUCTOR:
    3942     24355769 :       {
    3943     24355769 :         unsigned i;
    3944     24355769 :         constructor_elt *p;
    3945     24355769 :         vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
    3946     24355769 :         vec<constructor_elt, va_gc> *nelts = NULL;
    3947    116595669 :         FOR_EACH_VEC_SAFE_ELT (elts, i, p)
    3948              :           {
    3949     81049894 :             tree op = cp_fold (p->value, flags);
    3950     81049894 :             if (op == error_mark_node)
    3951              :               {
    3952            0 :                 x = error_mark_node;
    3953            0 :                 vec_free (nelts);
    3954              :                 break;
    3955              :               }
    3956     81049894 :             else if (op != p->value)
    3957              :               {
    3958      1248559 :                 if (nelts == NULL)
    3959       802322 :                   nelts = elts->copy ();
    3960      1248559 :                 (*nelts)[i].value = op;
    3961              :               }
    3962              :           }
    3963     24355769 :         if (nelts)
    3964              :           {
    3965       802322 :             x = build_constructor (TREE_TYPE (x), nelts);
    3966       802322 :             CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
    3967       802322 :               = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
    3968       802322 :             CONSTRUCTOR_MUTABLE_POISON (x)
    3969      1604644 :               = CONSTRUCTOR_MUTABLE_POISON (org_x);
    3970              :           }
    3971     24355769 :         if (VECTOR_TYPE_P (TREE_TYPE (x)))
    3972        78688 :           x = fold (x);
    3973              :         break;
    3974              :       }
    3975       823299 :     case TREE_VEC:
    3976       823299 :       {
    3977       823299 :         bool changed = false;
    3978       823299 :         int n = TREE_VEC_LENGTH (x);
    3979              : 
    3980      2069389 :         for (int i = 0; i < n; i++)
    3981              :           {
    3982      1246090 :             tree op = cp_fold (TREE_VEC_ELT (x, i), flags);
    3983      1246090 :             if (op != TREE_VEC_ELT (x, i))
    3984              :               {
    3985          865 :                 if (!changed)
    3986          822 :                   x = copy_node (x);
    3987          865 :                 TREE_VEC_ELT (x, i) = op;
    3988          865 :                 changed = true;
    3989              :               }
    3990              :           }
    3991              :       }
    3992              : 
    3993              :       break;
    3994              : 
    3995      3248091 :     case ARRAY_REF:
    3996      3248091 :     case ARRAY_RANGE_REF:
    3997              : 
    3998      3248091 :       loc = EXPR_LOCATION (x);
    3999      3248091 :       op0 = cp_fold (TREE_OPERAND (x, 0), flags);
    4000      3248091 :       op1 = cp_fold (TREE_OPERAND (x, 1), flags);
    4001      3248091 :       op2 = cp_fold (TREE_OPERAND (x, 2), flags);
    4002      3248091 :       op3 = cp_fold (TREE_OPERAND (x, 3), flags);
    4003              : 
    4004      3248091 :       if (op0 == error_mark_node
    4005      3248091 :           || op1 == error_mark_node
    4006      3248091 :           || op2 == error_mark_node
    4007      3248091 :           || op3 == error_mark_node)
    4008            0 :         x = error_mark_node;
    4009      3248091 :       else if (op0 != TREE_OPERAND (x, 0)
    4010      2231578 :           || op1 != TREE_OPERAND (x, 1)
    4011      1729493 :           || op2 != TREE_OPERAND (x, 2)
    4012      4977584 :           || op3 != TREE_OPERAND (x, 3))
    4013              :         {
    4014      1518598 :           x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
    4015      1518598 :           TREE_READONLY (x) = TREE_READONLY (org_x);
    4016      1518598 :           TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
    4017      1518598 :           TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
    4018              :         }
    4019              : 
    4020      3248091 :       if (!(flags & ff_only_non_odr))
    4021      1890900 :         x = fold (x);
    4022              :       break;
    4023              : 
    4024      1710082 :     case SAVE_EXPR:
    4025              :       /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
    4026              :          folding, evaluates to an invariant.  In that case no need to wrap
    4027              :          this folded tree with a SAVE_EXPR.  */
    4028      1710082 :       r = cp_fold (TREE_OPERAND (x, 0), flags);
    4029      1710082 :       if (tree_invariant_p (r))
    4030           57 :         x = r;
    4031              :       break;
    4032              : 
    4033           10 :     case REQUIRES_EXPR:
    4034           10 :       x = evaluate_requires_expr (x);
    4035           10 :       break;
    4036              : 
    4037              :     default:
    4038              :       return org_x;
    4039              :     }
    4040              : 
    4041   2417351070 :   if (EXPR_P (x) && TREE_CODE (x) == code)
    4042              :     {
    4043   2010777602 :       TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
    4044   2010777602 :       copy_warning (x, org_x);
    4045              :     }
    4046              : 
    4047   2417351070 :   if (!c.evaluation_restricted_p ())
    4048              :     {
    4049   2417299605 :       fold_cache->put (org_x, x);
    4050              :       /* Prevent that we try to fold an already folded result again.  */
    4051   2417299605 :       if (x != org_x)
    4052    759438901 :         fold_cache->put (x, x);
    4053              :     }
    4054              : 
    4055              :   return x;
    4056              : }
    4057              : 
    4058              : /* Look up "hot", "cold", "likely" or "unlikely" in attribute list LIST.  */
    4059              : 
    4060              : tree
    4061    313229226 : lookup_hotness_attribute (tree list)
    4062              : {
    4063    313337568 :   for (; list; list = TREE_CHAIN (list))
    4064              :     {
    4065      1997388 :       tree name = get_attribute_name (list);
    4066      1997388 :       if ((is_attribute_p ("hot", name)
    4067      1997388 :            || is_attribute_p ("cold", name)
    4068      1997385 :            || is_attribute_p ("likely", name)
    4069      1381302 :            || is_attribute_p ("unlikely", name))
    4070      3886443 :           && is_attribute_namespace_p ("", list))
    4071              :         break;
    4072              :     }
    4073    313229226 :   return list;
    4074              : }
    4075              : 
    4076              : /* Remove "hot", "cold", "likely" and "unlikely" attributes from LIST.  */
    4077              : 
    4078              : static tree
    4079      1889037 : remove_hotness_attribute (tree list)
    4080              : {
    4081      3778092 :   for (tree *p = &list; *p; )
    4082              :     {
    4083      1889055 :       tree l = *p;
    4084      1889055 :       tree name = get_attribute_name (l);
    4085      1889055 :       if ((is_attribute_p ("hot", name)
    4086      1889055 :            || is_attribute_p ("cold", name)
    4087      1889052 :            || is_attribute_p ("likely", name)
    4088      1272969 :            || is_attribute_p ("unlikely", name))
    4089      3778110 :           && is_attribute_namespace_p ("", l))
    4090              :         {
    4091      1889046 :           *p = TREE_CHAIN (l);
    4092      1889046 :           continue;
    4093              :         }
    4094            9 :       p = &TREE_CHAIN (l);
    4095              :     }
    4096      1889037 :   return list;
    4097              : }
    4098              : 
    4099              : /* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
    4100              :    PREDICT_EXPR.  */
    4101              : 
    4102              : tree
    4103    311340207 : process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc)
    4104              : {
    4105    311340207 :   if (std_attrs == error_mark_node)
    4106              :     return std_attrs;
    4107    311340189 :   if (tree attr = lookup_hotness_attribute (std_attrs))
    4108              :     {
    4109      1889037 :       tree name = get_attribute_name (attr);
    4110      1889037 :       bool hot = (is_attribute_p ("hot", name)
    4111      1889037 :                   || is_attribute_p ("likely", name));
    4112      1889037 :       tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL,
    4113              :                                       hot ? TAKEN : NOT_TAKEN);
    4114      1889037 :       SET_EXPR_LOCATION (pred, attrs_loc);
    4115      1889037 :       add_stmt (pred);
    4116      1889037 :       if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
    4117              :         {
    4118            9 :           auto_urlify_attributes sentinel;
    4119            9 :           warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
    4120              :                    get_attribute_name (other), name);
    4121            9 :         }
    4122      1889037 :       std_attrs = remove_hotness_attribute (std_attrs);
    4123              :     }
    4124              :   return std_attrs;
    4125              : }
    4126              : 
    4127              : /* Build IFN_ASSUME internal call for assume condition ARG.  */
    4128              : 
    4129              : tree
    4130        11859 : build_assume_call (location_t loc, tree arg)
    4131              : {
    4132        11859 :   if (!processing_template_decl)
    4133        11758 :     arg = fold_build_cleanup_point_expr (TREE_TYPE (arg), arg);
    4134        11859 :   return build_call_expr_internal_loc (loc, IFN_ASSUME, void_type_node,
    4135        11859 :                                        1, arg);
    4136              : }
    4137              : 
    4138              : /* If [[assume (cond)]] appears on this statement, handle it.  */
    4139              : 
    4140              : tree
    4141    245870544 : process_stmt_assume_attribute (tree std_attrs, tree statement,
    4142              :                                location_t attrs_loc)
    4143              : {
    4144    245870544 :   if (std_attrs == error_mark_node)
    4145              :     return std_attrs;
    4146    245870526 :   tree attr = lookup_attribute ("gnu", "assume", std_attrs);
    4147    245870526 :   if (!attr)
    4148              :     return std_attrs;
    4149              :   /* The next token after the assume attribute is not ';'.  */
    4150        11775 :   if (statement)
    4151              :     {
    4152           12 :       warning_at (attrs_loc, OPT_Wattributes,
    4153              :                   "%<assume%> attribute not followed by %<;%>");
    4154           12 :       attr = NULL_TREE;
    4155              :     }
    4156        23574 :   for (; attr; attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
    4157              :     {
    4158        11799 :       tree args = TREE_VALUE (attr);
    4159        11799 :       if (args && PACK_EXPANSION_P (args))
    4160              :         {
    4161            6 :           auto_diagnostic_group d;
    4162            6 :           error_at (attrs_loc, "pack expansion of %qE attribute",
    4163              :                     get_attribute_name (attr));
    4164            6 :           if (cxx_dialect >= cxx17)
    4165            4 :             inform (attrs_loc, "use fold expression in the attribute "
    4166              :                                "argument instead");
    4167            6 :           continue;
    4168            6 :         }
    4169        11793 :       int nargs = list_length (args);
    4170        11793 :       if (nargs != 1)
    4171              :         {
    4172           42 :           auto_diagnostic_group d;
    4173           42 :           error_at (attrs_loc, "wrong number of arguments specified for "
    4174              :                                "%qE attribute", get_attribute_name (attr));
    4175           42 :           inform (attrs_loc, "expected %i, found %i", 1, nargs);
    4176           42 :         }
    4177              :       else
    4178              :         {
    4179        11751 :           tree arg = TREE_VALUE (args);
    4180        11751 :           if (!type_dependent_expression_p (arg))
    4181        11650 :             arg = contextual_conv_bool (arg, tf_warning_or_error);
    4182        11751 :           if (error_operand_p (arg))
    4183           18 :             continue;
    4184        11733 :           finish_expr_stmt (build_assume_call (attrs_loc, arg));
    4185              :         }
    4186              :     }
    4187        11775 :   return remove_attribute ("gnu", "assume", std_attrs);
    4188              : }
    4189              : 
    4190              : /* Return the type std::source_location::__impl after performing
    4191              :    verification on it.  */
    4192              : 
    4193              : tree
    4194        10349 : get_source_location_impl_type ()
    4195              : {
    4196        10349 :   tree name = get_identifier ("source_location");
    4197        10349 :   tree decl = lookup_qualified_name (std_node, name);
    4198        10349 :   if (TREE_CODE (decl) != TYPE_DECL)
    4199              :     {
    4200            6 :       auto_diagnostic_group d;
    4201            6 :       if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
    4202            3 :         qualified_name_lookup_error (std_node, name, decl, input_location);
    4203              :       else
    4204            3 :         error ("%qD is not a type", decl);
    4205            6 :       return error_mark_node;
    4206            6 :     }
    4207        10343 :   name = get_identifier ("__impl");
    4208        10343 :   tree type = TREE_TYPE (decl);
    4209        10343 :   decl = lookup_qualified_name (type, name);
    4210        10343 :   if (TREE_CODE (decl) != TYPE_DECL)
    4211              :     {
    4212            9 :       auto_diagnostic_group d;
    4213            9 :       if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
    4214            6 :         qualified_name_lookup_error (type, name, decl, input_location);
    4215              :       else
    4216            3 :         error ("%qD is not a type", decl);
    4217            9 :       return error_mark_node;
    4218            9 :     }
    4219        10334 :   type = TREE_TYPE (decl);
    4220        10334 :   if (TREE_CODE (type) != RECORD_TYPE)
    4221              :     {
    4222            3 :       error ("%qD is not a class type", decl);
    4223            3 :       return error_mark_node;
    4224              :     }
    4225              : 
    4226        10331 :   int cnt = 0;
    4227        10331 :   for (tree field = TYPE_FIELDS (type);
    4228        51616 :        (field = next_aggregate_field (field)) != NULL_TREE;
    4229        41285 :        field = DECL_CHAIN (field))
    4230              :     {
    4231        41294 :       if (DECL_NAME (field) != NULL_TREE)
    4232              :         {
    4233        41294 :           const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
    4234        41294 :           if (strcmp (n, "_M_file_name") == 0
    4235        30966 :               || strcmp (n, "_M_function_name") == 0)
    4236              :             {
    4237        20653 :               if (TREE_TYPE (field) != const_string_type_node)
    4238              :                 {
    4239            3 :                   error ("%qD does not have %<const char *%> type", field);
    4240            3 :                   return error_mark_node;
    4241              :                 }
    4242        20650 :               cnt++;
    4243        20650 :               continue;
    4244              :             }
    4245        20641 :           else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0)
    4246              :             {
    4247        20638 :               if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
    4248              :                 {
    4249            3 :                   error ("%qD does not have integral type", field);
    4250            3 :                   return error_mark_node;
    4251              :                 }
    4252        20635 :               cnt++;
    4253        20635 :               continue;
    4254              :             }
    4255              :         }
    4256              :       cnt = 0;
    4257              :       break;
    4258              :     }
    4259        10325 :   if (cnt != 4)
    4260              :     {
    4261            9 :       error ("%<std::source_location::__impl%> does not contain only "
    4262              :              "non-static data members %<_M_file_name%>, "
    4263              :              "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
    4264            9 :       return error_mark_node;
    4265              :     }
    4266        10316 :   return build_qualified_type (type, TYPE_QUAL_CONST);
    4267              : }
    4268              : 
    4269              : /* Type for source_location_table hash_set.  */
    4270              : struct GTY((for_user)) source_location_table_entry {
    4271              :   location_t loc;
    4272              :   unsigned uid;
    4273              :   tree var;
    4274              : };
    4275              : 
    4276              : /* Traits class for function start hash maps below.  */
    4277              : 
    4278              : struct source_location_table_entry_hash
    4279              :   : ggc_remove <source_location_table_entry>
    4280              : {
    4281              :   typedef source_location_table_entry value_type;
    4282              :   typedef source_location_table_entry compare_type;
    4283              : 
    4284              :   static hashval_t
    4285        57767 :   hash (const source_location_table_entry &ref)
    4286              :   {
    4287        57767 :     inchash::hash hstate (0);
    4288        57767 :     hstate.add_int (ref.loc);
    4289        57767 :     hstate.add_int (ref.uid);
    4290        57767 :     return hstate.end ();
    4291              :   }
    4292              : 
    4293              :   static bool
    4294        50298 :   equal (const source_location_table_entry &ref1,
    4295              :          const source_location_table_entry &ref2)
    4296              :   {
    4297        50298 :     return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
    4298              :   }
    4299              : 
    4300              :   static void
    4301              :   mark_deleted (source_location_table_entry &ref)
    4302              :   {
    4303              :     ref.loc = UNKNOWN_LOCATION;
    4304              :     ref.uid = -1U;
    4305              :     ref.var = NULL_TREE;
    4306              :   }
    4307              : 
    4308              :   static const bool empty_zero_p = true;
    4309              : 
    4310              :   static void
    4311            0 :   mark_empty (source_location_table_entry &ref)
    4312              :   {
    4313            0 :     ref.loc = UNKNOWN_LOCATION;
    4314            0 :     ref.uid = 0;
    4315            0 :     ref.var = NULL_TREE;
    4316              :   }
    4317              : 
    4318              :   static bool
    4319        80055 :   is_deleted (const source_location_table_entry &ref)
    4320              :   {
    4321        80055 :     return (ref.loc == UNKNOWN_LOCATION
    4322            0 :             && ref.uid == -1U
    4323        80055 :             && ref.var == NULL_TREE);
    4324              :   }
    4325              : 
    4326              :   static bool
    4327       305527 :   is_empty (const source_location_table_entry &ref)
    4328              :   {
    4329       305527 :     return (ref.loc == UNKNOWN_LOCATION
    4330       136773 :             && ref.uid == 0
    4331       442300 :             && ref.var == NULL_TREE);
    4332              :   }
    4333              : 
    4334              :   static void
    4335            3 :   pch_nx (source_location_table_entry &p)
    4336              :   {
    4337            3 :     extern void gt_pch_nx (source_location_table_entry &);
    4338            3 :     gt_pch_nx (p);
    4339              :   }
    4340              : 
    4341              :   static void
    4342            3 :   pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
    4343              :   {
    4344            3 :     extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
    4345              :                            void *);
    4346            3 :     gt_pch_nx (&p, op, cookie);
    4347              :   }
    4348              : };
    4349              : 
    4350              : static GTY(()) hash_table <source_location_table_entry_hash>
    4351              :   *source_location_table;
    4352              : 
    4353              : /* Build a std::source_location::__impl from a location_t.  */
    4354              : 
    4355              : tree
    4356        11996 : build_source_location_impl (location_t loc, tree fndecl,
    4357              :                             tree source_location_impl)
    4358              : {
    4359        11996 :   if (source_location_table == NULL)
    4360          366 :     source_location_table
    4361          366 :       = hash_table <source_location_table_entry_hash>::create_ggc (64);
    4362        11996 :   const line_map_ordinary *map;
    4363        11996 :   source_location_table_entry entry;
    4364        11996 :   entry.loc
    4365        11996 :     = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
    4366              :                                 &map);
    4367        11996 :   entry.uid = fndecl ? DECL_UID (fndecl) : -1;
    4368        11996 :   entry.var = error_mark_node;
    4369        11996 :   source_location_table_entry *entryp
    4370        11996 :     = source_location_table->find_slot (entry, INSERT);
    4371              : 
    4372        11996 :   if (entryp->var)
    4373              :     return entryp->var;
    4374              : 
    4375         8865 :   tree var = build_decl (loc, VAR_DECL, generate_internal_label ("Lsrc_loc"),
    4376              :                          source_location_impl);
    4377         8865 :   TREE_STATIC (var) = 1;
    4378         8865 :   TREE_PUBLIC (var) = 0;
    4379         8865 :   DECL_ARTIFICIAL (var) = 1;
    4380         8865 :   DECL_IGNORED_P (var) = 1;
    4381         8865 :   DECL_EXTERNAL (var) = 0;
    4382         8865 :   DECL_DECLARED_CONSTEXPR_P (var) = 1;
    4383         8865 :   DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
    4384         8865 :   layout_decl (var, 0);
    4385              : 
    4386         8865 :   vec<constructor_elt, va_gc> *v = NULL;
    4387         8865 :   vec_alloc (v, 4);
    4388         8865 :   for (tree field = TYPE_FIELDS (source_location_impl);
    4389        44325 :         (field = next_aggregate_field (field)) != NULL_TREE;
    4390        35460 :         field = DECL_CHAIN (field))
    4391              :     {
    4392        35460 :       const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
    4393        35460 :       tree val = NULL_TREE;
    4394        35460 :       if (strcmp (n, "_M_file_name") == 0)
    4395              :         {
    4396         8865 :           if (const char *fname = LOCATION_FILE (loc))
    4397              :             {
    4398         8865 :               fname = remap_macro_filename (fname);
    4399         8865 :               val = build_string_literal (fname);
    4400              :             }
    4401              :           else
    4402            0 :             val = build_string_literal ("");
    4403              :         }
    4404        26595 :       else if (strcmp (n, "_M_function_name") == 0)
    4405              :         {
    4406         8865 :           const char *name = "";
    4407              : 
    4408         8865 :           if (fndecl)
    4409              :             {
    4410              :               /* If this is a coroutine, we should get the name of the user
    4411              :                  function rather than the actor we generate.  */
    4412         8490 :               if (tree ramp = DECL_RAMP_FN (fndecl))
    4413           12 :                 name = cxx_printable_name (ramp, 2);
    4414              :               else
    4415         8478 :                 name = cxx_printable_name (fndecl, 2);
    4416              :             }
    4417              : 
    4418         8865 :           val = build_string_literal (name);
    4419              :         }
    4420        17730 :       else if (strcmp (n, "_M_line") == 0)
    4421         8865 :         val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
    4422         8865 :       else if (strcmp (n, "_M_column") == 0)
    4423         8865 :         val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
    4424              :       else
    4425            0 :         gcc_unreachable ();
    4426        35460 :       CONSTRUCTOR_APPEND_ELT (v, field, val);
    4427              :     }
    4428              : 
    4429         8865 :   tree ctor = build_constructor (source_location_impl, v);
    4430         8865 :   TREE_CONSTANT (ctor) = 1;
    4431         8865 :   TREE_STATIC (ctor) = 1;
    4432         8865 :   DECL_INITIAL (var) = ctor;
    4433         8865 :   varpool_node::finalize_decl (var);
    4434         8865 :   *entryp = entry;
    4435         8865 :   entryp->var = var;
    4436         8865 :   return var;
    4437              : }
    4438              : 
    4439              : /* Fold the __builtin_source_location () call T.  */
    4440              : 
    4441              : tree
    4442        11022 : fold_builtin_source_location (const_tree t)
    4443              : {
    4444        11022 :   gcc_assert (TREE_CODE (t) == CALL_EXPR);
    4445              :   /* TREE_TYPE (t) is const std::source_location::__impl*  */
    4446        11022 :   tree source_location_impl = TREE_TYPE (TREE_TYPE (t));
    4447        11022 :   if (source_location_impl == error_mark_node)
    4448            0 :     return build_zero_cst (const_ptr_type_node);
    4449        11022 :   gcc_assert (CLASS_TYPE_P (source_location_impl)
    4450              :               && id_equal (TYPE_IDENTIFIER (source_location_impl), "__impl"));
    4451              : 
    4452        11022 :   location_t loc = EXPR_LOCATION (t);
    4453        11022 :   tree var = build_source_location_impl (loc, current_function_decl,
    4454              :                                          source_location_impl);
    4455        11022 :   return build_fold_addr_expr_with_type_loc (loc, var, TREE_TYPE (t));
    4456              : }
    4457              : 
    4458              : #include "gt-cp-cp-gimplify.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.