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