LCOV - code coverage report
Current view: top level - gcc/cp - cp-gimplify.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 94.3 % 2281 2150
Test Date: 2026-03-07 14:18:32 Functions: 100.0 % 82 82
Legend: Lines:     hit not hit

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