LCOV - code coverage report
Current view: top level - gcc/cp - cp-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.4 % 2313 2184
Test Date: 2026-10-24 16:24:59 Functions: 100.0 % 81 81
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.5.0-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.