LCOV - code coverage report
Current view: top level - gcc/cp - cp-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.2 % 2308 2175
Test Date: 2026-07-11 15:47:05 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     26153827 : remember_escalating_expr (tree t)
      58              : {
      59     26153827 :   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     26153827 :   if (!deferred_escalating_exprs)
      64        19797 :     deferred_escalating_exprs = hash_set<tree>::create_ggc (37);
      65     26153827 :   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    129918743 : struct cp_fold_data
      88              : {
      89              :   hash_set<tree> pset;
      90              :   fold_flags_t flags;
      91    199164810 :   cp_fold_data (fold_flags_t flags): flags (flags)
      92              :   {
      93    199164810 :     gcc_checking_assert (!(flags & ff_mce_false)
      94              :                          || !(flags & ff_only_non_odr));
      95    199164810 :   }
      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        18172 : genericize_try_block (tree *stmt_p)
     110              : {
     111        18172 :   tree body = TRY_STMTS (*stmt_p);
     112        18172 :   tree cleanup = TRY_HANDLERS (*stmt_p);
     113              : 
     114        18172 :   *stmt_p = build2 (TRY_CATCH_EXPR, void_type_node, body, cleanup);
     115        18172 : }
     116              : 
     117              : /* Genericize a HANDLER by converting to a CATCH_EXPR.  */
     118              : 
     119              : static void
     120        21270 : genericize_catch_block (tree *stmt_p)
     121              : {
     122        21270 :   tree type = HANDLER_TYPE (*stmt_p);
     123        21270 :   tree body = HANDLER_BODY (*stmt_p);
     124              : 
     125              :   /* FIXME should the caught type go in TREE_TYPE?  */
     126        21270 :   *stmt_p = build2 (CATCH_EXPR, void_type_node, type, body);
     127        21270 : }
     128              : 
     129              : /* A terser interface for building a representation of an exception
     130              :    specification.  */
     131              : 
     132              : static tree
     133         5832 : build_gimple_eh_filter_tree (tree body, tree allowed, tree failure)
     134              : {
     135         5832 :   tree t;
     136              : 
     137              :   /* FIXME should the allowed types go in TREE_TYPE?  */
     138         5832 :   t = build2 (EH_FILTER_EXPR, void_type_node, allowed, NULL_TREE);
     139         5832 :   append_to_statement_list (failure, &EH_FILTER_FAILURE (t));
     140              : 
     141         5832 :   t = build2 (TRY_CATCH_EXPR, void_type_node, NULL_TREE, t);
     142         5832 :   append_to_statement_list (body, &TREE_OPERAND (t, 0));
     143              : 
     144         5832 :   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         5832 : genericize_eh_spec_block (tree *stmt_p)
     152              : {
     153         5832 :   tree body = EH_SPEC_STMTS (*stmt_p);
     154         5832 :   tree allowed = EH_SPEC_RAISES (*stmt_p);
     155         5832 :   tree failure = build_call_n (call_unexpected_fn, 1, build_exc_ptr ());
     156              : 
     157         5832 :   *stmt_p = build_gimple_eh_filter_tree (body, allowed, failure);
     158         5832 :   suppress_warning (*stmt_p);
     159         5832 :   suppress_warning (TREE_OPERAND (*stmt_p, 1));
     160         5832 : }
     161              : 
     162              : /* Return the first non-compound statement in STMT.  */
     163              : 
     164              : tree
     165     14899824 : first_stmt (tree stmt)
     166              : {
     167     22598003 :   switch (TREE_CODE (stmt))
     168              :     {
     169      5963310 :     case STATEMENT_LIST:
     170      5963310 :       if (tree_statement_list_node *p = STATEMENT_LIST_HEAD (stmt))
     171      4038959 :         return first_stmt (p->stmt);
     172      1924351 :       return void_node;
     173              : 
     174      3659220 :     case BIND_EXPR:
     175      3659220 :       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     21952671 : genericize_if_stmt (tree *stmt_p)
     186              : {
     187     21952671 :   tree stmt, cond, then_, else_;
     188     21952671 :   location_t locus = EXPR_LOCATION (*stmt_p);
     189              : 
     190     21952671 :   stmt = *stmt_p;
     191     21952671 :   cond = IF_COND (stmt);
     192     21952671 :   then_ = THEN_CLAUSE (stmt);
     193     21952671 :   else_ = ELSE_CLAUSE (stmt);
     194              : 
     195     21952671 :   if (then_ && else_)
     196              :     {
     197      7449912 :       tree ft = first_stmt (then_);
     198      7449912 :       tree fe = first_stmt (else_);
     199      7449912 :       br_predictor pr;
     200      7449912 :       if (TREE_CODE (ft) == PREDICT_EXPR
     201        42617 :           && TREE_CODE (fe) == PREDICT_EXPR
     202           48 :           && (pr = PREDICT_EXPR_PREDICTOR (ft)) == PREDICT_EXPR_PREDICTOR (fe)
     203      7449951 :           && (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     21952671 :   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     21952615 :   if (!then_)
     241         2008 :     then_ = build_empty_stmt (locus);
     242     21952615 :   if (!else_)
     243     14500802 :     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     21952615 :   if (IF_STMT_CONSTEVAL_P (stmt))
     250              :     {
     251        75074 :       if (block_may_fallthru (then_))
     252        24299 :         stmt = build3 (COND_EXPR, void_type_node, boolean_false_node,
     253              :                        void_node, else_);
     254              :       else
     255        50775 :         stmt = else_;
     256              :     }
     257     21877541 :   else if (IF_STMT_CONSTEXPR_P (stmt))
     258      6910999 :     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     17184396 :   else if (integer_nonzerop (cond) && !TREE_SIDE_EFFECTS (else_))
     262        98715 :     stmt = then_;
     263     17085681 :   else if (integer_zerop (cond) && !TREE_SIDE_EFFECTS (then_))
     264        35353 :     stmt = else_;
     265              :   else
     266     17050328 :     stmt = build3 (COND_EXPR, void_type_node, cond, then_, else_);
     267     21952615 :   protected_set_expr_location_if_unset (stmt, locus);
     268     21952615 :   *stmt_p = stmt;
     269              : }
     270              : 
     271              : /* Hook into the middle of gimplifying an OMP_FOR node.  */
     272              : 
     273              : static enum gimplify_status
     274        45359 : cp_gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
     275              : {
     276        45359 :   tree for_stmt = *expr_p;
     277        45359 :   gimple_seq seq = NULL;
     278              : 
     279              :   /* Protect ourselves from recursion.  */
     280        45359 :   if (OMP_FOR_GIMPLIFYING_P (for_stmt))
     281              :     return GS_UNHANDLED;
     282        21076 :   OMP_FOR_GIMPLIFYING_P (for_stmt) = 1;
     283              : 
     284        21076 :   gimplify_and_add (for_stmt, &seq);
     285        21076 :   gimple_seq_add_seq (pre_p, seq);
     286              : 
     287        21076 :   OMP_FOR_GIMPLIFYING_P (for_stmt) = 0;
     288              : 
     289        21076 :   return GS_ALL_DONE;
     290              : }
     291              : 
     292              : /*  Gimplify an EXPR_STMT node.  */
     293              : 
     294              : static void
     295      4056709 : gimplify_expr_stmt (tree *stmt_p)
     296              : {
     297      4056709 :   tree stmt = EXPR_STMT_EXPR (*stmt_p);
     298              : 
     299      4056709 :   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      4052691 :   if (stmt && warn_unused_value)
     309              :     {
     310       307764 :       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       300918 :         warn_if_unused_value (stmt, input_location);
     319              :     }
     320              : 
     321      4056709 :   if (stmt == NULL_TREE)
     322         4018 :     stmt = alloc_stmt_list ();
     323              : 
     324      4056709 :   *stmt_p = stmt;
     325      4056709 : }
     326              : 
     327              : /* Gimplify initialization from an AGGR_INIT_EXPR.  */
     328              : 
     329              : static void
     330     11930734 : cp_gimplify_init_expr (tree *expr_p)
     331              : {
     332     11930734 :   tree from = TREE_OPERAND (*expr_p, 1);
     333     11930734 :   tree to = TREE_OPERAND (*expr_p, 0);
     334     11930734 :   tree t;
     335              : 
     336     11930734 :   if (TREE_CODE (from) == TARGET_EXPR)
     337       211956 :     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       211956 :         gcc_checking_assert (TARGET_EXPR_ELIDING_P (from)
     342              :                              || !TREE_ADDRESSABLE (TREE_TYPE (from)));
     343       211956 :         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           88 :             replace_decl (&init, TARGET_EXPR_SLOT (from), to);
     348           88 :             *expr_p = init;
     349           88 :             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     12021615 :   for (t = from; t; )
     358              :     {
     359     12021615 :       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     12021615 :       if (TREE_CODE (sub) == AGGR_INIT_EXPR
     367     12021615 :           || TREE_CODE (sub) == VEC_INIT_EXPR)
     368              :         {
     369       111290 :           if (TREE_CODE (sub) == AGGR_INIT_EXPR)
     370       111290 :             AGGR_INIT_EXPR_SLOT (sub) = to;
     371              :           else
     372            0 :             VEC_INIT_EXPR_SLOT (sub) = to;
     373       111290 :           *expr_p = from;
     374              : 
     375              :           /* The initialization is now a side-effect, so the container can
     376              :              become void.  */
     377       111290 :           if (from != sub)
     378           73 :             TREE_TYPE (from) = void_type_node;
     379              :         }
     380              : 
     381              :       /* Handle aggregate NSDMI.  */
     382     12021615 :       replace_placeholders (sub, to);
     383              : 
     384     12021615 :       if (t == sub)
     385              :         break;
     386              :       else
     387        90969 :         t = TREE_OPERAND (t, 1);
     388              :     }
     389              : 
     390              : }
     391              : 
     392              : /* Gimplify a MUST_NOT_THROW_EXPR.  */
     393              : 
     394              : static enum gimplify_status
     395       581513 : gimplify_must_not_throw_expr (tree *expr_p, gimple_seq *pre_p)
     396              : {
     397       581513 :   tree stmt = *expr_p;
     398       581513 :   tree temp = voidify_wrapper_expr (stmt, NULL);
     399       581513 :   tree body = TREE_OPERAND (stmt, 0);
     400       581513 :   gimple_seq try_ = NULL;
     401       581513 :   gimple_seq catch_ = NULL;
     402       581513 :   gimple *mnt;
     403              : 
     404       581513 :   gimplify_and_add (body, &try_);
     405       581513 :   mnt = gimple_build_eh_must_not_throw (call_terminate_fn);
     406       581513 :   gimple_seq_add_stmt_without_update (&catch_, mnt);
     407       581513 :   mnt = gimple_build_try (try_, catch_, GIMPLE_TRY_CATCH);
     408              : 
     409       581513 :   gimple_seq_add_stmt_without_update (pre_p, mnt);
     410       581513 :   if (temp)
     411              :     {
     412           33 :       *expr_p = temp;
     413           33 :       return GS_OK;
     414              :     }
     415              : 
     416       581480 :   *expr_p = NULL;
     417       581480 :   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     19991723 : simple_empty_class_p (tree type, tree op, tree_code code)
     429              : {
     430     23408890 :   if (TREE_CODE (op) == COMPOUND_EXPR)
     431       190846 :     return simple_empty_class_p (type, TREE_OPERAND (op, 1), code);
     432      4301825 :   if (SIMPLE_TARGET_EXPR_P (op)
     433     26448740 :       && TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
     434              :     /* The TARGET_EXPR is itself a simple copy, look through it.  */
     435      3226321 :     return simple_empty_class_p (type, TARGET_EXPR_INITIAL (op), code);
     436              : 
     437     19991723 :   if (TREE_CODE (op) == PARM_DECL
     438     19991723 :       && 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            9 :         return false;
     446              :     }
     447              : 
     448     19991714 :   return
     449     19991714 :     (TREE_CODE (op) == EMPTY_CLASS_EXPR
     450     19991684 :      || code == MODIFY_EXPR
     451     16961740 :      || is_gimple_lvalue (op)
     452     13399497 :      || INDIRECT_REF_P (op)
     453     12969734 :      || (TREE_CODE (op) == CONSTRUCTOR
     454      2881775 :          && CONSTRUCTOR_NELTS (op) == 0)
     455     10379465 :      || (TREE_CODE (op) == CALL_EXPR
     456      2712366 :          && !CALL_EXPR_RETURN_SLOT_OPT (op)))
     457     12219407 :     && !TREE_CLOBBER_P (op)
     458     31594072 :     && 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      2688278 : lvalue_has_side_effects (tree e)
     467              : {
     468      2688278 :   if (!TREE_SIDE_EFFECTS (e))
     469              :     return false;
     470        57540 :   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        52513 :   if (DECL_P (e))
     478              :     /* Just naming a variable has no side-effects.  */
     479              :     return false;
     480        35512 :   else if (INDIRECT_REF_P (e))
     481              :     /* Similarly, indirection has no side-effects.  */
     482        35378 :     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    202684106 : immediate_escalating_function_p (tree fn)
     492              : {
     493    202684106 :   if (!fn || !flag_immediate_escalation)
     494              :     return false;
     495              : 
     496    202683739 :   gcc_checking_assert (TREE_CODE (fn) == FUNCTION_DECL);
     497              : 
     498    202683739 :   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    206321371 :   if (LAMBDA_FUNCTION_P (fn))
     505              :     return true;
     506              :   /* -- a defaulted function that is not declared with the
     507              :         consteval specifier  */
     508    200618044 :   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    192810940 :   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    202640589 : unchecked_immediate_escalating_function_p (tree fn)
     520              : {
     521    202640589 :   return (immediate_escalating_function_p (fn)
     522    202640589 :           && !DECL_ESCALATION_CHECKED_P (fn));
     523              : }
     524              : 
     525              : /* Promote FN to an immediate function, including its clones.  */
     526              : 
     527              : void
     528        40890 : promote_function_to_consteval (tree fn)
     529              : {
     530        40890 :   SET_DECL_IMMEDIATE_FUNCTION_P (fn);
     531        40890 :   DECL_ESCALATION_CHECKED_P (fn) = true;
     532        40890 :   tree clone;
     533        66258 :   FOR_EACH_CLONE (clone, fn)
     534              :     {
     535        25368 :       SET_DECL_IMMEDIATE_FUNCTION_P (clone);
     536        25368 :       DECL_ESCALATION_CHECKED_P (clone) = true;
     537              :     }
     538        40890 : }
     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     16330639 : cp_fold_immediate (tree *tp, mce_value manifestly_const_eval,
     546              :                    tree decl /*= current_function_decl*/)
     547              : {
     548     16330639 :   if (cxx_dialect <= cxx17)
     549              :     return NULL_TREE;
     550              : 
     551     16323296 :   temp_override<tree> cfd (current_function_decl, decl);
     552              : 
     553     16323296 :   fold_flags_t flags = ff_none;
     554     16323296 :   if (manifestly_const_eval == mce_false)
     555      9584074 :     flags |= ff_mce_false;
     556              : 
     557     16323296 :   cp_fold_data data (flags);
     558     16323296 :   int save_errorcount = errorcount;
     559     16323296 :   tree r = cp_walk_tree (tp, cp_fold_immediate_r, &data, NULL);
     560     16323296 :   if (errorcount > save_errorcount)
     561           49 :     return integer_one_node;
     562              :   return r;
     563     16323296 : }
     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        37258 : gimplify_to_rvalue (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
     590              :                     bool (*gimple_test_f) (tree))
     591              : {
     592        37258 :   enum gimplify_status t
     593        37258 :     = gimplify_expr (expr_p, pre_p, post_p, gimple_test_f, fb_rvalue);
     594        37258 :   if (t == GS_ERROR)
     595              :     return GS_ERROR;
     596        37255 :   else if (is_gimple_variable (*expr_p) && TREE_CODE (*expr_p) != SSA_NAME)
     597         3085 :     *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      4294107 : cp_gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
     609              :                  bool ordered)
     610              : {
     611      4294107 :   enum gimplify_status t;
     612      4294107 :   if (ordered
     613       437413 :       && !is_gimple_reg_type (TREE_TYPE (*arg_p))
     614      4295975 :       && 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         1729 :       protected_set_expr_location (*arg_p, call_location);
     620         1729 :       return gimplify_expr (arg_p, pre_p, NULL, is_gimple_lvalue, fb_either);
     621              :     }
     622              :   else
     623              :     {
     624      4292378 :       t = gimplify_arg (arg_p, pre_p, call_location);
     625      4292378 :       if (t == GS_ERROR)
     626              :         return GS_ERROR;
     627      4292378 :       else if (ordered
     628       435684 :                && is_gimple_reg_type (TREE_TYPE (*arg_p))
     629       435545 :                && is_gimple_variable (*arg_p)
     630       220682 :                && TREE_CODE (*arg_p) != SSA_NAME
     631              :                /* No need to force references into register, references
     632              :                   can't be modified.  */
     633       134735 :                && !TYPE_REF_P (TREE_TYPE (*arg_p))
     634              :                /* And this can't be modified either.  */
     635      4381878 :                && *arg_p != current_class_ptr)
     636         8148 :         *arg_p = get_initialized_tmp_var (*arg_p, pre_p);
     637      4292378 :       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      1468147 : maybe_emit_clobber_object_begin (tree decl, gimple_seq *pre_p)
     647              : {
     648      1468147 :   if (VAR_P (decl)
     649      1467471 :       && auto_var_p (decl)
     650      1433187 :       && TREE_TYPE (decl) != error_mark_node
     651      1433178 :       && DECL_NONTRIVIALLY_INITIALIZED_P (decl)
     652              :       /* Don't do it if it is fully initialized.  */
     653       882637 :       && DECL_INITIAL (decl) == NULL_TREE
     654       443781 :       && !DECL_HAS_VALUE_EXPR_P (decl)
     655       443464 :       && !OPAQUE_TYPE_P (TREE_TYPE (decl))
     656              :       /* Nor going to have decl = .DEFERRED_INIT (...); added.  */
     657      1911611 :       && (flag_auto_var_init == AUTO_INIT_UNINITIALIZED
     658        85223 :           || lookup_attribute ("uninitialized", DECL_ATTRIBUTES (decl))
     659        85223 :           || lookup_attribute ("indeterminate", DECL_ATTRIBUTES (decl))))
     660              :     {
     661       358242 :       tree eltype = strip_array_types (TREE_TYPE (decl));
     662       358242 :       if (RECORD_OR_UNION_TYPE_P (eltype)
     663       358242 :           && !is_empty_class (eltype))
     664              :         {
     665       148760 :           tree clobber
     666       148760 :             = build_clobber (TREE_TYPE (decl), CLOBBER_OBJECT_BEGIN);
     667       148760 :           gimple *g = gimple_build_assign (decl, clobber);
     668       148760 :           gimple_set_location (g, DECL_SOURCE_LOCATION (decl));
     669       148760 :           gimple_seq_add_stmt_without_update (pre_p, g);
     670              :         }
     671              :     }
     672      1468147 : }
     673              : 
     674              : /* Do C++-specific gimplification.  Args are as for gimplify_expr.  */
     675              : 
     676              : int
     677    176001997 : cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
     678              : {
     679    176001997 :   int saved_stmts_are_full_exprs_p = 0;
     680    176001997 :   location_t loc = cp_expr_loc_or_input_loc (*expr_p);
     681    176001997 :   enum tree_code code = TREE_CODE (*expr_p);
     682    176001997 :   enum gimplify_status ret;
     683              : 
     684    176001997 :   if (STATEMENT_CODE_P (code))
     685              :     {
     686      4101983 :       saved_stmts_are_full_exprs_p = stmts_are_full_exprs_p ();
     687      8203966 :       current_stmt_tree ()->stmts_are_full_exprs_p
     688      4101983 :         = STMT_IS_FULL_EXPR_P (*expr_p);
     689              :     }
     690              : 
     691    176001997 :   switch (code)
     692              :     {
     693       362004 :     case AGGR_INIT_EXPR:
     694       362004 :       simplify_aggr_init_expr (expr_p);
     695       362004 :       ret = GS_OK;
     696       362004 :       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        19944 :     case THROW_EXPR:
     712              :       /* FIXME communicate throw type to back end, probably by moving
     713              :          THROW_EXPR into ../tree.def.  */
     714        19944 :       *expr_p = TREE_OPERAND (*expr_p, 0);
     715        19944 :       ret = GS_OK;
     716        19944 :       break;
     717              : 
     718       581513 :     case MUST_NOT_THROW_EXPR:
     719       581513 :       ret = gimplify_must_not_throw_expr (expr_p, pre_p);
     720       581513 :       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     11930734 :     case INIT_EXPR:
     726     11930734 :       cp_gimplify_init_expr (expr_p);
     727     11930734 :       if (TREE_CODE (*expr_p) != INIT_EXPR)
     728              :         return GS_OK;
     729              :       /* Fall through.  */
     730     16020472 :     case MODIFY_EXPR:
     731     11819356 :     modify_expr_case:
     732     16020472 :       {
     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     16020472 :         tree op0 = TREE_OPERAND (*expr_p, 0);
     736     16020472 :         tree op1 = TREE_OPERAND (*expr_p, 1);
     737              : 
     738     16020472 :         if (!error_operand_p (op0)
     739     16020472 :             && !error_operand_p (op1)
     740     16020453 :             && (TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op0))
     741     16017258 :                 || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (op1)))
     742     16023676 :             && !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     16020463 :         else if (simple_empty_class_p (TREE_TYPE (op0), op1, code))
     747              :           {
     748       220828 :             while (TREE_CODE (op1) == TARGET_EXPR)
     749              :               /* We're disconnecting the initializer from its target,
     750              :                  don't create a temporary.  */
     751         9989 :               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       210839 :             if (TREE_SIDE_EFFECTS (op1))
     757              :               {
     758        16057 :                 if (TREE_THIS_VOLATILE (op1)
     759            0 :                     && (REFERENCE_CLASS_P (op1) || DECL_P (op1)))
     760            0 :                   op1 = build_fold_addr_expr (op1);
     761              : 
     762        16057 :                 suppress_warning (op1, OPT_Wunused_result);
     763        16057 :                 gimplify_and_add (op1, pre_p);
     764              :               }
     765       210839 :             gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
     766              :                            is_gimple_lvalue, fb_lvalue);
     767       210839 :             *expr_p = TREE_OPERAND (*expr_p, 0);
     768       210839 :             if (code == RETURN_EXPR && REFERENCE_CLASS_P (*expr_p))
     769              :               /* Avoid 'return *<retval>;'  */
     770            6 :               *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     15809624 :        else if (flag_strong_eval_order > 1
     785     14439169 :                 && TREE_CODE (*expr_p) == MODIFY_EXPR
     786      2688278 :                 && lvalue_has_side_effects (op0)
     787     15846791 :                 && (TREE_CODE (op1) == CALL_EXPR
     788        30164 :                     || (SCALAR_TYPE_P (TREE_TYPE (op1))
     789        23949 :                         && !TREE_CONSTANT (op1))))
     790        21225 :          TREE_OPERAND (*expr_p, 1) = get_initialized_tmp_var (op1, pre_p);
     791              :       }
     792              :       ret = GS_OK;
     793              :       break;
     794              : 
     795        98299 :     case EMPTY_CLASS_EXPR:
     796              :       /* We create an empty CONSTRUCTOR with RECORD_TYPE.  */
     797        98299 :       *expr_p = build_constructor (TREE_TYPE (*expr_p), NULL);
     798        98299 :       ret = GS_OK;
     799        98299 :       break;
     800              : 
     801            0 :     case BASELINK:
     802            0 :       *expr_p = BASELINK_FUNCTIONS (*expr_p);
     803            0 :       ret = GS_OK;
     804            0 :       break;
     805              : 
     806        18172 :     case TRY_BLOCK:
     807        18172 :       genericize_try_block (expr_p);
     808        18172 :       ret = GS_OK;
     809        18172 :       break;
     810              : 
     811        21270 :     case HANDLER:
     812        21270 :       genericize_catch_block (expr_p);
     813        21270 :       ret = GS_OK;
     814        21270 :       break;
     815              : 
     816         5832 :     case EH_SPEC_BLOCK:
     817         5832 :       genericize_eh_spec_block (expr_p);
     818         5832 :       ret = GS_OK;
     819         5832 :       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        45359 :     case OMP_FOR:
     833        45359 :     case OMP_SIMD:
     834        45359 :     case OMP_DISTRIBUTE:
     835        45359 :     case OMP_LOOP:
     836        45359 :     case OMP_TASKLOOP:
     837        45359 :     case OMP_TILE:
     838        45359 :     case OMP_UNROLL:
     839        45359 :       ret = cp_gimplify_omp_for (expr_p, pre_p);
     840        45359 :       break;
     841              : 
     842      4056709 :     case EXPR_STMT:
     843      4056709 :       gimplify_expr_stmt (expr_p);
     844      4056709 :       ret = GS_OK;
     845      4056709 :       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     22748685 :       for (int i = 0; i < call_expr_nargs (*expr_p); ++i)
     862     13958604 :         if (check_out_of_consteval_use (CALL_EXPR_ARG (*expr_p, i)))
     863           10 :           ret = GS_ERROR;
     864      8790081 :       if (consteval_only_p (TREE_TYPE (*expr_p)))
     865            2 :         ret = GS_ERROR;
     866      8790081 :       if (flag_strong_eval_order == 2
     867      8284896 :           && CALL_EXPR_FN (*expr_p)
     868      7912340 :           && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p)
     869     15873781 :           && cp_get_callee_fndecl_nofold (*expr_p) == NULL_TREE)
     870              :         {
     871        37258 :           tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
     872        37258 :           enum gimplify_status t
     873        37258 :             = gimplify_to_rvalue (&CALL_EXPR_FN (*expr_p), pre_p, NULL,
     874              :                                   is_gimple_call_addr);
     875        37258 :           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        37255 :           else if (TREE_TYPE (CALL_EXPR_FN (*expr_p)) != fnptrtype)
     880         9099 :             CALL_EXPR_FN (*expr_p)
     881        18198 :               = build1 (NOP_EXPR, fnptrtype, CALL_EXPR_FN (*expr_p));
     882              :         }
     883      8790081 :       if (!CALL_EXPR_FN (*expr_p))
     884              :         /* Internal function call.  */
     885       395135 :         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      8394946 :       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        48920 :           gcc_assert (call_expr_nargs (*expr_p) == 2);
     912        48920 :           gcc_assert (!CALL_EXPR_ORDERED_ARGS (*expr_p));
     913        48920 :           enum gimplify_status t
     914        48920 :             = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 1), pre_p, loc,
     915        48920 :                                TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, 0)));
     916        48920 :           if (t == GS_ERROR)
     917              :             ret = GS_ERROR;
     918              :         }
     919      8346026 :       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       254520 :           int nargs = call_expr_nargs (*expr_p) - 1;
     924       254520 :           int last_side_effects_arg = -1;
     925       500364 :           for (int i = nargs; i > 0; --i)
     926       272993 :             if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
     927              :               {
     928              :                 last_side_effects_arg = i;
     929              :                 break;
     930              :               }
     931       538556 :           for (int i = 0; i < nargs; ++i)
     932              :             {
     933       284036 :               enum gimplify_status t
     934       284036 :                 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p, loc,
     935              :                                    i < last_side_effects_arg);
     936       284036 :               if (t == GS_ERROR)
     937            0 :                 ret = GS_ERROR;
     938              :             }
     939              :         }
     940      8091506 :       else if (flag_strong_eval_order
     941      8091506 :                && !CALL_EXPR_OPERATOR_SYNTAX (*expr_p))
     942              :         {
     943              :           /* If flag_strong_eval_order, evaluate the object argument first.  */
     944      7499839 :           tree fntype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
     945      7499839 :           if (INDIRECT_TYPE_P (fntype))
     946      7499836 :             fntype = TREE_TYPE (fntype);
     947      7499839 :           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      7499839 :           if (TREE_CODE (fntype) == METHOD_TYPE
     954      7499839 :               || (decl && DECL_LANG_SPECIFIC (decl)
     955      3527920 :                   && DECL_XOBJ_MEMBER_FUNCTION_P (decl)))
     956              :             {
     957      3961151 :               int nargs = call_expr_nargs (*expr_p);
     958      3961151 :               bool side_effects = false;
     959      5562019 :               for (int i = 1; i < nargs; ++i)
     960      1994481 :                 if (TREE_SIDE_EFFECTS (CALL_EXPR_ARG (*expr_p, i)))
     961              :                   {
     962              :                     side_effects = true;
     963              :                     break;
     964              :                   }
     965      3961151 :               enum gimplify_status t
     966      3961151 :                 = cp_gimplify_arg (&CALL_EXPR_ARG (*expr_p, 0), pre_p, loc,
     967              :                                    side_effects);
     968      3961151 :               if (t == GS_ERROR)
     969              :                 ret = GS_ERROR;
     970              :             }
     971              :         }
     972      8790045 :       if (ret != GS_ERROR)
     973              :         {
     974      8790030 :           tree decl = cp_get_callee_fndecl_nofold (*expr_p);
     975      8790030 :           if (!decl)
     976              :             break;
     977      8352731 :           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      8352722 :           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      8352689 :             gcc_checking_assert (!immediate_invocation_p (decl));
    1050              :         }
    1051              :       break;
    1052              : 
    1053       692947 :     case TARGET_EXPR:
    1054              :       /* A TARGET_EXPR that expresses direct-initialization should have been
    1055              :          elided by cp_gimplify_init_expr.  */
    1056       692947 :       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       692947 :       gcc_checking_assert (!TARGET_EXPR_ELIDING_P (*expr_p)
    1061              :                            || !TREE_ADDRESSABLE (TREE_TYPE (*expr_p)));
    1062       692947 :       if (flag_lifetime_dse > 1
    1063       692819 :           && TARGET_EXPR_INITIAL (*expr_p)
    1064      1376805 :           && VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (*expr_p))))
    1065       252271 :         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     20602705 :         ret = GS_OK;
    1075              :       break;
    1076              : 
    1077      1216104 :     case DECL_EXPR:
    1078      1216104 :       if (flag_lifetime_dse > 1)
    1079      1215876 :         maybe_emit_clobber_object_begin (DECL_EXPR_DECL (*expr_p), pre_p);
    1080              :       ret = GS_UNHANDLED;
    1081              :       break;
    1082              : 
    1083      1238867 :     case RETURN_EXPR:
    1084      1238867 :       if (TREE_OPERAND (*expr_p, 0)
    1085      1238867 :           && (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == INIT_EXPR
    1086        13131 :               || TREE_CODE (TREE_OPERAND (*expr_p, 0)) == MODIFY_EXPR))
    1087              :         {
    1088      1171172 :           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      1171172 :           goto modify_expr_case;
    1092              :         }
    1093              :       /* Fall through.  */
    1094              : 
    1095    143961910 :     default:
    1096    143961910 :       ret = (enum gimplify_status) c_gimplify_expr (expr_p, pre_p, post_p);
    1097    143961910 :       break;
    1098              :     }
    1099              : 
    1100              :   /* Restore saved state.  */
    1101    175890583 :   if (STATEMENT_CODE_P (code))
    1102      4101983 :     current_stmt_tree ()->stmts_are_full_exprs_p
    1103      4101983 :       = saved_stmts_are_full_exprs_p;
    1104              : 
    1105              :   return ret;
    1106              : }
    1107              : 
    1108              : bool
    1109   2038454143 : is_invisiref_parm (const_tree t)
    1110              : {
    1111   1910512325 :   return ((TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
    1112   2083452200 :           && 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       119283 : omp_var_to_track (tree decl)
    1141              : {
    1142       119283 :   tree type = TREE_TYPE (decl);
    1143       119283 :   if (is_invisiref_parm (decl))
    1144          537 :     type = TREE_TYPE (type);
    1145       118746 :   else if (TYPE_REF_P (type))
    1146         4213 :     type = TREE_TYPE (type);
    1147       144232 :   while (TREE_CODE (type) == ARRAY_TYPE)
    1148        24949 :     type = TREE_TYPE (type);
    1149       119283 :   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              :     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       132100 : any_non_eliding_target_exprs (tree ctor)
    1216              : {
    1217       616086 :   for (const constructor_elt &e : *CONSTRUCTOR_ELTS (ctor))
    1218              :     {
    1219       483989 :       if (TREE_CODE (e.value) == TARGET_EXPR
    1220       483989 :           && !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     84804621 : cp_genericize_init (tree *replace, tree from, tree to, vec<tree,va_gc>** flags)
    1233              : {
    1234     84804621 :   tree init = NULL_TREE;
    1235     84804621 :   if (TREE_CODE (from) == VEC_INIT_EXPR)
    1236         1148 :     init = expand_vec_init_expr (to, from, tf_warning_or_error, flags);
    1237     84803473 :   else if (TREE_CODE (from) == CONSTRUCTOR
    1238      4852457 :            && TREE_SIDE_EFFECTS (from)
    1239     84936980 :            && ((flag_exceptions
    1240       133420 :                 && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (from)))
    1241       132100 :                || any_non_eliding_target_exprs (from)))
    1242              :     {
    1243         1410 :       to = cp_stabilize_reference (to);
    1244         1410 :       replace_placeholders (from, to);
    1245         1410 :       init = split_nonconstant_init (to, from);
    1246              :     }
    1247              : 
    1248         2558 :   if (init)
    1249              :     {
    1250         2558 :       if (*replace == from)
    1251              :         /* Make cp_gimplify_init_expr call replace_decl on this
    1252              :            TARGET_EXPR_INITIAL.  */
    1253          708 :         init = fold_convert (void_type_node, init);
    1254         2558 :       *replace = init;
    1255              :     }
    1256     84804621 : }
    1257              : 
    1258              : /* For an INIT_EXPR, replace the INIT_EXPR itself.  */
    1259              : 
    1260              : static void
    1261     62822576 : cp_genericize_init_expr (tree *stmt_p)
    1262              : {
    1263     62822576 :   iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
    1264     62822576 :   tree to = TREE_OPERAND (*stmt_p, 0);
    1265     62822576 :   tree from = TREE_OPERAND (*stmt_p, 1);
    1266      7769783 :   if (SIMPLE_TARGET_EXPR_P (from)
    1267              :       /* Return gets confused if we clobber its INIT_EXPR this soon.  */
    1268     68704631 :       && TREE_CODE (to) != RESULT_DECL)
    1269       265919 :     from = TARGET_EXPR_INITIAL (from);
    1270     62822576 :   cp_genericize_init (stmt_p, from, to, nullptr);
    1271     62822576 : }
    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     21982045 : cp_genericize_target_expr (tree *stmt_p)
    1278              : {
    1279     21982045 :   iloc_sentinel ils = EXPR_LOCATION (*stmt_p);
    1280     21982045 :   tree slot = TARGET_EXPR_SLOT (*stmt_p);
    1281     21982045 :   vec<tree, va_gc> *flags = make_tree_vector ();
    1282     21982045 :   cp_genericize_init (&TARGET_EXPR_INITIAL (*stmt_p),
    1283     21982045 :                       TARGET_EXPR_INITIAL (*stmt_p), slot, &flags);
    1284     21982045 :   gcc_assert (!DECL_INITIAL (slot));
    1285     65946167 :   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     21982045 :   release_tree_vector (flags);
    1294     21982045 : }
    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              :   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     51573755 : 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          401 : cp_build_init_expr_for_ctor (tree call, tree init)
    1350              : {
    1351          401 :   tree a = CALL_EXPR_ARG (call, 0);
    1352          401 :   if (is_dummy_object (a))
    1353              :     return init;
    1354          401 :   const bool return_this = targetm.cxx.cdtor_returns_this ();
    1355          401 :   const location_t loc = EXPR_LOCATION (call);
    1356          401 :   if (return_this)
    1357            0 :     a = cp_save_expr (a);
    1358          401 :   tree s = build_fold_indirect_ref_loc (loc, a);
    1359          401 :   init = cp_build_init_expr (s, init);
    1360          401 :   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      1003172 : wipe_consteval_only_r (tree *stmt_p, int *, void *)
    1375              : {
    1376      1003172 :   if (TREE_CODE (*stmt_p) == DECL_EXPR)
    1377              :     {
    1378         1642 :       tree d = DECL_EXPR_DECL (*stmt_p);
    1379         1642 :       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      1003172 :   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   3216168439 : cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_)
    1391              : {
    1392   3216168439 :   auto data = static_cast<cp_fold_data *>(data_);
    1393   3216168439 :   tree stmt = *stmt_p;
    1394              :   /* The purpose of this is not to emit errors for mce_unknown.  */
    1395   3216168439 :   const tsubst_flags_t complain = (data->flags & ff_mce_false
    1396   3216168439 :                                    ? tf_error : tf_none);
    1397   3216168439 :   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   3216168439 :   if (TYPE_P (stmt)
    1402   3213810135 :       || 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   3213459420 :       || cp_unevaluated_operand
    1406   6429627859 :       || (current_function_decl
    1407   6248142810 :           && DECL_IMMEDIATE_FUNCTION_P (current_function_decl)))
    1408              :     {
    1409      2743422 :       *walk_subtrees = 0;
    1410      2743422 :       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   3213425017 :   if (flag_reflection
    1417     71789831 :       && complain
    1418     59337810 :       && (data->flags & ff_genericize)
    1419     45646867 :       && TREE_CODE (stmt) == STATEMENT_LIST)
    1420      3841519 :     for (tree s : tsi_range (stmt))
    1421      2591145 :       if (check_out_of_consteval_use (s))
    1422           16 :         *stmt_p = void_node;
    1423              : 
    1424   3213425017 :   tree decl = NULL_TREE;
    1425   3213425017 :   bool call_p = false;
    1426              : 
    1427              :   /* We are looking for &fn or fn().  */
    1428   3213425017 :   switch (code)
    1429              :     {
    1430     36498937 :     case DECL_EXPR:
    1431              :       /* Clear consteval-only DECL_EXPRs.  */
    1432     36498937 :       if (flag_reflection)
    1433              :         {
    1434       712238 :           tree d = DECL_EXPR_DECL (stmt);
    1435       712238 :           if (VAR_P (d) && consteval_only_p (d))
    1436          808 :             *stmt_p = void_node;
    1437              :         }
    1438              :       break;
    1439    155071134 :     case CALL_EXPR:
    1440    155071134 :     case AGGR_INIT_EXPR:
    1441    155071134 :       if (tree fn = cp_get_callee (stmt))
    1442    154808199 :         if (TREE_CODE (fn) != ADDR_EXPR || ADDR_EXPR_DENOTES_CALL_P (fn))
    1443    148087188 :           decl = cp_get_fndecl_from_callee (fn, /*fold*/false);
    1444    148087188 :       call_p = true;
    1445    148087188 :       break;
    1446        32941 :     case PTRMEM_CST:
    1447        32941 :       decl = PTRMEM_CST_MEMBER (stmt);
    1448        32941 :       break;
    1449    234159144 :     case ADDR_EXPR:
    1450    234159144 :       if (!ADDR_EXPR_DENOTES_CALL_P (stmt))
    1451     87793316 :         decl = TREE_OPERAND (stmt, 0);
    1452              :       break;
    1453     21479913 :     case IF_STMT:
    1454     21479913 :       if (IF_STMT_CONSTEVAL_P (stmt))
    1455              :         {
    1456        75089 :           if (!data->pset.add (stmt))
    1457              :             {
    1458        75089 :               cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_immediate_r, data_,
    1459              :                             nullptr);
    1460        75089 :               if (flag_reflection)
    1461              :                 /* Check & clear consteval-only DECL_EXPRs even here,
    1462              :                    because we wouldn't be walking this subtree otherwise.  */
    1463        26468 :                 cp_walk_tree (&THEN_CLAUSE (stmt), wipe_consteval_only_r,
    1464              :                               data_, nullptr);
    1465              :             }
    1466        75089 :           *walk_subtrees = 0;
    1467        75089 :           return NULL_TREE;
    1468              :         }
    1469              :       /* FALLTHRU */
    1470   2787587772 :     default:
    1471   2787587772 :       if (data->pset.add (stmt))
    1472    473436886 :         *walk_subtrees = 0;
    1473              :       return NULL_TREE;
    1474              :     }
    1475              : 
    1476    235914253 :   if (!decl || TREE_CODE (decl) != FUNCTION_DECL)
    1477    271202125 :     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    154560031 :   if (at_eof > 1 && unchecked_immediate_escalating_function_p (decl))
    1485              :     {
    1486              :       /* Set before the actual walk to avoid endless recursion.  */
    1487      5955945 :       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      5955945 :       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    309120062 :   if (DECL_IMMEDIATE_FUNCTION_P (decl))
    1502              :     {
    1503       474589 :       tree e = cxx_constant_value (stmt, tf_none);
    1504       474589 :       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          457 :               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       472054 :       else if ((data->flags & ff_genericize)
    1543       472054 :                && 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       472050 :       if (call_p)
    1557              :         {
    1558       567435 :           if (code == CALL_EXPR && DECL_CONSTRUCTOR_P (decl))
    1559            0 :             *stmt_p = cp_build_init_expr_for_ctor (stmt, e);
    1560              :           else
    1561       472050 :             *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    154085442 :   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     26154208 :       gcc_checking_assert (at_eof <= 1);
    1574     26154208 :       if (current_function_decl)
    1575     26153684 :         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        96294 : cp_fold_omp_clause_refs_r (tree *expr_p, int *walk_subtrees, void */*data*/)
    1594              : {
    1595        96294 :   tree expr = *expr_p;
    1596              : 
    1597        96294 :   if (TYPE_P (expr))
    1598              :     {
    1599            0 :       *walk_subtrees = 0;
    1600            0 :       return NULL_TREE;
    1601              :     }
    1602              : 
    1603        96294 :   if (DECL_P (expr))
    1604              :     {
    1605        53087 :       *walk_subtrees = 0;
    1606              : 
    1607        53087 :       if (decl_constant_var_p (expr)
    1608        53087 :           && 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   4434609145 : cp_fold_r (tree *stmt_p, int *walk_subtrees, void *data_)
    1635              : {
    1636   4434609145 :   cp_fold_data *data = (cp_fold_data*)data_;
    1637   4434609145 :   tree stmt = *stmt_p;
    1638   4434609145 :   enum tree_code code = TREE_CODE (stmt);
    1639              : 
    1640   4434609145 :   *stmt_p = stmt = cp_fold (*stmt_p, data->flags);
    1641              : 
    1642   4434609145 :   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    628614778 :       *walk_subtrees = 0;
    1650    628614778 :       return NULL_TREE;
    1651              :     }
    1652              : 
    1653   3805994367 :   code = TREE_CODE (stmt);
    1654   3805994367 :   switch (code)
    1655              :     {
    1656        51795 :       tree x;
    1657        51795 :       int i, n;
    1658        51795 :     case OMP_FOR:
    1659        51795 :     case OMP_SIMD:
    1660        51795 :     case OMP_DISTRIBUTE:
    1661        51795 :     case OMP_LOOP:
    1662        51795 :     case OMP_TASKLOOP:
    1663        51795 :     case OMP_TILE:
    1664        51795 :     case OMP_UNROLL:
    1665        51795 :     case OACC_LOOP:
    1666        51795 :       cp_walk_tree (&OMP_FOR_BODY (stmt), cp_fold_r, data, NULL);
    1667        51795 :       cp_walk_tree (&OMP_FOR_CLAUSES (stmt), cp_fold_r, data, NULL);
    1668        51795 :       cp_walk_tree (&OMP_FOR_INIT (stmt), cp_fold_r, data, NULL);
    1669        51795 :       x = OMP_FOR_COND (stmt);
    1670        51795 :       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        38215 :       else if (x && TREE_CODE (x) == TREE_VEC)
    1676              :         {
    1677        38215 :           n = TREE_VEC_LENGTH (x);
    1678        87772 :           for (i = 0; i < n; i++)
    1679              :             {
    1680        49557 :               tree o = TREE_VEC_ELT (x, i);
    1681        49557 :               if (o && TREE_CODE_CLASS (TREE_CODE (o)) == tcc_comparison)
    1682        47731 :                 cp_walk_tree (&TREE_OPERAND (o, 1), cp_fold_r, data, NULL);
    1683              :             }
    1684              :         }
    1685        51795 :       x = OMP_FOR_INCR (stmt);
    1686        51795 :       if (x && TREE_CODE (x) == TREE_VEC)
    1687              :         {
    1688        38215 :           n = TREE_VEC_LENGTH (x);
    1689        87772 :           for (i = 0; i < n; i++)
    1690              :             {
    1691        49557 :               tree o = TREE_VEC_ELT (x, i);
    1692        49557 :               if (o && TREE_CODE (o) == MODIFY_EXPR)
    1693        12044 :                 o = TREE_OPERAND (o, 1);
    1694        47731 :               if (o && (TREE_CODE (o) == PLUS_EXPR || TREE_CODE (o) == MINUS_EXPR
    1695        38587 :                         || 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        51795 :       cp_walk_tree (&OMP_FOR_PRE_BODY (stmt), cp_fold_r, data, NULL);
    1703        51795 :       *walk_subtrees = 0;
    1704        51795 :       return NULL_TREE;
    1705              : 
    1706       165846 :     case OMP_CLAUSE:
    1707       165846 :       if ((data->flags & ff_only_non_odr)
    1708        82934 :           && omp_clause_num_ops[OMP_CLAUSE_CODE (stmt)] >= 1
    1709        69545 :           && OMP_CLAUSE_CODE (stmt) >= OMP_CLAUSE_PRIVATE
    1710        69545 :           && OMP_CLAUSE_CODE (stmt) <= OMP_CLAUSE__SCANTEMP_
    1711       212008 :           && OMP_CLAUSE_DECL (stmt))
    1712              :         {
    1713        44980 :           tree *decl = &OMP_CLAUSE_DECL (stmt);
    1714        44980 :           cp_walk_tree (decl, cp_fold_omp_clause_refs_r, NULL, NULL);
    1715        44980 :           if (TREE_CODE (*decl) == ADDR_EXPR
    1716        44980 :               && DECL_P (TREE_OPERAND (*decl, 0)))
    1717          148 :             *decl = TREE_OPERAND (*decl, 0);
    1718        44980 :           data->pset.add (*decl);
    1719              :         }
    1720              :       break;
    1721              : 
    1722     45310428 :     case IF_STMT:
    1723     45310428 :       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       151430 :           cp_walk_tree (&ELSE_CLAUSE (stmt), cp_fold_r, data, NULL);
    1728       151430 :           cp_walk_tree (&IF_SCOPE (stmt), cp_fold_r, data, NULL);
    1729       151430 :           *walk_subtrees = 0;
    1730       151430 :           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    126806310 :     case INIT_EXPR:
    1738    126806310 :       if (data->flags & ff_genericize)
    1739     62822576 :         cp_genericize_init_expr (stmt_p);
    1740              :       break;
    1741              : 
    1742     45257119 :     case TARGET_EXPR:
    1743     45257119 :       if (!flag_no_inline
    1744     42776583 :           && (data->flags & ff_genericize))
    1745     20774300 :         if (tree &init = TARGET_EXPR_INITIAL (stmt))
    1746              :           {
    1747     20774300 :             tree folded = maybe_constant_init (init, TARGET_EXPR_SLOT (stmt),
    1748     20774300 :                                                (data->flags & ff_mce_false
    1749              :                                                 ? mce_false : mce_unknown));
    1750     20774300 :             if (folded != init && TREE_CONSTANT (folded))
    1751      1802703 :               init = folded;
    1752              :           }
    1753              : 
    1754              :       /* This needs to happen between the constexpr evaluation (which wants
    1755              :          pre-generic trees) and fold (which wants the cp_genericize_init
    1756              :          transformations).  */
    1757     45257119 :       if (data->flags & ff_genericize)
    1758     21982045 :         cp_genericize_target_expr (stmt_p);
    1759              : 
    1760     45257119 :       if (tree &init = TARGET_EXPR_INITIAL (stmt))
    1761              :         {
    1762     45257119 :           cp_walk_tree (&init, cp_fold_r, data, NULL);
    1763     45257119 :           cp_walk_tree (&TARGET_EXPR_CLEANUP (stmt), cp_fold_r, data, NULL);
    1764     45257119 :           *walk_subtrees = 0;
    1765              :           /* Folding might replace e.g. a COND_EXPR with a TARGET_EXPR; in
    1766              :              that case, strip it in favor of this one.  */
    1767     45257119 :           if (TREE_CODE (init) == TARGET_EXPR)
    1768              :             {
    1769          130 :               tree sub = TARGET_EXPR_INITIAL (init);
    1770          130 :               maybe_replace_decl (&sub, TARGET_EXPR_SLOT (init),
    1771          130 :                                   TARGET_EXPR_SLOT (stmt));
    1772          130 :               init = sub;
    1773              :             }
    1774              :         }
    1775              :       break;
    1776              : 
    1777              :     default:
    1778              :       break;
    1779              :     }
    1780              : 
    1781              :   return NULL_TREE;
    1782              : }
    1783              : 
    1784              : /* Fold ALL the trees!  FIXME we should be able to remove this, but
    1785              :    apparently that still causes optimization regressions.  */
    1786              : 
    1787              : void
    1788     68124183 : cp_fold_function (tree fndecl)
    1789              : {
    1790              :   /* By now all manifestly-constant-evaluated expressions will have
    1791              :      been constant-evaluated already if possible, so we can safely
    1792              :      pass ff_mce_false.  */
    1793     68124183 :   cp_fold_data data (ff_genericize | ff_mce_false);
    1794              :   /* Do cp_fold_immediate_r in separate whole IL walk instead of during
    1795              :      cp_fold_r, as otherwise expressions using results of immediate functions
    1796              :      might not be folded as cp_fold is called on those before cp_fold_r is
    1797              :      called on their argument.  */
    1798     68124183 :   if (cxx_dialect >= cxx20)
    1799              :     {
    1800     66167087 :       cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_immediate_r,
    1801              :                     &data, NULL);
    1802     66167087 :       data.pset.empty ();
    1803              :     }
    1804     68124183 :   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
    1805              : 
    1806              :   /* This is merely an optimization: if FNDECL has no i-e expressions,
    1807              :      we'll not save c_f_d, and we can safely say that FNDECL will not
    1808              :      be promoted to consteval.  */
    1809     68124183 :   if (deferred_escalating_exprs
    1810     68124183 :       && !deferred_escalating_exprs->contains (current_function_decl))
    1811     50835772 :     DECL_ESCALATION_CHECKED_P (fndecl) = true;
    1812     68124183 : }
    1813              : 
    1814              : /* Fold any non-ODR usages of constant variables in FNDECL.  This occurs
    1815              :    before saving the constexpr fundef, so do as little other folding
    1816              :    as possible.  */
    1817              : 
    1818              : void
    1819     69246067 : cp_fold_function_non_odr_use (tree fndecl)
    1820              : {
    1821     69246067 :   cp_fold_data data (ff_only_non_odr);
    1822     69246067 :   cp_walk_tree (&DECL_SAVED_TREE (fndecl), cp_fold_r, &data, NULL);
    1823     69246067 : }
    1824              : 
    1825              : /* We've stashed immediate-escalating functions.  Now see if they indeed
    1826              :    ought to be promoted to consteval.  */
    1827              : 
    1828              : void
    1829        98561 : process_and_check_pending_immediate_escalating_fns ()
    1830              : {
    1831              :   /* This will be null for -fno-immediate-escalation.  */
    1832        98561 :   if (!deferred_escalating_exprs)
    1833              :     return;
    1834              : 
    1835     28044788 :   for (auto e : *deferred_escalating_exprs)
    1836     14012571 :     if (TREE_CODE (e) == FUNCTION_DECL && !DECL_ESCALATION_CHECKED_P (e))
    1837      9572634 :       cp_fold_immediate (&DECL_SAVED_TREE (e), mce_false, e);
    1838              : 
    1839              :   /* We've escalated every function that could have been promoted to
    1840              :      consteval.  Check that we are not taking the address of a consteval
    1841              :      function.  */
    1842     28044931 :   for (auto e : *deferred_escalating_exprs)
    1843              :     {
    1844     14012571 :       if (TREE_CODE (e) == FUNCTION_DECL)
    1845     14012428 :         continue;
    1846          143 :       tree decl = (TREE_CODE (e) == PTRMEM_CST
    1847          143 :                    ? PTRMEM_CST_MEMBER (e)
    1848          143 :                    : TREE_OPERAND (e, 0));
    1849          286 :       if (DECL_IMMEDIATE_FUNCTION_P (decl))
    1850           12 :         taking_address_of_imm_fn_error (e, decl);
    1851              :     }
    1852              : 
    1853        19789 :   deferred_escalating_exprs = nullptr;
    1854              : }
    1855              : 
    1856              : /* Turn SPACESHIP_EXPR EXPR into GENERIC.  */
    1857              : 
    1858       235737 : static tree genericize_spaceship (tree expr)
    1859              : {
    1860       235737 :   iloc_sentinel s (cp_expr_location (expr));
    1861       235737 :   tree type = TREE_TYPE (expr);
    1862       235737 :   tree op0 = TREE_OPERAND (expr, 0);
    1863       235737 :   tree op1 = TREE_OPERAND (expr, 1);
    1864       235737 :   return genericize_spaceship (input_location, type, op0, op1);
    1865       235737 : }
    1866              : 
    1867              : /* If EXPR involves an anonymous VLA type, prepend a DECL_EXPR for that type
    1868              :    to trigger gimplify_type_sizes; otherwise a cast to pointer-to-VLA confuses
    1869              :    the middle-end (c++/88256).  If EXPR is a DECL, use add_stmt and return
    1870              :    NULL_TREE; otherwise return a COMPOUND_STMT of the DECL_EXPR and EXPR.  */
    1871              : 
    1872              : tree
    1873    142725683 : predeclare_vla (tree expr)
    1874              : {
    1875    142725683 :   tree type = TREE_TYPE (expr);
    1876    142725683 :   if (type == error_mark_node)
    1877              :     return expr;
    1878    142725497 :   if (is_typedef_decl (expr))
    1879    142725497 :     type = DECL_ORIGINAL_TYPE (expr);
    1880              : 
    1881              :   /* We need to strip pointers for gimplify_type_sizes.  */
    1882    142725497 :   tree vla = type;
    1883    217658654 :   while (POINTER_TYPE_P (vla))
    1884              :     {
    1885     77445062 :       if (TYPE_NAME (vla))
    1886              :         return expr;
    1887     74933157 :       vla = TREE_TYPE (vla);
    1888              :     }
    1889     72999277 :   if (vla == type || TYPE_NAME (vla)
    1890    140788485 :       || !variably_modified_type_p (vla, NULL_TREE))
    1891    140213277 :     return expr;
    1892              : 
    1893          315 :   tree decl = build_decl (input_location, TYPE_DECL, NULL_TREE, vla);
    1894          315 :   DECL_ARTIFICIAL (decl) = 1;
    1895          315 :   TYPE_NAME (vla) = decl;
    1896          315 :   tree dexp = build_stmt (input_location, DECL_EXPR, decl);
    1897          315 :   if (DECL_P (expr))
    1898              :     {
    1899            5 :       add_stmt (dexp);
    1900            5 :       return NULL_TREE;
    1901              :     }
    1902              :   else
    1903              :     {
    1904          310 :       expr = build2 (COMPOUND_EXPR, type, dexp, expr);
    1905          310 :       return expr;
    1906              :     }
    1907              : }
    1908              : 
    1909              : /* Perform any pre-gimplification lowering of C++ front end trees to
    1910              :    GENERIC.  */
    1911              : 
    1912              : static tree
    1913   1850407047 : cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
    1914              : {
    1915   1872360690 :   tree stmt = *stmt_p;
    1916   1872360690 :   struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
    1917   1872360690 :   hash_set<tree> *p_set = wtd->p_set;
    1918              : 
    1919              :   /* If in an OpenMP context, note var uses.  */
    1920   1872360690 :   if (UNLIKELY (wtd->omp_ctx != NULL)
    1921       597741 :       && (VAR_P (stmt)
    1922              :           || TREE_CODE (stmt) == PARM_DECL
    1923              :           || TREE_CODE (stmt) == RESULT_DECL)
    1924   1872468512 :       && omp_var_to_track (stmt))
    1925        12507 :     omp_cxx_notice_variable (wtd->omp_ctx, stmt);
    1926              : 
    1927              :   /* Don't dereference parms in a thunk, pass the references through. */
    1928     75358673 :   if ((TREE_CODE (stmt) == CALL_EXPR && call_from_lambda_thunk_p (stmt))
    1929   1947651165 :       || (TREE_CODE (stmt) == AGGR_INIT_EXPR && AGGR_INIT_FROM_THUNK_P (stmt)))
    1930              :     {
    1931        68412 :       *walk_subtrees = 0;
    1932        68412 :       return NULL;
    1933              :     }
    1934              : 
    1935              :   /* Dereference invisible reference parms.  */
    1936   1872292278 :   if (wtd->handle_invisiref_parm_p && is_invisiref_parm (stmt))
    1937              :     {
    1938      1309847 :       *stmt_p = convert_from_reference (stmt);
    1939      1309847 :       p_set->add (*stmt_p);
    1940      1309847 :       *walk_subtrees = 0;
    1941      1309847 :       return NULL;
    1942              :     }
    1943              : 
    1944              :   /* Map block scope extern declarations to visible declarations with the
    1945              :      same name and type in outer scopes if any.  */
    1946   1870982431 :   if (VAR_OR_FUNCTION_DECL_P (stmt) && DECL_LOCAL_DECL_P (stmt))
    1947        21883 :     if (tree alias = DECL_LOCAL_DECL_ALIAS (stmt))
    1948              :       {
    1949        21883 :         if (alias != error_mark_node)
    1950              :           {
    1951        21880 :             *stmt_p = alias;
    1952        21880 :             TREE_USED (alias) |= TREE_USED (stmt);
    1953              :           }
    1954        21883 :         *walk_subtrees = 0;
    1955        21883 :         return NULL;
    1956              :       }
    1957              : 
    1958   1870960548 :   if (TREE_CODE (stmt) == INTEGER_CST
    1959    214274977 :       && TYPE_REF_P (TREE_TYPE (stmt))
    1960          168 :       && (flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT))
    1961   1870960549 :       && !wtd->no_sanitize_p)
    1962              :     {
    1963            1 :       ubsan_maybe_instrument_reference (stmt_p);
    1964            1 :       if (*stmt_p != stmt)
    1965              :         {
    1966            1 :           *walk_subtrees = 0;
    1967            1 :           return NULL_TREE;
    1968              :         }
    1969              :     }
    1970              : 
    1971              :   /* Other than invisiref parms, don't walk the same tree twice.  */
    1972   1870960547 :   if (p_set->contains (stmt))
    1973              :     {
    1974    370954100 :       *walk_subtrees = 0;
    1975    370954100 :       return NULL_TREE;
    1976              :     }
    1977              : 
    1978   1500006447 :   if ((TREE_CODE (stmt) == VAR_DECL
    1979              :        || TREE_CODE (stmt) == PARM_DECL
    1980              :        || TREE_CODE (stmt) == RESULT_DECL)
    1981    161725831 :       && DECL_HAS_VALUE_EXPR_P (stmt))
    1982              :     {
    1983       811290 :       tree ve = DECL_VALUE_EXPR (stmt);
    1984       811290 :       cp_walk_tree (&ve, cp_genericize_r, data, NULL);
    1985       811290 :       SET_DECL_VALUE_EXPR (stmt, ve);
    1986              :     }
    1987              : 
    1988   1500006447 :   switch (TREE_CODE (stmt))
    1989              :     {
    1990    120792635 :     case ADDR_EXPR:
    1991    120792635 :       if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
    1992              :         {
    1993              :           /* If in an OpenMP context, note var uses.  */
    1994       564441 :           if (UNLIKELY (wtd->omp_ctx != NULL)
    1995       564441 :               && omp_var_to_track (TREE_OPERAND (stmt, 0)))
    1996          412 :             omp_cxx_notice_variable (wtd->omp_ctx, TREE_OPERAND (stmt, 0));
    1997       564441 :           *stmt_p = fold_convert (TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
    1998       564441 :           *walk_subtrees = 0;
    1999              :         }
    2000              :       break;
    2001              : 
    2002     44985571 :     case RETURN_EXPR:
    2003     44985571 :       if (TREE_OPERAND (stmt, 0))
    2004              :         {
    2005     44289489 :           if (error_operand_p (TREE_OPERAND (stmt, 0))
    2006     44289489 :               && warn_return_type)
    2007              :             /* Suppress -Wreturn-type for this function.  */
    2008           12 :             suppress_warning (current_function_decl, OPT_Wreturn_type);
    2009              : 
    2010     44289489 :           if (is_invisiref_parm (TREE_OPERAND (stmt, 0)))
    2011              :             /* Don't dereference an invisiref RESULT_DECL inside a
    2012              :                RETURN_EXPR.  */
    2013          626 :             *walk_subtrees = 0;
    2014     44289489 :           if (RETURN_EXPR_LOCAL_ADDR_P (stmt))
    2015              :             {
    2016              :               /* Don't return the address of a local variable.  */
    2017          175 :               tree *p = &TREE_OPERAND (stmt, 0);
    2018          350 :               while (TREE_CODE (*p) == COMPOUND_EXPR)
    2019            0 :                 p = &TREE_OPERAND (*p, 0);
    2020          175 :               if (TREE_CODE (*p) == INIT_EXPR)
    2021              :                 {
    2022          175 :                   tree op = TREE_OPERAND (*p, 1);
    2023          175 :                   tree new_op = build2 (COMPOUND_EXPR, TREE_TYPE (op), op,
    2024          175 :                                         build_zero_cst (TREE_TYPE (op)));
    2025          175 :                   TREE_OPERAND (*p, 1) = new_op;
    2026              :                 }
    2027              :             }
    2028              :         }
    2029              :       break;
    2030              : 
    2031        82821 :     case OMP_CLAUSE:
    2032        82821 :       switch (OMP_CLAUSE_CODE (stmt))
    2033              :         {
    2034         2590 :         case OMP_CLAUSE_LASTPRIVATE:
    2035              :           /* Don't dereference an invisiref in OpenMP clauses.  */
    2036         2590 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2037              :             {
    2038           53 :               *walk_subtrees = 0;
    2039           53 :               if (OMP_CLAUSE_LASTPRIVATE_STMT (stmt))
    2040           48 :                 cp_walk_tree (&OMP_CLAUSE_LASTPRIVATE_STMT (stmt),
    2041              :                               cp_genericize_r, data, NULL);
    2042              :             }
    2043              :           break;
    2044         2087 :         case OMP_CLAUSE_PRIVATE:
    2045              :           /* Don't dereference an invisiref in OpenMP clauses.  */
    2046         2087 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2047            8 :             *walk_subtrees = 0;
    2048         2079 :           else if (wtd->omp_ctx != NULL)
    2049              :             {
    2050              :               /* Private clause doesn't cause any references to the
    2051              :                  var in outer contexts, avoid calling
    2052              :                  omp_cxx_notice_variable for it.  */
    2053          584 :               struct cp_genericize_omp_taskreg *old = wtd->omp_ctx;
    2054          584 :               wtd->omp_ctx = NULL;
    2055          584 :               cp_walk_tree (&OMP_CLAUSE_DECL (stmt), cp_genericize_r,
    2056              :                             data, NULL);
    2057          584 :               wtd->omp_ctx = old;
    2058          584 :               *walk_subtrees = 0;
    2059              :             }
    2060              :           break;
    2061         6061 :         case OMP_CLAUSE_SHARED:
    2062         6061 :         case OMP_CLAUSE_FIRSTPRIVATE:
    2063         6061 :         case OMP_CLAUSE_COPYIN:
    2064         6061 :         case OMP_CLAUSE_COPYPRIVATE:
    2065         6061 :         case OMP_CLAUSE_INCLUSIVE:
    2066         6061 :         case OMP_CLAUSE_EXCLUSIVE:
    2067              :           /* Don't dereference an invisiref in OpenMP clauses.  */
    2068         6061 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2069           87 :             *walk_subtrees = 0;
    2070              :           break;
    2071         8491 :         case OMP_CLAUSE_REDUCTION:
    2072         8491 :         case OMP_CLAUSE_IN_REDUCTION:
    2073         8491 :         case OMP_CLAUSE_TASK_REDUCTION:
    2074              :           /* Don't dereference an invisiref in reduction clause's
    2075              :              OMP_CLAUSE_DECL either.  OMP_CLAUSE_REDUCTION_{INIT,MERGE}
    2076              :              still needs to be genericized.  */
    2077         8491 :           if (is_invisiref_parm (OMP_CLAUSE_DECL (stmt)))
    2078              :             {
    2079           38 :               *walk_subtrees = 0;
    2080           38 :               if (OMP_CLAUSE_REDUCTION_INIT (stmt))
    2081           38 :                 cp_walk_tree (&OMP_CLAUSE_REDUCTION_INIT (stmt),
    2082              :                               cp_genericize_r, data, NULL);
    2083           38 :               if (OMP_CLAUSE_REDUCTION_MERGE (stmt))
    2084           38 :                 cp_walk_tree (&OMP_CLAUSE_REDUCTION_MERGE (stmt),
    2085              :                               cp_genericize_r, data, NULL);
    2086              :             }
    2087              :           break;
    2088              :         default:
    2089              :           break;
    2090              :         }
    2091              :       break;
    2092              : 
    2093              :     /* Due to the way voidify_wrapper_expr is written, we don't get a chance
    2094              :        to lower this construct before scanning it, so we need to lower these
    2095              :        before doing anything else.  */
    2096      5819688 :     case CLEANUP_STMT:
    2097      5819688 :       *stmt_p = build2_loc (EXPR_LOCATION (stmt),
    2098      5819688 :                             CLEANUP_EH_ONLY (stmt) ? TRY_CATCH_EXPR
    2099              :                                                    : TRY_FINALLY_EXPR,
    2100              :                             void_type_node,
    2101      5819688 :                             CLEANUP_BODY (stmt),
    2102      5819688 :                             CLEANUP_EXPR (stmt));
    2103      5819688 :       break;
    2104              : 
    2105     21952671 :     case IF_STMT:
    2106     21952671 :       genericize_if_stmt (stmt_p);
    2107              :       /* *stmt_p has changed, tail recurse to handle it again.  */
    2108     21952671 :       return cp_genericize_r (stmt_p, walk_subtrees, data);
    2109              : 
    2110              :     /* COND_EXPR might have incompatible types in branches if one or both
    2111              :        arms are bitfields.  Fix it up now.  */
    2112     19731762 :     case COND_EXPR:
    2113     19731762 :       {
    2114     19731762 :         tree type_left
    2115     19731762 :           = (TREE_OPERAND (stmt, 1)
    2116     19731762 :              ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 1))
    2117              :              : NULL_TREE);
    2118     19731762 :         tree type_right
    2119     19731762 :           = (TREE_OPERAND (stmt, 2)
    2120     19731762 :              ? is_bitfield_expr_with_lowered_type (TREE_OPERAND (stmt, 2))
    2121              :              : NULL_TREE);
    2122     19731762 :         if (type_left
    2123     19731795 :             && !useless_type_conversion_p (TREE_TYPE (stmt),
    2124           33 :                                            TREE_TYPE (TREE_OPERAND (stmt, 1))))
    2125              :           {
    2126           30 :             TREE_OPERAND (stmt, 1)
    2127           30 :               = fold_convert (type_left, TREE_OPERAND (stmt, 1));
    2128           30 :             gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
    2129              :                                                    type_left));
    2130              :           }
    2131     19731762 :         if (type_right
    2132     19731779 :             && !useless_type_conversion_p (TREE_TYPE (stmt),
    2133           17 :                                            TREE_TYPE (TREE_OPERAND (stmt, 2))))
    2134              :           {
    2135           17 :             TREE_OPERAND (stmt, 2)
    2136           17 :               = fold_convert (type_right, TREE_OPERAND (stmt, 2));
    2137           17 :             gcc_assert (useless_type_conversion_p (TREE_TYPE (stmt),
    2138              :                                                    type_right));
    2139              :           }
    2140              :       }
    2141              :       break;
    2142              : 
    2143     26146738 :     case BIND_EXPR:
    2144     26146738 :       if (UNLIKELY (wtd->omp_ctx != NULL))
    2145              :         {
    2146        27053 :           tree decl;
    2147        33360 :           for (decl = BIND_EXPR_VARS (stmt); decl; decl = DECL_CHAIN (decl))
    2148         6307 :             if (VAR_P (decl)
    2149         6259 :                 && !DECL_EXTERNAL (decl)
    2150        12566 :                 && omp_var_to_track (decl))
    2151              :               {
    2152          586 :                 splay_tree_node n
    2153          586 :                   = splay_tree_lookup (wtd->omp_ctx->variables,
    2154              :                                        (splay_tree_key) decl);
    2155          586 :                 if (n == NULL)
    2156          586 :                   splay_tree_insert (wtd->omp_ctx->variables,
    2157              :                                      (splay_tree_key) decl,
    2158          586 :                                      TREE_STATIC (decl)
    2159              :                                      ? OMP_CLAUSE_DEFAULT_SHARED
    2160              :                                      : OMP_CLAUSE_DEFAULT_PRIVATE);
    2161              :               }
    2162              :         }
    2163     26146738 :       if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR))
    2164              :         {
    2165              :           /* The point here is to not sanitize static initializers.  */
    2166         3497 :           bool no_sanitize_p = wtd->no_sanitize_p;
    2167         3497 :           wtd->no_sanitize_p = true;
    2168         3497 :           for (tree decl = BIND_EXPR_VARS (stmt);
    2169         6778 :                decl;
    2170         3281 :                decl = DECL_CHAIN (decl))
    2171         3281 :             if (VAR_P (decl)
    2172         2876 :                 && TREE_STATIC (decl)
    2173         3355 :                 && DECL_INITIAL (decl))
    2174           12 :               cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL);
    2175         3497 :           wtd->no_sanitize_p = no_sanitize_p;
    2176              :         }
    2177     26146738 :       if (flag_reflection)
    2178              :         /* Wipe consteval-only vars from BIND_EXPR_VARS and BLOCK_VARS.  */
    2179      1076888 :         for (tree *p = &BIND_EXPR_VARS (stmt); *p; )
    2180              :           {
    2181       522733 :             if (VAR_P (*p) && consteval_only_p (*p))
    2182              :               {
    2183          844 :                 if (BIND_EXPR_BLOCK (stmt)
    2184          844 :                     && *p == BLOCK_VARS (BIND_EXPR_BLOCK (stmt)))
    2185          452 :                   BLOCK_VARS (BIND_EXPR_BLOCK (stmt)) = DECL_CHAIN (*p);
    2186          844 :                 *p = DECL_CHAIN (*p);
    2187          844 :                 continue;
    2188              :               }
    2189       521889 :             p = &DECL_CHAIN (*p);
    2190              :           }
    2191     26146738 :       wtd->bind_expr_stack.safe_push (stmt);
    2192     26146738 :       cp_walk_tree (&BIND_EXPR_BODY (stmt),
    2193              :                     cp_genericize_r, data, NULL);
    2194     26146738 :       wtd->bind_expr_stack.pop ();
    2195     26146738 :       break;
    2196              : 
    2197          972 :     case ASSERTION_STMT:
    2198          972 :     case PRECONDITION_STMT:
    2199          972 :     case POSTCONDITION_STMT:
    2200          972 :       if (tree check = build_contract_check (stmt))
    2201              :         {
    2202          972 :           *stmt_p = check;
    2203          972 :           return cp_genericize_r (stmt_p, walk_subtrees, data);
    2204              :         }
    2205              :       /* If we didn't build a check, replace it with void_node so we don't
    2206              :          leak contracts into GENERIC.  */
    2207            0 :       *stmt_p = void_node;
    2208            0 :       *walk_subtrees = 0;
    2209            0 :       break;
    2210              : 
    2211        18411 :     case USING_STMT:
    2212        18411 :       {
    2213        18411 :         tree block = NULL_TREE;
    2214              : 
    2215              :         /* Get the innermost inclosing GIMPLE_BIND that has a non NULL
    2216              :            BLOCK, and append an IMPORTED_DECL to its
    2217              :            BLOCK_VARS chained list.  */
    2218        18411 :         if (wtd->bind_expr_stack.exists ())
    2219              :           {
    2220        18411 :             int i;
    2221        18411 :             for (i = wtd->bind_expr_stack.length () - 1; i >= 0; i--)
    2222        18411 :               if ((block = BIND_EXPR_BLOCK (wtd->bind_expr_stack[i])))
    2223              :                 break;
    2224              :           }
    2225        18411 :         if (block)
    2226              :           {
    2227        18411 :             tree decl = TREE_OPERAND (stmt, 0);
    2228        18411 :             gcc_assert (decl);
    2229              : 
    2230        18411 :             if (undeduced_auto_decl (decl))
    2231              :               /* Omit from the GENERIC, the back-end can't handle it.  */;
    2232              :             else
    2233              :               {
    2234        18408 :                 tree using_directive = make_node (IMPORTED_DECL);
    2235        18408 :                 TREE_TYPE (using_directive) = void_type_node;
    2236        18408 :                 DECL_CONTEXT (using_directive) = current_function_decl;
    2237        36816 :                 DECL_SOURCE_LOCATION (using_directive)
    2238        18408 :                   = cp_expr_loc_or_input_loc (stmt);
    2239              : 
    2240        18408 :                 IMPORTED_DECL_ASSOCIATED_DECL (using_directive) = decl;
    2241        18408 :                 DECL_CHAIN (using_directive) = BLOCK_VARS (block);
    2242        18408 :                 BLOCK_VARS (block) = using_directive;
    2243              :               }
    2244              :           }
    2245              :         /* The USING_STMT won't appear in GENERIC.  */
    2246        18411 :         *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
    2247        18411 :         *walk_subtrees = 0;
    2248              :       }
    2249        18411 :       break;
    2250              : 
    2251     25743789 :     case DECL_EXPR:
    2252     25743789 :       if (TREE_CODE (DECL_EXPR_DECL (stmt)) == USING_DECL)
    2253              :         {
    2254              :           /* Using decls inside DECL_EXPRs are just dropped on the floor.  */
    2255        20879 :           *stmt_p = build1 (NOP_EXPR, void_type_node, integer_zero_node);
    2256        20879 :           *walk_subtrees = 0;
    2257              :         }
    2258              :       else
    2259              :         {
    2260     25722910 :           tree d = DECL_EXPR_DECL (stmt);
    2261     25722910 :           if (VAR_P (d))
    2262     51444099 :             gcc_assert (CP_DECL_THREAD_LOCAL_P (d) == DECL_THREAD_LOCAL_P (d));
    2263              :         }
    2264              :       break;
    2265              : 
    2266        11418 :     case OMP_PARALLEL:
    2267        11418 :     case OMP_TASK:
    2268        11418 :     case OMP_TASKLOOP:
    2269        11418 :       {
    2270        11418 :         struct cp_genericize_omp_taskreg omp_ctx;
    2271        11418 :         tree c, decl;
    2272        11418 :         splay_tree_node n;
    2273              : 
    2274        11418 :         *walk_subtrees = 0;
    2275        11418 :         cp_walk_tree (&OMP_CLAUSES (stmt), cp_genericize_r, data, NULL);
    2276        11418 :         omp_ctx.is_parallel = TREE_CODE (stmt) == OMP_PARALLEL;
    2277        11418 :         omp_ctx.default_shared = omp_ctx.is_parallel;
    2278        11418 :         omp_ctx.outer = wtd->omp_ctx;
    2279        11418 :         omp_ctx.variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
    2280        11418 :         wtd->omp_ctx = &omp_ctx;
    2281        27234 :         for (c = OMP_CLAUSES (stmt); c; c = OMP_CLAUSE_CHAIN (c))
    2282        15816 :           switch (OMP_CLAUSE_CODE (c))
    2283              :             {
    2284         4790 :             case OMP_CLAUSE_SHARED:
    2285         4790 :             case OMP_CLAUSE_PRIVATE:
    2286         4790 :             case OMP_CLAUSE_FIRSTPRIVATE:
    2287         4790 :             case OMP_CLAUSE_LASTPRIVATE:
    2288         4790 :               decl = OMP_CLAUSE_DECL (c);
    2289         4790 :               if (decl == error_mark_node || !omp_var_to_track (decl))
    2290              :                 break;
    2291          519 :               n = splay_tree_lookup (omp_ctx.variables, (splay_tree_key) decl);
    2292          519 :               if (n != NULL)
    2293              :                 break;
    2294         1020 :               splay_tree_insert (omp_ctx.variables, (splay_tree_key) decl,
    2295          510 :                                  OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED
    2296              :                                  ? OMP_CLAUSE_DEFAULT_SHARED
    2297              :                                  : OMP_CLAUSE_DEFAULT_PRIVATE);
    2298          510 :               if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE && omp_ctx.outer)
    2299           91 :                 omp_cxx_notice_variable (omp_ctx.outer, decl);
    2300              :               break;
    2301         1647 :             case OMP_CLAUSE_DEFAULT:
    2302         1647 :               if (OMP_CLAUSE_DEFAULT_KIND (c) == OMP_CLAUSE_DEFAULT_SHARED)
    2303          731 :                 omp_ctx.default_shared = true;
    2304              :             default:
    2305              :               break;
    2306              :             }
    2307        11418 :         if (TREE_CODE (stmt) == OMP_TASKLOOP)
    2308         1001 :           c_genericize_control_stmt (stmt_p, walk_subtrees, data,
    2309              :                                      cp_genericize_r, cp_walk_subtrees);
    2310              :         else
    2311        10417 :           cp_walk_tree (&OMP_BODY (stmt), cp_genericize_r, data, NULL);
    2312        11418 :         wtd->omp_ctx = omp_ctx.outer;
    2313        11418 :         splay_tree_delete (omp_ctx.variables);
    2314              :       }
    2315        11418 :       break;
    2316              : 
    2317         6923 :     case OMP_TARGET:
    2318         6923 :       cfun->has_omp_target = true;
    2319         6923 :       break;
    2320              : 
    2321       139802 :     case TRY_BLOCK:
    2322       139802 :       {
    2323       139802 :         *walk_subtrees = 0;
    2324       139802 :         tree try_block = wtd->try_block;
    2325       139802 :         wtd->try_block = stmt;
    2326       139802 :         cp_walk_tree (&TRY_STMTS (stmt), cp_genericize_r, data, NULL);
    2327       139802 :         wtd->try_block = try_block;
    2328       139802 :         cp_walk_tree (&TRY_HANDLERS (stmt), cp_genericize_r, data, NULL);
    2329              :       }
    2330       139802 :       break;
    2331              : 
    2332     25639730 :     case MUST_NOT_THROW_EXPR:
    2333              :       /* MUST_NOT_THROW_COND might be something else with TM.  */
    2334     25639730 :       if (MUST_NOT_THROW_COND (stmt) == NULL_TREE)
    2335              :         {
    2336     25639712 :           *walk_subtrees = 0;
    2337     25639712 :           tree try_block = wtd->try_block;
    2338     25639712 :           wtd->try_block = stmt;
    2339     25639712 :           cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
    2340     25639712 :           wtd->try_block = try_block;
    2341              :         }
    2342              :       break;
    2343              : 
    2344       144472 :     case THROW_EXPR:
    2345       144472 :       {
    2346       144472 :         location_t loc = location_of (stmt);
    2347       144472 :         if (warning_suppressed_p (stmt /* What warning? */))
    2348              :           /* Never mind.  */;
    2349        44921 :         else if (wtd->try_block)
    2350              :           {
    2351        10526 :             if (TREE_CODE (wtd->try_block) == MUST_NOT_THROW_EXPR)
    2352              :               {
    2353           18 :                 auto_diagnostic_group d;
    2354           31 :                 if (warning_at (loc, OPT_Wterminate,
    2355              :                                 "%<throw%> will always call %<terminate%>")
    2356           10 :                     && cxx_dialect >= cxx11
    2357           36 :                     && DECL_DESTRUCTOR_P (current_function_decl))
    2358            5 :                   inform (loc, "in C++11 destructors default to %<noexcept%>");
    2359           18 :               }
    2360              :           }
    2361              :         else
    2362              :           {
    2363          103 :             if (warn_cxx11_compat && cxx_dialect < cxx11
    2364          206 :                 && DECL_DESTRUCTOR_P (current_function_decl)
    2365            1 :                 && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))
    2366              :                     == NULL_TREE)
    2367        34396 :                 && (get_defaulted_eh_spec (current_function_decl)
    2368            1 :                     == empty_except_spec))
    2369            1 :               warning_at (loc, OPT_Wc__11_compat,
    2370              :                           "in C++11 this %<throw%> will call %<terminate%> "
    2371              :                           "because destructors default to %<noexcept%>");
    2372              :           }
    2373              :       }
    2374              :       break;
    2375              : 
    2376     41986631 :     case CONVERT_EXPR:
    2377     41986631 :       gcc_checking_assert (!AGGREGATE_TYPE_P (TREE_TYPE (stmt)));
    2378     41986631 :       gcc_assert (!CONVERT_EXPR_VBASE_PATH (stmt));
    2379              :       break;
    2380              : 
    2381       235737 :     case SPACESHIP_EXPR:
    2382       235737 :       *stmt_p = genericize_spaceship (*stmt_p);
    2383       235737 :       break;
    2384              : 
    2385        31810 :     case PTRMEM_CST:
    2386              :       /* By the time we get here we're handing off to the back end, so we don't
    2387              :          need or want to preserve PTRMEM_CST anymore.  */
    2388        31810 :       *stmt_p = cplus_expand_constant (stmt);
    2389        31810 :       *walk_subtrees = 0;
    2390        31810 :       break;
    2391              : 
    2392       280343 :     case MEM_REF:
    2393              :       /* For MEM_REF, make sure not to sanitize the second operand even
    2394              :          if it has reference type.  It is just an offset with a type
    2395              :          holding other information.  There is no other processing we
    2396              :          need to do for INTEGER_CSTs, so just ignore the second argument
    2397              :          unconditionally.  */
    2398       280343 :       cp_walk_tree (&TREE_OPERAND (stmt, 0), cp_genericize_r, data, NULL);
    2399       280343 :       *walk_subtrees = 0;
    2400       280343 :       break;
    2401              : 
    2402    119212903 :     case NOP_EXPR:
    2403    119212903 :       *stmt_p = predeclare_vla (*stmt_p);
    2404              : 
    2405              :       /* Warn of new allocations that are not big enough for the target
    2406              :          type.  */
    2407    119212903 :       if (warn_alloc_size
    2408      1079452 :           && TREE_CODE (TREE_OPERAND (stmt, 0)) == CALL_EXPR
    2409    119277505 :           && POINTER_TYPE_P (TREE_TYPE (stmt)))
    2410              :         {
    2411        23545 :           if (tree fndecl = get_callee_fndecl (TREE_OPERAND (stmt, 0)))
    2412        23531 :             if (DECL_IS_MALLOC (fndecl))
    2413              :               {
    2414         1165 :                 tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
    2415         1165 :                 tree alloc_size = lookup_attribute ("alloc_size", attrs);
    2416         1165 :                 if (alloc_size)
    2417         1163 :                   warn_for_alloc_size (EXPR_LOCATION (stmt),
    2418         1163 :                                        TREE_TYPE (TREE_TYPE (stmt)),
    2419         1163 :                                        TREE_OPERAND (stmt, 0), alloc_size);
    2420              :               }
    2421              :         }
    2422              : 
    2423    119212903 :       if (!wtd->no_sanitize_p
    2424    119212898 :           && sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT)
    2425    119228423 :           && TYPE_REF_P (TREE_TYPE (stmt)))
    2426         2403 :         ubsan_maybe_instrument_reference (stmt_p);
    2427              :       break;
    2428              : 
    2429     75286279 :     case CALL_EXPR:
    2430     75286279 :       if (!wtd->no_sanitize_p
    2431     75286279 :           && sanitize_flags_p ((SANITIZE_NULL
    2432              :                                 | SANITIZE_ALIGNMENT | SANITIZE_VPTR)))
    2433              :         {
    2434        15688 :           tree fn = CALL_EXPR_FN (stmt);
    2435        15688 :           if (fn != NULL_TREE
    2436         9699 :               && !error_operand_p (fn)
    2437         9699 :               && INDIRECT_TYPE_P (TREE_TYPE (fn))
    2438        25387 :               && TREE_CODE (TREE_TYPE (TREE_TYPE (fn))) == METHOD_TYPE)
    2439              :             {
    2440         5427 :               bool is_ctor
    2441         5427 :                 = TREE_CODE (fn) == ADDR_EXPR
    2442         5304 :                   && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
    2443        16035 :                   && DECL_CONSTRUCTOR_P (TREE_OPERAND (fn, 0));
    2444         5427 :               if (sanitize_flags_p (SANITIZE_NULL | SANITIZE_ALIGNMENT))
    2445         4816 :                 ubsan_maybe_instrument_member_call (stmt, is_ctor);
    2446         5427 :               if (sanitize_flags_p (SANITIZE_VPTR) && !is_ctor)
    2447         4595 :                 cp_ubsan_maybe_instrument_member_call (stmt);
    2448              :             }
    2449        10261 :           else if (fn == NULL_TREE
    2450         5989 :                    && CALL_EXPR_IFN (stmt) == IFN_UBSAN_NULL
    2451         4902 :                    && TREE_CODE (CALL_EXPR_ARG (stmt, 0)) == INTEGER_CST
    2452        10267 :                    && TYPE_REF_P (TREE_TYPE (CALL_EXPR_ARG (stmt, 0))))
    2453            6 :             *walk_subtrees = 0;
    2454              :         }
    2455              :       /* Fall through.  */
    2456     80100128 :     case AGGR_INIT_EXPR:
    2457              :       /* For calls to a multi-versioned function, overload resolution
    2458              :          returns the function with the highest target priority, that is,
    2459              :          the version that will checked for dispatching first.  If this
    2460              :          version is inlinable, a direct call to this version can be made
    2461              :          otherwise the call should go through the dispatcher.
    2462              :          This is done at multiple_target.cc for target_version semantics.  */
    2463     80100128 :       {
    2464     80100128 :         tree fn = cp_get_callee_fndecl_nofold (stmt);
    2465     80100128 :         if (TARGET_HAS_FMV_TARGET_ATTRIBUTE
    2466              :             && fn
    2467     78954093 :             && DECL_FUNCTION_VERSIONED (fn)
    2468     80100263 :             && (current_function_decl == NULL
    2469          135 :                 || !targetm.target_option.can_inline_p
    2470          135 :                       (current_function_decl, fn)))
    2471          123 :           if (tree dis = get_function_version_dispatcher (fn))
    2472              :             {
    2473          123 :               mark_versions_used (dis);
    2474          123 :               dis = build_address (dis);
    2475          123 :               if (TREE_CODE (stmt) == CALL_EXPR)
    2476          120 :                 CALL_EXPR_FN (stmt) = dis;
    2477              :               else
    2478            3 :                 AGGR_INIT_EXPR_FN (stmt) = dis;
    2479              :             }
    2480              :       }
    2481              :       break;
    2482              : 
    2483     20661676 :     case TARGET_EXPR:
    2484     20661676 :       if (TARGET_EXPR_INITIAL (stmt)
    2485     20661676 :           && TREE_CODE (TARGET_EXPR_INITIAL (stmt)) == CONSTRUCTOR
    2486     24413577 :           && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (TARGET_EXPR_INITIAL (stmt)))
    2487          166 :         TARGET_EXPR_NO_ELIDE (stmt) = 1;
    2488              :       break;
    2489              : 
    2490          665 :     case TEMPLATE_ID_EXPR:
    2491          665 :       gcc_assert (concept_check_p (stmt));
    2492              :       /* Emit the value of the concept check.  */
    2493          665 :       *stmt_p = evaluate_concept_check (stmt);
    2494          665 :       walk_subtrees = 0;
    2495          665 :       break;
    2496              : 
    2497         4205 :     case OMP_DISTRIBUTE:
    2498              :       /* Need to explicitly instantiate copy ctors on class iterators of
    2499              :          composite distribute parallel for.  */
    2500         4205 :       if (OMP_FOR_INIT (*stmt_p) == NULL_TREE)
    2501              :         {
    2502         3712 :           tree *data[4] = { NULL, NULL, NULL, NULL };
    2503         3712 :           tree inner = walk_tree (&OMP_FOR_BODY (*stmt_p),
    2504              :                                   find_combined_omp_for, data, NULL);
    2505         3712 :           if (inner != NULL_TREE
    2506         3678 :               && TREE_CODE (inner) == OMP_FOR)
    2507              :             {
    2508         4494 :               for (int i = 0; i < TREE_VEC_LENGTH (OMP_FOR_INIT (inner)); i++)
    2509         2829 :                 if (TREE_VEC_ELT (OMP_FOR_INIT (inner), i)
    2510         2813 :                     && OMP_FOR_ORIG_DECLS (inner)
    2511         2813 :                     && TREE_CODE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
    2512              :                                   i)) == TREE_LIST
    2513         2853 :                     && TREE_PURPOSE (TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner),
    2514              :                                      i)))
    2515              :                   {
    2516           12 :                     tree orig = TREE_VEC_ELT (OMP_FOR_ORIG_DECLS (inner), i);
    2517              :                     /* Class iterators aren't allowed on OMP_SIMD, so the only
    2518              :                        case we need to solve is distribute parallel for.  */
    2519           12 :                     gcc_assert (TREE_CODE (inner) == OMP_FOR
    2520              :                                 && data[1]);
    2521           12 :                     tree orig_decl = TREE_PURPOSE (orig);
    2522           12 :                     tree c, cl = NULL_TREE;
    2523           12 :                     for (c = OMP_FOR_CLAUSES (inner);
    2524           16 :                          c; c = OMP_CLAUSE_CHAIN (c))
    2525           12 :                       if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
    2526            5 :                            || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
    2527           13 :                           && OMP_CLAUSE_DECL (c) == orig_decl)
    2528              :                         {
    2529              :                           cl = c;
    2530              :                           break;
    2531              :                         }
    2532           12 :                     if (cl == NULL_TREE)
    2533              :                       {
    2534            4 :                         for (c = OMP_PARALLEL_CLAUSES (*data[1]);
    2535            4 :                              c; c = OMP_CLAUSE_CHAIN (c))
    2536            1 :                           if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_PRIVATE
    2537            1 :                               && OMP_CLAUSE_DECL (c) == orig_decl)
    2538              :                             {
    2539              :                               cl = c;
    2540              :                               break;
    2541              :                             }
    2542              :                       }
    2543            4 :                     if (cl)
    2544              :                       {
    2545            9 :                         orig_decl = require_complete_type (orig_decl);
    2546            9 :                         tree inner_type = TREE_TYPE (orig_decl);
    2547            9 :                         if (orig_decl == error_mark_node)
    2548            0 :                           continue;
    2549            9 :                         if (TYPE_REF_P (TREE_TYPE (orig_decl)))
    2550            0 :                           inner_type = TREE_TYPE (inner_type);
    2551              : 
    2552            9 :                         while (TREE_CODE (inner_type) == ARRAY_TYPE)
    2553            0 :                           inner_type = TREE_TYPE (inner_type);
    2554            9 :                         get_copy_ctor (inner_type, tf_warning_or_error);
    2555              :                       }
    2556              :                 }
    2557              :             }
    2558              :         }
    2559              :       /* FALLTHRU */
    2560              : 
    2561      4996711 :     case FOR_STMT:
    2562      4996711 :     case WHILE_STMT:
    2563      4996711 :     case DO_STMT:
    2564      4996711 :     case SWITCH_STMT:
    2565      4996711 :     case CONTINUE_STMT:
    2566      4996711 :     case BREAK_STMT:
    2567      4996711 :     case OMP_FOR:
    2568      4996711 :     case OMP_SIMD:
    2569      4996711 :     case OMP_LOOP:
    2570      4996711 :     case OMP_TILE:
    2571      4996711 :     case OMP_UNROLL:
    2572      4996711 :     case OACC_LOOP:
    2573              :       /* These cases are handled by shared code.  */
    2574      4996711 :       c_genericize_control_stmt (stmt_p, walk_subtrees, data,
    2575              :                                  cp_genericize_r, cp_walk_subtrees);
    2576      4996711 :       break;
    2577              : 
    2578     70364797 :     case STATEMENT_LIST:
    2579              :       /* As above, handled by shared code.  */
    2580     70364797 :       c_genericize_control_stmt (stmt_p, walk_subtrees, data,
    2581              :                                  cp_genericize_r, cp_walk_subtrees);
    2582              :       /* If a statement list is freed as part of genericisation it will be
    2583              :          pushed onto the top of a statement list cache stack.  A subsequent
    2584              :          action can cause a new statement list to be required - and the one
    2585              :          just pushed will be returned.  If that is marked as visited, it can
    2586              :          prevent a tail recursion from processing the 'new' statement list,
    2587              :          so we do not mark statement lists as visited.  */
    2588     70364797 :       return NULL_TREE;
    2589        76527 :       break;
    2590              : 
    2591        76527 :     case BIT_CAST_EXPR:
    2592        76527 :       *stmt_p = build1_loc (EXPR_LOCATION (stmt), VIEW_CONVERT_EXPR,
    2593        76527 :                             TREE_TYPE (stmt), TREE_OPERAND (stmt, 0));
    2594        76527 :       break;
    2595              : 
    2596     21814982 :     case MODIFY_EXPR:
    2597              :       /* Mark stores to parts of complex automatic non-addressable
    2598              :          variables as DECL_NOT_GIMPLE_REG_P for -O0.  This can't be
    2599              :          done during gimplification.  See PR119120.  */
    2600     21814982 :       if ((TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR
    2601     21786660 :            || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR)
    2602        56655 :           && !optimize
    2603          540 :           && DECL_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0))
    2604     21815076 :           && is_gimple_reg (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)))
    2605           50 :         DECL_NOT_GIMPLE_REG_P (TREE_OPERAND (TREE_OPERAND (stmt, 0), 0)) = 1;
    2606              :       break;
    2607              : 
    2608    849026134 :     default:
    2609    849026134 :       if (IS_TYPE_OR_DECL_P (stmt))
    2610    265452179 :         *walk_subtrees = 0;
    2611              :       break;
    2612              :     }
    2613              : 
    2614   1407688007 :   p_set->add (*stmt_p);
    2615              : 
    2616   1407688007 :   return NULL;
    2617              : }
    2618              : 
    2619              : /* Lower C++ front end trees to GENERIC in T_P.  */
    2620              : 
    2621              : static void
    2622     51573755 : cp_genericize_tree (tree* t_p, bool handle_invisiref_parm_p)
    2623              : {
    2624     51573755 :   struct cp_genericize_data wtd;
    2625              : 
    2626     51573755 :   wtd.p_set = new hash_set<tree>;
    2627     51573755 :   wtd.bind_expr_stack.create (0);
    2628     51573755 :   wtd.omp_ctx = NULL;
    2629     51573755 :   wtd.try_block = NULL_TREE;
    2630     51573755 :   wtd.no_sanitize_p = false;
    2631     51573755 :   wtd.handle_invisiref_parm_p = handle_invisiref_parm_p;
    2632     51573755 :   cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
    2633    103147510 :   delete wtd.p_set;
    2634     51573755 :   if (sanitize_flags_p (SANITIZE_VPTR))
    2635         5711 :     cp_ubsan_instrument_member_accesses (t_p);
    2636     51573755 : }
    2637              : 
    2638              : /* If a function that should end with a return in non-void
    2639              :    function doesn't obviously end with return, add ubsan
    2640              :    instrumentation code to verify it at runtime.  If -fsanitize=return
    2641              :    is not enabled, instrument __builtin_unreachable.  */
    2642              : 
    2643              : static void
    2644     51573755 : cp_maybe_instrument_return (tree fndecl)
    2645              : {
    2646     51573755 :   if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
    2647     73979326 :       || DECL_CONSTRUCTOR_P (fndecl)
    2648     36989663 :       || DECL_DESTRUCTOR_P (fndecl)
    2649     88563418 :       || !targetm.warn_func_return (fndecl))
    2650     14584104 :     return;
    2651              : 
    2652     36989651 :   if (!sanitize_flags_p (SANITIZE_RETURN, fndecl)
    2653              :       /* Don't add __builtin_unreachable () if not optimizing, it will not
    2654              :          improve any optimizations in that case, just break UB code.
    2655              :          Don't add it if -fsanitize=unreachable -fno-sanitize=return either,
    2656              :          UBSan covers this with ubsan_instrument_return above where sufficient
    2657              :          information is provided, while the __builtin_unreachable () below
    2658              :          if return sanitization is disabled will just result in hard to
    2659              :          understand runtime error without location.  */
    2660     36989651 :       && ((!optimize && !flag_unreachable_traps)
    2661     36985798 :           || sanitize_flags_p (SANITIZE_UNREACHABLE, fndecl)))
    2662           30 :     return;
    2663              : 
    2664     36989621 :   tree t = DECL_SAVED_TREE (fndecl);
    2665     63795040 :   while (t)
    2666              :     {
    2667     63795040 :       switch (TREE_CODE (t))
    2668              :         {
    2669      4920464 :         case BIND_EXPR:
    2670      4920464 :           t = BIND_EXPR_BODY (t);
    2671      4920464 :           continue;
    2672      8928316 :         case TRY_FINALLY_EXPR:
    2673      8928316 :         case CLEANUP_POINT_EXPR:
    2674      8928316 :           t = TREE_OPERAND (t, 0);
    2675      8928316 :           continue;
    2676     12959454 :         case STATEMENT_LIST:
    2677     12959454 :           {
    2678     12959454 :             tree_stmt_iterator i = tsi_last (t);
    2679     12963025 :             while (!tsi_end_p (i))
    2680              :               {
    2681     12960210 :                 tree p = tsi_stmt (i);
    2682     12960210 :                 if (TREE_CODE (p) != DEBUG_BEGIN_STMT)
    2683              :                   break;
    2684         3571 :                 tsi_prev (&i);
    2685              :               }
    2686     12959454 :             if (!tsi_end_p (i))
    2687              :               {
    2688     12956639 :                 t = tsi_stmt (i);
    2689     12956639 :                 continue;
    2690              :               }
    2691              :           }
    2692         2815 :           break;
    2693              :         case RETURN_EXPR:
    2694              :           return;
    2695              :         default:
    2696              :           break;
    2697     13848780 :         }
    2698              :       break;
    2699              :     }
    2700     20442340 :   if (t == NULL_TREE)
    2701              :     return;
    2702     20442340 :   tree *p = &DECL_SAVED_TREE (fndecl);
    2703     20442340 :   if (TREE_CODE (*p) == BIND_EXPR)
    2704       922886 :     p = &BIND_EXPR_BODY (*p);
    2705              : 
    2706     20442340 :   location_t loc = DECL_SOURCE_LOCATION (fndecl);
    2707     20442340 :   if (sanitize_flags_p (SANITIZE_RETURN, fndecl))
    2708         1790 :     t = ubsan_instrument_return (loc);
    2709              :   else
    2710     20440550 :     t = build_builtin_unreachable (BUILTINS_LOCATION);
    2711              : 
    2712     20442340 :   append_to_statement_list (t, p);
    2713              : }
    2714              : 
    2715              : void
    2716     68119761 : cp_genericize (tree fndecl)
    2717              : {
    2718     68119761 :   tree t;
    2719              : 
    2720              :   /* Fix up the types of parms passed by invisible reference.  */
    2721    180509059 :   for (t = DECL_ARGUMENTS (fndecl); t; t = DECL_CHAIN (t))
    2722    112389298 :     if (TREE_ADDRESSABLE (TREE_TYPE (t)))
    2723              :       {
    2724              :         /* If a function's arguments are copied to create a thunk,
    2725              :            then DECL_BY_REFERENCE will be set -- but the type of the
    2726              :            argument will be a pointer type, so we will never get
    2727              :            here.  */
    2728       129916 :         gcc_assert (!DECL_BY_REFERENCE (t));
    2729       129916 :         gcc_assert (DECL_ARG_TYPE (t) != TREE_TYPE (t));
    2730       129916 :         TREE_TYPE (t) = DECL_ARG_TYPE (t);
    2731       129916 :         DECL_BY_REFERENCE (t) = 1;
    2732       129916 :         TREE_ADDRESSABLE (t) = 0;
    2733       129916 :         relayout_decl (t);
    2734              :       }
    2735              : 
    2736              :   /* Do the same for the return value.  */
    2737     68119761 :   if (TREE_ADDRESSABLE (TREE_TYPE (DECL_RESULT (fndecl))))
    2738              :     {
    2739      1161888 :       t = DECL_RESULT (fndecl);
    2740      1161888 :       TREE_TYPE (t) = build_reference_type (TREE_TYPE (t));
    2741      1161888 :       DECL_BY_REFERENCE (t) = 1;
    2742      1161888 :       TREE_ADDRESSABLE (t) = 0;
    2743      1161888 :       relayout_decl (t);
    2744      1161888 :       if (DECL_NAME (t))
    2745              :         {
    2746              :           /* Adjust DECL_VALUE_EXPR of the original var.  */
    2747       130043 :           tree outer = outer_curly_brace_block (current_function_decl);
    2748       130043 :           tree var;
    2749              : 
    2750       130043 :           if (outer)
    2751       305781 :             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
    2752       305065 :               if (VAR_P (var)
    2753       294978 :                   && DECL_NAME (t) == DECL_NAME (var)
    2754       129327 :                   && DECL_HAS_VALUE_EXPR_P (var)
    2755       434392 :                   && DECL_VALUE_EXPR (var) == t)
    2756              :                 {
    2757       129327 :                   tree val = convert_from_reference (t);
    2758       129327 :                   SET_DECL_VALUE_EXPR (var, val);
    2759       129327 :                   break;
    2760              :                 }
    2761              :         }
    2762              :     }
    2763              : 
    2764              :   /* If we're a clone, the body is already GIMPLE.  */
    2765     68119761 :   if (DECL_CLONED_FUNCTION_P (fndecl))
    2766     16546006 :     return;
    2767              : 
    2768              :   /* Allow cp_genericize calls to be nested.  */
    2769     51573755 :   bc_state_t save_state;
    2770     51573755 :   save_bc_state (&save_state);
    2771              : 
    2772              :   /* We do want to see every occurrence of the parms, so we can't just use
    2773              :      walk_tree's hash functionality.  */
    2774     51573755 :   cp_genericize_tree (&DECL_SAVED_TREE (fndecl), true);
    2775              : 
    2776     51573755 :   cp_maybe_instrument_return (fndecl);
    2777              : 
    2778              :   /* Do everything else.  */
    2779     51573755 :   c_genericize (fndecl);
    2780     51573755 :   restore_bc_state (&save_state);
    2781              : }
    2782              : 
    2783              : /* Build code to apply FN to each member of ARG1 and ARG2.  FN may be
    2784              :    NULL if there is in fact nothing to do.  ARG2 may be null if FN
    2785              :    actually only takes one argument.  */
    2786              : 
    2787              : static tree
    2788         3680 : cxx_omp_clause_apply_fn (tree fn, tree arg1, tree arg2)
    2789              : {
    2790         3680 :   tree defparm, parm, t;
    2791         3680 :   int i = 0;
    2792         3680 :   int nargs;
    2793         3680 :   tree *argarray;
    2794              : 
    2795         3680 :   if (fn == NULL)
    2796              :     return NULL;
    2797              : 
    2798         2824 :   nargs = list_length (DECL_ARGUMENTS (fn));
    2799         2824 :   argarray = XALLOCAVEC (tree, nargs);
    2800              : 
    2801         2824 :   defparm = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (fn)));
    2802         2824 :   if (arg2)
    2803          944 :     defparm = TREE_CHAIN (defparm);
    2804              : 
    2805         2824 :   bool is_method = TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE;
    2806         2824 :   if (TREE_CODE (TREE_TYPE (arg1)) == ARRAY_TYPE)
    2807              :     {
    2808           27 :       tree inner_type = TREE_TYPE (arg1);
    2809           27 :       tree start1, end1, p1;
    2810           27 :       tree start2 = NULL, p2 = NULL;
    2811           27 :       tree ret = NULL, lab;
    2812              : 
    2813           27 :       start1 = arg1;
    2814           27 :       start2 = arg2;
    2815           27 :       do
    2816              :         {
    2817           27 :           inner_type = TREE_TYPE (inner_type);
    2818           27 :           start1 = build4 (ARRAY_REF, inner_type, start1,
    2819              :                            size_zero_node, NULL, NULL);
    2820           27 :           if (arg2)
    2821            9 :             start2 = build4 (ARRAY_REF, inner_type, start2,
    2822              :                              size_zero_node, NULL, NULL);
    2823              :         }
    2824           27 :       while (TREE_CODE (inner_type) == ARRAY_TYPE);
    2825           27 :       start1 = build_fold_addr_expr_loc (input_location, start1);
    2826           27 :       if (arg2)
    2827            9 :         start2 = build_fold_addr_expr_loc (input_location, start2);
    2828              : 
    2829           27 :       end1 = TYPE_SIZE_UNIT (TREE_TYPE (arg1));
    2830           27 :       end1 = fold_build_pointer_plus (start1, end1);
    2831              : 
    2832           27 :       p1 = create_tmp_var (TREE_TYPE (start1));
    2833           27 :       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, start1);
    2834           27 :       append_to_statement_list (t, &ret);
    2835              : 
    2836           27 :       if (arg2)
    2837              :         {
    2838            9 :           p2 = create_tmp_var (TREE_TYPE (start2));
    2839            9 :           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, start2);
    2840            9 :           append_to_statement_list (t, &ret);
    2841              :         }
    2842              : 
    2843           27 :       lab = create_artificial_label (input_location);
    2844           27 :       t = build1 (LABEL_EXPR, void_type_node, lab);
    2845           27 :       append_to_statement_list (t, &ret);
    2846              : 
    2847           27 :       argarray[i++] = p1;
    2848           27 :       if (arg2)
    2849            9 :         argarray[i++] = p2;
    2850              :       /* Handle default arguments.  */
    2851           27 :       for (parm = defparm; parm && parm != void_list_node;
    2852            0 :            parm = TREE_CHAIN (parm), i++)
    2853            0 :         argarray[i] = convert_default_arg (TREE_VALUE (parm),
    2854            0 :                                            TREE_PURPOSE (parm), fn,
    2855              :                                            i - is_method, tf_warning_or_error);
    2856           27 :       t = build_call_a (fn, i, argarray);
    2857           27 :       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
    2858            0 :         t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
    2859           27 :       t = fold_convert (void_type_node, t);
    2860           27 :       t = fold_build_cleanup_point_expr (TREE_TYPE (t), t);
    2861           27 :       append_to_statement_list (t, &ret);
    2862              : 
    2863           27 :       t = fold_build_pointer_plus (p1, TYPE_SIZE_UNIT (inner_type));
    2864           27 :       t = build2 (MODIFY_EXPR, TREE_TYPE (p1), p1, t);
    2865           27 :       append_to_statement_list (t, &ret);
    2866              : 
    2867           27 :       if (arg2)
    2868              :         {
    2869            9 :           t = fold_build_pointer_plus (p2, TYPE_SIZE_UNIT (inner_type));
    2870            9 :           t = build2 (MODIFY_EXPR, TREE_TYPE (p2), p2, t);
    2871            9 :           append_to_statement_list (t, &ret);
    2872              :         }
    2873              : 
    2874           27 :       t = build2 (NE_EXPR, boolean_type_node, p1, end1);
    2875           27 :       t = build3 (COND_EXPR, void_type_node, t, build_and_jump (&lab), NULL);
    2876           27 :       append_to_statement_list (t, &ret);
    2877              : 
    2878           27 :       return ret;
    2879              :     }
    2880              :   else
    2881              :     {
    2882         2797 :       argarray[i++] = build_fold_addr_expr_loc (input_location, arg1);
    2883         2797 :       if (arg2)
    2884          935 :         argarray[i++] = build_fold_addr_expr_loc (input_location, arg2);
    2885              :       /* Handle default arguments.  */
    2886         2802 :       for (parm = defparm; parm && parm != void_list_node;
    2887            5 :            parm = TREE_CHAIN (parm), i++)
    2888           10 :         argarray[i] = convert_default_arg (TREE_VALUE (parm),
    2889            5 :                                            TREE_PURPOSE (parm), fn,
    2890              :                                            i - is_method, tf_warning_or_error);
    2891         2797 :       t = build_call_a (fn, i, argarray);
    2892         2797 :       if (MAYBE_CLASS_TYPE_P (TREE_TYPE (t)))
    2893            1 :         t = build_cplus_new (TREE_TYPE (t), t, tf_warning_or_error);
    2894         2797 :       t = fold_convert (void_type_node, t);
    2895         2797 :       return fold_build_cleanup_point_expr (TREE_TYPE (t), t);
    2896              :     }
    2897              : }
    2898              : 
    2899              : /* Return code to initialize DECL with its default constructor, or
    2900              :    NULL if there's nothing to do.  */
    2901              : 
    2902              : tree
    2903        42566 : cxx_omp_clause_default_ctor (tree clause, tree decl, tree /*outer*/)
    2904              : {
    2905        42566 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2906        42566 :   tree ret = NULL;
    2907              : 
    2908        42566 :   if (info)
    2909         1401 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), decl, NULL);
    2910              : 
    2911        42566 :   return ret;
    2912              : }
    2913              : 
    2914              : /* Return code to initialize DST with a copy constructor from SRC.  */
    2915              : 
    2916              : tree
    2917        12366 : cxx_omp_clause_copy_ctor (tree clause, tree dst, tree src)
    2918              : {
    2919        12366 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2920        12366 :   tree ret = NULL;
    2921              : 
    2922        12366 :   if (info)
    2923          283 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 0), dst, src);
    2924          283 :   if (ret == NULL)
    2925        12148 :     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
    2926              : 
    2927        12366 :   return ret;
    2928              : }
    2929              : 
    2930              : /* Similarly, except use an assignment operator instead.  */
    2931              : 
    2932              : tree
    2933        12686 : cxx_omp_clause_assign_op (tree clause, tree dst, tree src)
    2934              : {
    2935        12686 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2936        12686 :   tree ret = NULL;
    2937              : 
    2938        12686 :   if (info)
    2939          748 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 2), dst, src);
    2940          748 :   if (ret == NULL)
    2941        11960 :     ret = build2 (MODIFY_EXPR, TREE_TYPE (dst), dst, src);
    2942              : 
    2943        12686 :   return ret;
    2944              : }
    2945              : 
    2946              : /* Return code to destroy DECL.  */
    2947              : 
    2948              : tree
    2949        62589 : cxx_omp_clause_dtor (tree clause, tree decl)
    2950              : {
    2951        62589 :   tree info = CP_OMP_CLAUSE_INFO (clause);
    2952        62589 :   tree ret = NULL;
    2953              : 
    2954        62589 :   if (info)
    2955         1248 :     ret = cxx_omp_clause_apply_fn (TREE_VEC_ELT (info, 1), decl, NULL);
    2956              : 
    2957        62589 :   return ret;
    2958              : }
    2959              : 
    2960              : /* True if OpenMP should privatize what this DECL points to rather
    2961              :    than the DECL itself.  */
    2962              : 
    2963              : bool
    2964       969387 : cxx_omp_privatize_by_reference (const_tree decl)
    2965              : {
    2966       969387 :   return (TYPE_REF_P (TREE_TYPE (decl))
    2967       969387 :           || is_invisiref_parm (decl));
    2968              : }
    2969              : 
    2970              : /* Return true if DECL is const qualified var having no mutable member.  */
    2971              : bool
    2972        15302 : cxx_omp_const_qual_no_mutable (tree decl)
    2973              : {
    2974        15302 :   tree type = TREE_TYPE (decl);
    2975        15302 :   if (TYPE_REF_P (type))
    2976              :     {
    2977          843 :       if (!is_invisiref_parm (decl))
    2978              :         return false;
    2979            0 :       type = TREE_TYPE (type);
    2980              : 
    2981            0 :       if (TREE_CODE (decl) == RESULT_DECL && DECL_NAME (decl))
    2982              :         {
    2983              :           /* NVR doesn't preserve const qualification of the
    2984              :              variable's type.  */
    2985            0 :           tree outer = outer_curly_brace_block (current_function_decl);
    2986            0 :           tree var;
    2987              : 
    2988            0 :           if (outer)
    2989            0 :             for (var = BLOCK_VARS (outer); var; var = DECL_CHAIN (var))
    2990            0 :               if (VAR_P (var)
    2991            0 :                   && DECL_NAME (decl) == DECL_NAME (var)
    2992            0 :                   && (TYPE_MAIN_VARIANT (type)
    2993            0 :                       == TYPE_MAIN_VARIANT (TREE_TYPE (var))))
    2994              :                 {
    2995            0 :                   if (TYPE_READONLY (TREE_TYPE (var)))
    2996            0 :                     type = TREE_TYPE (var);
    2997              :                   break;
    2998              :                 }
    2999              :         }
    3000              :     }
    3001              : 
    3002        14459 :   if (type == error_mark_node)
    3003              :     return false;
    3004              : 
    3005              :   /* Variables with const-qualified type having no mutable member
    3006              :      are predetermined shared.  */
    3007        14444 :   if (TYPE_READONLY (type) && !cp_has_mutable_p (type))
    3008              :     return true;
    3009              : 
    3010              :   return false;
    3011              : }
    3012              : 
    3013              : /* OMP_CLAUSE_DEFAULT_UNSPECIFIED unless OpenMP sharing attribute
    3014              :    of DECL is predetermined.  */
    3015              : 
    3016              : enum omp_clause_default_kind
    3017        55619 : cxx_omp_predetermined_sharing_1 (tree decl)
    3018              : {
    3019              :   /* Static data members are predetermined shared.  */
    3020        55619 :   if (TREE_STATIC (decl))
    3021              :     {
    3022        15161 :       tree ctx = CP_DECL_CONTEXT (decl);
    3023        15161 :       if (TYPE_P (ctx) && MAYBE_CLASS_TYPE_P (ctx))
    3024              :         return OMP_CLAUSE_DEFAULT_SHARED;
    3025              : 
    3026        15055 :       if (c_omp_predefined_variable (decl))
    3027              :         return OMP_CLAUSE_DEFAULT_SHARED;
    3028              :     }
    3029              : 
    3030              :   /* this may not be specified in data-sharing clauses, still we need
    3031              :      to predetermined it firstprivate.  */
    3032        55468 :   if (decl == current_class_ptr)
    3033          113 :     return OMP_CLAUSE_DEFAULT_FIRSTPRIVATE;
    3034              : 
    3035              :   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
    3036              : }
    3037              : 
    3038              : /* Likewise, but also include the artificial vars.  We don't want to
    3039              :    disallow the artificial vars being mentioned in explicit clauses,
    3040              :    as we use artificial vars e.g. for loop constructs with random
    3041              :    access iterators other than pointers, but during gimplification
    3042              :    we want to treat them as predetermined.  */
    3043              : 
    3044              : enum omp_clause_default_kind
    3045        35112 : cxx_omp_predetermined_sharing (tree decl)
    3046              : {
    3047        35112 :   enum omp_clause_default_kind ret = cxx_omp_predetermined_sharing_1 (decl);
    3048        35112 :   if (ret != OMP_CLAUSE_DEFAULT_UNSPECIFIED)
    3049              :     return ret;
    3050              : 
    3051              :   /* Predetermine artificial variables holding integral values, those
    3052              :      are usually result of gimplify_one_sizepos or SAVE_EXPR
    3053              :      gimplification.  */
    3054        34895 :   if (VAR_P (decl)
    3055        22984 :       && DECL_ARTIFICIAL (decl)
    3056         7154 :       && INTEGRAL_TYPE_P (TREE_TYPE (decl))
    3057        35419 :       && !(DECL_LANG_SPECIFIC (decl)
    3058            2 :            && DECL_OMP_PRIVATIZED_MEMBER (decl)))
    3059              :     return OMP_CLAUSE_DEFAULT_SHARED;
    3060              : 
    3061              :   /* Similarly for typeinfo symbols.  */
    3062        34373 :   if (VAR_P (decl) && DECL_ARTIFICIAL (decl) && DECL_TINFO_P (decl))
    3063           60 :     return OMP_CLAUSE_DEFAULT_SHARED;
    3064              : 
    3065              :   return OMP_CLAUSE_DEFAULT_UNSPECIFIED;
    3066              : }
    3067              : 
    3068              : enum omp_clause_defaultmap_kind
    3069        17639 : cxx_omp_predetermined_mapping (tree decl)
    3070              : {
    3071              :   /* Predetermine artificial variables holding integral values, those
    3072              :      are usually result of gimplify_one_sizepos or SAVE_EXPR
    3073              :      gimplification.  */
    3074        17639 :   if (VAR_P (decl)
    3075         1673 :       && DECL_ARTIFICIAL (decl)
    3076          142 :       && INTEGRAL_TYPE_P (TREE_TYPE (decl))
    3077        17705 :       && !(DECL_LANG_SPECIFIC (decl)
    3078            6 :            && DECL_OMP_PRIVATIZED_MEMBER (decl)))
    3079              :     return OMP_CLAUSE_DEFAULTMAP_FIRSTPRIVATE;
    3080              : 
    3081        17573 :   if (c_omp_predefined_variable (decl))
    3082           12 :     return OMP_CLAUSE_DEFAULTMAP_TO;
    3083              : 
    3084              :   return OMP_CLAUSE_DEFAULTMAP_CATEGORY_UNSPECIFIED;
    3085              : }
    3086              : 
    3087              : /* Finalize an implicitly determined clause.  */
    3088              : 
    3089              : void
    3090        64226 : cxx_omp_finish_clause (tree c, gimple_seq *, bool /* openacc */)
    3091              : {
    3092        64226 :   tree decl, inner_type;
    3093        64226 :   bool make_shared = false;
    3094              : 
    3095        64226 :   if (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_FIRSTPRIVATE
    3096        56752 :       && OMP_CLAUSE_CODE (c) != OMP_CLAUSE_PRIVATE
    3097        94267 :       && (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LASTPRIVATE
    3098         4752 :           || !OMP_CLAUSE_LASTPRIVATE_LOOP_IV (c)))
    3099              :     return;
    3100              : 
    3101        34200 :   decl = OMP_CLAUSE_DECL (c);
    3102        34200 :   decl = require_complete_type (decl);
    3103        34200 :   inner_type = TREE_TYPE (decl);
    3104        34200 :   if (decl == error_mark_node)
    3105        34200 :     make_shared = true;
    3106        34200 :   else if (TYPE_REF_P (TREE_TYPE (decl)))
    3107           86 :     inner_type = TREE_TYPE (inner_type);
    3108              : 
    3109              :   /* We're interested in the base element, not arrays.  */
    3110        34442 :   while (TREE_CODE (inner_type) == ARRAY_TYPE)
    3111          242 :     inner_type = TREE_TYPE (inner_type);
    3112              : 
    3113              :   /* Check for special function availability by building a call to one.
    3114              :      Save the results, because later we won't be in the right context
    3115              :      for making these queries.  */
    3116        34200 :   bool first = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE;
    3117        34200 :   bool last = OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE;
    3118        34200 :   if (!make_shared
    3119        34200 :       && CLASS_TYPE_P (inner_type)
    3120        34423 :       && cxx_omp_create_clause_info (c, inner_type, !first, first, last,
    3121              :                                      true))
    3122              :     make_shared = true;
    3123              : 
    3124        34194 :   if (make_shared)
    3125              :     {
    3126            6 :       OMP_CLAUSE_CODE (c) = OMP_CLAUSE_SHARED;
    3127            6 :       OMP_CLAUSE_SHARED_FIRSTPRIVATE (c) = 0;
    3128            6 :       OMP_CLAUSE_SHARED_READONLY (c) = 0;
    3129              :     }
    3130              : }
    3131              : 
    3132              : tree
    3133           38 : cxx_omp_finish_mapper_clauses (tree clauses)
    3134              : {
    3135           38 :   return finish_omp_clauses (clauses, C_ORT_OMP);
    3136              : }
    3137              : 
    3138              : /* Return true if DECL's DECL_VALUE_EXPR (if any) should be
    3139              :    disregarded in OpenMP construct, because it is going to be
    3140              :    remapped during OpenMP lowering.  SHARED is true if DECL
    3141              :    is going to be shared, false if it is going to be privatized.  */
    3142              : 
    3143              : bool
    3144       668400 : cxx_omp_disregard_value_expr (tree decl, bool shared)
    3145              : {
    3146       668400 :   if (shared)
    3147              :     return false;
    3148       401469 :   if (VAR_P (decl)
    3149       379566 :       && DECL_HAS_VALUE_EXPR_P (decl)
    3150         9549 :       && DECL_ARTIFICIAL (decl)
    3151         9038 :       && DECL_LANG_SPECIFIC (decl)
    3152       409368 :       && DECL_OMP_PRIVATIZED_MEMBER (decl))
    3153              :     return true;
    3154       396056 :   if (VAR_P (decl) && DECL_CONTEXT (decl) && is_capture_proxy (decl))
    3155              :     return true;
    3156              :   return false;
    3157              : }
    3158              : 
    3159              : /* Fold any non-ODR-usages of a constant variable in expression X.  */
    3160              : 
    3161              : static tree
    3162    585564941 : cp_fold_non_odr_use_1 (tree x)
    3163              : {
    3164    585564941 :   tree var = x;
    3165    883173916 :   while (!VAR_P (var))
    3166    808249221 :     switch (TREE_CODE (var))
    3167              :       {
    3168    285526504 :       case ARRAY_REF:
    3169    285526504 :       case BIT_FIELD_REF:
    3170    285526504 :       case COMPONENT_REF:
    3171    285526504 :       case VIEW_CONVERT_EXPR:
    3172    285526504 :       CASE_CONVERT:
    3173    285526504 :         var = TREE_OPERAND (var, 0);
    3174    285526504 :         break;
    3175              : 
    3176     28650583 :       case INDIRECT_REF:
    3177     28650583 :         if (REFERENCE_REF_P (var))
    3178     12082471 :           var = TREE_OPERAND (var, 0);
    3179              :         else
    3180              :           return x;
    3181     12082471 :         break;
    3182              : 
    3183              :       default:
    3184              :         return x;
    3185              :       }
    3186              : 
    3187     74924695 :   if (TREE_THIS_VOLATILE (var)
    3188     74924695 :       || !decl_constant_var_p (var))
    3189     69091840 :     return x;
    3190              : 
    3191              :   /* We mustn't fold std::hardware_destructive_interference_size here
    3192              :      so that maybe_warn_about_constant_value can complain if it's used
    3193              :      in a manifestly constant-evaluated context.  */
    3194      5832855 :   if (decl_in_std_namespace_p (var)
    3195      2874227 :       && DECL_NAME (var)
    3196      8707082 :       && id_equal (DECL_NAME (var), "hardware_destructive_interference_size"))
    3197              :     return x;
    3198              : 
    3199      5832855 :   tree t = maybe_constant_value (x);
    3200      5832855 :   return TREE_CONSTANT (t) ? t : x;
    3201              : }
    3202              : 
    3203              : /* Fold expression X which is used as an rvalue if RVAL is true.  */
    3204              : 
    3205              : static tree
    3206   2583535051 : cp_fold_maybe_rvalue (tree x, bool rval, fold_flags_t flags)
    3207              : {
    3208   2604341229 :   while (true)
    3209              :     {
    3210   2593938140 :       if (rval && (flags & ff_only_non_odr))
    3211    568769000 :         x = cp_fold_non_odr_use_1 (x);
    3212   2593938140 :       x = cp_fold (x, flags);
    3213   2593938140 :       if (rval)
    3214              :         {
    3215   1733512380 :           x = mark_rvalue_use (x);
    3216   1733512380 :           if (!(flags & ff_only_non_odr)
    3217   1733512380 :               && DECL_P (x) && !TYPE_REF_P (TREE_TYPE (x)))
    3218              :             {
    3219    260962785 :               tree v = decl_constant_value (x);
    3220    260962785 :               if (v != x && v != error_mark_node)
    3221              :                 {
    3222     10403089 :                   x = v;
    3223     10403089 :                   continue;
    3224              :                 }
    3225              :             }
    3226              :         }
    3227   2583535051 :       break;
    3228     10403089 :     }
    3229   2583535051 :   return x;
    3230              : }
    3231              : 
    3232              : tree
    3233     76763467 : cp_fold_maybe_rvalue (tree x, bool rval)
    3234              : {
    3235     76763467 :   return cp_fold_maybe_rvalue (x, rval, ff_none);
    3236              : }
    3237              : 
    3238              : /* Fold expression X which is used as an rvalue.  */
    3239              : 
    3240              : static tree
    3241    274159352 : cp_fold_rvalue (tree x, fold_flags_t flags)
    3242              : {
    3243     10205494 :   return cp_fold_maybe_rvalue (x, true, flags);
    3244              : }
    3245              : 
    3246              : tree
    3247      2125047 : cp_fold_rvalue (tree x)
    3248              : {
    3249      2125047 :   return cp_fold_rvalue (x, ff_none);
    3250              : }
    3251              : 
    3252              : /* Fold any non-ODR used constants in an expression X which
    3253              :    is used as an rvalue if RVAL is true.  */
    3254              : 
    3255              : tree
    3256       736582 : cp_fold_non_odr_use (tree x, bool rval)
    3257              : {
    3258       736582 :   return cp_fold_maybe_rvalue (x, rval, ff_only_non_odr);
    3259              : }
    3260              : 
    3261              : /* Perform folding on expression X.  */
    3262              : 
    3263              : static tree
    3264    287537451 : cp_fully_fold (tree x, mce_value manifestly_const_eval)
    3265              : {
    3266    287537451 :   if (processing_template_decl)
    3267              :     return x;
    3268              :   /* FIXME cp_fold ought to be a superset of maybe_constant_value so we don't
    3269              :      have to call both.  */
    3270    261828811 :   if (cxx_dialect >= cxx11)
    3271              :     {
    3272    260704748 :       x = maybe_constant_value (x, /*decl=*/NULL_TREE, manifestly_const_eval);
    3273              :       /* Sometimes we are given a CONSTRUCTOR but the call above wraps it into
    3274              :          a TARGET_EXPR; undo that here.  */
    3275    260704748 :       if (TREE_CODE (x) == TARGET_EXPR)
    3276       671473 :         x = TARGET_EXPR_INITIAL (x);
    3277    260033275 :       else if (TREE_CODE (x) == VIEW_CONVERT_EXPR
    3278     27706158 :                && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR
    3279    260033461 :                && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x))
    3280          186 :         x = TREE_OPERAND (x, 0);
    3281              :     }
    3282    261828811 :   fold_flags_t flags = ff_none;
    3283    261828811 :   if (manifestly_const_eval == mce_false)
    3284     45471264 :     flags |= ff_mce_false;
    3285    261828811 :   return cp_fold_rvalue (x, flags);
    3286              : }
    3287              : 
    3288              : tree
    3289    242066187 : cp_fully_fold (tree x)
    3290              : {
    3291    242066187 :   return cp_fully_fold (x, mce_unknown);
    3292              : }
    3293              : 
    3294              : /* Likewise, but also fold recursively, which cp_fully_fold doesn't perform
    3295              :    in some cases.  */
    3296              : 
    3297              : tree
    3298     47754327 : cp_fully_fold_init (tree x)
    3299              : {
    3300     47754327 :   if (processing_template_decl)
    3301      2283063 :     return x;
    3302     45471264 :   x = cp_fully_fold (x, mce_false);
    3303     45471264 :   cp_fold_data data (ff_mce_false);
    3304     45471264 :   if (cxx_dialect >= cxx20)
    3305              :     {
    3306     44831591 :       cp_walk_tree (&x, cp_fold_immediate_r, &data, NULL);
    3307     44831591 :       data.pset.empty ();
    3308              :     }
    3309     45471264 :   cp_walk_tree (&x, cp_fold_r, &data, NULL);
    3310     45471264 :   return x;
    3311     45471264 : }
    3312              : 
    3313              : /* c-common interface to cp_fold.  If IN_INIT, this is in a static initializer
    3314              :    and certain changes are made to the folding done.  Or should be (FIXME).  We
    3315              :    never touch maybe_const, as it is only used for the C front-end
    3316              :    C_MAYBE_CONST_EXPR.  */
    3317              : 
    3318              : tree
    3319     76763467 : c_fully_fold (tree x, bool /*in_init*/, bool */*maybe_const*/, bool lval)
    3320              : {
    3321     76763467 :   return cp_fold_maybe_rvalue (x, !lval);
    3322              : }
    3323              : 
    3324              : static GTY((deletable)) hash_map<tree, tree> *fold_caches[3];
    3325              : 
    3326              : /* Subroutine of cp_fold.  Returns which fold cache to use according
    3327              :    to the given flags.  We need multiple caches since the result of
    3328              :    folding may depend on which flags are used.  */
    3329              : 
    3330              : static hash_map<tree, tree> *&
    3331   4780804633 : get_fold_cache (fold_flags_t flags)
    3332              : {
    3333            0 :   if (flags & ff_mce_false)
    3334   2152721207 :     return fold_caches[2];
    3335   2628083426 :   else if (flags & ff_only_non_odr)
    3336   2263909165 :     return fold_caches[1];
    3337              :   else
    3338    364174261 :     return fold_caches[0];
    3339              : }
    3340              : 
    3341              : /* Dispose of the whole FOLD_CACHE.  */
    3342              : 
    3343              : void
    3344     40953823 : clear_fold_cache (void)
    3345              : {
    3346    163815292 :   for (auto& fold_cache : fold_caches)
    3347    122861469 :     if (fold_cache != NULL)
    3348    147300825 :       fold_cache->empty ();
    3349     40953823 : }
    3350              : 
    3351              : /*  This function tries to fold an expression X.
    3352              :     To avoid combinatorial explosion, folding results are kept in fold_cache.
    3353              :     If X is invalid, we don't fold at all.
    3354              :     For performance reasons we don't cache expressions representing a
    3355              :     declaration or constant.
    3356              :     Function returns X or its folded variant.  */
    3357              : 
    3358              : static tree
    3359   7783492391 : cp_fold (tree x, fold_flags_t flags)
    3360              : {
    3361   7783492391 :   tree op0, op1, op2, op3;
    3362   7783492391 :   tree org_x = x, r = NULL_TREE;
    3363   7783492391 :   enum tree_code code;
    3364   7783492391 :   location_t loc;
    3365   7783492391 :   bool rval_ops = true;
    3366              : 
    3367   7783492391 :   if (!x || x == error_mark_node)
    3368              :     return x;
    3369              : 
    3370   7776996069 :   if (EXPR_P (x) && (!TREE_TYPE (x) || TREE_TYPE (x) == error_mark_node))
    3371              :     return x;
    3372              : 
    3373              :   /* Don't bother to cache DECLs or constants.  */
    3374   7776695909 :   if (DECL_P (x) || CONSTANT_CLASS_P (x))
    3375              :     return x;
    3376              : 
    3377   4780804633 :   auto& fold_cache = get_fold_cache (flags);
    3378   4780804633 :   if (fold_cache == NULL)
    3379       518537 :     fold_cache = hash_map<tree, tree>::create_ggc (101);
    3380              : 
    3381   4780804633 :   if (tree *cached = fold_cache->get (x))
    3382              :     {
    3383              :       /* unshare_expr doesn't recurse into SAVE_EXPRs.  If SAVE_EXPR's
    3384              :          argument has been folded into a tree invariant, make sure it is
    3385              :          unshared.  See PR112727.  */
    3386   1096960200 :       if (TREE_CODE (x) == SAVE_EXPR && *cached != x)
    3387           85 :         return unshare_expr (*cached);
    3388   1096960115 :       return *cached;
    3389              :     }
    3390              : 
    3391   3683844433 :   uid_sensitive_constexpr_evaluation_checker c;
    3392              : 
    3393   3683844433 :   code = TREE_CODE (x);
    3394   3683844433 :   switch (code)
    3395              :     {
    3396    209315169 :     case CLEANUP_POINT_EXPR:
    3397              :       /* Strip CLEANUP_POINT_EXPR if the expression doesn't have side
    3398              :          effects.  */
    3399    209315169 :       r = cp_fold (TREE_OPERAND (x, 0), flags);
    3400    209315169 :       if (!TREE_SIDE_EFFECTS (r) && !(flags & ff_only_non_odr))
    3401      2399867 :         x = r;
    3402              :       break;
    3403              : 
    3404      1703963 :     case SIZEOF_EXPR:
    3405      1703963 :       x = fold_sizeof_expr (x);
    3406      1703963 :       break;
    3407              : 
    3408    327632649 :     case VIEW_CONVERT_EXPR:
    3409    327632649 :       rval_ops = false;
    3410              :       /* FALLTHRU */
    3411   1009719765 :     case NON_LVALUE_EXPR:
    3412   1009719765 :     CASE_CONVERT:
    3413              : 
    3414   1009719765 :       if (VOID_TYPE_P (TREE_TYPE (x)))
    3415              :         {
    3416              :           /* This is just to make sure we don't end up with casts to
    3417              :              void from error_mark_node.  If we just return x, then
    3418              :              cp_fold_r might fold the operand into error_mark_node and
    3419              :              leave the conversion in the IR.  STRIP_USELESS_TYPE_CONVERSION
    3420              :              during gimplification doesn't like such casts.
    3421              :              Don't create a new tree if op0 != TREE_OPERAND (x, 0), the
    3422              :              folding of the operand should be in the caches and if in cp_fold_r
    3423              :              it will modify it in place.  */
    3424     92094371 :           op0 = cp_fold (TREE_OPERAND (x, 0), flags);
    3425     92094371 :           if (op0 == error_mark_node)
    3426          107 :             x = error_mark_node;
    3427              :           break;
    3428              :         }
    3429              : 
    3430    917625394 :       loc = EXPR_LOCATION (x);
    3431    917625394 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3432              : 
    3433    917625394 :       if (op0 == error_mark_node)
    3434            0 :         x = error_mark_node;
    3435    917625394 :       else if (flags & ff_only_non_odr)
    3436              :         {
    3437    341608023 :           if (op0 != TREE_OPERAND (x, 0))
    3438      2080625 :             x = build1_loc (loc, code, TREE_TYPE (x), op0);
    3439    341608023 :           if (code == NOP_EXPR)
    3440    174766144 :             REINTERPRET_CAST_P (x) = REINTERPRET_CAST_P (org_x);
    3441              :         }
    3442    576017371 :       else if (code == CONVERT_EXPR
    3443     45576915 :           && SCALAR_TYPE_P (TREE_TYPE (x))
    3444    621593266 :           && op0 != void_node)
    3445              :         /* During parsing we used convert_to_*_nofold; re-convert now using the
    3446              :            folding variants, since fold() doesn't do those transformations.  */
    3447     41185686 :         x = fold (convert (TREE_TYPE (x), op0));
    3448    534831685 :       else if (op0 != TREE_OPERAND (x, 0))
    3449    142046114 :         x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
    3450              :       else
    3451    392785571 :         x = fold (x);
    3452              : 
    3453              :       /* Conversion of an out-of-range value has implementation-defined
    3454              :          behavior; the language considers it different from arithmetic
    3455              :          overflow, which is undefined.  */
    3456    917625394 :       if (TREE_CODE (op0) == INTEGER_CST
    3457    917625394 :           && TREE_OVERFLOW_P (x) && !TREE_OVERFLOW_P (op0))
    3458           44 :         TREE_OVERFLOW (x) = false;
    3459              : 
    3460              :       break;
    3461              : 
    3462          261 :     case EXCESS_PRECISION_EXPR:
    3463          261 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3464          261 :       if (op0 == error_mark_node)
    3465            0 :         x = error_mark_node;
    3466          261 :       else if (flags & ff_only_non_odr)
    3467              :         {
    3468           67 :           if (op0 != TREE_OPERAND (x, 0))
    3469            0 :             x = build1_loc (EXPR_LOCATION (x), code, TREE_TYPE (x), op0);
    3470              :         }
    3471              :       else
    3472          194 :         x = fold_convert_loc (EXPR_LOCATION (x), TREE_TYPE (x), op0);
    3473              :       break;
    3474              : 
    3475    126840436 :     case INDIRECT_REF:
    3476              :       /* We don't need the decltype(auto) obfuscation anymore.  */
    3477    126840436 :       if (REF_PARENTHESIZED_P (x))
    3478              :         {
    3479          776 :           tree p = maybe_undo_parenthesized_ref (x);
    3480          776 :           if (p != x)
    3481            0 :             return cp_fold (p, flags);
    3482              :         }
    3483              :       /* When folding non-ODR usages of constants, we also want to
    3484              :          remove any constant-initialized references, even when
    3485              :          used as lvalues.  */
    3486    126840436 :       if ((flags & ff_only_non_odr) && REFERENCE_REF_P (x))
    3487              :         {
    3488     16795941 :           op0 = cp_fold_non_odr_use_1 (TREE_OPERAND (x, 0));
    3489     16795941 :           if (op0 != TREE_OPERAND (x, 0))
    3490         1518 :             return convert_from_reference (cp_fold (op0, flags));
    3491              :         }
    3492    126838918 :       goto unary;
    3493              : 
    3494    315956150 :     case ADDR_EXPR:
    3495    315956150 :       loc = EXPR_LOCATION (x);
    3496    315956150 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), false, flags);
    3497              : 
    3498              :       /* Cope with user tricks that amount to offsetof.  */
    3499    315956150 :       if (op0 != error_mark_node
    3500    315956150 :           && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (op0))
    3501    433271926 :           && !(flags & ff_only_non_odr))
    3502              :         {
    3503     65066932 :           tree val = get_base_address (op0);
    3504     65066932 :           if (val
    3505     65066932 :               && INDIRECT_REF_P (val)
    3506     25418697 :               && COMPLETE_TYPE_P (TREE_TYPE (val))
    3507     90485539 :               && TREE_CONSTANT (TREE_OPERAND (val, 0)))
    3508              :             {
    3509          261 :               val = TREE_OPERAND (val, 0);
    3510          261 :               STRIP_NOPS (val);
    3511          261 :               val = maybe_constant_value (val);
    3512          261 :               if (TREE_CODE (val) == INTEGER_CST)
    3513          127 :                 return fold_offsetof (op0, TREE_TYPE (x));
    3514              :             }
    3515              :         }
    3516    315956023 :       goto finish_unary;
    3517              : 
    3518              :     case REALPART_EXPR:
    3519              :     case IMAGPART_EXPR:
    3520    169155127 :       rval_ops = false;
    3521              :       /* FALLTHRU */
    3522    169155127 :     case CONJ_EXPR:
    3523    169155127 :     case FIX_TRUNC_EXPR:
    3524    169155127 :     case FLOAT_EXPR:
    3525    169155127 :     case NEGATE_EXPR:
    3526    169155127 :     case ABS_EXPR:
    3527    169155127 :     case ABSU_EXPR:
    3528    169155127 :     case BIT_NOT_EXPR:
    3529    169155127 :     case TRUTH_NOT_EXPR:
    3530    169155127 :     case FIXED_CONVERT_EXPR:
    3531    169155127 :     unary:
    3532              : 
    3533    169155127 :       loc = EXPR_LOCATION (x);
    3534    169155127 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3535              : 
    3536    485111150 :     finish_unary:
    3537    485111150 :       if (op0 == error_mark_node)
    3538            0 :         x = error_mark_node;
    3539    485111150 :       else if (op0 != TREE_OPERAND (x, 0))
    3540              :         {
    3541     31499997 :           if (flags & ff_only_non_odr)
    3542       424079 :             x = build1_loc (loc, code, TREE_TYPE (x), op0);
    3543              :           else
    3544     31075918 :             x = fold_build1_loc (loc, code, TREE_TYPE (x), op0);
    3545     31499997 :           if (code == INDIRECT_REF
    3546      9593411 :               && (INDIRECT_REF_P (x) || TREE_CODE (x) == MEM_REF))
    3547              :             {
    3548      9593284 :               TREE_READONLY (x) = TREE_READONLY (org_x);
    3549      9593284 :               TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
    3550      9593284 :               TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
    3551              :             }
    3552              :         }
    3553    453611153 :       else if (!(flags & ff_only_non_odr))
    3554    223901409 :         x = fold (x);
    3555              : 
    3556    485111150 :       gcc_assert (TREE_CODE (x) != COND_EXPR
    3557              :                   || !VOID_TYPE_P (TREE_TYPE (TREE_OPERAND (x, 0))));
    3558              :       break;
    3559              : 
    3560       318480 :     case UNARY_PLUS_EXPR:
    3561       318480 :       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
    3562       318480 :       if (op0 == error_mark_node)
    3563            0 :         x = error_mark_node;
    3564       318480 :       else if (flags & ff_only_non_odr)
    3565              :         {
    3566       125857 :           if (op0 != TREE_OPERAND (x, 0))
    3567           12 :             x = build1_loc (EXPR_LOCATION (x), code, TREE_TYPE (x), op0);
    3568              :         }
    3569              :       else
    3570       192623 :         x = fold_convert (TREE_TYPE (x), op0);
    3571              :       break;
    3572              : 
    3573    199903599 :     case POSTDECREMENT_EXPR:
    3574    199903599 :     case POSTINCREMENT_EXPR:
    3575    199903599 :     case INIT_EXPR:
    3576    199903599 :     case PREDECREMENT_EXPR:
    3577    199903599 :     case PREINCREMENT_EXPR:
    3578    199903599 :     case COMPOUND_EXPR:
    3579    199903599 :     case MODIFY_EXPR:
    3580    199903599 :       rval_ops = false;
    3581              :       /* FALLTHRU */
    3582    414569359 :     case POINTER_PLUS_EXPR:
    3583    414569359 :     case PLUS_EXPR:
    3584    414569359 :     case POINTER_DIFF_EXPR:
    3585    414569359 :     case MINUS_EXPR:
    3586    414569359 :     case MULT_EXPR:
    3587    414569359 :     case TRUNC_DIV_EXPR:
    3588    414569359 :     case CEIL_DIV_EXPR:
    3589    414569359 :     case FLOOR_DIV_EXPR:
    3590    414569359 :     case ROUND_DIV_EXPR:
    3591    414569359 :     case TRUNC_MOD_EXPR:
    3592    414569359 :     case CEIL_MOD_EXPR:
    3593    414569359 :     case ROUND_MOD_EXPR:
    3594    414569359 :     case RDIV_EXPR:
    3595    414569359 :     case EXACT_DIV_EXPR:
    3596    414569359 :     case MIN_EXPR:
    3597    414569359 :     case MAX_EXPR:
    3598    414569359 :     case LSHIFT_EXPR:
    3599    414569359 :     case RSHIFT_EXPR:
    3600    414569359 :     case LROTATE_EXPR:
    3601    414569359 :     case RROTATE_EXPR:
    3602    414569359 :     case BIT_AND_EXPR:
    3603    414569359 :     case BIT_IOR_EXPR:
    3604    414569359 :     case BIT_XOR_EXPR:
    3605    414569359 :     case TRUTH_AND_EXPR:
    3606    414569359 :     case TRUTH_ANDIF_EXPR:
    3607    414569359 :     case TRUTH_OR_EXPR:
    3608    414569359 :     case TRUTH_ORIF_EXPR:
    3609    414569359 :     case TRUTH_XOR_EXPR:
    3610    414569359 :     case LT_EXPR: case LE_EXPR:
    3611    414569359 :     case GT_EXPR: case GE_EXPR:
    3612    414569359 :     case EQ_EXPR: case NE_EXPR:
    3613    414569359 :     case UNORDERED_EXPR: case ORDERED_EXPR:
    3614    414569359 :     case UNLT_EXPR: case UNLE_EXPR:
    3615    414569359 :     case UNGT_EXPR: case UNGE_EXPR:
    3616    414569359 :     case UNEQ_EXPR: case LTGT_EXPR:
    3617    414569359 :     case RANGE_EXPR: case COMPLEX_EXPR:
    3618              : 
    3619    414569359 :       loc = EXPR_LOCATION (x);
    3620    414569359 :       op0 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 0), rval_ops, flags);
    3621    414569359 :       bool clear_decl_read;
    3622    414569359 :       clear_decl_read = false;
    3623    414569359 :       if (code == MODIFY_EXPR
    3624     51956475 :           && (VAR_P (op0) || TREE_CODE (op0) == PARM_DECL)
    3625    429014877 :           && !DECL_READ_P (op0))
    3626              :         clear_decl_read = true;
    3627    414569359 :       op1 = cp_fold_maybe_rvalue (TREE_OPERAND (x, 1),
    3628              :                                   code != COMPOUND_EXPR, flags);
    3629    414569359 :       if (clear_decl_read)
    3630       774726 :         DECL_READ_P (op0) = 0;
    3631              : 
    3632    414569359 :       if (flags & ff_only_non_odr)
    3633              :         {
    3634    180575166 :           if (op0 == error_mark_node || op1 == error_mark_node)
    3635           24 :             x = error_mark_node;
    3636    180575142 :           else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
    3637              :             {
    3638      8035043 :               if (code == INIT_EXPR && op1 != TREE_OPERAND (x, 1))
    3639      2523609 :                 set_target_expr_eliding (op1);
    3640      8035043 :               x = build2_loc (loc, code, TREE_TYPE (x), op0, op1);
    3641              :             }
    3642              :           break;
    3643              :         }
    3644              : 
    3645              :       /* decltype(nullptr) has only one value, so optimize away all comparisons
    3646              :          with that type right away, keeping them in the IL causes troubles for
    3647              :          various optimizations.  */
    3648    233994193 :       if (COMPARISON_CLASS_P (org_x)
    3649     38504135 :           && TREE_CODE (TREE_TYPE (op0)) == NULLPTR_TYPE
    3650    233994220 :           && TREE_CODE (TREE_TYPE (op1)) == NULLPTR_TYPE)
    3651              :         {
    3652           27 :           switch (code)
    3653              :             {
    3654           12 :             case EQ_EXPR:
    3655           12 :               x = constant_boolean_node (true, TREE_TYPE (x));
    3656           12 :               break;
    3657           15 :             case NE_EXPR:
    3658           15 :               x = constant_boolean_node (false, TREE_TYPE (x));
    3659           15 :               break;
    3660            0 :             default:
    3661            0 :               gcc_unreachable ();
    3662              :             }
    3663           27 :           return omit_two_operands_loc (loc, TREE_TYPE (x), x,
    3664           27 :                                         op0, op1);
    3665              :         }
    3666              : 
    3667    233994166 :       if (op0 == error_mark_node || op1 == error_mark_node)
    3668          102 :         x = error_mark_node;
    3669    233994064 :       else if (op0 != TREE_OPERAND (x, 0) || op1 != TREE_OPERAND (x, 1))
    3670    161097375 :         x = fold_build2_loc (loc, code, TREE_TYPE (x), op0, op1);
    3671              :       else
    3672     72896689 :         x = fold (x);
    3673              : 
    3674              :       /* This is only needed for -Wnonnull-compare and only if
    3675              :          TREE_NO_WARNING (org_x), but to avoid that option affecting code
    3676              :          generation, we do it always.  */
    3677    233994166 :       if (COMPARISON_CLASS_P (org_x))
    3678              :         {
    3679     38504108 :           if (x == error_mark_node || TREE_CODE (x) == INTEGER_CST)
    3680              :             ;
    3681     37368565 :           else if (COMPARISON_CLASS_P (x))
    3682              :             {
    3683     36437875 :               if (warn_nonnull_compare
    3684     36437875 :                   && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
    3685       122805 :                 suppress_warning (x, OPT_Wnonnull_compare);
    3686              :             }
    3687              :           /* Otherwise give up on optimizing these, let GIMPLE folders
    3688              :              optimize those later on.  */
    3689       930690 :           else if (op0 != TREE_OPERAND (org_x, 0)
    3690       930690 :                    || op1 != TREE_OPERAND (org_x, 1))
    3691              :             {
    3692       928767 :               x = build2_loc (loc, code, TREE_TYPE (org_x), op0, op1);
    3693       928767 :               if (warn_nonnull_compare
    3694       928767 :                   && warning_suppressed_p (org_x, OPT_Wnonnull_compare))
    3695           16 :                 suppress_warning (x, OPT_Wnonnull_compare);
    3696              :             }
    3697              :           else
    3698         1923 :             x = org_x;
    3699              :         }
    3700              : 
    3701              :       break;
    3702              : 
    3703      9887014 :     case VEC_COND_EXPR:
    3704      9887014 :     case COND_EXPR:
    3705      9887014 :       loc = EXPR_LOCATION (x);
    3706      9887014 :       op0 = cp_fold_rvalue (TREE_OPERAND (x, 0), flags);
    3707      9887014 :       op1 = cp_fold (TREE_OPERAND (x, 1), flags);
    3708      9887014 :       op2 = cp_fold (TREE_OPERAND (x, 2), flags);
    3709              : 
    3710      9887014 :       if (flags & ff_only_non_odr)
    3711              :         {
    3712      4155193 :           if (op0 == error_mark_node
    3713      4155187 :               || op1 == error_mark_node
    3714      4155187 :               || op2 == error_mark_node)
    3715            6 :             x = error_mark_node;
    3716      4155187 :           else if (op0 != TREE_OPERAND (x, 0)
    3717      4078075 :                    || op1 != TREE_OPERAND (x, 1)
    3718      8005165 :                    || op2 != TREE_OPERAND (x, 2))
    3719       319989 :             x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
    3720              :           break;
    3721              :         }
    3722              : 
    3723      5731821 :       if (TREE_CODE (TREE_TYPE (x)) == BOOLEAN_TYPE)
    3724              :         {
    3725        21022 :           warning_sentinel s (warn_int_in_bool_context);
    3726        21022 :           if (!VOID_TYPE_P (TREE_TYPE (op1)))
    3727        21022 :             op1 = cp_truthvalue_conversion (op1, tf_warning_or_error);
    3728        21022 :           if (!VOID_TYPE_P (TREE_TYPE (op2)))
    3729        21001 :             op2 = cp_truthvalue_conversion (op2, tf_warning_or_error);
    3730        21022 :         }
    3731      5710799 :       else if (VOID_TYPE_P (TREE_TYPE (x)))
    3732              :         {
    3733      1838260 :           if (TREE_CODE (op0) == INTEGER_CST)
    3734              :             {
    3735              :               /* If the condition is constant, fold can fold away
    3736              :                  the COND_EXPR.  If some statement-level uses of COND_EXPR
    3737              :                  have one of the branches NULL, avoid folding crash.  */
    3738       302140 :               if (!op1)
    3739            0 :                 op1 = build_empty_stmt (loc);
    3740       302140 :               if (!op2)
    3741           12 :                 op2 = build_empty_stmt (loc);
    3742              :             }
    3743              :           else
    3744              :             {
    3745              :               /* Otherwise, don't bother folding a void condition, since
    3746              :                  it can't produce a constant value.  */
    3747      1536120 :               if (op0 != TREE_OPERAND (x, 0)
    3748      1447412 :                   || op1 != TREE_OPERAND (x, 1)
    3749      2629653 :                   || op2 != TREE_OPERAND (x, 2))
    3750       444858 :                 x = build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
    3751              :               break;
    3752              :             }
    3753              :         }
    3754              : 
    3755      4195701 :       if (op0 == error_mark_node
    3756      4195701 :           || op1 == error_mark_node
    3757      4195687 :           || op2 == error_mark_node)
    3758           62 :         x = error_mark_node;
    3759      4195639 :       else if (op0 != TREE_OPERAND (x, 0)
    3760      1656647 :                || op1 != TREE_OPERAND (x, 1)
    3761      5496829 :                || op2 != TREE_OPERAND (x, 2))
    3762      3001646 :         x = fold_build3_loc (loc, code, TREE_TYPE (x), op0, op1, op2);
    3763              :       else
    3764      1193993 :         x = fold (x);
    3765              : 
    3766              :       /* A COND_EXPR might have incompatible types in branches if one or both
    3767              :          arms are bitfields.  If folding exposed such a branch, fix it up.  */
    3768      4195701 :       if (TREE_CODE (x) != code
    3769       937839 :           && x != error_mark_node
    3770      5133478 :           && !useless_type_conversion_p (TREE_TYPE (org_x), TREE_TYPE (x)))
    3771        17690 :         x = fold_convert (TREE_TYPE (org_x), x);
    3772              : 
    3773              :       break;
    3774              : 
    3775    229678695 :     case CALL_EXPR:
    3776    229678695 :       {
    3777    229678695 :         tree callee = get_callee_fndecl (x);
    3778              : 
    3779              :         /* "Inline" calls to std::move/forward and other cast-like functions
    3780              :            by simply folding them into a corresponding cast to their return
    3781              :            type.  This is cheaper than relying on the middle end to do so, and
    3782              :            also means we avoid generating useless debug info for them at all.
    3783              : 
    3784              :            At this point the argument has already been converted into a
    3785              :            reference, so it suffices to use a NOP_EXPR to express the
    3786              :            cast.  */
    3787    229678695 :         if ((OPTION_SET_P (flag_fold_simple_inlines)
    3788    229678695 :              ? flag_fold_simple_inlines
    3789    229678380 :              : !flag_no_inline)
    3790    217632005 :             && !(flags & ff_only_non_odr)
    3791    125713840 :             && call_expr_nargs (x) == 1
    3792     66152806 :             && decl_in_std_namespace_p (callee)
    3793     42450485 :             && DECL_NAME (callee) != NULL_TREE
    3794    272129180 :             && (id_equal (DECL_NAME (callee), "move")
    3795     41148357 :                 || id_equal (DECL_NAME (callee), "forward")
    3796     39540353 :                 || id_equal (DECL_NAME (callee), "forward_like")
    3797     39540207 :                 || id_equal (DECL_NAME (callee), "addressof")
    3798              :                 /* This addressof equivalent is used heavily in libstdc++.  */
    3799     39201085 :                 || id_equal (DECL_NAME (callee), "__addressof")
    3800     38815840 :                 || id_equal (DECL_NAME (callee), "to_underlying")
    3801     38815834 :                 || id_equal (DECL_NAME (callee), "as_const")))
    3802              :           {
    3803      3637226 :             r = CALL_EXPR_ARG (x, 0);
    3804              :             /* These type-checks must be performed here, because invalid
    3805              :                definitions of these functions could fail to ensure those and
    3806              :                build_nop could misbehave.  See PR122185.  */
    3807      3637226 :             if (id_equal (DECL_NAME (callee), "to_underlying")
    3808      3637226 :                 ? TREE_CODE (TREE_TYPE (r)) == ENUMERAL_TYPE
    3809            6 :                   && INTEGRAL_TYPE_P (TREE_TYPE (x))
    3810      6550073 :                 : INDIRECT_TYPE_P (TREE_TYPE (x))
    3811      6550061 :                   && INDIRECT_TYPE_P (TREE_TYPE (r)))
    3812              :               {
    3813      3637211 :                 r = build_nop (TREE_TYPE (x), r);
    3814      3637211 :                 x = cp_fold (r, flags);
    3815              :               }
    3816              :             break;
    3817              :           }
    3818              : 
    3819    226041469 :         int sv = optimize, nw = sv;
    3820              : 
    3821              :         /* Some built-in function calls will be evaluated at compile-time in
    3822              :            fold ().  Set optimize to 1 when folding __builtin_constant_p inside
    3823              :            a constexpr function so that fold_builtin_1 doesn't fold it to 0.  */
    3824    223667171 :         if (callee && fndecl_built_in_p (callee) && !optimize
    3825      2038833 :             && DECL_IS_BUILTIN_CONSTANT_P (callee)
    3826        47987 :             && current_function_decl
    3827    226089440 :             && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
    3828              :           nw = 1;
    3829              : 
    3830    223667171 :         if (callee && !(flags & ff_only_non_odr)
    3831    353544520 :             && fndecl_built_in_p (callee, BUILT_IN_FRONTEND))
    3832              :           {
    3833        60151 :             iloc_sentinel ils (EXPR_LOCATION (x));
    3834        60151 :             switch (DECL_FE_FUNCTION_CODE (callee))
    3835              :               {
    3836        55134 :               case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
    3837              :                 /* Defer folding __builtin_is_constant_evaluated unless
    3838              :                    we know this isn't a manifestly constant-evaluated
    3839              :                    context.  */
    3840        55134 :                 if (flags & ff_mce_false)
    3841        27947 :                   x = boolean_false_node;
    3842              :                 break;
    3843            3 :               case CP_BUILT_IN_SOURCE_LOCATION:
    3844            3 :                 x = fold_builtin_source_location (x);
    3845            3 :                 break;
    3846          456 :               case CP_BUILT_IN_IS_CORRESPONDING_MEMBER:
    3847          912 :                 x = fold_builtin_is_corresponding_member
    3848          456 :                         (EXPR_LOCATION (x), call_expr_nargs (x),
    3849              :                          &CALL_EXPR_ARG (x, 0));
    3850          456 :                 break;
    3851          400 :               case CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS:
    3852          800 :                 x = fold_builtin_is_pointer_inverconvertible_with_class
    3853          400 :                         (EXPR_LOCATION (x), call_expr_nargs (x),
    3854              :                          &CALL_EXPR_ARG (x, 0));
    3855          400 :                 break;
    3856              :               default:
    3857              :                 break;
    3858              :               }
    3859        60151 :             break;
    3860        60151 :           }
    3861              : 
    3862    225981318 :         bool changed = false;
    3863    225981318 :         int m = call_expr_nargs (x);
    3864    556969881 :         for (int i = 0; i < m; i++)
    3865              :           {
    3866    330988563 :             r = cp_fold (CALL_EXPR_ARG (x, i), flags);
    3867    330988563 :             if (r != CALL_EXPR_ARG (x, i))
    3868              :               {
    3869    108919208 :                 if (r == error_mark_node)
    3870              :                   {
    3871            0 :                     x = error_mark_node;
    3872            0 :                     break;
    3873              :                   }
    3874    108919208 :                 if (!changed)
    3875     69382980 :                   x = copy_node (x);
    3876    108919208 :                 CALL_EXPR_ARG (x, i) = r;
    3877    108919208 :                 changed = true;
    3878              :               }
    3879              :           }
    3880              :         /* Don't fold away the function entirely if we're just folding
    3881              :            non-ODR-used variables.  */
    3882    225981318 :         if (x == error_mark_node || (flags & ff_only_non_odr))
    3883              :           break;
    3884              : 
    3885    128818948 :         optimize = nw;
    3886    128818948 :         r = fold (x);
    3887    128818948 :         optimize = sv;
    3888              : 
    3889    128818948 :         if (TREE_CODE (r) != CALL_EXPR)
    3890              :           {
    3891      2698120 :             x = cp_fold (r, flags);
    3892      2698120 :             break;
    3893              :           }
    3894              : 
    3895    126120828 :         optimize = nw;
    3896              : 
    3897              :         /* Invoke maybe_constant_value for functions declared
    3898              :            constexpr and not called with AGGR_INIT_EXPRs.
    3899              :            TODO:
    3900              :            Do constexpr expansion of expressions where the call itself is not
    3901              :            constant, but the call followed by an INDIRECT_REF is.  */
    3902    124744780 :         if (callee && DECL_DECLARED_CONSTEXPR_P (callee)
    3903              :             && !(flags & ff_only_non_odr)
    3904    188295092 :             && (!flag_no_inline
    3905      3491587 :                 || lookup_attribute ("always_inline",
    3906      3491587 :                                      DECL_ATTRIBUTES (callee))))
    3907              :           {
    3908     59458039 :             mce_value manifestly_const_eval = mce_unknown;
    3909     59458039 :             if (flags & ff_mce_false)
    3910              :               /* Allow folding __builtin_is_constant_evaluated to false during
    3911              :                  constexpr evaluation of this call.  */
    3912     46069710 :               manifestly_const_eval = mce_false;
    3913     59458039 :             r = maybe_constant_value (x, /*decl=*/NULL_TREE,
    3914              :                                       manifestly_const_eval);
    3915              :           }
    3916    126120828 :         optimize = sv;
    3917              : 
    3918    126120828 :         if (TREE_CODE (r) != CALL_EXPR)
    3919              :           {
    3920      9104132 :             if (DECL_CONSTRUCTOR_P (callee))
    3921          401 :               r = cp_build_init_expr_for_ctor (x, r);
    3922      4552066 :             x = r;
    3923      4552066 :             break;
    3924              :           }
    3925              : 
    3926              :         break;
    3927              :       }
    3928              : 
    3929     24115602 :     case CONSTRUCTOR:
    3930     24115602 :       {
    3931     24115602 :         unsigned i;
    3932     24115602 :         constructor_elt *p;
    3933     24115602 :         vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (x);
    3934     24115602 :         vec<constructor_elt, va_gc> *nelts = NULL;
    3935    104693979 :         FOR_EACH_VEC_SAFE_ELT (elts, i, p)
    3936              :           {
    3937     80578377 :             tree op = cp_fold (p->value, flags);
    3938     80578377 :             if (op == error_mark_node)
    3939              :               {
    3940            0 :                 x = error_mark_node;
    3941            0 :                 vec_free (nelts);
    3942              :                 break;
    3943              :               }
    3944     80578377 :             else if (op != p->value)
    3945              :               {
    3946      1235719 :                 if (nelts == NULL)
    3947       790779 :                   nelts = elts->copy ();
    3948      1235719 :                 (*nelts)[i].value = op;
    3949              :               }
    3950              :           }
    3951     24115602 :         if (nelts)
    3952              :           {
    3953       790779 :             x = build_constructor (TREE_TYPE (x), nelts);
    3954       790779 :             CONSTRUCTOR_PLACEHOLDER_BOUNDARY (x)
    3955       790779 :               = CONSTRUCTOR_PLACEHOLDER_BOUNDARY (org_x);
    3956       790779 :             CONSTRUCTOR_MUTABLE_POISON (x)
    3957      1581558 :               = CONSTRUCTOR_MUTABLE_POISON (org_x);
    3958              :           }
    3959     24115602 :         if (VECTOR_TYPE_P (TREE_TYPE (x)))
    3960        78687 :           x = fold (x);
    3961              :         break;
    3962              :       }
    3963       813720 :     case TREE_VEC:
    3964       813720 :       {
    3965       813720 :         bool changed = false;
    3966       813720 :         int n = TREE_VEC_LENGTH (x);
    3967              : 
    3968      2046073 :         for (int i = 0; i < n; i++)
    3969              :           {
    3970      1232353 :             tree op = cp_fold (TREE_VEC_ELT (x, i), flags);
    3971      1232353 :             if (op != TREE_VEC_ELT (x, i))
    3972              :               {
    3973          865 :                 if (!changed)
    3974          822 :                   x = copy_node (x);
    3975          865 :                 TREE_VEC_ELT (x, i) = op;
    3976          865 :                 changed = true;
    3977              :               }
    3978              :           }
    3979              :       }
    3980              : 
    3981              :       break;
    3982              : 
    3983      3234490 :     case ARRAY_REF:
    3984      3234490 :     case ARRAY_RANGE_REF:
    3985              : 
    3986      3234490 :       loc = EXPR_LOCATION (x);
    3987      3234490 :       op0 = cp_fold (TREE_OPERAND (x, 0), flags);
    3988      3234490 :       op1 = cp_fold (TREE_OPERAND (x, 1), flags);
    3989      3234490 :       op2 = cp_fold (TREE_OPERAND (x, 2), flags);
    3990      3234490 :       op3 = cp_fold (TREE_OPERAND (x, 3), flags);
    3991              : 
    3992      3234490 :       if (op0 == error_mark_node
    3993      3234490 :           || op1 == error_mark_node
    3994      3234490 :           || op2 == error_mark_node
    3995      3234490 :           || op3 == error_mark_node)
    3996            0 :         x = error_mark_node;
    3997      3234490 :       else if (op0 != TREE_OPERAND (x, 0)
    3998      2221747 :           || op1 != TREE_OPERAND (x, 1)
    3999      1721411 :           || op2 != TREE_OPERAND (x, 2)
    4000      4955901 :           || op3 != TREE_OPERAND (x, 3))
    4001              :         {
    4002      1513079 :           x = build4_loc (loc, code, TREE_TYPE (x), op0, op1, op2, op3);
    4003      1513079 :           TREE_READONLY (x) = TREE_READONLY (org_x);
    4004      1513079 :           TREE_SIDE_EFFECTS (x) = TREE_SIDE_EFFECTS (org_x);
    4005      1513079 :           TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
    4006              :         }
    4007              : 
    4008      3234490 :       if (!(flags & ff_only_non_odr))
    4009      1883286 :         x = fold (x);
    4010              :       break;
    4011              : 
    4012      1687436 :     case SAVE_EXPR:
    4013              :       /* A SAVE_EXPR might contain e.g. (0 * i) + (0 * j), which, after
    4014              :          folding, evaluates to an invariant.  In that case no need to wrap
    4015              :          this folded tree with a SAVE_EXPR.  */
    4016      1687436 :       r = cp_fold (TREE_OPERAND (x, 0), flags);
    4017      1687436 :       if (tree_invariant_p (r))
    4018           57 :         x = r;
    4019              :       break;
    4020              : 
    4021           10 :     case REQUIRES_EXPR:
    4022           10 :       x = evaluate_requires_expr (x);
    4023           10 :       break;
    4024              : 
    4025              :     default:
    4026              :       return org_x;
    4027              :     }
    4028              : 
    4029   2390155087 :   if (EXPR_P (x) && TREE_CODE (x) == code)
    4030              :     {
    4031   1988708528 :       TREE_THIS_VOLATILE (x) = TREE_THIS_VOLATILE (org_x);
    4032   1988708528 :       copy_warning (x, org_x);
    4033              :     }
    4034              : 
    4035   2390155087 :   if (!c.evaluation_restricted_p ())
    4036              :     {
    4037   2390104473 :       fold_cache->put (org_x, x);
    4038              :       /* Prevent that we try to fold an already folded result again.  */
    4039   2390104473 :       if (x != org_x)
    4040    750449426 :         fold_cache->put (x, x);
    4041              :     }
    4042              : 
    4043              :   return x;
    4044              : }
    4045              : 
    4046              : /* Look up "hot", "cold", "likely" or "unlikely" in attribute list LIST.  */
    4047              : 
    4048              : tree
    4049    311732576 : lookup_hotness_attribute (tree list)
    4050              : {
    4051    311840429 :   for (; list; list = TREE_CHAIN (list))
    4052              :     {
    4053      1987667 :       tree name = get_attribute_name (list);
    4054      1987667 :       if ((is_attribute_p ("hot", name)
    4055      1987667 :            || is_attribute_p ("cold", name)
    4056      1987664 :            || is_attribute_p ("likely", name)
    4057      1375054 :            || is_attribute_p ("unlikely", name))
    4058      3867490 :           && is_attribute_namespace_p ("", list))
    4059              :         break;
    4060              :     }
    4061    311732576 :   return list;
    4062              : }
    4063              : 
    4064              : /* Remove "hot", "cold", "likely" and "unlikely" attributes from LIST.  */
    4065              : 
    4066              : static tree
    4067      1879805 : remove_hotness_attribute (tree list)
    4068              : {
    4069      3759628 :   for (tree *p = &list; *p; )
    4070              :     {
    4071      1879823 :       tree l = *p;
    4072      1879823 :       tree name = get_attribute_name (l);
    4073      1879823 :       if ((is_attribute_p ("hot", name)
    4074      1879823 :            || is_attribute_p ("cold", name)
    4075      1879820 :            || is_attribute_p ("likely", name)
    4076      1267210 :            || is_attribute_p ("unlikely", name))
    4077      3759646 :           && is_attribute_namespace_p ("", l))
    4078              :         {
    4079      1879814 :           *p = TREE_CHAIN (l);
    4080      1879814 :           continue;
    4081              :         }
    4082            9 :       p = &TREE_CHAIN (l);
    4083              :     }
    4084      1879805 :   return list;
    4085              : }
    4086              : 
    4087              : /* If [[likely]] or [[unlikely]] appear on this statement, turn it into a
    4088              :    PREDICT_EXPR.  */
    4089              : 
    4090              : tree
    4091    309852789 : process_stmt_hotness_attribute (tree std_attrs, location_t attrs_loc)
    4092              : {
    4093    309852789 :   if (std_attrs == error_mark_node)
    4094              :     return std_attrs;
    4095    309852771 :   if (tree attr = lookup_hotness_attribute (std_attrs))
    4096              :     {
    4097      1879805 :       tree name = get_attribute_name (attr);
    4098      1879805 :       bool hot = (is_attribute_p ("hot", name)
    4099      1879805 :                   || is_attribute_p ("likely", name));
    4100      1879805 :       tree pred = build_predict_expr (hot ? PRED_HOT_LABEL : PRED_COLD_LABEL,
    4101              :                                       hot ? TAKEN : NOT_TAKEN);
    4102      1879805 :       SET_EXPR_LOCATION (pred, attrs_loc);
    4103      1879805 :       add_stmt (pred);
    4104      1879805 :       if (tree other = lookup_hotness_attribute (TREE_CHAIN (attr)))
    4105              :         {
    4106            9 :           auto_urlify_attributes sentinel;
    4107            9 :           warning (OPT_Wattributes, "ignoring attribute %qE after earlier %qE",
    4108              :                    get_attribute_name (other), name);
    4109            9 :         }
    4110      1879805 :       std_attrs = remove_hotness_attribute (std_attrs);
    4111              :     }
    4112              :   return std_attrs;
    4113              : }
    4114              : 
    4115              : /* Build IFN_ASSUME internal call for assume condition ARG.  */
    4116              : 
    4117              : tree
    4118        11793 : build_assume_call (location_t loc, tree arg)
    4119              : {
    4120        11793 :   if (!processing_template_decl)
    4121        11692 :     arg = fold_build_cleanup_point_expr (TREE_TYPE (arg), arg);
    4122        11793 :   return build_call_expr_internal_loc (loc, IFN_ASSUME, void_type_node,
    4123        11793 :                                        1, arg);
    4124              : }
    4125              : 
    4126              : /* If [[assume (cond)]] appears on this statement, handle it.  */
    4127              : 
    4128              : tree
    4129    245722900 : process_stmt_assume_attribute (tree std_attrs, tree statement,
    4130              :                                location_t attrs_loc)
    4131              : {
    4132    245722900 :   if (std_attrs == error_mark_node)
    4133              :     return std_attrs;
    4134    245722882 :   tree attr = lookup_attribute ("gnu", "assume", std_attrs);
    4135    245722882 :   if (!attr)
    4136              :     return std_attrs;
    4137              :   /* The next token after the assume attribute is not ';'.  */
    4138        11709 :   if (statement)
    4139              :     {
    4140           12 :       warning_at (attrs_loc, OPT_Wattributes,
    4141              :                   "%<assume%> attribute not followed by %<;%>");
    4142           12 :       attr = NULL_TREE;
    4143              :     }
    4144        23442 :   for (; attr; attr = lookup_attribute ("gnu", "assume", TREE_CHAIN (attr)))
    4145              :     {
    4146        11733 :       tree args = TREE_VALUE (attr);
    4147        11733 :       if (args && PACK_EXPANSION_P (args))
    4148              :         {
    4149            6 :           auto_diagnostic_group d;
    4150            6 :           error_at (attrs_loc, "pack expansion of %qE attribute",
    4151              :                     get_attribute_name (attr));
    4152            6 :           if (cxx_dialect >= cxx17)
    4153            4 :             inform (attrs_loc, "use fold expression in the attribute "
    4154              :                                "argument instead");
    4155            6 :           continue;
    4156            6 :         }
    4157        11727 :       int nargs = list_length (args);
    4158        11727 :       if (nargs != 1)
    4159              :         {
    4160           42 :           auto_diagnostic_group d;
    4161           42 :           error_at (attrs_loc, "wrong number of arguments specified for "
    4162              :                                "%qE attribute", get_attribute_name (attr));
    4163           42 :           inform (attrs_loc, "expected %i, found %i", 1, nargs);
    4164           42 :         }
    4165              :       else
    4166              :         {
    4167        11685 :           tree arg = TREE_VALUE (args);
    4168        11685 :           if (!type_dependent_expression_p (arg))
    4169        11584 :             arg = contextual_conv_bool (arg, tf_warning_or_error);
    4170        11685 :           if (error_operand_p (arg))
    4171           18 :             continue;
    4172        11667 :           finish_expr_stmt (build_assume_call (attrs_loc, arg));
    4173              :         }
    4174              :     }
    4175        11709 :   return remove_attribute ("gnu", "assume", std_attrs);
    4176              : }
    4177              : 
    4178              : /* Return the type std::source_location::__impl after performing
    4179              :    verification on it.  */
    4180              : 
    4181              : tree
    4182        10290 : get_source_location_impl_type ()
    4183              : {
    4184        10290 :   tree name = get_identifier ("source_location");
    4185        10290 :   tree decl = lookup_qualified_name (std_node, name);
    4186        10290 :   if (TREE_CODE (decl) != TYPE_DECL)
    4187              :     {
    4188            6 :       auto_diagnostic_group d;
    4189            6 :       if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
    4190            3 :         qualified_name_lookup_error (std_node, name, decl, input_location);
    4191              :       else
    4192            3 :         error ("%qD is not a type", decl);
    4193            6 :       return error_mark_node;
    4194            6 :     }
    4195        10284 :   name = get_identifier ("__impl");
    4196        10284 :   tree type = TREE_TYPE (decl);
    4197        10284 :   decl = lookup_qualified_name (type, name);
    4198        10284 :   if (TREE_CODE (decl) != TYPE_DECL)
    4199              :     {
    4200            9 :       auto_diagnostic_group d;
    4201            9 :       if (decl == error_mark_node || TREE_CODE (decl) == TREE_LIST)
    4202            6 :         qualified_name_lookup_error (type, name, decl, input_location);
    4203              :       else
    4204            3 :         error ("%qD is not a type", decl);
    4205            9 :       return error_mark_node;
    4206            9 :     }
    4207        10275 :   type = TREE_TYPE (decl);
    4208        10275 :   if (TREE_CODE (type) != RECORD_TYPE)
    4209              :     {
    4210            3 :       error ("%qD is not a class type", decl);
    4211            3 :       return error_mark_node;
    4212              :     }
    4213              : 
    4214        10272 :   int cnt = 0;
    4215        10272 :   for (tree field = TYPE_FIELDS (type);
    4216        51321 :        (field = next_aggregate_field (field)) != NULL_TREE;
    4217        41049 :        field = DECL_CHAIN (field))
    4218              :     {
    4219        41058 :       if (DECL_NAME (field) != NULL_TREE)
    4220              :         {
    4221        41058 :           const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
    4222        41058 :           if (strcmp (n, "_M_file_name") == 0
    4223        30789 :               || strcmp (n, "_M_function_name") == 0)
    4224              :             {
    4225        20535 :               if (TREE_TYPE (field) != const_string_type_node)
    4226              :                 {
    4227            3 :                   error ("%qD does not have %<const char *%> type", field);
    4228            3 :                   return error_mark_node;
    4229              :                 }
    4230        20532 :               cnt++;
    4231        20532 :               continue;
    4232              :             }
    4233        20523 :           else if (strcmp (n, "_M_line") == 0 || strcmp (n, "_M_column") == 0)
    4234              :             {
    4235        20520 :               if (TREE_CODE (TREE_TYPE (field)) != INTEGER_TYPE)
    4236              :                 {
    4237            3 :                   error ("%qD does not have integral type", field);
    4238            3 :                   return error_mark_node;
    4239              :                 }
    4240        20517 :               cnt++;
    4241        20517 :               continue;
    4242              :             }
    4243              :         }
    4244              :       cnt = 0;
    4245              :       break;
    4246              :     }
    4247        10263 :   if (cnt != 4)
    4248              :     {
    4249            9 :       error ("%<std::source_location::__impl%> does not contain only "
    4250              :              "non-static data members %<_M_file_name%>, "
    4251              :              "%<_M_function_name%>, %<_M_line%> and %<_M_column%>");
    4252            9 :       return error_mark_node;
    4253              :     }
    4254        10257 :   return build_qualified_type (type, TYPE_QUAL_CONST);
    4255              : }
    4256              : 
    4257              : /* Type for source_location_table hash_set.  */
    4258              : struct GTY((for_user)) source_location_table_entry {
    4259              :   location_t loc;
    4260              :   unsigned uid;
    4261              :   tree var;
    4262              : };
    4263              : 
    4264              : /* Traits class for function start hash maps below.  */
    4265              : 
    4266              : struct source_location_table_entry_hash
    4267              :   : ggc_remove <source_location_table_entry>
    4268              : {
    4269              :   typedef source_location_table_entry value_type;
    4270              :   typedef source_location_table_entry compare_type;
    4271              : 
    4272              :   static hashval_t
    4273        54518 :   hash (const source_location_table_entry &ref)
    4274              :   {
    4275        54518 :     inchash::hash hstate (0);
    4276        54518 :     hstate.add_int (ref.loc);
    4277        54518 :     hstate.add_int (ref.uid);
    4278        54518 :     return hstate.end ();
    4279              :   }
    4280              : 
    4281              :   static bool
    4282        46578 :   equal (const source_location_table_entry &ref1,
    4283              :          const source_location_table_entry &ref2)
    4284              :   {
    4285        46578 :     return ref1.loc == ref2.loc && ref1.uid == ref2.uid;
    4286              :   }
    4287              : 
    4288              :   static void
    4289              :   mark_deleted (source_location_table_entry &ref)
    4290              :   {
    4291              :     ref.loc = UNKNOWN_LOCATION;
    4292              :     ref.uid = -1U;
    4293              :     ref.var = NULL_TREE;
    4294              :   }
    4295              : 
    4296              :   static const bool empty_zero_p = true;
    4297              : 
    4298              :   static void
    4299            0 :   mark_empty (source_location_table_entry &ref)
    4300              :   {
    4301            0 :     ref.loc = UNKNOWN_LOCATION;
    4302            0 :     ref.uid = 0;
    4303            0 :     ref.var = NULL_TREE;
    4304              :   }
    4305              : 
    4306              :   static bool
    4307        76580 :   is_deleted (const source_location_table_entry &ref)
    4308              :   {
    4309        76580 :     return (ref.loc == UNKNOWN_LOCATION
    4310            0 :             && ref.uid == -1U
    4311        76580 :             && ref.var == NULL_TREE);
    4312              :   }
    4313              : 
    4314              :   static bool
    4315       301744 :   is_empty (const source_location_table_entry &ref)
    4316              :   {
    4317       301744 :     return (ref.loc == UNKNOWN_LOCATION
    4318       139944 :             && ref.uid == 0
    4319       441688 :             && ref.var == NULL_TREE);
    4320              :   }
    4321              : 
    4322              :   static void
    4323            3 :   pch_nx (source_location_table_entry &p)
    4324              :   {
    4325            3 :     extern void gt_pch_nx (source_location_table_entry &);
    4326            3 :     gt_pch_nx (p);
    4327            3 :   }
    4328              : 
    4329              :   static void
    4330            3 :   pch_nx (source_location_table_entry &p, gt_pointer_operator op, void *cookie)
    4331              :   {
    4332            3 :     extern void gt_pch_nx (source_location_table_entry *, gt_pointer_operator,
    4333              :                            void *);
    4334            3 :     gt_pch_nx (&p, op, cookie);
    4335            3 :   }
    4336              : };
    4337              : 
    4338              : static GTY(()) hash_table <source_location_table_entry_hash>
    4339              :   *source_location_table;
    4340              : 
    4341              : /* Build a std::source_location::__impl from a location_t.  */
    4342              : 
    4343              : tree
    4344        11990 : build_source_location_impl (location_t loc, tree fndecl,
    4345              :                             tree source_location_impl)
    4346              : {
    4347        11990 :   if (source_location_table == NULL)
    4348          364 :     source_location_table
    4349          364 :       = hash_table <source_location_table_entry_hash>::create_ggc (64);
    4350        11990 :   const line_map_ordinary *map;
    4351        11990 :   source_location_table_entry entry;
    4352        11990 :   entry.loc
    4353        11990 :     = linemap_resolve_location (line_table, loc, LRK_MACRO_EXPANSION_POINT,
    4354              :                                 &map);
    4355        11990 :   entry.uid = fndecl ? DECL_UID (fndecl) : -1;
    4356        11990 :   entry.var = error_mark_node;
    4357        11990 :   source_location_table_entry *entryp
    4358        11990 :     = source_location_table->find_slot (entry, INSERT);
    4359              : 
    4360        11990 :   if (entryp->var)
    4361              :     return entryp->var;
    4362              : 
    4363         8859 :   tree var = build_decl (loc, VAR_DECL, generate_internal_label ("Lsrc_loc"),
    4364              :                          source_location_impl);
    4365         8859 :   TREE_STATIC (var) = 1;
    4366         8859 :   TREE_PUBLIC (var) = 0;
    4367         8859 :   DECL_ARTIFICIAL (var) = 1;
    4368         8859 :   DECL_IGNORED_P (var) = 1;
    4369         8859 :   DECL_EXTERNAL (var) = 0;
    4370         8859 :   DECL_DECLARED_CONSTEXPR_P (var) = 1;
    4371         8859 :   DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (var) = 1;
    4372         8859 :   layout_decl (var, 0);
    4373              : 
    4374         8859 :   vec<constructor_elt, va_gc> *v = NULL;
    4375         8859 :   vec_alloc (v, 4);
    4376         8859 :   for (tree field = TYPE_FIELDS (source_location_impl);
    4377        44295 :         (field = next_aggregate_field (field)) != NULL_TREE;
    4378        35436 :         field = DECL_CHAIN (field))
    4379              :     {
    4380        35436 :       const char *n = IDENTIFIER_POINTER (DECL_NAME (field));
    4381        35436 :       tree val = NULL_TREE;
    4382        35436 :       if (strcmp (n, "_M_file_name") == 0)
    4383              :         {
    4384         8859 :           if (const char *fname = LOCATION_FILE (loc))
    4385              :             {
    4386         8859 :               fname = remap_macro_filename (fname);
    4387         8859 :               val = build_string_literal (fname);
    4388              :             }
    4389              :           else
    4390            0 :             val = build_string_literal ("");
    4391              :         }
    4392        26577 :       else if (strcmp (n, "_M_function_name") == 0)
    4393              :         {
    4394         8859 :           const char *name = "";
    4395              : 
    4396         8859 :           if (fndecl)
    4397              :             {
    4398              :               /* If this is a coroutine, we should get the name of the user
    4399              :                  function rather than the actor we generate.  */
    4400         8484 :               if (tree ramp = DECL_RAMP_FN (fndecl))
    4401           12 :                 name = cxx_printable_name (ramp, 2);
    4402              :               else
    4403         8472 :                 name = cxx_printable_name (fndecl, 2);
    4404              :             }
    4405              : 
    4406         8859 :           val = build_string_literal (name);
    4407              :         }
    4408        17718 :       else if (strcmp (n, "_M_line") == 0)
    4409         8859 :         val = build_int_cst (TREE_TYPE (field), LOCATION_LINE (loc));
    4410         8859 :       else if (strcmp (n, "_M_column") == 0)
    4411         8859 :         val = build_int_cst (TREE_TYPE (field), LOCATION_COLUMN (loc));
    4412              :       else
    4413            0 :         gcc_unreachable ();
    4414        35436 :       CONSTRUCTOR_APPEND_ELT (v, field, val);
    4415              :     }
    4416              : 
    4417         8859 :   tree ctor = build_constructor (source_location_impl, v);
    4418         8859 :   TREE_CONSTANT (ctor) = 1;
    4419         8859 :   TREE_STATIC (ctor) = 1;
    4420         8859 :   DECL_INITIAL (var) = ctor;
    4421         8859 :   varpool_node::finalize_decl (var);
    4422         8859 :   *entryp = entry;
    4423         8859 :   entryp->var = var;
    4424         8859 :   return var;
    4425              : }
    4426              : 
    4427              : /* Fold the __builtin_source_location () call T.  */
    4428              : 
    4429              : tree
    4430        11022 : fold_builtin_source_location (const_tree t)
    4431              : {
    4432        11022 :   gcc_assert (TREE_CODE (t) == CALL_EXPR);
    4433              :   /* TREE_TYPE (t) is const std::source_location::__impl*  */
    4434        11022 :   tree source_location_impl = TREE_TYPE (TREE_TYPE (t));
    4435        11022 :   if (source_location_impl == error_mark_node)
    4436            0 :     return build_zero_cst (const_ptr_type_node);
    4437        11022 :   gcc_assert (CLASS_TYPE_P (source_location_impl)
    4438              :               && id_equal (TYPE_IDENTIFIER (source_location_impl), "__impl"));
    4439              : 
    4440        11022 :   location_t loc = EXPR_LOCATION (t);
    4441        11022 :   tree var = build_source_location_impl (loc, current_function_decl,
    4442              :                                          source_location_impl);
    4443        11022 :   return build_fold_addr_expr_with_type_loc (loc, var, TREE_TYPE (t));
    4444              : }
    4445              : 
    4446              : #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.