LCOV - code coverage report
Current view: top level - gcc/cp - cp-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.2 % 2308 2175
Test Date: 2026-06-20 15:32:29 Functions: 100.0 % 82 82
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.