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