LCOV - code coverage report
Current view: top level - gcc/cp - cp-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.2 % 2295 2162
Test Date: 2026-05-11 19:44:49 Functions: 100.0 % 82 82
Legend: Lines:     hit not hit

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