LCOV - code coverage report
Current view: top level - gcc/cp - constexpr.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 92.9 % 6627 6155
Test Date: 2026-09-12 16:25:28 Functions: 99.5 % 201 200
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Perform C++ constant expression evaluation, including calls to
       2              :    constexpr functions.  These routines are used both during actual parsing
       3              :    and during the instantiation of template functions.
       4              : 
       5              :    Copyright (C) 1998-2026 Free Software Foundation, Inc.
       6              : 
       7              :    This file is part of GCC.
       8              : 
       9              :    GCC is free software; you can redistribute it and/or modify it
      10              :    under the terms of the GNU General Public License as published by
      11              :    the Free Software Foundation; either version 3, or (at your option)
      12              :    any later version.
      13              : 
      14              :    GCC is distributed in the hope that it will be useful, but
      15              :    WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      17              :    General Public License for more details.
      18              : 
      19              : You should have received a copy of the GNU General Public License
      20              : along with GCC; see the file COPYING3.  If not see
      21              : <http://www.gnu.org/licenses/>.  */
      22              : 
      23              : #include "config.h"
      24              : #include "system.h"
      25              : #include "coretypes.h"
      26              : #include "cp-tree.h"
      27              : #include "varasm.h"
      28              : #include "c-family/c-objc.h"
      29              : #include "tree-iterator.h"
      30              : #include "gimplify.h"
      31              : #include "builtins.h"
      32              : #include "tree-inline.h"
      33              : #include "ubsan.h"
      34              : #include "timevar.h"
      35              : #include "fold-const-call.h"
      36              : #include "stor-layout.h"
      37              : #include "cgraph.h"
      38              : #include "opts.h"
      39              : #include "stringpool.h"
      40              : #include "attribs.h"
      41              : #include "fold-const.h"
      42              : #include "intl.h"
      43              : #include "toplev.h"
      44              : #include "contracts.h"
      45              : 
      46              : static bool verify_constant (tree, bool, bool *, bool *);
      47              : #define VERIFY_CONSTANT(X)                                              \
      48              : do {                                                                    \
      49              :   if (verify_constant ((X), ctx->quiet, non_constant_p, overflow_p)) \
      50              :     return t;                                                           \
      51              :  } while (0)
      52              : 
      53              : static HOST_WIDE_INT find_array_ctor_elt (tree ary, tree dindex,
      54              :                                           bool insert = false);
      55              : static int array_index_cmp (tree key, tree index);
      56              : 
      57              : /* Returns true iff FUN is an instantiation of a constexpr function
      58              :    template or a defaulted constexpr function.  */
      59              : 
      60              : bool
      61    195703438 : is_instantiation_of_constexpr (tree fun)
      62              : {
      63    271107931 :   return ((DECL_TEMPLOID_INSTANTIATION (fun)
      64    120795107 :            && DECL_DECLARED_CONSTEXPR_P (DECL_TI_TEMPLATE (fun)))
      65    290888135 :           || (DECL_DEFAULTED_FN (fun)
      66            0 :               && DECL_DECLARED_CONSTEXPR_P (fun)));
      67              : }
      68              : 
      69              : /* Return true if T is a literal type.   */
      70              : 
      71              : bool
      72    195255477 : literal_type_p (tree t)
      73              : {
      74    196913746 :   if (SCALAR_TYPE_P (t)
      75     92375945 :       || VECTOR_TYPE_P (t)
      76     92344292 :       || TYPE_REF_P (t)
      77     76553626 :       || (VOID_TYPE_P (t) && cxx_dialect >= cxx14))
      78              :     return true;
      79     73252860 :   if (CLASS_TYPE_P (t))
      80              :     {
      81     71594379 :       t = complete_type (t);
      82     71594379 :       gcc_assert (COMPLETE_TYPE_P (t) || errorcount);
      83     71594379 :       return CLASSTYPE_LITERAL_P (t);
      84              :     }
      85      1658481 :   if (TREE_CODE (t) == ARRAY_TYPE)
      86      1658269 :     return literal_type_p (strip_array_types (t));
      87              :   return false;
      88              : }
      89              : 
      90              : /* If DECL is a variable declared `constexpr', require its type
      91              :    be literal.  Return error_mark_node if we give an error, the
      92              :    DECL otherwise.  */
      93              : 
      94              : tree
      95    339903893 : ensure_literal_type_for_constexpr_object (tree decl)
      96              : {
      97    339903893 :   tree type = TREE_TYPE (decl);
      98    339903893 :   if (VAR_P (decl)
      99    128322615 :       && (DECL_DECLARED_CONSTEXPR_P (decl)
     100     89518204 :           || var_in_constexpr_fn (decl))
     101    398421125 :       && !processing_template_decl)
     102              :     {
     103     37979109 :       tree stype = strip_array_types (type);
     104     37979109 :       if (CLASS_TYPE_P (stype) && !COMPLETE_TYPE_P (complete_type (stype)))
     105              :         /* Don't complain here, we'll complain about incompleteness
     106              :            when we try to initialize the variable.  */;
     107     37979103 :       else if (!literal_type_p (type))
     108              :         {
     109        24251 :           if (DECL_DECLARED_CONSTEXPR_P (decl))
     110              :             {
     111           53 :               auto_diagnostic_group d;
     112           53 :               error_at (DECL_SOURCE_LOCATION (decl),
     113              :                         "the type %qT of %<constexpr%> variable %qD "
     114              :                         "is not literal", type, decl);
     115           53 :               explain_non_literal_class (type);
     116           53 :               decl = error_mark_node;
     117           53 :             }
     118        24198 :           else if (cxx_dialect < cxx23)
     119              :             {
     120        18410 :               if (!is_instantiation_of_constexpr (current_function_decl))
     121              :                 {
     122            8 :                   auto_diagnostic_group d;
     123            8 :                   error_at (DECL_SOURCE_LOCATION (decl),
     124              :                             "variable %qD of non-literal type %qT in "
     125              :                             "%<constexpr%> function only available with "
     126              :                             "%<-std=c++23%> or %<-std=gnu++23%>", decl, type);
     127            8 :                   explain_non_literal_class (type);
     128            8 :                   decl = error_mark_node;
     129            8 :                 }
     130        18410 :               cp_function_chain->invalid_constexpr = true;
     131              :             }
     132              :         }
     133     37954852 :       else if (DECL_DECLARED_CONSTEXPR_P (decl)
     134     37954852 :                && variably_modified_type_p (type, NULL_TREE))
     135              :         {
     136            4 :           error_at (DECL_SOURCE_LOCATION (decl),
     137              :                     "%<constexpr%> variable %qD has variably-modified "
     138              :                     "type %qT", decl, type);
     139            4 :           decl = error_mark_node;
     140              :         }
     141              :     }
     142    339903893 :   return decl;
     143              : }
     144              : 
     145              : /* Issue a diagnostic with text GMSGID for constructs that are invalid in
     146              :    constexpr functions.  CONSTEXPR_FUNDEF_P is true if we're checking
     147              :    a constexpr function body; if so, don't report hard errors and issue
     148              :    a pedwarn pre-C++23, or a warning in C++23, if requested by
     149              :    -Winvalid-constexpr.  Otherwise, we're not in the context where we are
     150              :    checking if a function can be marked 'constexpr', so give a hard error.  */
     151              : 
     152              : ATTRIBUTE_GCC_DIAG(3,4)
     153              : static bool
     154         1044 : constexpr_error (location_t location, bool constexpr_fundef_p,
     155              :                  const char *gmsgid, ...)
     156              : {
     157         1044 :   diagnostics::diagnostic_info diagnostic;
     158         1044 :   va_list ap;
     159         1044 :   rich_location richloc (line_table, location);
     160         1044 :   va_start (ap, gmsgid);
     161         1044 :   bool ret;
     162         1044 :   if (!constexpr_fundef_p)
     163              :     {
     164              :       /* Report an error that cannot be suppressed.  */
     165          742 :       diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
     166              :                            diagnostics::kind::error);
     167          742 :       ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
     168              :     }
     169          302 :   else if (warn_invalid_constexpr)
     170              :     {
     171          163 :       diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc,
     172          163 :                            (cxx_dialect < cxx23
     173              :                             ? diagnostics::kind::pedwarn
     174              :                             : diagnostics::kind::warning));
     175          163 :       diagnostic.m_option_id = OPT_Winvalid_constexpr;
     176          163 :       ret = diagnostic_report_diagnostic (global_dc, &diagnostic);
     177              :     }
     178              :   else
     179              :     ret = false;
     180         1044 :   va_end (ap);
     181         2088 :   return ret;
     182         1044 : }
     183              : 
     184              : struct constexpr_fundef_hasher : ggc_ptr_hash<constexpr_fundef>
     185              : {
     186              :   static hashval_t hash (const constexpr_fundef *);
     187              :   static bool equal (const constexpr_fundef *, const constexpr_fundef *);
     188              : };
     189              : 
     190              : /* This table holds all constexpr function definitions seen in
     191              :    the current translation unit.  */
     192              : 
     193              : static GTY (()) hash_table<constexpr_fundef_hasher> *constexpr_fundef_table;
     194              : 
     195              : /* Utility function used for managing the constexpr function table.
     196              :    Return true if the entries pointed to by P and Q are for the
     197              :    same constexpr function.  */
     198              : 
     199              : inline bool
     200    993736864 : constexpr_fundef_hasher::equal (const constexpr_fundef *lhs,
     201              :                                 const constexpr_fundef *rhs)
     202              : {
     203    965814735 :   return lhs->decl == rhs->decl;
     204              : }
     205              : 
     206              : /* Utility function used for managing the constexpr function table.
     207              :    Return a hash value for the entry pointed to by Q.  */
     208              : 
     209              : inline hashval_t
     210    962568515 : constexpr_fundef_hasher::hash (const constexpr_fundef *fundef)
     211              : {
     212    962568515 :   return DECL_UID (fundef->decl);
     213              : }
     214              : 
     215              : /* Return a previously saved definition of function FUN.   */
     216              : 
     217              : constexpr_fundef *
     218    110731273 : retrieve_constexpr_fundef (tree fun)
     219              : {
     220    110731273 :   if (constexpr_fundef_table == NULL)
     221              :     return NULL;
     222              : 
     223    110727237 :   constexpr_fundef fundef = { fun, NULL_TREE, NULL_TREE, NULL_TREE };
     224    110727237 :   return constexpr_fundef_table->find (&fundef);
     225              : }
     226              : 
     227              : /* Check whether the parameter and return types of FUN are valid for a
     228              :    constexpr function, and complain if COMPLAIN.  */
     229              : 
     230              : bool
     231     32016796 : is_valid_constexpr_fn (tree fun, bool complain)
     232              : {
     233     32016796 :   bool ret = true;
     234              : 
     235     64033592 :   if (DECL_INHERITED_CTOR (fun)
     236      3713215 :       && TREE_CODE (fun) == TEMPLATE_DECL)
     237              :     {
     238            0 :       ret = false;
     239            0 :       if (complain)
     240            0 :         error ("inherited constructor %qD is not %<constexpr%>",
     241            0 :                DECL_INHERITED_CTOR (fun));
     242              :     }
     243              :   else
     244              :     {
     245     32016796 :       for (tree parm = FUNCTION_FIRST_USER_PARM (fun);
     246     64670445 :            parm != NULL_TREE; parm = TREE_CHAIN (parm))
     247     32653649 :         if (!literal_type_p (TREE_TYPE (parm)))
     248              :           {
     249        13017 :             ret = false;
     250        13017 :             if (complain)
     251              :               {
     252           23 :                 auto_diagnostic_group d;
     253           23 :                 if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
     254              :                                      "invalid type for parameter %d of "
     255              :                                      "%<constexpr%> function %q+#D",
     256           23 :                                      DECL_PARM_INDEX (parm), fun))
     257           15 :                   explain_non_literal_class (TREE_TYPE (parm));
     258           23 :               }
     259              :           }
     260              :     }
     261              : 
     262     53093974 :   if (LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun)) && cxx_dialect < cxx17)
     263              :     {
     264            4 :       ret = false;
     265            4 :       if (complain)
     266            3 :         inform (DECL_SOURCE_LOCATION (fun),
     267              :                 "lambdas are implicitly %<constexpr%> only in C++17 and later");
     268              :     }
     269     64033584 :   else if (DECL_DESTRUCTOR_P (fun) && cxx_dialect < cxx20)
     270              :     {
     271            0 :       ret = false;
     272            0 :       if (complain)
     273            0 :         error_at (DECL_SOURCE_LOCATION (fun),
     274              :                   "%<constexpr%> destructors only available with "
     275              :                   "%<-std=c++20%> or %<-std=gnu++20%>");
     276              :     }
     277     32016792 :   else if (!DECL_CONSTRUCTOR_P (fun) && !DECL_DESTRUCTOR_P (fun))
     278              :     {
     279     27622837 :       tree rettype = TREE_TYPE (TREE_TYPE (fun));
     280     27622837 :       if (!literal_type_p (rettype))
     281              :         {
     282        50918 :           ret = false;
     283        50918 :           if (complain)
     284              :             {
     285           21 :               auto_diagnostic_group d;
     286           21 :               if (constexpr_error (input_location, /*constexpr_fundef_p*/true,
     287              :                                    "invalid return type %qT of %<constexpr%> "
     288              :                                    "function %q+D", rettype, fun))
     289           10 :                 explain_non_literal_class (rettype);
     290           21 :             }
     291              :         }
     292              : 
     293              :       /* C++14 DR 1684 removed this restriction.  */
     294     27622837 :       if (cxx_dialect < cxx14
     295        32976 :           && DECL_IOBJ_MEMBER_FUNCTION_P (fun)
     296     27623960 :           && !CLASSTYPE_LITERAL_P (DECL_CONTEXT (fun)))
     297              :         {
     298            1 :           ret = false;
     299            1 :           if (complain)
     300              :             {
     301            1 :               auto_diagnostic_group d;
     302            1 :               if (pedwarn (DECL_SOURCE_LOCATION (fun), OPT_Wpedantic,
     303              :                              "enclosing class of %<constexpr%> non-static"
     304              :                              " member function %q+#D is not a literal type",
     305              :                              fun))
     306            1 :                 explain_non_literal_class (DECL_CONTEXT (fun));
     307            1 :             }
     308              :         }
     309              :     }
     310      4393955 :   else if (CLASSTYPE_VBASECLASSES (DECL_CONTEXT (fun)) && cxx_dialect < cxx26)
     311              :     {
     312           69 :       ret = false;
     313           69 :       if (complain)
     314              :         {
     315           10 :           if (DECL_CONSTRUCTOR_P (fun))
     316            8 :             error ("%<constexpr%> constructor in %q#T that has "
     317              :                    "virtual base classes only available with "
     318            8 :                    "%<-std=c++2c%> or %<-std=gnu++2c%>", DECL_CONTEXT (fun));
     319              :           else
     320            2 :             error ("%<constexpr%> destructor in %q#T that has "
     321              :                    "virtual base classes only available with "
     322            2 :                    "%<-std=c++2c%> or %<-std=gnu++2c%>", DECL_CONTEXT (fun));
     323              :         }
     324              :     }
     325              : 
     326     32016796 :   return ret;
     327              : }
     328              : 
     329              : /* Subroutine of build_data_member_initialization.  MEMBER is a COMPONENT_REF
     330              :    for a member of an anonymous aggregate, INIT is the initializer for that
     331              :    member, and VEC_OUTER is the vector of constructor elements for the class
     332              :    whose constructor we are processing.  Add the initializer to the vector
     333              :    and return true to indicate success.  */
     334              : 
     335              : static bool
     336         4571 : build_anon_member_initialization (tree member, tree init,
     337              :                                   vec<constructor_elt, va_gc> **vec_outer)
     338              : {
     339              :   /* MEMBER presents the relevant fields from the inside out, but we need
     340              :      to build up the initializer from the outside in so that we can reuse
     341              :      previously built CONSTRUCTORs if this is, say, the second field in an
     342              :      anonymous struct.  So we use a vec as a stack.  */
     343         4571 :   auto_vec<tree, 2> fields;
     344         9238 :   do
     345              :     {
     346         9238 :       fields.safe_push (TREE_OPERAND (member, 1));
     347         9238 :       member = TREE_OPERAND (member, 0);
     348              :     }
     349         9238 :   while (ANON_AGGR_TYPE_P (TREE_TYPE (member))
     350        18482 :          && TREE_CODE (member) == COMPONENT_REF);
     351              : 
     352              :   /* VEC has the constructor elements vector for the context of FIELD.
     353              :      If FIELD is an anonymous aggregate, we will push inside it.  */
     354              :   vec<constructor_elt, va_gc> **vec = vec_outer;
     355              :   tree field;
     356         9238 :   while (field = fields.pop(),
     357         9238 :          ANON_AGGR_TYPE_P (TREE_TYPE (field)))
     358              :     {
     359         4667 :       tree ctor;
     360              :       /* If there is already an outer constructor entry for the anonymous
     361              :          aggregate FIELD, use it; otherwise, insert one.  */
     362         4667 :       if (vec_safe_is_empty (*vec)
     363          198 :           || (*vec)->last().index != field)
     364              :         {
     365         4565 :           ctor = build_constructor (TREE_TYPE (field), NULL);
     366         4565 :           CONSTRUCTOR_APPEND_ELT (*vec, field, ctor);
     367              :         }
     368              :       else
     369          102 :         ctor = (*vec)->last().value;
     370         4667 :       vec = &CONSTRUCTOR_ELTS (ctor);
     371              :     }
     372              : 
     373              :   /* Now we're at the innermost field, the one that isn't an anonymous
     374              :      aggregate.  Add its initializer to the CONSTRUCTOR and we're done.  */
     375         4571 :   gcc_assert (fields.is_empty());
     376         4571 :   CONSTRUCTOR_APPEND_ELT (*vec, field, init);
     377              : 
     378         4571 :   return true;
     379         4571 : }
     380              : 
     381              : /* Subroutine of  build_constexpr_constructor_member_initializers.
     382              :    The expression tree T represents a data member initialization
     383              :    in a (constexpr) constructor definition.  Build a pairing of
     384              :    the data member with its initializer, and prepend that pair
     385              :    to the existing initialization pair INITS.  */
     386              : 
     387              : static bool
     388      6142078 : build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
     389              : {
     390      6857000 :   tree member, init;
     391      6857000 :   if (TREE_CODE (t) == CLEANUP_POINT_EXPR)
     392      3127638 :     t = TREE_OPERAND (t, 0);
     393      6857000 :   if (TREE_CODE (t) == EXPR_STMT)
     394      3126424 :     t = TREE_OPERAND (t, 0);
     395      6857000 :   if (t == error_mark_node)
     396              :     return false;
     397      6856991 :   if (TREE_CODE (t) == STATEMENT_LIST)
     398              :     {
     399      1619255 :       for (tree stmt : tsi_range (t))
     400       909229 :         if (! build_data_member_initialization (stmt, vec))
     401      6142078 :           return false;
     402              :       return true;
     403              :     }
     404      6146965 :   if (TREE_CODE (t) == CLEANUP_STMT)
     405              :     {
     406              :       /* We can't see a CLEANUP_STMT in a constructor for a literal class,
     407              :          but we can in a constexpr constructor for a non-literal class.  Just
     408              :          ignore it; either all the initialization will be constant, in which
     409              :          case the cleanup can't run, or it can't be constexpr.
     410              :          Still recurse into CLEANUP_BODY.  */
     411       680686 :       return build_data_member_initialization (CLEANUP_BODY (t), vec);
     412              :     }
     413      5466279 :   if (TREE_CODE (t) == CONVERT_EXPR)
     414      3050538 :     t = TREE_OPERAND (t, 0);
     415      5466279 :   if (TREE_CODE (t) == INIT_EXPR)
     416              :     {
     417      2904171 :       member = TREE_OPERAND (t, 0);
     418      2904171 :       init = break_out_target_exprs (TREE_OPERAND (t, 1));
     419              :     }
     420      2562108 :   else if (TREE_CODE (t) == CALL_EXPR)
     421              :     {
     422      2083663 :       tree fn = get_callee_fndecl (t);
     423      4167326 :       if (!fn || !DECL_CONSTRUCTOR_P (fn))
     424              :         /* We're only interested in calls to subobject constructors.  */
     425              :         return true;
     426      1670025 :       member = CALL_EXPR_ARG (t, 0);
     427              :       /* We don't use build_cplus_new here because it complains about
     428              :          abstract bases.  Leaving the call unwrapped means that it has the
     429              :          wrong type, but cxx_eval_constant_expression doesn't care.  */
     430      1670025 :       init = break_out_target_exprs (t);
     431              :     }
     432       478445 :   else if (TREE_CODE (t) == BIND_EXPR)
     433        34236 :     return build_data_member_initialization (BIND_EXPR_BODY (t), vec);
     434              :   else
     435              :     /* Don't add anything else to the CONSTRUCTOR.  */
     436              :     return true;
     437      4574196 :   if (INDIRECT_REF_P (member))
     438        61848 :     member = TREE_OPERAND (member, 0);
     439      4574196 :   if (TREE_CODE (member) == NOP_EXPR)
     440              :     {
     441       565104 :       tree op = member;
     442       565104 :       STRIP_NOPS (op);
     443       565104 :       if (TREE_CODE (op) == ADDR_EXPR)
     444              :         {
     445          688 :           gcc_assert (same_type_ignoring_top_level_qualifiers_p
     446              :                       (TREE_TYPE (TREE_TYPE (op)),
     447              :                        TREE_TYPE (TREE_TYPE (member))));
     448              :           /* Initializing a cv-qualified member; we need to look through
     449              :              the const_cast.  */
     450              :           member = op;
     451              :         }
     452       564416 :       else if (op == current_class_ptr
     453      1128681 :                && (same_type_ignoring_top_level_qualifiers_p
     454       564265 :                    (TREE_TYPE (TREE_TYPE (member)),
     455              :                     current_class_type)))
     456              :         /* Delegating constructor.  */
     457              :         member = op;
     458              :       else
     459              :         {
     460              :           /* This is an initializer for an empty base; keep it for now so
     461              :              we can check it in cxx_eval_bare_aggregate.  */
     462       486578 :           gcc_assert (is_empty_class (TREE_TYPE (TREE_TYPE (member))));
     463              :         }
     464              :     }
     465      4574196 :   if (TREE_CODE (member) == ADDR_EXPR)
     466      1167457 :     member = TREE_OPERAND (member, 0);
     467      4574196 :   if (TREE_CODE (member) == COMPONENT_REF)
     468              :     {
     469      3983895 :       tree aggr = TREE_OPERAND (member, 0);
     470      3983895 :       if (TREE_CODE (aggr) == VAR_DECL)
     471              :         /* Initializing a local variable, don't add anything.  */
     472              :         return true;
     473      3983893 :       if (TREE_CODE (aggr) != COMPONENT_REF)
     474              :         /* Normal member initialization.  */
     475      3979319 :         member = TREE_OPERAND (member, 1);
     476         4574 :       else if (VAR_P (get_base_address (aggr)))
     477              :         /* Initializing a local variable, don't add anything.  */
     478              :         return true;
     479         4571 :       else if (ANON_AGGR_TYPE_P (TREE_TYPE (aggr)))
     480              :         /* Initializing a member of an anonymous union.  */
     481         4571 :         return build_anon_member_initialization (member, init, vec);
     482              :       else
     483              :         /* We're initializing a vtable pointer in a base.  Leave it as
     484              :            COMPONENT_REF so we remember the path to get to the vfield.  */
     485            0 :         gcc_assert (TREE_TYPE (member) == vtbl_ptr_type_node);
     486              :     }
     487              : 
     488              :   /* Value-initialization can produce multiple initializers for the
     489              :      same field; use the last one.  */
     490      5704732 :   if (!vec_safe_is_empty (*vec) && (*vec)->last().index == member)
     491           80 :     (*vec)->last().value = init;
     492              :   else
     493      4569540 :     CONSTRUCTOR_APPEND_ELT (*vec, member, init);
     494              :   return true;
     495              : }
     496              : 
     497              : /* Subroutine of check_constexpr_ctor_body_1 and constexpr_fn_retval.
     498              :    In C++11 mode checks that the TYPE_DECLs in the BIND_EXPR_VARS of a
     499              :    BIND_EXPR conform to 7.1.5/3/4 on typedef and alias declarations.  */
     500              : 
     501              : static bool
     502         2402 : check_constexpr_bind_expr_vars (tree t)
     503              : {
     504         2402 :   gcc_assert (TREE_CODE (t) == BIND_EXPR);
     505              : 
     506         3240 :   for (tree var = BIND_EXPR_VARS (t); var; var = DECL_CHAIN (var))
     507          850 :     if (TREE_CODE (var) == TYPE_DECL
     508          831 :         && DECL_IMPLICIT_TYPEDEF_P (var)
     509          872 :         && !LAMBDA_TYPE_P (TREE_TYPE (var)))
     510              :       return false;
     511              :   return true;
     512              : }
     513              : 
     514              : /* Subroutine of check_constexpr_ctor_body.  */
     515              : 
     516              : static bool
     517         4137 : check_constexpr_ctor_body_1 (tree last, tree list)
     518              : {
     519         4137 :   switch (TREE_CODE (list))
     520              :     {
     521            6 :     case DECL_EXPR:
     522            6 :       if (TREE_CODE (DECL_EXPR_DECL (list)) == USING_DECL
     523            6 :           || TREE_CODE (DECL_EXPR_DECL (list)) == TYPE_DECL)
     524              :         return true;
     525              :       return false;
     526              : 
     527            4 :     case CLEANUP_POINT_EXPR:
     528            4 :       return check_constexpr_ctor_body (last, TREE_OPERAND (list, 0),
     529            4 :                                         /*complain=*/false);
     530              : 
     531         2059 :     case BIND_EXPR:
     532         2059 :        if (!check_constexpr_bind_expr_vars (list)
     533         2059 :            || !check_constexpr_ctor_body (last, BIND_EXPR_BODY (list),
     534              :                                           /*complain=*/false))
     535              :          return false;
     536              :        return true;
     537              : 
     538              :     case USING_STMT:
     539              :     case STATIC_ASSERT:
     540              :     case DEBUG_BEGIN_STMT:
     541              :       return true;
     542              : 
     543              :     default:
     544              :       return false;
     545              :     }
     546              : }
     547              : 
     548              : /* Make sure that there are no statements after LAST in the constructor
     549              :    body represented by LIST.  */
     550              : 
     551              : bool
     552      6078297 : check_constexpr_ctor_body (tree last, tree list, bool complain)
     553              : {
     554              :   /* C++14 doesn't require a constexpr ctor to have an empty body.  */
     555      6078297 :   if (cxx_dialect >= cxx14)
     556              :     return true;
     557              : 
     558        13845 :   bool ok = true;
     559        13845 :   if (TREE_CODE (list) == STATEMENT_LIST)
     560              :     {
     561        13817 :       tree_stmt_iterator i = tsi_last (list);
     562        17855 :       for (; !tsi_end_p (i); tsi_prev (&i))
     563              :         {
     564        15727 :           tree t = tsi_stmt (i);
     565        15727 :           if (t == last)
     566              :             break;
     567         4109 :           if (!check_constexpr_ctor_body_1 (last, t))
     568              :             {
     569              :               ok = false;
     570              :               break;
     571              :             }
     572              :         }
     573              :     }
     574           28 :   else if (list != last
     575           28 :            && !check_constexpr_ctor_body_1 (last, list))
     576              :     ok = false;
     577        13845 :   if (!ok && complain)
     578              :     {
     579           50 :       pedwarn (input_location, OPT_Wc__14_extensions,
     580              :                "%<constexpr%> constructor does not have empty body");
     581           50 :       ok = true;
     582              :     }
     583              :   return ok;
     584              : }
     585              : 
     586              : /* V is a vector of constructor elements built up for the base and member
     587              :    initializers of a constructor for TYPE.  They need to be in increasing
     588              :    offset order, which they might not be yet if TYPE has a primary base
     589              :    which is not first in the base-clause or a vptr and at least one base
     590              :    all of which are non-primary.  */
     591              : 
     592              : static vec<constructor_elt, va_gc> *
     593      3634557 : sort_constexpr_mem_initializers (tree type, vec<constructor_elt, va_gc> *v)
     594              : {
     595      3634557 :   tree pri = CLASSTYPE_PRIMARY_BINFO (type);
     596      3634557 :   tree field_type;
     597      3634557 :   unsigned i;
     598      3634557 :   constructor_elt *ce;
     599              : 
     600      3634557 :   if (pri)
     601        89717 :     field_type = BINFO_TYPE (pri);
     602      3544840 :   else if (TYPE_CONTAINS_VPTR_P (type))
     603        37816 :     field_type = vtbl_ptr_type_node;
     604              :   else
     605              :     return v;
     606              : 
     607              :   /* Find the element for the primary base or vptr and move it to the
     608              :      beginning of the vec.  */
     609       169403 :   for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
     610       131463 :     if (TREE_TYPE (ce->index) == field_type)
     611              :       break;
     612              : 
     613       149878 :   if (i > 0 && i < vec_safe_length (v))
     614              :     {
     615           28 :       vec<constructor_elt, va_gc> &vref = *v;
     616           28 :       constructor_elt elt = vref[i];
     617           56 :       for (; i > 0; --i)
     618           28 :         vref[i] = vref[i-1];
     619           28 :       vref[0] = elt;
     620              :     }
     621              : 
     622              :   return v;
     623              : }
     624              : 
     625              : /* Build compile-time evalable representations of member-initializer list
     626              :    for a constexpr constructor.  */
     627              : 
     628              : static tree
     629      3712352 : build_constexpr_constructor_member_initializers (tree type, tree body)
     630              : {
     631      3712352 :   vec<constructor_elt, va_gc> *vec = NULL;
     632      3712352 :   bool ok = true;
     633      5791806 :   while (true)
     634      5791806 :     switch (TREE_CODE (body))
     635              :       {
     636      2079375 :       case MUST_NOT_THROW_EXPR:
     637      2079375 :       case EH_SPEC_BLOCK:
     638      2079375 :       case TRY_FINALLY_EXPR: // For C++26 postconditions.
     639      2079375 :         body = TREE_OPERAND (body, 0);
     640      2079375 :         break;
     641              : 
     642           79 :       case STATEMENT_LIST:
     643      2079639 :         for (tree stmt : tsi_range (body))
     644              :           {
     645          161 :             body = stmt;
     646          161 :             if (TREE_CODE (body) == BIND_EXPR)
     647              :               break;
     648              :           }
     649              :         break;
     650              : 
     651      3712352 :       case BIND_EXPR:
     652      3712352 :         body = BIND_EXPR_BODY (body);
     653      3712352 :         goto found;
     654              : 
     655            0 :       default:
     656            0 :         gcc_unreachable ();
     657              :     }
     658      3712352 :  found:
     659      3712352 :   if (TREE_CODE (body) == TRY_BLOCK)
     660              :     {
     661           31 :       body = TREE_OPERAND (body, 0);
     662           31 :       if (TREE_CODE (body) == BIND_EXPR)
     663           31 :         body = BIND_EXPR_BODY (body);
     664              :     }
     665      3712352 :   if (TREE_CODE (body) == CLEANUP_POINT_EXPR)
     666              :     {
     667      2007508 :       body = TREE_OPERAND (body, 0);
     668      2007508 :       if (TREE_CODE (body) == EXPR_STMT)
     669      2007472 :         body = TREE_OPERAND (body, 0);
     670      2007508 :       if (TREE_CODE (body) == INIT_EXPR
     671      2007508 :           && (same_type_ignoring_top_level_qualifiers_p
     672            0 :               (TREE_TYPE (TREE_OPERAND (body, 0)),
     673              :                current_class_type)))
     674              :         {
     675              :           /* Trivial copy.  */
     676            0 :           return TREE_OPERAND (body, 1);
     677              :         }
     678      2007508 :       ok = build_data_member_initialization (body, &vec);
     679              :     }
     680      1704844 :   else if (TREE_CODE (body) == STATEMENT_LIST)
     681              :     {
     682      4919296 :       for (tree stmt : tsi_range (body))
     683              :         {
     684      3219897 :           ok = build_data_member_initialization (stmt, &vec);
     685      3219897 :           if (!ok)
     686              :             break;
     687              :         }
     688              :     }
     689         5444 :   else if (EXPR_P (body))
     690         5444 :     ok = build_data_member_initialization (body, &vec);
     691              :   else
     692            0 :     gcc_assert (errorcount > 0);
     693      3712352 :   if (ok)
     694              :     {
     695      3712343 :       if (vec_safe_length (vec) > 0)
     696              :         {
     697              :           /* In a delegating constructor, return the target.  */
     698      3438953 :           constructor_elt *ce = &(*vec)[0];
     699      3438953 :           if (ce->index == current_class_ptr)
     700              :             {
     701        77786 :               body = ce->value;
     702        77786 :               vec_free (vec);
     703        77786 :               return body;
     704              :             }
     705              :         }
     706      3634557 :       vec = sort_constexpr_mem_initializers (type, vec);
     707      3634557 :       return build_constructor (type, vec);
     708              :     }
     709              :   else
     710            9 :     return error_mark_node;
     711              : }
     712              : 
     713              : /* We have an expression tree T that represents a call, either CALL_EXPR
     714              :    or AGGR_INIT_EXPR.  If the call is lexically to a named function,
     715              :    return the _DECL for that function.  */
     716              : 
     717              : static tree
     718    567618407 : get_function_named_in_call (tree t)
     719              : {
     720    567618407 :   tree callee = cp_get_callee (t);
     721    567618407 :   tree fun = cp_get_fndecl_from_callee (callee, /*fold*/false);
     722    567618407 :   return fun ? fun : callee;
     723              : }
     724              : 
     725              : /* Subroutine of check_constexpr_fundef.  BODY is the body of a function
     726              :    declared to be constexpr, or a sub-statement thereof.  Returns the
     727              :    return value if suitable, error_mark_node for a statement not allowed in
     728              :    a constexpr function, or NULL_TREE if no return value was found.  */
     729              : 
     730              : tree
     731        70609 : constexpr_fn_retval (tree body)
     732              : {
     733        77425 :   switch (TREE_CODE (body))
     734              :     {
     735        18785 :     case STATEMENT_LIST:
     736        18785 :       {
     737        18785 :         tree expr = NULL_TREE;
     738        56285 :         for (tree stmt : tsi_range (body))
     739              :           {
     740        37529 :             tree s = constexpr_fn_retval (stmt);
     741        37529 :             if (s == error_mark_node)
     742              :               return error_mark_node;
     743        37502 :             else if (s == NULL_TREE)
     744              :               /* Keep iterating.  */;
     745        18750 :             else if (expr)
     746              :               /* Multiple return statements.  */
     747              :               return error_mark_node;
     748              :             else
     749              :               expr = s;
     750              :           }
     751              :         return expr;
     752              :       }
     753              : 
     754        33030 :     case RETURN_EXPR:
     755        33030 :       return break_out_target_exprs (TREE_OPERAND (body, 0));
     756              : 
     757           20 :     case DECL_EXPR:
     758           20 :       {
     759           20 :         tree decl = DECL_EXPR_DECL (body);
     760           20 :         if (TREE_CODE (decl) == USING_DECL
     761              :             /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__.  */
     762           20 :             || DECL_ARTIFICIAL (decl))
     763              :           return NULL_TREE;
     764            6 :         return error_mark_node;
     765              :       }
     766              : 
     767         6479 :     case CLEANUP_POINT_EXPR:
     768         6479 :       return constexpr_fn_retval (TREE_OPERAND (body, 0));
     769              : 
     770          343 :     case BIND_EXPR:
     771          343 :       if (!check_constexpr_bind_expr_vars (body))
     772            6 :         return error_mark_node;
     773          337 :       return constexpr_fn_retval (BIND_EXPR_BODY (body));
     774              : 
     775              :     case USING_STMT:
     776              :     case DEBUG_BEGIN_STMT:
     777              :       return NULL_TREE;
     778              : 
     779            0 :     case CALL_EXPR:
     780            0 :         {
     781            0 :           tree fun = get_function_named_in_call (body);
     782            0 :           if (fun != NULL_TREE
     783            0 :               && fndecl_built_in_p (fun, BUILT_IN_UNREACHABLE))
     784              :             return NULL_TREE;
     785              :         }
     786              :       /* Fallthru.  */
     787              : 
     788           30 :     default:
     789           30 :       return error_mark_node;
     790              :     }
     791              : }
     792              : 
     793              : /* Subroutine of check_constexpr_fundef.  BODY is the DECL_SAVED_TREE of
     794              :    FUN; do the necessary transformations to turn it into a single expression
     795              :    that we can store in the hash table.  */
     796              : 
     797              : static tree
     798     31302833 : massage_constexpr_body (tree fun, tree body)
     799              : {
     800     62605666 :   if (DECL_CONSTRUCTOR_P (fun))
     801      3712352 :     body = build_constexpr_constructor_member_initializers
     802      3712352 :       (DECL_CONTEXT (fun), body);
     803     27590481 :   else if (cxx_dialect < cxx14)
     804              :     {
     805        32845 :       if (TREE_CODE (body) == EH_SPEC_BLOCK)
     806            1 :         body = EH_SPEC_STMTS (body);
     807        32845 :       if (TREE_CODE (body) == MUST_NOT_THROW_EXPR)
     808        21455 :         body = TREE_OPERAND (body, 0);
     809        32845 :       body = constexpr_fn_retval (body);
     810              :     }
     811     31302833 :   return body;
     812              : }
     813              : 
     814              : /* CTYPE is a type constructed from BODY.  Return true if some
     815              :    bases/fields are uninitialized, and complain if COMPLAIN.  */
     816              : 
     817              : static bool
     818      3363958 : cx_check_missing_mem_inits (tree ctype, tree body, bool complain)
     819              : {
     820              :   /* We allow uninitialized bases/fields in C++20.  */
     821      3363958 :   if (cxx_dialect >= cxx20)
     822              :     return false;
     823              : 
     824        13698 :   unsigned nelts = 0;
     825              : 
     826        13698 :   if (body)
     827              :     {
     828        13694 :       if (TREE_CODE (body) != CONSTRUCTOR)
     829              :         return false;
     830        13641 :       nelts = CONSTRUCTOR_NELTS (body);
     831              :     }
     832        13645 :   tree field = TYPE_FIELDS (ctype);
     833              : 
     834        13645 :   if (TREE_CODE (ctype) == UNION_TYPE)
     835              :     {
     836          110 :       if (nelts == 0 && next_aggregate_field (field))
     837              :         {
     838            2 :           if (complain)
     839            2 :             error ("%<constexpr%> constructor for union %qT must "
     840              :                    "initialize exactly one non-static data member", ctype);
     841              :           return true;
     842              :         }
     843              :       return false;
     844              :     }
     845              : 
     846              :   /* Iterate over the CONSTRUCTOR, checking any missing fields don't
     847              :      need an explicit initialization.  */
     848              :   bool bad = false;
     849        28790 :   for (unsigned i = 0; i <= nelts; ++i)
     850              :     {
     851        28790 :       tree index = NULL_TREE;
     852        28790 :       if (i < nelts)
     853              :         {
     854        15255 :           index = CONSTRUCTOR_ELT (body, i)->index;
     855              :           /* Skip vptr adjustment represented with a COMPONENT_REF.  */
     856        15255 :           if (TREE_CODE (index) != FIELD_DECL)
     857          627 :             continue;
     858              :         }
     859              : 
     860       497916 :       for (; field != index; field = DECL_CHAIN (field))
     861              :         {
     862       469759 :           tree ftype;
     863       469759 :           if (TREE_CODE (field) != FIELD_DECL)
     864       469731 :             continue;
     865         1789 :           if (DECL_UNNAMED_BIT_FIELD (field))
     866           10 :             continue;
     867              :           /* Artificial fields can be ignored unless they're bases.  */
     868         1779 :           if (DECL_ARTIFICIAL (field) && !DECL_FIELD_IS_BASE (field))
     869            6 :             continue;
     870         1773 :           if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
     871              :             {
     872              :               /* Recurse to check the anonymous aggregate member.  */
     873            8 :               bad |= cx_check_missing_mem_inits
     874            4 :                 (TREE_TYPE (field), NULL_TREE, complain);
     875            4 :               if (bad && !complain)
     876            6 :                 return true;
     877            4 :               continue;
     878              :             }
     879         1769 :           ftype = TREE_TYPE (field);
     880         1769 :           if (!ftype || !TYPE_P (ftype) || !COMPLETE_TYPE_P (ftype))
     881              :             /* A flexible array can't be initialized here, so don't complain
     882              :                that it isn't.  */
     883            1 :             continue;
     884         1768 :           if (is_empty_field (field))
     885              :             /* An empty field doesn't need an initializer.  */
     886         1733 :             continue;
     887           35 :           ftype = strip_array_types (ftype);
     888           35 :           if (type_has_constexpr_default_constructor (ftype))
     889              :             {
     890              :               /* It's OK to skip a member with a trivial constexpr ctor.
     891              :                  A constexpr ctor that isn't trivial should have been
     892              :                  added in by now.  */
     893            7 :               gcc_checking_assert (!TYPE_HAS_COMPLEX_DFLT (ftype)
     894              :                                    || errorcount != 0);
     895            7 :               continue;
     896              :             }
     897           28 :           if (!complain)
     898              :             return true;
     899           22 :           auto_diagnostic_group d;
     900           22 :           error ("member %qD must be initialized by mem-initializer "
     901              :                  "in %<constexpr%> constructor", field);
     902           22 :           inform (DECL_SOURCE_LOCATION (field), "declared here");
     903           22 :           bad = true;
     904           22 :         }
     905        28157 :       if (field == NULL_TREE)
     906              :         break;
     907              : 
     908        14628 :       if (ANON_AGGR_TYPE_P (TREE_TYPE (index)))
     909              :         {
     910              :           /* Check the anonymous aggregate initializer is valid.  */
     911           38 :           bad |= cx_check_missing_mem_inits
     912           38 :             (TREE_TYPE (index), CONSTRUCTOR_ELT (body, i)->value, complain);
     913           38 :           if (bad && !complain)
     914              :             return true;
     915              :         }
     916        14628 :       field = DECL_CHAIN (field);
     917              :     }
     918              : 
     919              :   return bad;
     920              : }
     921              : 
     922              : /* We are processing the definition of the constexpr function FUN.
     923              :    Check that its body fulfills the appropriate requirements and
     924              :    enter it in the constexpr function definition table.  */
     925              : 
     926              : void
     927    168707711 : maybe_save_constexpr_fundef (tree fun)
     928              : {
     929    168707711 :   if (processing_template_decl
     930     69777739 :       || cp_function_chain->invalid_constexpr
     931    238467149 :       || (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun)))
     932    137405172 :     return;
     933              : 
     934              :   /* With -fimplicit-constexpr, try to make inlines constexpr.  We'll
     935              :      actually set DECL_DECLARED_CONSTEXPR_P below if the checks pass.  */
     936     53346698 :   bool implicit = false;
     937     53346698 :   if (flag_implicit_constexpr)
     938              :     {
     939           22 :       if (DECL_DELETING_DESTRUCTOR_P (fun)
     940           22 :           && decl_implicit_constexpr_p (DECL_CLONED_FUNCTION (fun)))
     941              :         /* Don't inherit implicit constexpr from the non-deleting
     942              :            destructor.  */
     943            0 :         DECL_DECLARED_CONSTEXPR_P (fun) = false;
     944              : 
     945           22 :       if (!DECL_DECLARED_CONSTEXPR_P (fun)
     946           18 :           && DECL_DECLARED_INLINE_P (fun)
     947           36 :           && !lookup_attribute ("noinline", DECL_ATTRIBUTES (fun)))
     948              :         implicit = true;
     949              :     }
     950              : 
     951     53346698 :   if (!DECL_DECLARED_CONSTEXPR_P (fun) && !implicit)
     952              :     return;
     953              : 
     954     31358461 :   bool complain = !DECL_GENERATED_P (fun) && !implicit;
     955              : 
     956     31358461 :   if (!is_valid_constexpr_fn (fun, complain))
     957              :     return;
     958              : 
     959     31302753 :   tree massaged = massage_constexpr_body (fun, DECL_SAVED_TREE (fun));
     960     31302753 :   if (massaged == NULL_TREE || massaged == error_mark_node)
     961              :     {
     962           72 :       if (!DECL_CONSTRUCTOR_P (fun) && complain)
     963           22 :         error ("body of %<constexpr%> function %qD not a return-statement",
     964              :                fun);
     965              :       return;
     966              :     }
     967              : 
     968     31302717 :   bool potential = potential_rvalue_constant_expression (massaged);
     969     31302717 :   if (!potential && complain)
     970          258 :     require_potential_rvalue_constant_expression_fncheck (massaged);
     971              : 
     972     35015046 :   if (DECL_CONSTRUCTOR_P (fun) && potential
     973     35010988 :       && !DECL_DEFAULTED_FN (fun))
     974              :     {
     975      3363902 :       if (cx_check_missing_mem_inits (DECL_CONTEXT (fun),
     976              :                                       massaged, complain))
     977              :         potential = false;
     978      3363876 :       else if (cxx_dialect > cxx11)
     979              :         {
     980              :           /* What we got from massage_constexpr_body is pretty much just the
     981              :              ctor-initializer, also check the body.  */
     982      3359045 :           massaged = DECL_SAVED_TREE (fun);
     983      3359045 :           potential = potential_rvalue_constant_expression (massaged);
     984      3359045 :           if (!potential && complain)
     985           20 :             require_potential_rvalue_constant_expression_fncheck (massaged);
     986              :         }
     987              :     }
     988              : 
     989     31302717 :   if (!potential && complain
     990              :       /* If -Wno-invalid-constexpr was specified, we haven't complained
     991              :          about non-constant expressions yet.  Register the function and
     992              :          complain in explain_invalid_constexpr_fn if the function is
     993              :          called.  */
     994          298 :       && warn_invalid_constexpr != 0)
     995              :     return;
     996              : 
     997     31302550 :   if (implicit)
     998              :     {
     999           14 :       if (potential)
    1000              :         {
    1001            3 :           DECL_DECLARED_CONSTEXPR_P (fun) = true;
    1002            3 :           DECL_LANG_SPECIFIC (fun)->u.fn.implicit_constexpr = true;
    1003            6 :           if (DECL_CONSTRUCTOR_P (fun))
    1004            0 :             TYPE_HAS_CONSTEXPR_CTOR (DECL_CONTEXT (fun)) = true;
    1005              :         }
    1006              :       else
    1007              :         /* Don't bother keeping the pre-generic body of unsuitable functions
    1008              :            not explicitly declared constexpr.  */
    1009              :         return;
    1010              :     }
    1011              : 
    1012     31302539 :   constexpr_fundef entry = {fun, NULL_TREE, NULL_TREE, NULL_TREE};
    1013     31302539 :   bool clear_ctx = false;
    1014     31302539 :   if (DECL_RESULT (fun) && DECL_CONTEXT (DECL_RESULT (fun)) == NULL_TREE)
    1015              :     {
    1016     31302539 :       clear_ctx = true;
    1017     31302539 :       DECL_CONTEXT (DECL_RESULT (fun)) = fun;
    1018              :     }
    1019     31302539 :   tree saved_fn = current_function_decl;
    1020     31302539 :   current_function_decl = fun;
    1021     31302539 :   entry.body = copy_fn (entry.decl, entry.parms, entry.result);
    1022     31302539 :   current_function_decl = saved_fn;
    1023     31302539 :   if (clear_ctx)
    1024     31302539 :     DECL_CONTEXT (DECL_RESULT (entry.decl)) = NULL_TREE;
    1025     31302539 :   if (!potential)
    1026              :     /* For a template instantiation, we want to remember the pre-generic body
    1027              :        for explain_invalid_constexpr_fn, but do tell cxx_eval_call_expression
    1028              :        that it doesn't need to bother trying to expand the function.  */
    1029        61049 :     entry.result = error_mark_node;
    1030              : 
    1031     31302539 :   register_constexpr_fundef (entry);
    1032              : }
    1033              : 
    1034              : /* BODY is a validated and massaged definition of a constexpr
    1035              :    function.  Register it in the hash table.  */
    1036              : 
    1037              : void
    1038     31340865 : register_constexpr_fundef (const constexpr_fundef &value)
    1039              : {
    1040              :   /* Create the constexpr function table if necessary.  */
    1041     31340865 :   if (constexpr_fundef_table == NULL)
    1042        27792 :     constexpr_fundef_table
    1043        27792 :       = hash_table<constexpr_fundef_hasher>::create_ggc (101);
    1044              : 
    1045     31340865 :   constexpr_fundef **slot = constexpr_fundef_table->find_slot
    1046     31340865 :     (const_cast<constexpr_fundef *> (&value), INSERT);
    1047              : 
    1048     31340865 :   gcc_assert (*slot == NULL);
    1049     31340865 :   *slot = ggc_alloc<constexpr_fundef> ();
    1050     31340865 :   **slot = value;
    1051     31340865 : }
    1052              : 
    1053              : /* FUN is a non-constexpr (or, with -Wno-invalid-constexpr, a constexpr
    1054              :    function called in a context that requires a constant expression).
    1055              :    If it comes from a constexpr template, explain why the instantiation
    1056              :    isn't constexpr.  Otherwise, explain why the function cannot be used
    1057              :    in a constexpr context.  */
    1058              : 
    1059              : void
    1060         1063 : explain_invalid_constexpr_fn (tree fun)
    1061              : {
    1062         1063 :   static hash_set<tree> *diagnosed;
    1063         1063 :   tree body;
    1064              : 
    1065              :   /* Don't try to explain a function we already complained about.  */
    1066         1063 :   if (function *f = DECL_STRUCT_FUNCTION (fun))
    1067          859 :     if (f->language->erroneous)
    1068         1063 :       return;
    1069              : 
    1070              :   /* In C++23, a function marked 'constexpr' may not actually be a constant
    1071              :      expression.  We haven't diagnosed the problem yet: -Winvalid-constexpr
    1072              :      wasn't enabled.  The function was called, so diagnose why it cannot be
    1073              :      used in a constant expression.  */
    1074         1014 :   if (warn_invalid_constexpr == 0 && DECL_DECLARED_CONSTEXPR_P (fun))
    1075              :     /* Go on.  */;
    1076              :   /* Only diagnose defaulted functions, lambdas, or instantiations.  */
    1077          978 :   else if (!DECL_DEFAULTED_FN (fun)
    1078         1230 :            && !LAMBDA_TYPE_P (CP_DECL_CONTEXT (fun))
    1079          941 :            && !(flag_implicit_constexpr
    1080            9 :                 && !DECL_DECLARED_CONSTEXPR_P (fun)
    1081            9 :                 && DECL_DECLARED_INLINE_P (fun))
    1082         1913 :            && !is_instantiation_of_constexpr (fun))
    1083              :     {
    1084          917 :       inform (DECL_SOURCE_LOCATION (fun), "%qD declared here", fun);
    1085            3 :       if (flag_implicit_constexpr && !maybe_constexpr_fn (fun)
    1086          920 :           && decl_defined_p (fun))
    1087            3 :         inform (DECL_SOURCE_LOCATION (fun),
    1088              :                 "%<-fimplicit-constexpr%> only affects %<inline%> functions");
    1089              :       return;
    1090              :     }
    1091           97 :   if (diagnosed == NULL)
    1092           74 :     diagnosed = new hash_set<tree>;
    1093           97 :   if (diagnosed->add (fun))
    1094              :     /* Already explained.  */
    1095              :     return;
    1096              : 
    1097           96 :   iloc_sentinel ils = input_location;
    1098           96 :   if (!lambda_static_thunk_p (fun))
    1099              :     {
    1100              :       /* Diagnostics should completely ignore the static thunk, so leave
    1101              :          input_location set to our caller's location.  */
    1102           84 :       input_location = DECL_SOURCE_LOCATION (fun);
    1103           84 :       inform (input_location,
    1104              :               "%qD is not usable as a %<constexpr%> function because:", fun);
    1105              :     }
    1106              :   /* First check the declaration.  */
    1107           96 :   if (is_valid_constexpr_fn (fun, true))
    1108              :     {
    1109              :       /* Then if it's OK, the body.  */
    1110           90 :       if (!DECL_DECLARED_CONSTEXPR_P (fun)
    1111           90 :           && DECL_DEFAULTED_FN (fun))
    1112           10 :         explain_implicit_non_constexpr (fun);
    1113              :       else
    1114              :         {
    1115           80 :           if (constexpr_fundef *fd = retrieve_constexpr_fundef (fun))
    1116           54 :             body = fd->body;
    1117              :           else
    1118           26 :             body = DECL_SAVED_TREE (fun);
    1119           80 :           tree massaged = massage_constexpr_body (fun, body);
    1120           80 :           require_potential_rvalue_constant_expression (massaged);
    1121          160 :           if (DECL_CONSTRUCTOR_P (fun))
    1122              :             {
    1123           14 :               cx_check_missing_mem_inits (DECL_CONTEXT (fun), massaged, true);
    1124           14 :               if (cxx_dialect > cxx11)
    1125              :                 /* Also check the body, not just the ctor-initializer.  */
    1126           12 :                 require_potential_rvalue_constant_expression (body);
    1127              :             }
    1128           66 :           else if (massaged == NULL_TREE || massaged == error_mark_node)
    1129            1 :             error ("body of %<constexpr%> function %qD not a return-statement",
    1130              :                    fun);
    1131              :         }
    1132              :     }
    1133           96 : }
    1134              : 
    1135              : /* Objects of this type represent calls to constexpr functions
    1136              :    along with the bindings of parameters to their arguments, for
    1137              :    the purpose of compile time evaluation.  */
    1138              : 
    1139              : struct GTY((for_user)) constexpr_call {
    1140              :   /* Description of the constexpr function definition.  */
    1141              :   constexpr_fundef *fundef = nullptr;
    1142              :   /* Parameter bindings environment.  A TREE_VEC of arguments.  */
    1143              :   tree bindings = NULL_TREE;
    1144              :   /* Result of the call, indexed by the value of
    1145              :      constexpr_ctx::manifestly_const_eval.
    1146              :        unknown_type_node means the call is being evaluated.
    1147              :        error_mark_node means that the evaluation was erroneous or otherwise
    1148              :        uncacheable (e.g. because it depends on the caller).
    1149              :        Otherwise, the actual value of the call.  */
    1150              :   tree results[3] = { NULL_TREE, NULL_TREE, NULL_TREE };
    1151              :   /* The hash of this call; we remember it here to avoid having to
    1152              :      recalculate it when expanding the hash table.  */
    1153              :   hashval_t hash = 0;
    1154              : 
    1155              :   /* The result slot corresponding to the given mce_value.  */
    1156     65160434 :   tree& result (mce_value mce) { return results[1 + int(mce)]; }
    1157              : };
    1158              : 
    1159              : struct constexpr_call_hasher : ggc_ptr_hash<constexpr_call>
    1160              : {
    1161              :   static hashval_t hash (constexpr_call *);
    1162              :   static bool equal (constexpr_call *, constexpr_call *);
    1163              : };
    1164              : 
    1165              : enum constexpr_switch_state {
    1166              :   /* Used when processing a switch for the first time by cxx_eval_switch_expr
    1167              :      and default: label for that switch has not been seen yet.  */
    1168              :   css_default_not_seen,
    1169              :   /* Used when processing a switch for the first time by cxx_eval_switch_expr
    1170              :      and default: label for that switch has been seen already.  */
    1171              :   css_default_seen,
    1172              :   /* Used when processing a switch for the second time by
    1173              :      cxx_eval_switch_expr, where default: label should match.  */
    1174              :   css_default_processing
    1175              : };
    1176              : 
    1177              : /* The constexpr expansion context part which needs one instance per
    1178              :    cxx_eval_outermost_constant_expr invocation.  VALUES is a map of values of
    1179              :    variables initialized within the expression.  */
    1180              : 
    1181              : class constexpr_global_ctx {
    1182              :   /* Values for any temporaries or local variables within the
    1183              :      constant-expression.  Objects outside their lifetime have
    1184              :      value 'void_node' or 'void_list_node', the former if they are outside
    1185              :      of lifetime but still before storage has been deallocated.  */
    1186              :   hash_map<tree,tree> values;
    1187              : public:
    1188              :   /* Number of cxx_eval_constant_expression calls (except skipped ones,
    1189              :      on simple constants or location wrappers) encountered during current
    1190              :      cxx_eval_outermost_constant_expr call.  */
    1191              :   HOST_WIDE_INT constexpr_ops_count;
    1192              :   /* Heap VAR_DECLs created during the evaluation of the outermost constant
    1193              :      expression.  */
    1194              :   auto_vec<tree, 16> heap_vars;
    1195              :   /* Vector of caught exceptions, including exceptions still not active at
    1196              :      the start of a handler (those are immediately followed up by HANDLER_TYPE
    1197              :      until __cxa_begin_catch finishes).  If __cxa_begin_catch or
    1198              :      __cxa_get_exception_ptr need to create temporaries, the VAR_DECL of the
    1199              :      exception object is wrapped in the vector into a TREE_LIST where
    1200              :      TREE_VALUE of it is the VAR_DECL of the exception object and TREE_PURPOSE
    1201              :      one of the temporaries, others chained through DECL_CHAIN.  */
    1202              :   auto_vec<tree, 2> caught_exceptions;
    1203              :   /* Cleanups that need to be evaluated at the end of CLEANUP_POINT_EXPR.  */
    1204              :   vec<tree> *cleanups;
    1205              :   /* If non-null, only allow modification of existing values of the variables
    1206              :      in this set.  Set by modifiable_tracker, below.  */
    1207              :   hash_set<tree> *modifiable;
    1208              :   /* If cxx_eval_outermost_constant_expr is called on the consteval block
    1209              :      operator (), this is the FUNCTION_DECL of that operator ().  */
    1210              :   tree consteval_block;
    1211              :   /* Number of heap VAR_DECL deallocations.  */
    1212              :   unsigned heap_dealloc_count;
    1213              :   /* Number of uncaught exceptions.  */
    1214              :   unsigned uncaught_exceptions;
    1215              :   /* A contract statement that failed or was not constant, we only store the
    1216              :      first one that fails.  */
    1217              :   tree contract_statement;
    1218              :   /* [basic.contract.eval]/7.3 if this expression would otherwise be constant
    1219              :      then a non-const contract makes the program ill-formed.  */
    1220              :   bool contract_condition_non_const;
    1221              :   /* Some metafunctions aren't dependent just on their arguments, but also
    1222              :      on various other dependencies, e.g. has_identifier on a function parameter
    1223              :      reflection can change depending on further declarations of corresponding
    1224              :      function, is_complete_type depends on type definitions and template
    1225              :      specializations in between the calls, define_aggregate even defines
    1226              :      class types, etc.  Thus, we need to arrange for calls which call
    1227              :      at least some metafunctions to be non-cacheable, because their behavior
    1228              :      might not be the same.  Until we figure out which exact metafunctions
    1229              :      need this and which don't, do it for all of them.
    1230              :      Also used for some cases in constexpr EH, e.g. __cxa_rethrow,
    1231              :      __builtin_uncaught_exceptions and __builtin_current_exception, which can
    1232              :      be also dependent on some state (pending uncaught or caught exceptions)
    1233              :      not tracked in the constexpr call caching.  */
    1234              :   bool state_dependent;
    1235              : 
    1236              :   /* Constructor.  */
    1237    578608694 :   constexpr_global_ctx ()
    1238    578608694 :     : constexpr_ops_count (0), cleanups (NULL), modifiable (nullptr),
    1239    578608694 :       consteval_block (NULL_TREE), heap_dealloc_count (0),
    1240    578608694 :       uncaught_exceptions (0), contract_statement (NULL_TREE),
    1241    578608694 :       contract_condition_non_const (false), state_dependent (false) {}
    1242              : 
    1243    464856333 :   bool is_outside_lifetime (tree t)
    1244              :   {
    1245    464856333 :     if (tree *p = values.get (t))
    1246    209226804 :       if (*p == void_node || *p == void_list_node)
    1247          268 :         return true;
    1248              :     return false;
    1249              :   }
    1250    588075610 :  tree get_value (tree t)
    1251              :   {
    1252    588075610 :     if (tree *p = values.get (t))
    1253    307791354 :       if (*p != void_node && *p != void_list_node)
    1254    299586122 :         return *p;
    1255              :     return NULL_TREE;
    1256              :   }
    1257         4326 :   tree *get_raw_value_ptr (tree t)
    1258              :   {
    1259         4326 :     return values.get (t);
    1260              :   }
    1261    125185547 :   tree *get_value_ptr (tree t, bool initializing)
    1262              :   {
    1263    125185547 :     if (modifiable && !modifiable->contains (t))
    1264              :       return nullptr;
    1265    125185536 :     if (tree *p = values.get (t))
    1266              :       {
    1267    125176009 :         if (*p != void_node && *p != void_list_node)
    1268              :           return p;
    1269           63 :         else if (initializing)
    1270              :           {
    1271           21 :             *p = NULL_TREE;
    1272           21 :             return p;
    1273              :           }
    1274              :       }
    1275              :     return nullptr;
    1276              :   }
    1277    302303150 :   void put_value (tree t, tree v)
    1278              :   {
    1279    302303150 :     bool already_in_map = values.put (t, v);
    1280    302303150 :     if (!already_in_map && modifiable)
    1281           30 :       modifiable->add (t);
    1282    302303150 :   }
    1283    242185419 :   void destroy_value (tree t, bool past_storage_end = true)
    1284              :   {
    1285    242185419 :     if (TREE_CODE (t) == VAR_DECL
    1286    242185419 :         || TREE_CODE (t) == PARM_DECL
    1287              :         || TREE_CODE (t) == RESULT_DECL)
    1288    242479969 :       values.put (t, past_storage_end ? void_list_node : void_node);
    1289              :     else
    1290         9261 :       values.remove (t);
    1291    242185419 :   }
    1292     19298716 :   void clear_value (tree t)
    1293              :   {
    1294     38597432 :     values.remove (t);
    1295              :   }
    1296              : };
    1297              : 
    1298              : /* Helper class for constexpr_global_ctx.  In some cases we want to avoid
    1299              :    side-effects from evaluation of a particular subexpression of a
    1300              :    constant-expression.  In such cases we use modifiable_tracker to prevent
    1301              :    modification of variables created outside of that subexpression.
    1302              : 
    1303              :    ??? We could change the hash_set to a hash_map, allow and track external
    1304              :    modifications, and roll them back in the destructor.  It's not clear to me
    1305              :    that this would be worthwhile.  */
    1306              : 
    1307              : class modifiable_tracker
    1308              : {
    1309              :   hash_set<tree> set;
    1310              :   constexpr_global_ctx *global;
    1311              : public:
    1312       173601 :   modifiable_tracker (constexpr_global_ctx *g): global(g)
    1313              :   {
    1314       173601 :     global->modifiable = &set;
    1315       173601 :   }
    1316       173601 :   ~modifiable_tracker ()
    1317              :   {
    1318       173631 :     for (tree t: set)
    1319           30 :       global->clear_value (t);
    1320       173601 :     global->modifiable = nullptr;
    1321       173601 :   }
    1322              : };
    1323              : 
    1324              : /* The constexpr expansion context.  CALL is the current function
    1325              :    expansion, CTOR is the current aggregate initializer, OBJECT is the
    1326              :    object being initialized by CTOR, either a VAR_DECL or a _REF.    */
    1327              : 
    1328              : struct constexpr_ctx {
    1329              :   /* The part of the context that needs to be unique to the whole
    1330              :      cxx_eval_outermost_constant_expr invocation.  */
    1331              :   constexpr_global_ctx *global;
    1332              :   /* The innermost call we're evaluating.  */
    1333              :   constexpr_call *call;
    1334              :   /* SAVE_EXPRs and TARGET_EXPR_SLOT vars of TARGET_EXPRs that we've seen
    1335              :      within the current LOOP_EXPR.  NULL if we aren't inside a loop.  */
    1336              :   vec<tree> *save_exprs;
    1337              :   /* The CONSTRUCTOR we're currently building up for an aggregate
    1338              :      initializer.  */
    1339              :   tree ctor;
    1340              :   /* The object we're building the CONSTRUCTOR for.  */
    1341              :   tree object;
    1342              :   /* If inside SWITCH_EXPR.  */
    1343              :   constexpr_switch_state *css_state;
    1344              :   /* The aggregate initialization context inside which this one is nested.  This
    1345              :      is used by lookup_placeholder to resolve PLACEHOLDER_EXPRs.  */
    1346              :   const constexpr_ctx *parent;
    1347              : 
    1348              :   /* Whether we should error on a non-constant expression or fail quietly.
    1349              :      This flag needs to be here, but some of the others could move to global
    1350              :      if they get larger than a word.  */
    1351              :   bool quiet;
    1352              :   /* Whether we are strictly conforming to constant expression rules or
    1353              :      trying harder to get a constant value.  */
    1354              :   bool strict;
    1355              :   /* Whether __builtin_is_constant_evaluated () should be true.  */
    1356              :   mce_value manifestly_const_eval;
    1357              : };
    1358              : 
    1359              : /* Return ctx->quiet.  For use in reflect.cc.  */
    1360              : 
    1361              : bool
    1362         1376 : cxx_constexpr_quiet_p (const constexpr_ctx *ctx)
    1363              : {
    1364         1376 :   return ctx->quiet;
    1365              : }
    1366              : 
    1367              : /* Return ctx->manifestly_const_eval.  For use in reflect.cc.  */
    1368              : 
    1369              : mce_value
    1370          400 : cxx_constexpr_manifestly_const_eval (const constexpr_ctx *ctx)
    1371              : {
    1372          400 :   return ctx->manifestly_const_eval;
    1373              : }
    1374              : 
    1375              : /* Return ctx->call->fundef->decl or NULL_TREE.  For use in
    1376              :    reflect.cc.  */
    1377              : 
    1378              : tree
    1379         2128 : cxx_constexpr_caller (const constexpr_ctx *ctx)
    1380              : {
    1381         2128 :   if (ctx->call)
    1382          958 :     return ctx->call->fundef->decl;
    1383              :   else
    1384              :     return NULL_TREE;
    1385              : }
    1386              : 
    1387              : /* Return ctx->global->consteval_block.  For use in reflect.cc.  */
    1388              : 
    1389              : tree
    1390          158 : cxx_constexpr_consteval_block (const constexpr_ctx *ctx)
    1391              : {
    1392          158 :   return ctx->global->consteval_block;
    1393              : }
    1394              : 
    1395              : /* Predicates for the meaning of *jump_target.  */
    1396              : 
    1397              : static bool
    1398    110837068 : returns (tree *jump_target)
    1399              : {
    1400     19440511 :   return *jump_target && TREE_CODE (*jump_target) == RETURN_EXPR;
    1401              : }
    1402              : 
    1403              : static bool
    1404    105239982 : breaks (tree *jump_target)
    1405              : {
    1406    105239982 :   return (*jump_target
    1407    105239982 :           && ((TREE_CODE (*jump_target) == LABEL_DECL
    1408          339 :                && LABEL_DECL_BREAK (*jump_target))
    1409      1378512 :               || TREE_CODE (*jump_target) == BREAK_STMT
    1410      1239849 :               || TREE_CODE (*jump_target) == EXIT_EXPR));
    1411              : }
    1412              : 
    1413              : static bool
    1414    142204532 : continues (tree *jump_target)
    1415              : {
    1416    142204532 :   return (*jump_target
    1417    142204532 :           && ((TREE_CODE (*jump_target) == LABEL_DECL
    1418          339 :                && LABEL_DECL_CONTINUE (*jump_target))
    1419      1255320 :               || TREE_CODE (*jump_target) == CONTINUE_STMT));
    1420              : }
    1421              : 
    1422              : static bool
    1423     12831777 : switches (tree *jump_target)
    1424              : {
    1425        78155 :   return *jump_target && TREE_CODE (*jump_target) == INTEGER_CST;
    1426              : }
    1427              : 
    1428              : static bool
    1429   1921696652 : throws (tree *jump_target)
    1430              : {
    1431              :   /* void_node is for use in potential_constant_expression_1, otherwise
    1432              :      it should an artificial VAR_DECL created by constant evaluation
    1433              :      of __cxa_allocate_exception ().  */
    1434    213138306 :   return (*jump_target && (VAR_P (*jump_target) || *jump_target == void_node));
    1435              : }
    1436              : 
    1437              : /* True if the constexpr relaxations afforded by P2280R4 for unknown
    1438              :    references and objects are in effect.  */
    1439              : 
    1440              : static bool
    1441    271198965 : p2280_active_p (const constexpr_ctx *ctx)
    1442              : {
    1443     34581288 :   if (ctx->manifestly_const_eval != mce_true)
    1444              :     /* Disable these relaxations during speculative constexpr folding,
    1445              :        as it can significantly increase compile time/memory use
    1446              :        (PR119387).  */
    1447              :     return false;
    1448              : 
    1449              :   /* P2280R4 was accepted as a DR against C++11.  */
    1450            0 :   return cxx_dialect >= cxx11;
    1451              : }
    1452              : 
    1453              : /* Remove T from the global values map, checking for attempts to destroy
    1454              :    a value that has already finished its lifetime.  */
    1455              : 
    1456              : static void
    1457    241797433 : destroy_value_checked (const constexpr_ctx* ctx, tree t, bool *non_constant_p)
    1458              : {
    1459    241797433 :   if (t == error_mark_node || TREE_TYPE (t) == error_mark_node)
    1460              :     return;
    1461              : 
    1462              :   /* Don't error again here if we've already reported a problem.  */
    1463    241797372 :   if (!*non_constant_p
    1464    210434582 :       && DECL_P (t)
    1465              :       /* Non-trivial destructors have their lifetimes ended explicitly
    1466              :          with a clobber, so don't worry about it here.  */
    1467    210425519 :       && (!TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (t))
    1468              :           /* ...except parameters are remapped in cxx_eval_call_expression,
    1469              :              and the destructor call during cleanup won't be able to tell that
    1470              :              this value has already been destroyed, so complain now.  This is
    1471              :              not quite unobservable, but is extremely unlikely to crop up in
    1472              :              practice; see g++.dg/cpp2a/constexpr-lifetime2.C.  */
    1473       774710 :           || TREE_CODE (t) == PARM_DECL)
    1474    451449716 :       && ctx->global->is_outside_lifetime (t))
    1475              :     {
    1476           54 :       if (!ctx->quiet)
    1477              :         {
    1478           18 :           auto_diagnostic_group d;
    1479           18 :           error ("destroying %qE outside its lifetime", t);
    1480           18 :           inform (DECL_SOURCE_LOCATION (t), "declared here");
    1481           18 :         }
    1482           54 :       *non_constant_p = true;
    1483              :     }
    1484    241797372 :   ctx->global->destroy_value (t);
    1485              : }
    1486              : 
    1487              : /* This internal flag controls whether we should avoid doing anything during
    1488              :    constexpr evaluation that would cause extra DECL_UID generation, such as
    1489              :    template instantiation and function body copying.  */
    1490              : 
    1491              : static bool uid_sensitive_constexpr_evaluation_value;
    1492              : 
    1493              : /* An internal counter that keeps track of the number of times
    1494              :    uid_sensitive_constexpr_evaluation_p returned true.  */
    1495              : 
    1496              : static unsigned uid_sensitive_constexpr_evaluation_true_counter;
    1497              : 
    1498              : /* The accessor for uid_sensitive_constexpr_evaluation_value which also
    1499              :    increments the corresponding counter.  */
    1500              : 
    1501              : static bool
    1502      9094980 : uid_sensitive_constexpr_evaluation_p ()
    1503              : {
    1504      9007600 :   if (uid_sensitive_constexpr_evaluation_value)
    1505              :     {
    1506       244089 :       ++uid_sensitive_constexpr_evaluation_true_counter;
    1507       244080 :       return true;
    1508              :     }
    1509              :   else
    1510              :     return false;
    1511              : }
    1512              : 
    1513              : /* The default constructor for uid_sensitive_constexpr_evaluation_sentinel
    1514              :    enables the internal flag for uid_sensitive_constexpr_evaluation_p
    1515              :    during the lifetime of the sentinel object.  Upon its destruction, the
    1516              :    previous value of uid_sensitive_constexpr_evaluation_p is restored.  */
    1517              : 
    1518     81518177 : uid_sensitive_constexpr_evaluation_sentinel
    1519              : ::uid_sensitive_constexpr_evaluation_sentinel ()
    1520     81518177 :   : ovr (uid_sensitive_constexpr_evaluation_value, true)
    1521              : {
    1522     81518177 : }
    1523              : 
    1524              : /* The default constructor for uid_sensitive_constexpr_evaluation_checker
    1525              :    records the current number of times that uid_sensitive_constexpr_evaluation_p
    1526              :    has been called and returned true.  */
    1527              : 
    1528   3877033947 : uid_sensitive_constexpr_evaluation_checker
    1529              : ::uid_sensitive_constexpr_evaluation_checker ()
    1530   3877033947 :   : saved_counter (uid_sensitive_constexpr_evaluation_true_counter)
    1531              : {
    1532   3877033947 : }
    1533              : 
    1534              : /* Returns true iff uid_sensitive_constexpr_evaluation_p is true, and
    1535              :    some constexpr evaluation was restricted due to u_s_c_e_p being called
    1536              :    and returning true during the lifetime of this checker object.  */
    1537              : 
    1538              : bool
    1539   2571570293 : uid_sensitive_constexpr_evaluation_checker::evaluation_restricted_p () const
    1540              : {
    1541   2571570293 :   return (uid_sensitive_constexpr_evaluation_value
    1542   2571570293 :           && saved_counter != uid_sensitive_constexpr_evaluation_true_counter);
    1543              : }
    1544              : 
    1545              : 
    1546              : /* A table of all constexpr calls that have been evaluated by the
    1547              :    compiler in this translation unit.  */
    1548              : 
    1549              : static GTY (()) hash_table<constexpr_call_hasher> *constexpr_call_table;
    1550              : 
    1551              : /* Compute a hash value for a constexpr call representation.  */
    1552              : 
    1553              : inline hashval_t
    1554    225615553 : constexpr_call_hasher::hash (constexpr_call *info)
    1555              : {
    1556    225615553 :   return info->hash;
    1557              : }
    1558              : 
    1559              : /* Return true if the objects pointed to by P and Q represent calls
    1560              :    to the same constexpr function with the same arguments.
    1561              :    Otherwise, return false.  */
    1562              : 
    1563              : bool
    1564    234295023 : constexpr_call_hasher::equal (constexpr_call *lhs, constexpr_call *rhs)
    1565              : {
    1566    234295023 :   if (lhs == rhs)
    1567              :     return true;
    1568    234295023 :   if (lhs->hash != rhs->hash)
    1569              :     return false;
    1570     27922129 :   if (!constexpr_fundef_hasher::equal (lhs->fundef, rhs->fundef))
    1571              :     return false;
    1572     27922129 :   return cp_tree_equal (lhs->bindings, rhs->bindings);
    1573              : }
    1574              : 
    1575              : /* Initialize the constexpr call table, if needed.  */
    1576              : 
    1577              : static void
    1578     36959086 : maybe_initialize_constexpr_call_table (void)
    1579              : {
    1580     36959086 :   if (constexpr_call_table == NULL)
    1581        18748 :     constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
    1582     36959086 : }
    1583              : 
    1584              : /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
    1585              :    a function happens to get called recursively, we unshare the callee
    1586              :    function's body and evaluate this unshared copy instead of evaluating the
    1587              :    original body.
    1588              : 
    1589              :    FUNDEF_COPIES_TABLE is a per-function freelist of these unshared function
    1590              :    copies.  The underlying data structure of FUNDEF_COPIES_TABLE is a hash_map
    1591              :    that's keyed off of the original FUNCTION_DECL and whose value is a
    1592              :    TREE_LIST of this function's unused copies awaiting reuse.
    1593              : 
    1594              :    This is not GC-deletable to avoid GC affecting UID generation.  */
    1595              : 
    1596              : static GTY(()) decl_tree_map *fundef_copies_table;
    1597              : 
    1598              : /* Reuse a copy or create a new unshared copy of the function FUN.
    1599              :    Return this copy.  We use a TREE_LIST whose PURPOSE is body, VALUE
    1600              :    is parms, TYPE is result.  */
    1601              : 
    1602              : static tree
    1603     86767136 : get_fundef_copy (constexpr_fundef *fundef)
    1604              : {
    1605     86767136 :   tree copy;
    1606     86767136 :   bool existed;
    1607     86767136 :   tree *slot = &(hash_map_safe_get_or_insert<hm_ggc>
    1608     86767136 :                  (fundef_copies_table, fundef->decl, &existed, 127));
    1609              : 
    1610     86767136 :   if (!existed)
    1611              :     {
    1612              :       /* There is no cached function available, or in use.  We can use
    1613              :          the function directly.  That the slot is now created records
    1614              :          that this function is now in use.  */
    1615      7634079 :       copy = build_tree_list (fundef->body, fundef->parms);
    1616      7634079 :       TREE_TYPE (copy) = fundef->result;
    1617              :     }
    1618     79133057 :   else if (*slot == NULL_TREE)
    1619              :     {
    1620         4438 :       if (uid_sensitive_constexpr_evaluation_p ())
    1621            9 :         return NULL_TREE;
    1622              : 
    1623              :       /* We've already used the function itself, so make a copy.  */
    1624         4429 :       copy = build_tree_list (NULL, NULL);
    1625         4429 :       tree saved_body = DECL_SAVED_TREE (fundef->decl);
    1626         4429 :       tree saved_parms = DECL_ARGUMENTS (fundef->decl);
    1627         4429 :       tree saved_result = DECL_RESULT (fundef->decl);
    1628         4429 :       tree saved_fn = current_function_decl;
    1629         4429 :       DECL_SAVED_TREE (fundef->decl) = fundef->body;
    1630         4429 :       DECL_ARGUMENTS (fundef->decl) = fundef->parms;
    1631         4429 :       DECL_RESULT (fundef->decl) = fundef->result;
    1632         4429 :       current_function_decl = fundef->decl;
    1633         4429 :       TREE_PURPOSE (copy) = copy_fn (fundef->decl, TREE_VALUE (copy),
    1634         4429 :                                      TREE_TYPE (copy));
    1635         4429 :       current_function_decl = saved_fn;
    1636         4429 :       DECL_RESULT (fundef->decl) = saved_result;
    1637         4429 :       DECL_ARGUMENTS (fundef->decl) = saved_parms;
    1638         4429 :       DECL_SAVED_TREE (fundef->decl) = saved_body;
    1639              :     }
    1640              :   else
    1641              :     {
    1642              :       /* We have a cached function available.  */
    1643     79128619 :       copy = *slot;
    1644     79128619 :       *slot = TREE_CHAIN (copy);
    1645              :     }
    1646              : 
    1647              :   return copy;
    1648              : }
    1649              : 
    1650              : /* Save the copy COPY of function FUN for later reuse by
    1651              :    get_fundef_copy().  By construction, there will always be an entry
    1652              :    to find.  */
    1653              : 
    1654              : static void
    1655     86767123 : save_fundef_copy (tree fun, tree copy)
    1656              : {
    1657     86767123 :   tree *slot = fundef_copies_table->get (fun);
    1658     86767123 :   TREE_CHAIN (copy) = *slot;
    1659     86767123 :   *slot = copy;
    1660     86767123 : }
    1661              : 
    1662              : static tree cxx_eval_bare_aggregate (const constexpr_ctx *, tree,
    1663              :                                      value_cat, bool *, bool *, tree *);
    1664              : static tree cxx_fold_indirect_ref (const constexpr_ctx *, location_t, tree, tree,
    1665              :                                    bool *, tree *);
    1666              : static tree find_heap_var_refs (tree *, int *, void *);
    1667              : 
    1668              : /* For exception object EXC if it has class type and usable what () method
    1669              :    which returns cv char * return the xmalloced string literal which it returns
    1670              :    if possible, otherwise return NULL.  */
    1671              : 
    1672              : static char *
    1673          396 : exception_what_str (const constexpr_ctx *ctx, tree exc)
    1674              : {
    1675          396 :   tree type = strip_array_types (TREE_TYPE (exc));
    1676          396 :   if (!CLASS_TYPE_P (type))
    1677              :     return NULL;
    1678          340 :   tree std_exception = lookup_qualified_name (std_node, "exception",
    1679              :                                               LOOK_want::NORMAL, false);
    1680          340 :   if (TREE_CODE (std_exception) != TYPE_DECL)
    1681              :     return NULL;
    1682          334 :   if (!CLASS_TYPE_P (TREE_TYPE (std_exception)))
    1683              :     return NULL;
    1684          334 :   base_kind b_kind;
    1685          334 :   tree binfo = lookup_base (type, TREE_TYPE (std_exception), ba_check, &b_kind,
    1686              :                             tf_none);
    1687          334 :   if (binfo == NULL_TREE || binfo == error_mark_node)
    1688              :     return NULL;
    1689          326 :   if (type != TREE_TYPE (exc))
    1690          288 :     exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
    1691          326 :   tree call
    1692          326 :     = finish_class_member_access_expr (exc, get_identifier ("what"), false,
    1693              :                                        tf_none);
    1694          326 :   if (call == error_mark_node)
    1695              :     return NULL;
    1696          326 :   releasing_vec what_args;
    1697          326 :   call = finish_call_expr (call, &what_args, false, false, tf_none);
    1698          326 :   if (call == error_mark_node)
    1699              :     return NULL;
    1700          326 :   if (TREE_CODE (TREE_TYPE (call)) != POINTER_TYPE
    1701          326 :       || !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
    1702          326 :       || !COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (call)))
    1703          326 :       || !tree_int_cst_equal (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (call))),
    1704          326 :                               TYPE_SIZE_UNIT (char_type_node))
    1705          652 :       || TYPE_PRECISION (TREE_TYPE (TREE_TYPE (call))) != BITS_PER_UNIT)
    1706              :     return NULL;
    1707          326 :   if (!potential_constant_expression (call))
    1708              :     return NULL;
    1709          326 :   bool non_constant_p = false, overflow_p = false;
    1710          326 :   tree jmp_target = NULL;
    1711          326 :   tree ptr = cxx_eval_constant_expression (ctx, call, vc_prvalue,
    1712              :                                            &non_constant_p, &overflow_p,
    1713              :                                            &jmp_target);
    1714          652 :   if (throws (&jmp_target) || non_constant_p)
    1715              :     return NULL;
    1716          326 :   if (reduced_constant_expression_p (ptr))
    1717           42 :     if (const char *msg = c_getstr (ptr))
    1718           42 :       return xstrdup (msg);
    1719          284 :   auto_vec <char, 32> v;
    1720        11754 :   for (unsigned i = 0; i < INT_MAX; ++i)
    1721              :     {
    1722        11754 :       tree t = call;
    1723        11754 :       if (i)
    1724        11470 :         t = build2 (POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, size_int (i));
    1725        11754 :       t = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (t)), t);
    1726        11754 :       non_constant_p = false;
    1727        11754 :       overflow_p = false;
    1728        11754 :       jmp_target = NULL;
    1729        11754 :       tree t2 = cxx_eval_constant_expression (ctx, t, vc_prvalue,
    1730              :                                               &non_constant_p, &overflow_p,
    1731              :                                               &jmp_target);
    1732        11754 :       if (throws (&jmp_target)
    1733        11754 :           || non_constant_p
    1734        11754 :           || !tree_fits_shwi_p (t2))
    1735            0 :         return NULL;
    1736        11754 :       char c = tree_to_shwi (t2);
    1737        11754 :       v.safe_push (c);
    1738        11754 :       if (c == '\0')
    1739              :         break;
    1740              :     }
    1741          568 :   return xstrdup (v.address ());
    1742          610 : }
    1743              : 
    1744              : /* Diagnose constant expression evaluation encountering call to
    1745              :    std::terminate due to exception EXC.  */
    1746              : 
    1747              : static void
    1748           22 : diagnose_std_terminate (location_t loc, const constexpr_ctx *ctx, tree exc)
    1749              : {
    1750           22 :   tree type = strip_array_types (TREE_TYPE (exc));
    1751           22 :   if (char *str = exception_what_str (ctx, exc))
    1752              :     {
    1753            4 :       error_at (loc, "%qs called after throwing an exception of type %qT; "
    1754              :                      "%<what()%>: %qs", "std::terminate", type, str);
    1755            4 :       free (str);
    1756              :     }
    1757              :   else
    1758              :     {
    1759           18 :       if (type != TREE_TYPE (exc))
    1760           18 :         exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
    1761           18 :       bool non_constant_p = false, overflow_p = false;
    1762           18 :       tree jmp_target = NULL;
    1763           18 :       tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
    1764              :                                                &non_constant_p, &overflow_p,
    1765              :                                                &jmp_target);
    1766           18 :       gcc_assert (!throws (&jmp_target) && !non_constant_p);
    1767           18 :       if (reduced_constant_expression_p (val))
    1768           18 :         error_at (loc, "%qs called after throwing an exception %qE",
    1769              :                        "std::terminate", val);
    1770              :       else
    1771            0 :         error_at (loc, "%qs called after throwing an exception of type %qT",
    1772              :                        "std::terminate", type);
    1773              :     }
    1774           22 : }
    1775              : 
    1776              : /* Diagnose constant expression evaluation encountering call to
    1777              :    uncaught exception EXC.  */
    1778              : 
    1779              : static void
    1780          374 : diagnose_uncaught_exception (location_t loc, const constexpr_ctx *ctx, tree exc)
    1781              : {
    1782          374 :   tree type = strip_array_types (TREE_TYPE (exc));
    1783          374 :   if (char *str = exception_what_str (ctx, exc))
    1784              :     {
    1785          322 :       error_at (loc, "uncaught exception of type %qT; %<what()%>: %qs", type, str);
    1786          322 :       free (str);
    1787              :     }
    1788              :   else
    1789              :     {
    1790           52 :       if (type != TREE_TYPE (exc))
    1791           52 :         exc = build4 (ARRAY_REF, type, exc, size_zero_node, NULL, NULL);
    1792           52 :       bool non_constant_p = false, overflow_p = false;
    1793           52 :       tree jmp_target = NULL;
    1794           52 :       tree val = cxx_eval_constant_expression (ctx, exc, vc_prvalue,
    1795              :                                                &non_constant_p, &overflow_p,
    1796              :                                                &jmp_target);
    1797           52 :       gcc_assert (!throws (&jmp_target) && !non_constant_p);
    1798           52 :       if (reduced_constant_expression_p (val))
    1799           50 :         error_at (loc, "uncaught exception %qE", val);
    1800              :       else
    1801            2 :         error_at (loc, "uncaught exception of type %qT", type);
    1802              :     }
    1803          374 : }
    1804              : 
    1805              : /* Kinds of __cxa_* functions (and a few other EH related ones) we handle as
    1806              :    magic constexpr functions for C++26.  */
    1807              : 
    1808              : enum cxa_builtin {
    1809              :   CXA_NONE = 0,
    1810              :   CXA_ALLOCATE_EXCEPTION = 1,
    1811              :   CXA_FREE_EXCEPTION = 2,
    1812              :   CXA_THROW = 3,
    1813              :   CXA_BEGIN_CATCH = 4,
    1814              :   CXA_END_CATCH = 5,
    1815              :   CXA_RETHROW = 6,
    1816              :   CXA_GET_EXCEPTION_PTR = 7,
    1817              :   CXA_BAD_CAST = 8,
    1818              :   CXA_BAD_TYPEID = 9,
    1819              :   CXA_THROW_BAD_ARRAY_NEW_LENGTH = 10,
    1820              :   STD_RETHROW_EXCEPTION = 11,
    1821              :   BUILTIN_EH_PTR_ADJUST_REF = 12,
    1822              :   BUILTIN_UNCAUGHT_EXCEPTIONS = 13,
    1823              :   BUILTIN_CURRENT_EXCEPTION = 14
    1824              : };
    1825              : 
    1826              : /* Return cxa_builtin if FNDECL is a __cxa_* function handled as
    1827              :    magic constexpr function for C++26.  Return CXA_NONE otherwise.  */
    1828              : 
    1829              : static enum cxa_builtin
    1830     36922134 : cxx_cxa_builtin_fn_p (tree fndecl)
    1831              : {
    1832     36922134 :   if (cxx_dialect < cxx26)
    1833              :     return CXA_NONE;
    1834      3662375 :   if (DECL_LANGUAGE (fndecl) != lang_c)
    1835              :     {
    1836      3055422 :       if (!decl_in_std_namespace_p (fndecl))
    1837              :         return CXA_NONE;
    1838      1290489 :       if (id_equal (DECL_NAME (fndecl), "rethrow_exception"))
    1839              :         return STD_RETHROW_EXCEPTION;
    1840      1290447 :       return CXA_NONE;
    1841              :     }
    1842       606953 :   if (!startswith (IDENTIFIER_POINTER (DECL_NAME (fndecl)), "__cxa_"))
    1843              :     return CXA_NONE;
    1844        81315 :   if (id_equal (DECL_NAME (fndecl), "__cxa_allocate_exception"))
    1845              :     return CXA_ALLOCATE_EXCEPTION;
    1846        25415 :   if (id_equal (DECL_NAME (fndecl), "__cxa_free_exception"))
    1847              :     return CXA_FREE_EXCEPTION;
    1848        25413 :   if (id_equal (DECL_NAME (fndecl), "__cxa_throw"))
    1849              :     return CXA_THROW;
    1850        16088 :   if (id_equal (DECL_NAME (fndecl), "__cxa_begin_catch"))
    1851              :     return CXA_BEGIN_CATCH;
    1852         4823 :   if (id_equal (DECL_NAME (fndecl), "__cxa_end_catch"))
    1853              :     return CXA_END_CATCH;
    1854         1080 :   if (id_equal (DECL_NAME (fndecl), "__cxa_rethrow"))
    1855              :     return CXA_RETHROW;
    1856          974 :   if (id_equal (DECL_NAME (fndecl), "__cxa_get_exception_ptr"))
    1857              :     return CXA_GET_EXCEPTION_PTR;
    1858          930 :   if (id_equal (DECL_NAME (fndecl), "__cxa_bad_cast"))
    1859              :     return CXA_BAD_CAST;
    1860          634 :   if (id_equal (DECL_NAME (fndecl), "__cxa_bad_typeid"))
    1861              :     return CXA_BAD_TYPEID;
    1862          621 :   if (id_equal (DECL_NAME (fndecl), "__cxa_throw_bad_array_new_length"))
    1863           33 :     return CXA_THROW_BAD_ARRAY_NEW_LENGTH;
    1864              :   return CXA_NONE;
    1865              : }
    1866              : 
    1867              : /* Helper function for cxx_eval_cxa_builtin_fn.
    1868              :    Check if ARG is a valid first argument of __cxa_throw or
    1869              :    __cxa_free_exception or __builtin_eh_ptr_adjust_ref.  Return NULL_TREE if
    1870              :    not, otherwise return the artificial __cxa_allocate_exception allocated
    1871              :    VAR_DECL.  FREE_EXC is true for __cxa_free_exception, false otherwise.  */
    1872              : 
    1873              : static tree
    1874         1916 : cxa_check_throw_arg (tree arg, bool free_exc)
    1875              : {
    1876         1916 :   STRIP_NOPS (arg);
    1877         1916 :   if (TREE_CODE (arg) != ADDR_EXPR)
    1878              :     return NULL_TREE;
    1879         1916 :   arg = TREE_OPERAND (arg, 0);
    1880         1916 :   if (!VAR_P (arg)
    1881         1916 :       || !DECL_ARTIFICIAL (arg)
    1882         1916 :       || ((!free_exc || DECL_NAME (arg) != heap_uninit_identifier)
    1883         1916 :           && DECL_NAME (arg) != heap_identifier)
    1884         3832 :       || !DECL_LANG_SPECIFIC (arg))
    1885            0 :     return NULL_TREE;
    1886              :   return arg;
    1887              : }
    1888              : 
    1889              : /* Helper function for cxx_eval_cxa_builtin_fn.
    1890              :    "Allocate" on the constexpr heap an exception object of TYPE
    1891              :    with REFCOUNT.  */
    1892              : 
    1893              : static tree
    1894        17900 : cxa_allocate_exception (location_t loc, const constexpr_ctx *ctx, tree type,
    1895              :                         tree refcount)
    1896              : {
    1897        17900 :   tree var = build_decl (loc, VAR_DECL, heap_uninit_identifier, type);
    1898        17900 :   DECL_ARTIFICIAL (var) = 1;
    1899        17900 :   retrofit_lang_decl (var);
    1900        17900 :   DECL_EXCEPTION_REFCOUNT (var) = refcount;
    1901        17900 :   ctx->global->heap_vars.safe_push (var);
    1902        17900 :   return var;
    1903              : }
    1904              : 
    1905              : /* Evaluate various __cxa_* calls as magic constexpr builtins for
    1906              :    C++26 constexpr exception support (P3068R5).  */
    1907              : 
    1908              : static tree
    1909        30350 : cxx_eval_cxa_builtin_fn (const constexpr_ctx *ctx, tree call,
    1910              :                          enum cxa_builtin kind, tree fndecl,
    1911              :                          bool *non_constant_p, bool *overflow_p,
    1912              :                          tree *jump_target)
    1913              : {
    1914        30350 :   int nargs = call_expr_nargs (call);
    1915        30350 :   location_t loc = cp_expr_loc_or_input_loc (call);
    1916        30350 :   tree args[4], arg;
    1917        30350 :   if (nargs > 4)
    1918              :     {
    1919            0 :     invalid_nargs:
    1920            0 :       if (!ctx->quiet)
    1921            0 :         error_at (loc, "call to %qD function with incorrect "
    1922              :                   "number of arguments", fndecl);
    1923            0 :       *non_constant_p = true;
    1924            0 :       return call;
    1925              :     }
    1926        30350 :   if ((kind == CXA_BEGIN_CATCH || kind == CXA_GET_EXCEPTION_PTR)
    1927         7542 :       && nargs == 1
    1928         7542 :       && (arg = CALL_EXPR_ARG (call, 0))
    1929         7542 :       && TREE_CODE (arg) == CALL_EXPR
    1930         7542 :       && call_expr_nargs (arg) == 1
    1931        37892 :       && integer_zerop (CALL_EXPR_ARG (arg, 0)))
    1932         7542 :     if (tree fun = get_function_named_in_call (arg))
    1933         7542 :       if (fndecl_built_in_p (fun, BUILT_IN_EH_POINTER))
    1934              :         {
    1935         7542 :           if (ctx->global->caught_exceptions.length () < 2)
    1936              :             {
    1937         3767 :             no_caught_exceptions:
    1938         3767 :               if (!ctx->quiet)
    1939            0 :                 error_at (loc, "%qD called with no caught exceptions pending",
    1940              :                           fndecl);
    1941         3767 :               *non_constant_p = true;
    1942         3767 :               return call;
    1943              :             }
    1944              :           /* Both __cxa_get_exception_ptr (__builtin_eh_pointer (0))
    1945              :              and __cxa_begin_catch (__builtin_eh_pointer (0)) calls expect
    1946              :              ctx->global->caught_exceptions vector to end with
    1947              :              __cxa_allocate_exception created artificial VAR_DECL (the
    1948              :              exception object) followed by handler type, pushed by TRY_BLOCK
    1949              :              evaluation.  The only difference between the functions is that
    1950              :              __cxa_begin_catch pops the handler type from the vector and keeps
    1951              :              the VAR_DECL last and decreases uncaught_exceptions.  The
    1952              :              VAR_DECL after __cxa_begin_catch serves as the current exception
    1953              :              and is then popped in __cxa_end_catch evaluation.  */
    1954         3775 :           tree handler_type = ctx->global->caught_exceptions.last ();
    1955         3775 :           if (handler_type && (VAR_P (handler_type)
    1956         3693 :                                || TREE_CODE (handler_type) == TREE_LIST))
    1957            0 :             goto no_caught_exceptions;
    1958         3775 :           unsigned idx = ctx->global->caught_exceptions.length () - 2;
    1959         3775 :           arg = ctx->global->caught_exceptions[idx];
    1960         3775 :           if (TREE_CODE (arg) == TREE_LIST)
    1961            0 :             arg = TREE_VALUE (arg);
    1962         3775 :           gcc_assert (VAR_P (arg));
    1963         3775 :           if (kind == CXA_BEGIN_CATCH)
    1964              :             {
    1965         3747 :               ctx->global->caught_exceptions.pop ();
    1966         3747 :               --ctx->global->uncaught_exceptions;
    1967              :             }
    1968         3775 :           if (handler_type == NULL_TREE)
    1969              :             /* Used for catch (...).  Just return void.  */
    1970           82 :             return void_node;
    1971         3693 :           else if (POINTER_TYPE_P (handler_type))
    1972              :             {
    1973              :               /* Used for catch of a pointer.  */
    1974           66 :               if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
    1975           66 :                 arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
    1976              :                               size_zero_node, NULL_TREE, NULL_TREE);
    1977           66 :               arg = cp_convert (handler_type, arg,
    1978           66 :                                 ctx->quiet ? tf_none : tf_warning_or_error);
    1979           66 :               if (arg == error_mark_node)
    1980              :                 {
    1981            0 :                   *non_constant_p = true;
    1982            0 :                   return call;
    1983              :                 }
    1984              :             }
    1985              :           else
    1986              :             {
    1987              :               /* Used for catch of a non-pointer type.  */
    1988         3627 :               tree exc_type = strip_array_types (TREE_TYPE (arg));
    1989         3607 :               if (TYPE_PTRMEM_P (handler_type)
    1990         3673 :                   && !same_type_ignoring_top_level_qualifiers_p
    1991           46 :                                 (handler_type, exc_type))
    1992              :                 {
    1993           46 :                   if (TREE_CODE (TREE_TYPE (arg)) == ARRAY_TYPE)
    1994           46 :                     arg = build4 (ARRAY_REF, TREE_TYPE (TREE_TYPE (arg)), arg,
    1995              :                                   size_zero_node, NULL_TREE, NULL_TREE);
    1996           46 :                   arg = cp_convert (handler_type, arg,
    1997           46 :                                     ctx->quiet ? tf_none
    1998              :                                     : tf_warning_or_error);
    1999           46 :                   if (arg == error_mark_node)
    2000              :                     {
    2001            0 :                       *non_constant_p = true;
    2002            0 :                       return call;
    2003              :                     }
    2004           46 :                   tree var = build_decl (loc, VAR_DECL, heap_identifier,
    2005           46 :                                          handler_type);
    2006           46 :                   DECL_ARTIFICIAL (var) = 1;
    2007           46 :                   ctx->global->heap_vars.safe_push (var);
    2008           46 :                   ctx->global->put_value (var, NULL_TREE);
    2009           46 :                   tree init = build2_loc (loc, INIT_EXPR, handler_type,
    2010              :                                           var, arg);
    2011           46 :                   arg = ctx->global->caught_exceptions[idx];
    2012           46 :                   if (TREE_CODE (arg) == TREE_LIST)
    2013              :                     {
    2014            0 :                       DECL_CHAIN (var) = TREE_PURPOSE (arg);
    2015            0 :                       TREE_PURPOSE (arg) = var;
    2016              :                     }
    2017              :                   else
    2018           46 :                     ctx->global->caught_exceptions[idx]
    2019           92 :                       = build_tree_list (var, arg);
    2020           46 :                   arg = cp_build_addr_expr (var, tf_none);
    2021           46 :                   arg = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (arg),
    2022              :                                     init, arg);
    2023              :                 }
    2024              :               else
    2025              :                 {
    2026         3581 :                   tree exc_ptr_type = build_pointer_type (exc_type);
    2027         3581 :                   arg = build_fold_addr_expr_with_type (arg, exc_ptr_type);
    2028         3581 :                   if (CLASS_TYPE_P (handler_type))
    2029              :                     {
    2030         3491 :                       tree ptr_type = build_pointer_type (handler_type);
    2031         3491 :                       arg = cp_convert (ptr_type, arg,
    2032         3491 :                                         ctx->quiet ? tf_none
    2033              :                                         : tf_warning_or_error);
    2034         3491 :                       if (arg == error_mark_node)
    2035              :                         {
    2036            0 :                           *non_constant_p = true;
    2037            0 :                           return call;
    2038              :                         }
    2039              :                     }
    2040              :                 }
    2041              :             }
    2042         3693 :           return cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    2043              :                                                non_constant_p, overflow_p,
    2044         3693 :                                                jump_target);
    2045              :         }
    2046        42947 :   for (int i = 0; i < nargs; ++i)
    2047              :     {
    2048        20139 :       args[i] = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (call, i),
    2049              :                                               vc_prvalue, non_constant_p,
    2050              :                                               overflow_p, jump_target);
    2051        20139 :       if (*non_constant_p)
    2052              :         return call;
    2053        20139 :       if (*jump_target)
    2054              :         return NULL_TREE;
    2055              :     }
    2056        22808 :   switch (kind)
    2057              :     {
    2058        14601 :     case CXA_ALLOCATE_EXCEPTION:
    2059        14601 :       if (nargs != 1)
    2060            0 :         goto invalid_nargs;
    2061        14601 :       if (!tree_fits_uhwi_p (args[0]))
    2062              :         {
    2063            0 :           if (!ctx->quiet)
    2064            0 :             error_at (loc, "cannot allocate exception: size not constant");
    2065            0 :           *non_constant_p = true;
    2066            0 :           return call;
    2067              :         }
    2068              :       else
    2069              :         {
    2070        29202 :           tree type = build_array_type_nelts (char_type_node,
    2071        14601 :                                               tree_to_uhwi (args[0]));
    2072        14601 :           tree var = cxa_allocate_exception (loc, ctx, type, size_zero_node);
    2073        14601 :           ctx->global->put_value (var, NULL_TREE);
    2074        14601 :           return fold_convert (ptr_type_node, build_address (var));
    2075              :         }
    2076            2 :     case CXA_FREE_EXCEPTION:
    2077            2 :       if (nargs != 1)
    2078            0 :         goto invalid_nargs;
    2079            2 :       arg = cxa_check_throw_arg (args[0], true);
    2080            2 :       if (arg == NULL_TREE)
    2081              :         {
    2082            0 :         invalid_ptr:
    2083            0 :           if (!ctx->quiet)
    2084            0 :             error_at (loc, "first argument to %qD function not result of "
    2085              :                       "%<__cxa_allocate_exception%>", fndecl);
    2086            0 :           *non_constant_p = true;
    2087            0 :           return call;
    2088              :         }
    2089            2 :       DECL_NAME (arg) = heap_deleted_identifier;
    2090            2 :       ctx->global->destroy_value (arg);
    2091            2 :       ctx->global->heap_dealloc_count++;
    2092            2 :       return void_node;
    2093         1748 :     case CXA_THROW:
    2094         1748 :       if (nargs != 3)
    2095            0 :         goto invalid_nargs;
    2096         1748 :       arg = cxa_check_throw_arg (args[0], false);
    2097         1748 :       if (arg == NULL_TREE)
    2098            0 :         goto invalid_ptr;
    2099         1748 :       DECL_EXCEPTION_REFCOUNT (arg)
    2100         1748 :         = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
    2101              :                       size_one_node);
    2102         1748 :       ++ctx->global->uncaught_exceptions;
    2103         1748 :       *jump_target = arg;
    2104         1748 :       return void_node;
    2105            0 :     case CXA_BEGIN_CATCH:
    2106            0 :     case CXA_GET_EXCEPTION_PTR:
    2107            0 :       goto invalid_nargs;
    2108         3743 :     case CXA_END_CATCH:
    2109         3743 :       if (nargs != 0)
    2110            0 :         goto invalid_nargs;
    2111         3743 :       if (ctx->global->caught_exceptions.is_empty ())
    2112              :         {
    2113            0 :         no_active_exc:
    2114            0 :           if (!ctx->quiet)
    2115            0 :             error_at (loc, "%qD called with no caught exceptions active",
    2116              :                       fndecl);
    2117            0 :           *non_constant_p = true;
    2118            0 :           return call;
    2119              :         }
    2120              :       else
    2121              :         {
    2122         3743 :           arg = ctx->global->caught_exceptions.pop ();
    2123         3743 :           if (arg == NULL_TREE
    2124         3743 :               || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
    2125            0 :             goto no_active_exc;
    2126         3743 :           if (TREE_CODE (arg) == TREE_LIST)
    2127              :             {
    2128           92 :               for (tree aux = TREE_PURPOSE (arg); aux; aux = DECL_CHAIN (aux))
    2129              :                 {
    2130           46 :                   DECL_NAME (aux) = heap_deleted_identifier;
    2131           46 :                   ctx->global->destroy_value (aux);
    2132           46 :                   ctx->global->heap_dealloc_count++;
    2133              :                 }
    2134           46 :               arg = TREE_VALUE (arg);
    2135              :             }
    2136         3743 :           DECL_CHAIN (arg) = NULL_TREE;
    2137         3821 :         free_except:
    2138         3821 :           DECL_EXCEPTION_REFCOUNT (arg)
    2139         3821 :             = size_binop (MINUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
    2140              :                           size_one_node);
    2141         3821 :           if (integer_zerop (DECL_EXCEPTION_REFCOUNT (arg)))
    2142              :             {
    2143         3611 :               if (type_build_dtor_call (TREE_TYPE (arg)))
    2144              :                 {
    2145              :                   /* So that we don't complain about out-of-consteval use.  */
    2146         3393 :                   temp_override<tree> ovr (current_function_decl);
    2147         3393 :                   if (ctx->call && ctx->call->fundef)
    2148         3393 :                     current_function_decl = ctx->call->fundef->decl;
    2149         3393 :                   tree cleanup
    2150         3415 :                     = cxx_maybe_build_cleanup (arg, (ctx->quiet ? tf_none
    2151              :                                                      : tf_warning_or_error));
    2152         3393 :                   if (cleanup == error_mark_node)
    2153            0 :                     *non_constant_p = true;
    2154         3393 :                   tree jmp_target = NULL_TREE;
    2155         3393 :                   cxx_eval_constant_expression (ctx, cleanup, vc_discard,
    2156              :                                                 non_constant_p, overflow_p,
    2157              :                                                 &jmp_target);
    2158         3393 :                   if (throws (&jmp_target))
    2159            0 :                     *jump_target = jmp_target;
    2160         3393 :                 }
    2161         3611 :               DECL_NAME (arg) = heap_deleted_identifier;
    2162         3611 :               ctx->global->destroy_value (arg);
    2163         3611 :               ctx->global->heap_dealloc_count++;
    2164              :             }
    2165              :         }
    2166         3821 :       return void_node;
    2167           98 :     case CXA_RETHROW:
    2168           98 :       if (nargs != 0)
    2169            0 :         goto invalid_nargs;
    2170           98 :       unsigned idx;
    2171          196 :       FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
    2172           82 :         if (arg == NULL_TREE || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
    2173            0 :           --idx;
    2174              :         else
    2175              :           break;
    2176           98 :       if (arg == NULL_TREE)
    2177              :         {
    2178           16 :           if (!ctx->quiet)
    2179            4 :             error_at (loc, "%qD called with no caught exceptions active",
    2180              :                       fndecl);
    2181           16 :           *non_constant_p = true;
    2182           16 :           return call;
    2183              :         }
    2184           82 :       if (TREE_CODE (arg) == TREE_LIST)
    2185            0 :         arg = TREE_VALUE (arg);
    2186           82 :       DECL_EXCEPTION_REFCOUNT (arg)
    2187           82 :         = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
    2188           82 :       ++ctx->global->uncaught_exceptions;
    2189              :       /* Don't cache calls which rethrow, they depend on the current
    2190              :          exception which might be caught in the caller.  */
    2191           82 :       ctx->global->state_dependent = true;
    2192           82 :       *jump_target = arg;
    2193           82 :       return void_node;
    2194          163 :     case CXA_BAD_CAST:
    2195          163 :     case CXA_BAD_TYPEID:
    2196          163 :     case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
    2197          163 :       if (nargs != 0)
    2198            0 :         goto invalid_nargs;
    2199              :       else
    2200              :         {
    2201          163 :           tree name;
    2202          163 :           switch (kind)
    2203              :             {
    2204          123 :             case CXA_BAD_CAST:
    2205          123 :               name = get_identifier ("bad_cast");
    2206          123 :               break;
    2207            7 :             case CXA_BAD_TYPEID:
    2208            7 :               name = get_identifier ("bad_typeid");
    2209            7 :               break;
    2210           33 :             case CXA_THROW_BAD_ARRAY_NEW_LENGTH:
    2211           33 :               name = get_identifier ("bad_array_new_length");
    2212           33 :               break;
    2213              :             default:
    2214              :               gcc_unreachable ();
    2215              :             }
    2216          163 :           tree decl = lookup_qualified_name (std_node, name);
    2217          163 :           if (TREE_CODE (decl) != TYPE_DECL
    2218          135 :               || !CLASS_TYPE_P (TREE_TYPE (decl))
    2219          298 :               || !type_build_ctor_call (TREE_TYPE (decl)))
    2220              :             {
    2221           28 :               if (!ctx->quiet)
    2222            8 :                 error_at (loc, "%qD called without %<std::%D%> being defined",
    2223              :                           fndecl, name);
    2224           28 :               *non_constant_p = true;
    2225           28 :               return call;
    2226              :             }
    2227          135 :           tree type = TREE_TYPE (decl);
    2228          135 :           tree var = cxa_allocate_exception (loc, ctx, type, size_one_node);
    2229          135 :           tree ctor
    2230          135 :             = build_special_member_call (var, complete_ctor_identifier,
    2231              :                                          NULL, type, LOOKUP_NORMAL,
    2232          135 :                                          ctx->quiet ? tf_none
    2233              :                                          : tf_warning_or_error);
    2234          135 :           if (ctor == error_mark_node)
    2235              :             {
    2236            0 :               *non_constant_p = true;
    2237            0 :               return call;
    2238              :             }
    2239          135 :           if (TREE_CONSTANT (ctor))
    2240            0 :             ctx->global->put_value (var, ctor);
    2241              :           else
    2242              :             {
    2243          135 :               ctx->global->put_value (var, NULL_TREE);
    2244          135 :               cxx_eval_constant_expression (ctx, ctor, vc_discard,
    2245              :                                             non_constant_p, overflow_p,
    2246              :                                             jump_target);
    2247          135 :               if (*non_constant_p)
    2248              :                 return call;
    2249          135 :               if (throws (jump_target))
    2250              :                 return NULL_TREE;
    2251              :             }
    2252          135 :           ++ctx->global->uncaught_exceptions;
    2253          135 :           *jump_target = var;
    2254              :         }
    2255          135 :       return void_node;
    2256           82 :     case BUILTIN_UNCAUGHT_EXCEPTIONS:
    2257           82 :       if (nargs != 0)
    2258            0 :         goto invalid_nargs;
    2259              :       /* Similarly to __builtin_is_constant_evaluated (), we don't
    2260              :          want to give a definite answer during mce_unknown evaluation,
    2261              :          because that might prevent evaluation later on when some
    2262              :          exceptions might be uncaught.  But unlike that, we don't
    2263              :          want to constant fold it even during cp_fold, because at runtime
    2264              :          std::uncaught_exceptions () might still be non-zero.  */
    2265           82 :       if (ctx->manifestly_const_eval != mce_true)
    2266              :         {
    2267           46 :           *non_constant_p = true;
    2268           46 :           return call;
    2269              :         }
    2270              :       /* Don't cache calls which call __builtin_uncaught_exceptions (),
    2271              :          they depend on the current uncaught exceptions which might
    2272              :          be the state from their caller.  */
    2273           36 :       ctx->global->state_dependent = true;
    2274           36 :       return build_int_cst (integer_type_node,
    2275           36 :                             ctx->global->uncaught_exceptions);
    2276         2205 :     case BUILTIN_CURRENT_EXCEPTION:
    2277         2205 :       if (nargs != 0)
    2278            0 :         goto invalid_nargs;
    2279              :       else
    2280              :         {
    2281         2205 :           tree name = get_identifier ("exception_ptr");
    2282         2205 :           tree decl = lookup_qualified_name (std_node, name);
    2283         2205 :           tree fld;
    2284         2205 :           if (TREE_CODE (decl) != TYPE_DECL
    2285         2205 :               || !CLASS_TYPE_P (TREE_TYPE (decl))
    2286         2205 :               || !COMPLETE_TYPE_P (TREE_TYPE (decl))
    2287         2205 :               || !(fld = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (decl))))
    2288         2205 :               || DECL_ARTIFICIAL (fld)
    2289         2205 :               || TREE_CODE (TREE_TYPE (fld)) != POINTER_TYPE
    2290         2205 :               || next_aggregate_field (DECL_CHAIN (fld))
    2291         4410 :               || !tree_int_cst_equal (TYPE_SIZE (TREE_TYPE (decl)),
    2292         2205 :                                       TYPE_SIZE (TREE_TYPE (fld))))
    2293              :             {
    2294            0 :               if (!ctx->quiet)
    2295            0 :                 error_at (loc, "%qD called without supportable %qs",
    2296              :                           fndecl, "std::exception_ptr");
    2297            0 :               *non_constant_p = true;
    2298            0 :               return call;
    2299              :             }
    2300         4410 :           FOR_EACH_VEC_ELT_REVERSE (ctx->global->caught_exceptions, idx, arg)
    2301           42 :             if (arg == NULL_TREE
    2302           42 :                 || (!VAR_P (arg) && TREE_CODE (arg) != TREE_LIST))
    2303            0 :               --idx;
    2304              :             else
    2305              :               break;
    2306              :           /* Similarly to __builtin_is_constant_evaluated (), we don't
    2307              :              want to give a definite answer during mce_unknown evaluation,
    2308              :              because that might prevent evaluation later on when some
    2309              :              exceptions might be current.  But unlike that, we don't
    2310              :              want to constant fold it to null even during cp_fold, because
    2311              :              at runtime std::current_exception () might still be non-null.  */
    2312         2205 :           if (ctx->manifestly_const_eval != mce_true && arg == NULL_TREE)
    2313              :             {
    2314         2151 :               *non_constant_p = true;
    2315         2151 :               return call;
    2316              :             }
    2317           54 :           if (arg == NULL_TREE)
    2318           12 :             arg = build_zero_cst (TREE_TYPE (fld));
    2319              :           else
    2320              :             {
    2321           42 :               if (TREE_CODE (arg) == TREE_LIST)
    2322            0 :                 arg = TREE_VALUE (arg);
    2323           42 :               DECL_EXCEPTION_REFCOUNT (arg)
    2324           42 :                 = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
    2325              :                               size_one_node);
    2326           42 :               arg = fold_convert (ptr_type_node, build_address (arg));
    2327              :             }
    2328              :           /* Don't cache calls which call __builtin_current_exception (),
    2329              :              they depend on the current exception which might be caught
    2330              :              in the caller.  */
    2331           54 :           ctx->global->state_dependent = true;
    2332           54 :           return build_constructor_single (TREE_TYPE (decl), fld, arg);
    2333              :         }
    2334           40 :     case STD_RETHROW_EXCEPTION:
    2335           40 :       if (nargs != 1)
    2336            0 :         goto invalid_nargs;
    2337           40 :       if (TYPE_REF_P (TREE_TYPE (args[0])))
    2338              :         {
    2339           40 :           arg = args[0];
    2340           40 :           STRIP_NOPS (arg);
    2341           40 :           if (TREE_CODE (arg) == ADDR_EXPR)
    2342              :             {
    2343           40 :               args[0]
    2344           40 :                 = cxx_eval_constant_expression (ctx, TREE_OPERAND (arg, 0),
    2345              :                                                 vc_prvalue, non_constant_p,
    2346              :                                                 overflow_p, jump_target);
    2347           40 :               if (*non_constant_p)
    2348              :                 return call;
    2349           40 :               if (*jump_target)
    2350              :                 return NULL_TREE;
    2351              :             }
    2352              :         }
    2353           40 :       if (TREE_CODE (args[0]) != CONSTRUCTOR
    2354           40 :           || CONSTRUCTOR_NELTS (args[0]) != 1)
    2355              :         {
    2356            0 :         invalid_std_rethrow:
    2357            0 :           if (!ctx->quiet)
    2358            0 :             error_at (loc, "%qD called with unexpected %qs argument",
    2359              :                       fndecl, "std::exception_ptr");
    2360            0 :           *non_constant_p = true;
    2361            0 :           return void_node;
    2362              :         }
    2363           40 :       arg = cxa_check_throw_arg (CONSTRUCTOR_ELT (args[0], 0)->value, false);
    2364           40 :       if (arg == NULL_TREE)
    2365            0 :         goto invalid_std_rethrow;
    2366           40 :       DECL_EXCEPTION_REFCOUNT (arg)
    2367           40 :         = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg), size_one_node);
    2368           40 :       ++ctx->global->uncaught_exceptions;
    2369           40 :       *jump_target = arg;
    2370           40 :       return void_node;
    2371          126 :     case BUILTIN_EH_PTR_ADJUST_REF:
    2372          126 :       if (nargs != 2)
    2373            0 :         goto invalid_nargs;
    2374          126 :       arg = cxa_check_throw_arg (args[0], false);
    2375          126 :       if (arg == NULL_TREE)
    2376            0 :         goto invalid_ptr;
    2377          126 :       if (integer_onep (args[1]))
    2378           48 :         DECL_EXCEPTION_REFCOUNT (arg)
    2379           96 :           = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (arg),
    2380              :                         size_one_node);
    2381           78 :       else if (integer_minus_onep (args[1]))
    2382           78 :         goto free_except;
    2383              :       else
    2384              :         {
    2385            0 :           if (!ctx->quiet)
    2386            0 :             error_at (loc, "%qD called with second argument "
    2387              :                       "other than 1 or -1", fndecl);
    2388            0 :           *non_constant_p = true;
    2389              :         }
    2390           48 :       return void_node;
    2391            0 :     default:
    2392            0 :       gcc_unreachable ();
    2393              :     }
    2394              : }
    2395              : 
    2396              : /* Variables and functions to manage constexpr call expansion context.
    2397              :    These do not need to be marked for PCH or GC.  */
    2398              : 
    2399              : /* FIXME remember and print actual constant arguments.  */
    2400              : static vec<tree> call_stack;
    2401              : static int call_stack_tick;
    2402              : static int last_cx_error_tick;
    2403              : 
    2404              : /* Attempt to evaluate T which represents a call to __builtin_constexpr_diag.
    2405              :    The arguments should be an integer (0 for inform, 1 for warning, 2 for
    2406              :    error) optionally with 16 ored in if it should use caller's caller location
    2407              :    instead of caller's location and 2 messages which are either a pointer to
    2408              :    a STRING_CST or class with data () and size () member functions like
    2409              :    string_view or u8string_view.  The first message is a tag, with "" passed
    2410              :    for no tag, data () should return const char *, the tag should only contain
    2411              :    alphanumeric letters or underscores.  The second message is the diagnostic
    2412              :    message, data () can be either const char * or const char8_t *.  size ()
    2413              :    should return the corresponding length of the strings in bytes as an
    2414              :    integer.  */
    2415              : 
    2416              : static tree
    2417          210 : cxx_eval_constexpr_diag (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
    2418              :                          bool *overflow_p, tree *jump_target)
    2419              : {
    2420          210 :   location_t loc = EXPR_LOCATION (t);
    2421          210 :   if (call_expr_nargs (t) != 3)
    2422              :     {
    2423           12 :       if (!ctx->quiet)
    2424           12 :         error_at (loc, "wrong number of arguments to %qs call",
    2425              :                   "__builtin_constexpr_diag");
    2426           12 :       *non_constant_p = true;
    2427           12 :       return t;
    2428              :     }
    2429              :   tree args[3];
    2430          792 :   for (int i = 0; i < 3; ++i)
    2431              :     {
    2432          594 :       tree arg = convert_from_reference (CALL_EXPR_ARG (t, i));
    2433          594 :       arg = cxx_eval_constant_expression (ctx, arg,
    2434              :                                           (i == 0
    2435          534 :                                            || POINTER_TYPE_P (TREE_TYPE (arg)))
    2436          990 :                                           ? vc_prvalue : vc_glvalue,
    2437              :                                           non_constant_p, overflow_p,
    2438              :                                           jump_target);
    2439          594 :       if (*jump_target)
    2440              :         return NULL_TREE;
    2441          594 :       if (*non_constant_p)
    2442              :         return t;
    2443          594 :       args[i] = arg;
    2444              :     }
    2445          396 :   if (TREE_CODE (args[0]) != INTEGER_CST
    2446          198 :       || wi::to_widest (args[0]) < 0
    2447          194 :       || wi::to_widest (args[0]) > 18
    2448          396 :       || (wi::to_widest (args[0]) & 15) > 2)
    2449              :     {
    2450            8 :       if (!ctx->quiet)
    2451            8 :         error_at (loc, "first %qs call argument should be 0, 1, 2, 16, 17 or "
    2452              :                   "18", "__builtin_constexpr_diag");
    2453            8 :       *non_constant_p = true;
    2454            8 :       return t;
    2455              :     }
    2456          190 :   const char *msgs[2] = {};
    2457          190 :   int lens[3] = {};
    2458          950 :   cexpr_str cstrs[2];
    2459          478 :   diagnostics::kind kind = diagnostics::kind::error;
    2460          478 :   for (int i = 1; i < 3; ++i)
    2461              :     {
    2462          344 :       tree arg = args[i];
    2463          344 :       if (POINTER_TYPE_P (TREE_TYPE (arg)))
    2464              :         {
    2465          206 :           tree str = arg;
    2466          206 :           STRIP_NOPS (str);
    2467          206 :           if (TREE_CODE (str) == ADDR_EXPR
    2468          206 :               && TREE_CODE (TREE_OPERAND (str, 0)) == STRING_CST)
    2469              :             {
    2470          206 :               str = TREE_OPERAND (str, 0);
    2471          206 :               tree eltype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (str)));
    2472          206 :               if (eltype == char_type_node
    2473           24 :                   || (i == 2 && eltype == char8_type_node))
    2474          344 :                 arg = str;
    2475              :             }
    2476              :         }
    2477          344 :       cstrs[i - 1].message = arg;
    2478          344 :       if (!cstrs[i - 1].type_check (loc, i == 2))
    2479              :         {
    2480           40 :           *non_constant_p = true;
    2481           40 :           return t;
    2482              :         }
    2483          304 :       if (!cstrs[i - 1].extract (loc, msgs[i - 1], lens[i - 1], ctx,
    2484              :                                  non_constant_p, overflow_p, jump_target))
    2485              :         {
    2486           16 :           if (*jump_target)
    2487              :             return NULL_TREE;
    2488           16 :           *non_constant_p = true;
    2489           16 :           return t;
    2490              :         }
    2491              :     }
    2492          134 :   if (msgs[0])
    2493              :     {
    2494          726 :       for (int i = 0; i < lens[0]; ++i)
    2495          596 :         if (!ISALNUM (msgs[0][i]) && msgs[0][i] != '_')
    2496              :           {
    2497            4 :             if (!ctx->quiet)
    2498            4 :               error_at (loc, "%qs tag string contains %qc character other than"
    2499              :                              " letters, digits or %<_%>",
    2500              :                         "__builtin_constexpr_diag", msgs[0][i]);
    2501            4 :             *non_constant_p = true;
    2502            4 :             return t;
    2503              :           }
    2504              :     }
    2505          130 :   if (ctx->manifestly_const_eval == mce_unknown)
    2506              :     {
    2507            0 :       *non_constant_p = true;
    2508            0 :       return t;
    2509              :     }
    2510          130 :   int arg0 = tree_to_uhwi (args[0]);
    2511          130 :   if (arg0 & 16)
    2512              :     {
    2513           32 :       arg0 &= 15;
    2514           32 :       if (!call_stack.is_empty ())
    2515              :         {
    2516           32 :           tree call = call_stack.last ();
    2517           32 :           if (EXPR_HAS_LOCATION (call))
    2518           32 :             loc = EXPR_LOCATION (call);
    2519              :         }
    2520              :     }
    2521          130 :   if (arg0 == 0)
    2522              :     kind = diagnostics::kind::note;
    2523           82 :   else if (arg0 == 1)
    2524           36 :     kind = diagnostics::kind::warning;
    2525          130 :   if (lens[0])
    2526              :     {
    2527           88 :       const char *color = "error";
    2528           88 :       if (kind == diagnostics::kind::note)
    2529              :         color = "note";
    2530           60 :       else if (kind == diagnostics::kind::warning)
    2531           32 :         color = "warning";
    2532           88 :       emit_diagnostic (kind, loc, 0, "constexpr message: %.*s [%r%.*s%R]",
    2533              :                        lens[1], msgs[1], color, lens[0], msgs[0]);
    2534              :     }
    2535              :   else
    2536           42 :     emit_diagnostic (kind, loc, 0, "constexpr message: %.*s",
    2537              :                      lens[1], msgs[1]);
    2538          130 :   return void_node;
    2539          570 : }
    2540              : 
    2541              : static tree eval_and_check_array_index (const constexpr_ctx *, tree, bool,
    2542              :                                         bool *, bool *, tree *);
    2543              : 
    2544              : /* Helper function for cxx_eval_is_within_lifetime and
    2545              :    cxx_eval_start_lifetime.  Check if ARG is within lifetime.  */
    2546              : 
    2547              : static tree
    2548         4368 : is_within_lifetime (location_t loc, const constexpr_ctx *ctx, tree t, tree fun,
    2549              :                     tree arg, bool *non_constant_p, bool *overflow_p,
    2550              :                     tree *jump_target)
    2551              : {
    2552         4368 :   auto_vec <tree, 4> refs;
    2553         4368 :   tree obj;
    2554         9889 :   for (obj = arg; ; obj = TREE_OPERAND (obj, 0))
    2555              :     {
    2556         9889 :       switch (TREE_CODE (obj))
    2557              :         {
    2558         5521 :         case COMPONENT_REF:
    2559         5521 :         case ARRAY_REF:
    2560         5521 :         case REALPART_EXPR:
    2561         5521 :         case IMAGPART_EXPR:
    2562         5521 :           refs.safe_push (obj);
    2563         5521 :           continue;
    2564         4368 :         default:
    2565         4368 :           break;
    2566              :         }
    2567         4368 :       break;
    2568              :     }
    2569         4368 :   tree *valp = nullptr;
    2570         4368 :   bool check_mutable = false;
    2571         4368 :   if (DECL_P (obj))
    2572              :     {
    2573         4326 :       valp = ctx->global->get_raw_value_ptr (obj);
    2574         4326 :       if (!valp
    2575          858 :           && VAR_P (obj)
    2576          858 :           && TREE_STATIC (obj)
    2577         4596 :           && decl_constant_var_p (obj))
    2578              :         {
    2579          258 :           valp = &DECL_INITIAL (obj);
    2580          258 :           check_mutable = true;
    2581              :         }
    2582              :     }
    2583         4326 :   if (!valp || *valp == void_list_node)
    2584              :     {
    2585          828 :       if (!ctx->quiet)
    2586              :         {
    2587           57 :           auto_diagnostic_group d;
    2588           57 :           if (DECL_P (obj) && DECL_NAME (obj) == heap_deleted_identifier)
    2589              :             {
    2590            3 :               error_at (loc, "%qE on allocated storage after deallocation "
    2591            3 :                         "is not a constant expression", DECL_NAME (fun));
    2592            3 :               inform (DECL_SOURCE_LOCATION (obj), "allocated here");
    2593              :             }
    2594           54 :           else if (DECL_P (obj) && ctx->global->is_outside_lifetime (obj))
    2595              :             {
    2596           45 :               error_at (loc, "%qE on %qE after its storage has been released "
    2597           45 :                         "is not a constant expression", DECL_NAME (fun), obj);
    2598           45 :               inform (DECL_SOURCE_LOCATION (obj), "declared here");
    2599              :             }
    2600              :           else
    2601            9 :             error_at (loc, "%qE on %qE from outside current evaluation "
    2602            9 :                       "is not a constant expression", DECL_NAME (fun), obj);
    2603           57 :         }
    2604          828 :       *non_constant_p = true;
    2605          828 :       return t;
    2606              :     }
    2607         3540 :   tree val = *valp;
    2608         3540 :   if (val == void_node)
    2609           15 :     return boolean_false_node;
    2610         3525 :   unsigned i;
    2611         3525 :   tree ref;
    2612              :   /* Magic value used for val when inside the following loop when
    2613              :      inside of an omitted part of initializer due to it being
    2614              :      uninitialized.  In this case return boolean_true_node unless
    2615              :      there is some union member access, in unitialized union
    2616              :      no member is within lifetime.  */
    2617         3525 :   const tree val_uninit = global_namespace;
    2618              :   /* Magic value used for val when inside the following loop when
    2619              :      inside of an omitted part of initializer due to it being
    2620              :      zero initialized.  In this case return boolean_true_node unless
    2621              :      there is some union member access except for the first member.  */
    2622         3525 :   const tree val_zero_init = std_node;
    2623         3525 :   if (val == NULL_TREE)
    2624          141 :     val = val_uninit;
    2625        10631 :   FOR_EACH_VEC_ELT_REVERSE (refs, i, ref)
    2626         4240 :     switch (TREE_CODE (ref))
    2627              :       {
    2628           18 :       case REALPART_EXPR:
    2629           18 :       case IMAGPART_EXPR:
    2630           18 :         if (TREE_CODE (val) == COMPLEX_EXPR
    2631           18 :             && (TREE_OPERAND (val, TREE_CODE (ref) == IMAGPART_EXPR)
    2632           12 :                 == void_node))
    2633            6 :           return boolean_false_node;
    2634           12 :         return boolean_true_node;
    2635         3477 :       case COMPONENT_REF:
    2636         3477 :         if (check_mutable && DECL_MUTABLE_P (TREE_OPERAND (ref, 1)))
    2637              :           {
    2638           12 :             if (!ctx->quiet)
    2639            3 :               error_at (loc, "%qE on %<mutable%> sub-object %qD",
    2640            3 :                         DECL_NAME (fun), TREE_OPERAND (ref, 1));
    2641           12 :             *non_constant_p = true;
    2642           12 :             return t;
    2643              :           }
    2644         3465 :         if (TREE_CODE (TREE_TYPE (TREE_OPERAND (ref, 0))) == UNION_TYPE)
    2645              :           {
    2646         1202 :             tree union_type = TREE_TYPE (TREE_OPERAND (ref, 0));
    2647         1202 :             if (val == val_zero_init)
    2648              :               {
    2649           48 :                 if (TREE_OPERAND (ref, 1)
    2650           24 :                     != next_aggregate_field (TYPE_FIELDS (union_type)))
    2651           15 :                   return boolean_false_node;
    2652            9 :                 continue;
    2653              :               }
    2654         1178 :             else if (val == val_uninit)
    2655           93 :               return boolean_false_node;
    2656              :             else
    2657              :               {
    2658         1085 :                 gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
    2659         1085 :                 if (CONSTRUCTOR_NELTS (val) == 0)
    2660              :                   {
    2661          129 :                     if (CONSTRUCTOR_NO_CLEARING (val))
    2662          117 :                       return boolean_false_node;
    2663           12 :                     tree first
    2664           12 :                       = next_aggregate_field (TYPE_FIELDS (union_type));
    2665           12 :                     if (first != TREE_OPERAND (ref, 1))
    2666            3 :                       return boolean_false_node;
    2667            9 :                     val = val_zero_init;
    2668            9 :                     continue;
    2669            9 :                   }
    2670              :                 else
    2671              :                   {
    2672          956 :                     if (CONSTRUCTOR_ELT (val, 0)->index
    2673          956 :                         != TREE_OPERAND (ref, 1))
    2674          272 :                       return boolean_false_node;
    2675          684 :                     val = CONSTRUCTOR_ELT (val, 0)->value;
    2676          684 :                     if (val == void_node)
    2677            0 :                       return boolean_false_node;
    2678          684 :                     continue;
    2679              :                   }
    2680              :               }
    2681              :           }
    2682         2263 :         if (val == val_zero_init || val == val_uninit)
    2683           36 :           continue;
    2684         2227 :         gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
    2685              :         unsigned int j;
    2686              :         tree field, value;
    2687         3608 :         FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (val), j, field, value)
    2688         2163 :           if (field == TREE_OPERAND (ref, 1))
    2689              :             {
    2690          782 :               if (value == void_node)
    2691            6 :                 return boolean_false_node;
    2692              :               val = value;
    2693              :               ref = NULL_TREE;
    2694              :               break;
    2695              :             }
    2696         2221 :         if (ref == NULL_TREE)
    2697          776 :           continue;
    2698         1445 :         if (CONSTRUCTOR_NO_CLEARING (val))
    2699              :           {
    2700         1403 :             if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
    2701           42 :               return boolean_false_node;
    2702              :             val = val_uninit;
    2703              :           }
    2704              :         else
    2705              :           val = val_zero_init;
    2706         1403 :         continue;
    2707          745 :       case ARRAY_REF:
    2708          745 :         field = eval_and_check_array_index (ctx, ref, false,
    2709              :                                             non_constant_p, overflow_p,
    2710              :                                             jump_target);
    2711          745 :         if (*jump_target)
    2712              :           return NULL_TREE;
    2713          745 :         if (*non_constant_p)
    2714              :           return t;
    2715          733 :         if (val == val_zero_init || val == val_uninit)
    2716            9 :           continue;
    2717          724 :         if (TREE_CODE (val) == STRING_CST)
    2718            0 :           return boolean_true_node;
    2719          724 :         gcc_assert (TREE_CODE (val) == CONSTRUCTOR);
    2720          724 :         HOST_WIDE_INT idx;
    2721          724 :         idx = find_array_ctor_elt (val, field, false);
    2722          724 :         if (idx != -1)
    2723              :           {
    2724          340 :             val = CONSTRUCTOR_ELT (val, idx)->value;
    2725          340 :             if (val == void_node)
    2726           30 :               return boolean_false_node;
    2727          310 :             continue;
    2728              :           }
    2729          384 :         if (CONSTRUCTOR_NO_CLEARING (val))
    2730              :           {
    2731          159 :             if (CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (val))
    2732           39 :               return boolean_false_node;
    2733              :             val = val_uninit;
    2734              :           }
    2735              :         else
    2736              :           val = val_zero_init;
    2737          345 :         continue;
    2738            0 :       default:
    2739            0 :         gcc_unreachable ();
    2740         1748 :       }
    2741         2866 :   return boolean_true_node;
    2742         4368 : }
    2743              : 
    2744              : /* Attempt to evaluate T which represents a call to
    2745              :    __builtin_is_within_lifetime.  */
    2746              : 
    2747              : static tree
    2748         3026 : cxx_eval_is_within_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
    2749              :                              bool *non_constant_p, bool *overflow_p,
    2750              :                              tree *jump_target)
    2751              : {
    2752         3026 :   location_t loc = EXPR_LOCATION (t);
    2753         3026 :   tree arg = CALL_EXPR_ARG (t, 0);
    2754         3026 :   arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    2755              :                                       non_constant_p, overflow_p,
    2756              :                                       jump_target);
    2757         3026 :   if (*jump_target)
    2758              :     return NULL_TREE;
    2759         3026 :   if (*non_constant_p)
    2760              :     return t;
    2761              :   /* Need to strip casts to pointers to void, but should preserve
    2762              :      pointer casts within the innermost pointer to void cast if
    2763              :      any, so that e.g. pointers to heap allocations are handled
    2764              :      correctly.  */
    2765              :   tree p = arg;
    2766         5082 :   while (CONVERT_EXPR_P (p) || TREE_CODE (p) == NON_LVALUE_EXPR)
    2767              :     {
    2768         2226 :       if (!TYPE_PTR_P (TREE_TYPE (p)))
    2769              :         break;
    2770         2226 :       if (VOID_TYPE_P (TREE_TYPE (TREE_TYPE (p))))
    2771          174 :         arg = TREE_OPERAND (p, 0);
    2772         2226 :       p = TREE_OPERAND (p, 0);
    2773              :     }
    2774         2856 :   if (integer_zerop (arg))
    2775              :     {
    2776           24 :       if (!ctx->quiet)
    2777            6 :         error_at (loc, "%qE called with a null pointer",
    2778            6 :                   DECL_NAME (fun));
    2779           24 :       *non_constant_p = true;
    2780           24 :       return t;
    2781              :     }
    2782         2832 :   if (POINTER_TYPE_P (TREE_TYPE (arg))
    2783         2832 :       && (TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == FUNCTION_TYPE
    2784         2811 :           || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) == METHOD_TYPE))
    2785              :     {
    2786           21 :       if (!ctx->quiet)
    2787            6 :         error_at (loc, "%qE called with pointer to function",
    2788            6 :                   DECL_NAME (fun));
    2789           21 :       *non_constant_p = true;
    2790           21 :       return t;
    2791              :     }
    2792         2811 :   arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
    2793         2811 :   arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
    2794              :                                       non_constant_p, overflow_p,
    2795              :                                       jump_target);
    2796         2811 :   if (*jump_target)
    2797              :     return NULL_TREE;
    2798         2811 :   if (*non_constant_p)
    2799              :     return t;
    2800         2811 :   return is_within_lifetime (loc, ctx, t, fun, arg,
    2801         2811 :                              non_constant_p, overflow_p, jump_target);
    2802              : }
    2803              : 
    2804              : static tree cxx_eval_store_expression (const constexpr_ctx *, tree,
    2805              :                                        value_cat, bool *, bool *,
    2806              :                                        tree *);
    2807              : 
    2808              : /* Attempt to evaluate T which represents a call to
    2809              :    __builtin_start_lifetime.  */
    2810              : 
    2811              : static tree
    2812         1563 : cxx_eval_start_lifetime (const constexpr_ctx *ctx, tree t, tree fun,
    2813              :                          bool *non_constant_p, bool *overflow_p,
    2814              :                          tree *jump_target)
    2815              : {
    2816         1563 :   location_t loc = EXPR_LOCATION (t);
    2817         1563 :   tree arg = CALL_EXPR_ARG (t, 0), within_lifetime;
    2818         1563 :   arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    2819              :                                       non_constant_p, overflow_p,
    2820              :                                       jump_target);
    2821         1563 :   if (*jump_target)
    2822              :     return NULL_TREE;
    2823         1563 :   if (*non_constant_p)
    2824              :     return t;
    2825         1563 :   arg = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (arg)), arg);
    2826         1563 :   arg = cxx_eval_constant_expression (ctx, arg, vc_glvalue,
    2827              :                                       non_constant_p, overflow_p,
    2828              :                                       jump_target);
    2829         1563 :   if (*jump_target)
    2830              :     return NULL_TREE;
    2831         1563 :   if (*non_constant_p)
    2832              :     return t;
    2833         1563 :   switch (TREE_CODE (arg))
    2834              :     {
    2835         1557 :     case COMPONENT_REF:
    2836         1557 :     case ARRAY_REF:
    2837         1557 :     case REALPART_EXPR:
    2838         1557 :     case IMAGPART_EXPR:
    2839         1557 :       within_lifetime
    2840         1557 :         = is_within_lifetime (loc, ctx, t, fun, TREE_OPERAND (arg, 0),
    2841              :                               non_constant_p, overflow_p, jump_target);
    2842         1557 :       if (*jump_target)
    2843              :         return NULL_TREE;
    2844         1557 :       if (*non_constant_p)
    2845              :         return t;
    2846         1557 :       if (within_lifetime != boolean_true_node)
    2847              :         {
    2848           90 :           if (!ctx->quiet)
    2849           30 :             error_at (loc, "%qE with containing object not within lifetime",
    2850           30 :                       DECL_NAME (fun));
    2851           90 :           *non_constant_p = true;
    2852           90 :           return t;
    2853              :         }
    2854              :       break;
    2855              :     default:
    2856              :       break;
    2857              :     }
    2858         1473 :   tree ctor = build_constructor (TREE_TYPE (arg), NULL);
    2859         1473 :   CONSTRUCTOR_NO_CLEARING (ctor) = 1;
    2860         1473 :   CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
    2861         1473 :   tree modopexpr
    2862         1473 :     = build3_loc (loc, MODOP_EXPR, TREE_TYPE (arg), arg, ctor, NULL_TREE);
    2863         1473 :   arg = cxx_eval_store_expression (ctx, modopexpr, vc_discard, non_constant_p,
    2864              :                                    overflow_p, jump_target);
    2865         1473 :   ggc_free (modopexpr);
    2866         1473 :   if (*jump_target)
    2867              :     return NULL_TREE;
    2868         1473 :   if (*non_constant_p)
    2869              :     return t;
    2870         1469 :   return void_node;
    2871              : }
    2872              : 
    2873              : /* Attempt to evaluate T which represents a call to a builtin function.
    2874              :    We assume here that all builtin functions evaluate to scalar types
    2875              :    represented by _CST nodes.  */
    2876              : 
    2877              : static tree
    2878     20742282 : cxx_eval_builtin_function_call (const constexpr_ctx *ctx, tree t, tree fun,
    2879              :                                 value_cat lval,
    2880              :                                 bool *non_constant_p, bool *overflow_p,
    2881              :                                 tree *jump_target)
    2882              : {
    2883     20742282 :   const int nargs = call_expr_nargs (t);
    2884     20742282 :   tree *args = (tree *) alloca (nargs * sizeof (tree));
    2885     20742282 :   tree new_call;
    2886     20742282 :   int i;
    2887              : 
    2888              :   /* Don't fold __builtin_constant_p within a constexpr function.  */
    2889     20742282 :   bool bi_const_p = DECL_IS_BUILTIN_CONSTANT_P (fun);
    2890              : 
    2891              :   /* If we aren't requiring a constant expression, defer __builtin_constant_p
    2892              :      in a constexpr function until we have values for the parameters.  */
    2893      3568476 :   if (bi_const_p
    2894      3568476 :       && ctx->manifestly_const_eval != mce_true
    2895      1750634 :       && current_function_decl
    2896      1749505 :       && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
    2897              :     {
    2898      1397558 :       *non_constant_p = true;
    2899      1397558 :       return t;
    2900              :     }
    2901              : 
    2902     19344724 :   if (fndecl_built_in_p (fun, BUILT_IN_FRONTEND))
    2903      3999681 :     switch (DECL_FE_FUNCTION_CODE (fun))
    2904              :       {
    2905      3976469 :       case CP_BUILT_IN_IS_CONSTANT_EVALUATED:
    2906              :         /* For __builtin_is_constant_evaluated, defer it if not
    2907              :            ctx->manifestly_const_eval (as sometimes we try to constant evaluate
    2908              :            without manifestly_const_eval even expressions or parts thereof
    2909              :            which will later be manifestly const_eval evaluated), otherwise fold
    2910              :            it to true.  */
    2911      3976469 :         if (ctx->manifestly_const_eval == mce_unknown)
    2912              :           {
    2913      3928275 :             *non_constant_p = true;
    2914      3928275 :             return t;
    2915              :           }
    2916        48194 :         return constant_boolean_node (ctx->manifestly_const_eval == mce_true,
    2917        48194 :                                       boolean_type_node);
    2918              : 
    2919        10917 :       case CP_BUILT_IN_SOURCE_LOCATION:
    2920        10917 :         {
    2921        10917 :           temp_override<tree> ovr (current_function_decl);
    2922        10917 :           if (ctx->call && ctx->call->fundef)
    2923         2753 :             current_function_decl = ctx->call->fundef->decl;
    2924        10917 :           return fold_builtin_source_location (t);
    2925        10917 :         }
    2926              : 
    2927          126 :       case CP_BUILT_IN_EH_PTR_ADJUST_REF:
    2928          126 :         return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_EH_PTR_ADJUST_REF,
    2929              :                                         fun, non_constant_p, overflow_p,
    2930          126 :                                         jump_target);
    2931              : 
    2932         2205 :       case CP_BUILT_IN_CURRENT_EXCEPTION:
    2933         2205 :         return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_CURRENT_EXCEPTION,
    2934              :                                         fun, non_constant_p, overflow_p,
    2935         2205 :                                         jump_target);
    2936              : 
    2937           82 :       case CP_BUILT_IN_UNCAUGHT_EXCEPTIONS:
    2938           82 :         return cxx_eval_cxa_builtin_fn (ctx, t, BUILTIN_UNCAUGHT_EXCEPTIONS,
    2939              :                                         fun, non_constant_p, overflow_p,
    2940           82 :                                         jump_target);
    2941              : 
    2942          210 :       case CP_BUILT_IN_CONSTEXPR_DIAG:
    2943          210 :         return cxx_eval_constexpr_diag (ctx, t, non_constant_p, overflow_p,
    2944          210 :                                         jump_target);
    2945              : 
    2946         3026 :       case CP_BUILT_IN_IS_WITHIN_LIFETIME:
    2947         3026 :         return cxx_eval_is_within_lifetime (ctx, t, fun, non_constant_p,
    2948         3026 :                                             overflow_p, jump_target);
    2949              : 
    2950         1563 :       case CP_BUILT_IN_START_LIFETIME:
    2951         1563 :         return cxx_eval_start_lifetime (ctx, t, fun, non_constant_p,
    2952         1563 :                                         overflow_p, jump_target);
    2953              : 
    2954              :       default:
    2955              :         break;
    2956              :       }
    2957              : 
    2958     15350126 :   int strops = 0;
    2959     15350126 :   int strret = 0;
    2960     15350126 :   bool bos = false;
    2961     15350126 :   if (fndecl_built_in_p (fun, BUILT_IN_NORMAL))
    2962     14002878 :     switch (DECL_FUNCTION_CODE (fun))
    2963              :       {
    2964              :       case BUILT_IN_STRLEN:
    2965              :       case BUILT_IN_STRNLEN:
    2966     15349975 :         strops = 1;
    2967              :         break;
    2968       201107 :       case BUILT_IN_MEMCHR:
    2969       201107 :       case BUILT_IN_STRCHR:
    2970       201107 :       case BUILT_IN_STRRCHR:
    2971       201107 :         strops = 1;
    2972       201107 :         strret = 1;
    2973       201107 :         break;
    2974       112583 :       case BUILT_IN_MEMCMP:
    2975       112583 :       case BUILT_IN_STRCMP:
    2976       112583 :         strops = 2;
    2977       112583 :         break;
    2978        49873 :       case BUILT_IN_STRSTR:
    2979        49873 :         strops = 2;
    2980        49873 :         strret = 1;
    2981        49873 :         break;
    2982           66 :       case BUILT_IN_ASAN_POINTER_COMPARE:
    2983           66 :       case BUILT_IN_ASAN_POINTER_SUBTRACT:
    2984           66 :       case BUILT_IN_OBSERVABLE_CHKPT:
    2985              :         /* These builtins shall be ignored during constant expression
    2986              :            evaluation.  */
    2987           66 :         return void_node;
    2988           85 :       case BUILT_IN_UNREACHABLE:
    2989           85 :       case BUILT_IN_TRAP:
    2990           85 :         if (!*non_constant_p && !ctx->quiet)
    2991              :           {
    2992              :             /* Do not allow__builtin_unreachable in constexpr function.
    2993              :                The __builtin_unreachable call with BUILTINS_LOCATION
    2994              :                comes from cp_maybe_instrument_return.  */
    2995           25 :             if (EXPR_LOCATION (t) == BUILTINS_LOCATION)
    2996            0 :               error ("%<constexpr%> call flows off the end of the function");
    2997              :             else
    2998           25 :               error ("%q+E is not a constant expression", t);
    2999              :           }
    3000           85 :         *non_constant_p = true;
    3001           85 :         return t;
    3002         2881 :       case BUILT_IN_OBJECT_SIZE:
    3003         2881 :       case BUILT_IN_DYNAMIC_OBJECT_SIZE:
    3004         2881 :         bos = ctx->manifestly_const_eval == mce_true;
    3005         2881 :         break;
    3006              :       default:
    3007              :         break;
    3008              :       }
    3009              : 
    3010              :   /* Be permissive for arguments to built-ins; __builtin_constant_p should
    3011              :      return constant false for a non-constant argument.  */
    3012     15349975 :   constexpr_ctx new_ctx = *ctx;
    3013     15349975 :   new_ctx.quiet = true;
    3014     41712504 :   for (i = 0; i < nargs; ++i)
    3015              :     {
    3016     26362531 :       tree arg = CALL_EXPR_ARG (t, i);
    3017     26362531 :       tree oarg = arg;
    3018              : 
    3019              :       /* To handle string built-ins we need to pass ADDR_EXPR<STRING_CST> since
    3020              :          expand_builtin doesn't know how to look in the values table.  */
    3021     26362531 :       bool strop = i < strops;
    3022     26362531 :       if (strop)
    3023              :         {
    3024       688075 :           STRIP_NOPS (arg);
    3025       688075 :           if (TREE_CODE (arg) == ADDR_EXPR)
    3026         8152 :             arg = TREE_OPERAND (arg, 0);
    3027              :           else
    3028              :             strop = false;
    3029              :         }
    3030              : 
    3031              :       /* If builtin_valid_in_constant_expr_p is true,
    3032              :          potential_constant_expression_1 has not recursed into the arguments
    3033              :          of the builtin, verify it here.  */
    3034     26362531 :       if (!builtin_valid_in_constant_expr_p (fun)
    3035     26362531 :           || potential_constant_expression (arg))
    3036              :         {
    3037     26362394 :           bool dummy1 = false, dummy2 = false;
    3038     26362394 :           tree jmp_target = NULL_TREE;
    3039     26362394 :           arg = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
    3040              :                                               &dummy1, &dummy2, &jmp_target);
    3041     26362392 :           if (jmp_target)
    3042              :             {
    3043            0 :               *jump_target = jmp_target;
    3044            0 :               return NULL_TREE;
    3045              :             }
    3046              :         }
    3047              : 
    3048     26362529 :       if (bi_const_p)
    3049              :         /* For __builtin_constant_p, fold all expressions with constant values
    3050              :            even if they aren't C++ constant-expressions.  */
    3051      2170916 :         arg = cp_fold_rvalue (arg);
    3052     24191613 :       else if (strop)
    3053              :         {
    3054         8152 :           if (TREE_CODE (arg) == CONSTRUCTOR)
    3055          100 :             arg = braced_lists_to_strings (TREE_TYPE (arg), arg);
    3056         8152 :           if (TREE_CODE (arg) == STRING_CST)
    3057         3042 :             arg = build_address (arg);
    3058              :           else
    3059              :             arg = oarg;
    3060              :         }
    3061              : 
    3062     26362529 :       args[i] = arg;
    3063              :     }
    3064     15349973 :   if (bos)
    3065              :     {
    3066          102 :       tree arg = args[0];
    3067          102 :       STRIP_NOPS (arg);
    3068          102 :       if (TREE_CODE (arg) == ADDR_EXPR)
    3069          102 :         args[0] = arg;
    3070              :     }
    3071              : 
    3072     15349973 :   bool save_ffbcp = force_folding_builtin_constant_p;
    3073     15349973 :   force_folding_builtin_constant_p |= ctx->manifestly_const_eval == mce_true;
    3074     15349973 :   tree save_cur_fn = current_function_decl;
    3075              :   /* Return name of ctx->call->fundef->decl for __builtin_FUNCTION ().  */
    3076     15349973 :   if (fndecl_built_in_p (fun, BUILT_IN_FUNCTION)
    3077           37 :       && ctx->call
    3078     15349977 :       && ctx->call->fundef)
    3079            4 :     current_function_decl = ctx->call->fundef->decl;
    3080     15349973 :   if (fndecl_built_in_p (fun,
    3081              :                          CP_BUILT_IN_IS_POINTER_INTERCONVERTIBLE_WITH_CLASS,
    3082              :                          BUILT_IN_FRONTEND))
    3083              :     {
    3084          336 :       location_t loc = EXPR_LOCATION (t);
    3085          336 :       if (nargs >= 1)
    3086          333 :         VERIFY_CONSTANT (args[0]);
    3087          136 :       new_call
    3088          136 :         = fold_builtin_is_pointer_inverconvertible_with_class (loc, nargs,
    3089              :                                                                args);
    3090              :     }
    3091     15349637 :   else if (fndecl_built_in_p (fun,
    3092              :                               CP_BUILT_IN_IS_CORRESPONDING_MEMBER,
    3093              :                               BUILT_IN_FRONTEND))
    3094              :     {
    3095          471 :       location_t loc = EXPR_LOCATION (t);
    3096          471 :       if (nargs >= 2)
    3097              :         {
    3098          465 :           VERIFY_CONSTANT (args[0]);
    3099          237 :           VERIFY_CONSTANT (args[1]);
    3100              :         }
    3101          243 :       new_call = fold_builtin_is_corresponding_member (loc, nargs, args);
    3102              :     }
    3103     15349166 :   else if (fndecl_built_in_p (fun, CP_BUILT_IN_IS_STRING_LITERAL,
    3104              :                               BUILT_IN_FRONTEND))
    3105              :     {
    3106         4276 :       location_t loc = EXPR_LOCATION (t);
    3107         4276 :       if (nargs >= 1)
    3108              :         {
    3109         4276 :           tree arg = CALL_EXPR_ARG (t, 0);
    3110         4276 :           arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    3111              :                                               non_constant_p, overflow_p,
    3112              :                                               jump_target);
    3113         4276 :           if (*jump_target)
    3114              :             return NULL_TREE;
    3115         4276 :           args[0] = arg;
    3116              :         }
    3117         4276 :       new_call = fold_builtin_is_string_literal (loc, nargs, args);
    3118              :     }
    3119              :   else
    3120     30689780 :     new_call = fold_builtin_call_array (EXPR_LOCATION (t), TREE_TYPE (t),
    3121     15344890 :                                         CALL_EXPR_FN (t), nargs, args);
    3122     15349545 :   current_function_decl = save_cur_fn;
    3123     15349545 :   force_folding_builtin_constant_p = save_ffbcp;
    3124     15349545 :   if (new_call == NULL)
    3125              :     {
    3126     10439498 :       if (!*non_constant_p && !ctx->quiet)
    3127              :         {
    3128            0 :           new_call = build_call_array_loc (EXPR_LOCATION (t), TREE_TYPE (t),
    3129            0 :                                            CALL_EXPR_FN (t), nargs, args);
    3130            0 :           error ("%q+E is not a constant expression", new_call);
    3131              :         }
    3132     10439498 :       *non_constant_p = true;
    3133     10439498 :       return t;
    3134              :     }
    3135              : 
    3136      4910047 :   if (!potential_constant_expression (new_call))
    3137              :     {
    3138          861 :       if (!*non_constant_p && !ctx->quiet)
    3139            4 :         error ("%q+E is not a constant expression", new_call);
    3140          861 :       *non_constant_p = true;
    3141          861 :       return t;
    3142              :     }
    3143              : 
    3144      4909186 :   if (strret)
    3145              :     {
    3146              :       /* memchr returns a pointer into the first argument, but we replaced the
    3147              :          argument above with a STRING_CST; put it back it now.  */
    3148          283 :       tree op = CALL_EXPR_ARG (t, strret-1);
    3149          283 :       STRIP_NOPS (new_call);
    3150          283 :       if (TREE_CODE (new_call) == POINTER_PLUS_EXPR)
    3151          142 :         TREE_OPERAND (new_call, 0) = op;
    3152          141 :       else if (TREE_CODE (new_call) == ADDR_EXPR)
    3153      4909186 :         new_call = op;
    3154              :     }
    3155              : 
    3156      4909186 :   return cxx_eval_constant_expression (&new_ctx, new_call, lval,
    3157              :                                        non_constant_p, overflow_p,
    3158      4909186 :                                        jump_target);
    3159              : }
    3160              : 
    3161              : /* TEMP is the constant value of a temporary object of type TYPE.  Adjust
    3162              :    the type of the value to match.  */
    3163              : 
    3164              : static tree
    3165    136819057 : adjust_temp_type (tree type, tree temp)
    3166              : {
    3167    136819057 :   if (same_type_p (TREE_TYPE (temp), type))
    3168              :     return temp;
    3169              :   /* Avoid wrapping an aggregate value in a NOP_EXPR.  */
    3170     62954841 :   if (TREE_CODE (temp) == CONSTRUCTOR)
    3171              :     {
    3172              :       /* build_constructor wouldn't retain various CONSTRUCTOR flags.  */
    3173      3812882 :       tree t = copy_node (temp);
    3174      3812882 :       TREE_TYPE (t) = type;
    3175      3812882 :       return t;
    3176              :     }
    3177     59141959 :   if (TREE_CODE (temp) == EMPTY_CLASS_EXPR)
    3178            0 :     return build0 (EMPTY_CLASS_EXPR, type);
    3179     59141959 :   gcc_assert (scalarish_type_p (type));
    3180              :   /* Now we know we're dealing with a scalar, and a prvalue of non-class
    3181              :      type is cv-unqualified.  */
    3182     59141959 :   return cp_fold_convert (cv_unqualified (type), temp);
    3183              : }
    3184              : 
    3185              : /* If T is a CONSTRUCTOR, return an unshared copy of T and any
    3186              :    sub-CONSTRUCTORs.  Otherwise return T.
    3187              : 
    3188              :    We use this whenever we initialize an object as a whole, whether it's a
    3189              :    parameter, a local variable, or a subobject, so that subsequent
    3190              :    modifications don't affect other places where it was used.  */
    3191              : 
    3192              : tree
    3193    123567213 : unshare_constructor (tree t MEM_STAT_DECL)
    3194              : {
    3195    123567213 :   if (!t || TREE_CODE (t) != CONSTRUCTOR)
    3196              :     return t;
    3197     18677270 :   auto_vec <tree*, 4> ptrs;
    3198     18677270 :   ptrs.safe_push (&t);
    3199     18677270 :   while (!ptrs.is_empty ())
    3200              :     {
    3201     24575015 :       tree *p = ptrs.pop ();
    3202     24575015 :       tree n = copy_node (*p PASS_MEM_STAT);
    3203     40776457 :       CONSTRUCTOR_ELTS (n) = vec_safe_copy (CONSTRUCTOR_ELTS (*p) PASS_MEM_STAT);
    3204     24575015 :       *p = n;
    3205     24575015 :       vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (n);
    3206     24575015 :       constructor_elt *ce;
    3207     94415483 :       for (HOST_WIDE_INT i = 0; vec_safe_iterate (v, i, &ce); ++i)
    3208              :         {
    3209     26588183 :           if (ce->index && TREE_CODE (ce->index) == RANGE_EXPR)
    3210          773 :             ce->index = copy_node (ce->index PASS_MEM_STAT);
    3211     26588183 :           if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
    3212      5897745 :             ptrs.safe_push (&ce->value);
    3213              :         }
    3214              :     }
    3215     18677270 :   return t;
    3216     18677270 : }
    3217              : 
    3218              : /* If T is a CONSTRUCTOR, ggc_free T and any sub-CONSTRUCTORs.  */
    3219              : 
    3220              : static void
    3221       881634 : free_constructor (tree t)
    3222              : {
    3223       881634 :   if (!t || TREE_CODE (t) != CONSTRUCTOR)
    3224            0 :     return;
    3225       881634 :   releasing_vec ctors;
    3226       881634 :   vec_safe_push (ctors, t);
    3227      2684307 :   while (!ctors->is_empty ())
    3228              :     {
    3229       921039 :       tree c = ctors->pop ();
    3230       921039 :       if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (c))
    3231              :         {
    3232              :           constructor_elt *ce;
    3233       394318 :           for (HOST_WIDE_INT i = 0; vec_safe_iterate (elts, i, &ce); ++i)
    3234       255267 :             if (ce->value && TREE_CODE (ce->value) == CONSTRUCTOR)
    3235        39405 :               vec_safe_push (ctors, ce->value);
    3236       139051 :           ggc_free (elts);
    3237              :         }
    3238       921039 :       ggc_free (c);
    3239              :     }
    3240       881634 : }
    3241              : 
    3242              : /* Helper function of cxx_bind_parameters_in_call.  Return non-NULL
    3243              :    if *TP is address of a static variable (or part of it) currently being
    3244              :    constructed or of a heap artificial variable.  */
    3245              : 
    3246              : static tree
    3247     48164526 : addr_of_non_const_var (tree *tp, int *walk_subtrees, void *data)
    3248              : {
    3249     48164526 :   if (TREE_CODE (*tp) == ADDR_EXPR)
    3250      8921839 :     if (tree var = get_base_address (TREE_OPERAND (*tp, 0)))
    3251      8921839 :       if (VAR_P (var) && TREE_STATIC (var))
    3252              :         {
    3253      5508157 :           if (DECL_NAME (var) == heap_uninit_identifier
    3254      5508157 :               || DECL_NAME (var) == heap_identifier
    3255      5508157 :               || DECL_NAME (var) == heap_vec_uninit_identifier
    3256     11016314 :               || DECL_NAME (var) == heap_vec_identifier)
    3257              :             return var;
    3258              : 
    3259      5508157 :           constexpr_global_ctx *global = (constexpr_global_ctx *) data;
    3260      5508157 :           if (global->get_value (var))
    3261              :             return var;
    3262              :         }
    3263     47717312 :   if (TYPE_P (*tp))
    3264         2493 :     *walk_subtrees = false;
    3265              :   return NULL_TREE;
    3266              : }
    3267              : 
    3268              : /* Subroutine of cxx_eval_call_expression.
    3269              :    We are processing a call expression (either CALL_EXPR or
    3270              :    AGGR_INIT_EXPR) in the context of CTX.  Evaluate
    3271              :    all arguments and bind their values to correspondings
    3272              :    parameters, making up the NEW_CALL context.  */
    3273              : 
    3274              : static tree
    3275    184526375 : cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t, tree fun,
    3276              :                              tree orig_fun, bool *non_constant_p,
    3277              :                              bool *overflow_p, bool *non_constant_args,
    3278              :                              tree *jump_target)
    3279              : {
    3280    184526375 :   int nargs = call_expr_nargs (t);
    3281    184526375 :   tree parms = DECL_ARGUMENTS (fun);
    3282    184526375 :   int i, j = 0;
    3283    184526375 :   if (DECL_HAS_IN_CHARGE_PARM_P (fun) && fun != orig_fun)
    3284         1523 :     ++nargs;
    3285    184526375 :   if (DECL_HAS_VTT_PARM_P (fun)
    3286         1525 :       && fun != orig_fun
    3287    184527898 :       && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
    3288         1082 :           || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
    3289          463 :     ++nargs;
    3290              :   /* We don't record ellipsis args below.  */
    3291    184526375 :   int nparms = list_length (parms);
    3292    184526375 :   int nbinds = nargs < nparms ? nargs : nparms;
    3293    184526375 :   tree binds = make_tree_vec (nbinds);
    3294              : 
    3295              :   /* The call is not a constant expression if it involves the cdtor for a type
    3296              :      with virtual bases before C++26.  */
    3297    184526375 :   if (cxx_dialect < cxx26
    3298    184526375 :       && (DECL_HAS_IN_CHARGE_PARM_P (fun) || DECL_HAS_VTT_PARM_P (fun)))
    3299              :     {
    3300           17 :       if (!ctx->quiet)
    3301              :         {
    3302            3 :           error_at (cp_expr_loc_or_input_loc (t),
    3303              :                     "call to non-%<constexpr%> function %qD", fun);
    3304            3 :           explain_invalid_constexpr_fn (fun);
    3305              :         }
    3306           17 :       *non_constant_p = true;
    3307           17 :       return binds;
    3308              :     }
    3309              : 
    3310    331644680 :   for (i = 0; i < nargs; ++i)
    3311              :     {
    3312    221493931 :       tree x, arg;
    3313    221493931 :       tree type = parms ? TREE_TYPE (parms) : void_type_node;
    3314    221493931 :       if (parms && DECL_BY_REFERENCE (parms))
    3315        26929 :         type = TREE_TYPE (type);
    3316    221493931 :       if (i == 1
    3317    221493931 :           && j == 0
    3318     47412875 :           && DECL_HAS_IN_CHARGE_PARM_P (fun)
    3319    221495322 :           && orig_fun != fun)
    3320              :         {
    3321         1391 :           if (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
    3322         1391 :               || DECL_COMPLETE_DESTRUCTOR_P (orig_fun))
    3323          428 :             x = boolean_true_node;
    3324              :           else
    3325          963 :             x = boolean_false_node;
    3326              :           j = -1;
    3327              :         }
    3328    221492540 :       else if (i == 2
    3329    221492540 :                && j == -1
    3330         1391 :                && DECL_HAS_VTT_PARM_P (fun)
    3331         1391 :                && orig_fun != fun
    3332    221493931 :                && (DECL_COMPLETE_CONSTRUCTOR_P (orig_fun)
    3333          985 :                    || DECL_COMPLETE_DESTRUCTOR_P (orig_fun)))
    3334              :         {
    3335          428 :           x = build_zero_cst (type);
    3336          428 :           j = -2;
    3337              :         }
    3338              :       else
    3339    221492112 :         x = get_nth_callarg (t, i + j);
    3340              :       /* For member function, the first argument is a pointer to the implied
    3341              :          object.  For a constructor, it might still be a dummy object, in
    3342              :          which case we get the real argument from ctx.  */
    3343    325068742 :       if (i == 0 && DECL_CONSTRUCTOR_P (fun)
    3344    244586486 :           && is_dummy_object (x))
    3345              :         {
    3346     11830859 :           x = ctx->object;
    3347     11830859 :           x = build_address (x);
    3348              :         }
    3349    221493931 :       if (TREE_ADDRESSABLE (type))
    3350              :         {
    3351              :           /* Undo convert_for_arg_passing work here.  */
    3352        39401 :           x = convert_from_reference (x);
    3353        39401 :           arg = cxx_eval_constant_expression (ctx, x, vc_glvalue,
    3354              :                                               non_constant_p, overflow_p,
    3355              :                                               jump_target);
    3356              :         }
    3357              :       else
    3358              :         /* Normally we would strip a TARGET_EXPR in an initialization context
    3359              :            such as this, but here we do the elision differently: we keep the
    3360              :            TARGET_EXPR, and use its CONSTRUCTOR as the value of the parm.  */
    3361    221454530 :         arg = cxx_eval_constant_expression (ctx, x, vc_prvalue,
    3362              :                                             non_constant_p, overflow_p,
    3363              :                                             jump_target);
    3364    221493931 :       if (*jump_target)
    3365              :         break;
    3366              :       /* Check we aren't dereferencing a null pointer when calling a non-static
    3367              :          member function, which is undefined behaviour.  */
    3368    162534316 :       if (i == 0 && DECL_OBJECT_MEMBER_FUNCTION_P (fun)
    3369     92449005 :           && integer_zerop (arg)
    3370              :           /* But ignore calls from within compiler-generated code, to handle
    3371              :              cases like lambda function pointer conversion operator thunks
    3372              :              which pass NULL as the 'this' pointer.  */
    3373    221668529 :           && !(TREE_CODE (t) == CALL_EXPR && CALL_FROM_THUNK_P (t)))
    3374              :         {
    3375          527 :           if (!ctx->quiet)
    3376            6 :             error_at (cp_expr_loc_or_input_loc (x),
    3377              :                       "dereferencing a null pointer");
    3378          527 :           *non_constant_p = true;
    3379              :         }
    3380              :       /* Don't VERIFY_CONSTANT here.  */
    3381    221493847 :       if (*non_constant_p && ctx->quiet)
    3382              :         break;
    3383              :       /* Just discard ellipsis args after checking their constantitude.  */
    3384    147118322 :       if (!parms)
    3385          360 :         continue;
    3386              : 
    3387    147117962 :       if (!*non_constant_p)
    3388              :         {
    3389              :           /* Make sure the binding has the same type as the parm.  But
    3390              :              only for constant args.  */
    3391    147117188 :           if (TREE_ADDRESSABLE (type))
    3392              :             {
    3393        26176 :               if (!same_type_p (type, TREE_TYPE (arg)))
    3394              :                 {
    3395            9 :                   arg = build_fold_addr_expr (arg);
    3396            9 :                   arg = cp_fold_convert (build_reference_type (type), arg);
    3397            9 :                   arg = convert_from_reference (arg);
    3398              :                 }
    3399              :             }
    3400    147091012 :           else if (!TYPE_REF_P (type))
    3401    105545597 :             arg = adjust_temp_type (type, arg);
    3402    147117188 :           if (!TREE_CONSTANT (arg))
    3403     97130699 :             *non_constant_args = true;
    3404     49986489 :           else if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
    3405              :             /* The destructor needs to see any modifications the callee makes
    3406              :                to the argument.  */
    3407            0 :             *non_constant_args = true;
    3408              :             /* If arg is or contains address of a heap artificial variable or
    3409              :                of a static variable being constructed, avoid caching the
    3410              :                function call, as those variables might be modified by the
    3411              :                function, or might be modified by the callers in between
    3412              :                the cached function and just read by the function.  */
    3413     49986489 :           else if (!*non_constant_args
    3414     49986489 :                    && cp_walk_tree (&arg, addr_of_non_const_var, ctx->global,
    3415              :                                     NULL))
    3416       447214 :             *non_constant_args = true;
    3417              : 
    3418              :           /* For virtual calls, adjust the this argument, so that it is
    3419              :              the object on which the method is called, rather than
    3420              :              one of its bases.  */
    3421    147117188 :           if (i == 0 && DECL_VIRTUAL_P (fun))
    3422              :             {
    3423        27404 :               tree addr = arg;
    3424        27404 :               STRIP_NOPS (addr);
    3425        27404 :               if (TREE_CODE (addr) == ADDR_EXPR)
    3426              :                 {
    3427        27367 :                   tree obj = TREE_OPERAND (addr, 0);
    3428        27367 :                   while (TREE_CODE (obj) == COMPONENT_REF
    3429        11820 :                          && DECL_FIELD_IS_BASE (TREE_OPERAND (obj, 1))
    3430        39265 :                          && !same_type_ignoring_top_level_qualifiers_p
    3431        11727 :                                         (TREE_TYPE (obj), DECL_CONTEXT (fun)))
    3432          171 :                     obj = TREE_OPERAND (obj, 0);
    3433        27367 :                   if (obj != TREE_OPERAND (addr, 0))
    3434          168 :                     arg = build_fold_addr_expr_with_type (obj,
    3435              :                                                           TREE_TYPE (arg));
    3436              :                 }
    3437              :             }
    3438    147117188 :           TREE_VEC_ELT (binds, i) = arg;
    3439              :         }
    3440    147117962 :       parms = TREE_CHAIN (parms);
    3441              :     }
    3442              : 
    3443              :   return binds;
    3444              : }
    3445              : 
    3446              : static int
    3447    109556501 : push_cx_call_context (tree call)
    3448              : {
    3449    109556501 :   ++call_stack_tick;
    3450    109556501 :   if (!EXPR_HAS_LOCATION (call))
    3451        78459 :     SET_EXPR_LOCATION (call, input_location);
    3452    109556501 :   call_stack.safe_push (call);
    3453    109556501 :   int len = call_stack.length ();
    3454    109556501 :   if (len > max_constexpr_depth)
    3455           33 :     return false;
    3456              :   return len;
    3457              : }
    3458              : 
    3459              : static void
    3460    109556497 : pop_cx_call_context (void)
    3461              : {
    3462    109556497 :   ++call_stack_tick;
    3463    109556497 :   call_stack.pop ();
    3464    109556497 : }
    3465              : 
    3466              : vec<tree>
    3467       258649 : cx_error_context (void)
    3468              : {
    3469       258649 :   vec<tree> r = vNULL;
    3470       258649 :   if (call_stack_tick != last_cx_error_tick
    3471       258649 :       && !call_stack.is_empty ())
    3472              :     r = call_stack;
    3473       258649 :   last_cx_error_tick = call_stack_tick;
    3474       258649 :   return r;
    3475              : }
    3476              : 
    3477              : /* E is an operand of a failed assertion, fold it either with or without
    3478              :    constexpr context.  */
    3479              : 
    3480              : static tree
    3481          829 : fold_operand (tree e, const constexpr_ctx *ctx)
    3482              : {
    3483          829 :   if (ctx)
    3484              :     {
    3485           32 :       bool new_non_constant_p = false, new_overflow_p = false;
    3486           32 :       tree jmp_target = NULL_TREE;
    3487           32 :       e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
    3488              :                                         &new_non_constant_p,
    3489              :                                         &new_overflow_p, &jmp_target);
    3490              :     }
    3491              :   else
    3492          797 :     e = fold_non_dependent_expr (e, tf_none, /*manifestly_const_eval=*/true);
    3493          829 :   return e;
    3494              : }
    3495              : 
    3496              : /* If we have a condition in conjunctive normal form (CNF), find the first
    3497              :    failing clause.  In other words, given an expression like
    3498              : 
    3499              :      true && true && false && true && false
    3500              : 
    3501              :    return the first 'false'.  EXPR is the expression.  */
    3502              : 
    3503              : static tree
    3504          332 : find_failing_clause_r (const constexpr_ctx *ctx, tree expr)
    3505              : {
    3506          437 :   if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
    3507              :     {
    3508              :       /* First check the left side...  */
    3509          192 :       tree e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 0));
    3510          192 :       if (e == NULL_TREE)
    3511              :         /* ...if we didn't find a false clause, check the right side.  */
    3512          105 :         e = find_failing_clause_r (ctx, TREE_OPERAND (expr, 1));
    3513              :       return e;
    3514              :     }
    3515          245 :   tree e = contextual_conv_bool (expr, tf_none);
    3516          245 :   e = fold_operand (e, ctx);
    3517          245 :   if (integer_zerop (e))
    3518              :     /* This is the failing clause.  */
    3519          140 :     return expr;
    3520              :   return NULL_TREE;
    3521              : }
    3522              : 
    3523              : /* Wrapper for find_failing_clause_r.  */
    3524              : 
    3525              : tree
    3526         1984 : find_failing_clause (const constexpr_ctx *ctx, tree expr)
    3527              : {
    3528         1984 :   if (TREE_CODE (expr) == TRUTH_ANDIF_EXPR)
    3529          140 :     if (tree e = find_failing_clause_r (ctx, expr))
    3530         1984 :       expr = e;
    3531         1984 :   return expr;
    3532              : }
    3533              : 
    3534              : /* Emit additional diagnostics for failing condition BAD.
    3535              :    Used by finish_static_assert and IFN_ASSUME constexpr diagnostics.
    3536              :    If SHOW_EXPR_P is true, print the condition (because it was
    3537              :    instantiation-dependent).  */
    3538              : 
    3539              : void
    3540         1984 : diagnose_failing_condition (tree bad, location_t cloc, bool show_expr_p,
    3541              :                             const constexpr_ctx *ctx /* = nullptr */)
    3542              : {
    3543              :   /* Nobody wants to see the artificial (bool) cast.  */
    3544         1984 :   bad = tree_strip_nop_conversions (bad);
    3545         1984 :   if (TREE_CODE (bad) == CLEANUP_POINT_EXPR)
    3546            3 :     bad = TREE_OPERAND (bad, 0);
    3547              : 
    3548         1984 :   auto_diagnostic_nesting_level sentinel;
    3549              : 
    3550              :   /* Actually explain the failure if this is a concept check or a
    3551              :      requires-expression.  */
    3552         1984 :   if (concept_check_p (bad) || TREE_CODE (bad) == REQUIRES_EXPR)
    3553          334 :     diagnose_constraints (cloc, bad, NULL_TREE);
    3554              :   /* Similarly if this is a standard trait.  */
    3555         1650 :   else if (maybe_diagnose_standard_trait (cloc, bad))
    3556              :     ;
    3557         1295 :   else if (COMPARISON_CLASS_P (bad)
    3558         1295 :            && (ARITHMETIC_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))
    3559           76 :                || REFLECTION_TYPE_P (TREE_TYPE (TREE_OPERAND (bad, 0)))))
    3560              :     {
    3561          292 :       tree op0 = fold_operand (TREE_OPERAND (bad, 0), ctx);
    3562          292 :       tree op1 = fold_operand (TREE_OPERAND (bad, 1), ctx);
    3563          292 :       tree cond = build2 (TREE_CODE (bad), boolean_type_node, op0, op1);
    3564          292 :       inform (cloc, "the comparison reduces to %qE", cond);
    3565              :     }
    3566         1003 :   else if (show_expr_p)
    3567          755 :     inform (cloc, "%qE evaluates to false", bad);
    3568         1984 : }
    3569              : 
    3570              : /* Process an assert/assume of ORIG_ARG.  If it's not supposed to be evaluated,
    3571              :    do it without changing the current evaluation state.  If it evaluates to
    3572              :    false, complain and return false; otherwise, return true.  */
    3573              : 
    3574              : static bool
    3575       173593 : cxx_eval_assert (const constexpr_ctx *ctx, tree arg, const char *msg,
    3576              :                  location_t loc, bool evaluated,
    3577              :                  bool *non_constant_p, bool *overflow_p)
    3578              : {
    3579       173593 :   if (*non_constant_p)
    3580              :     return true;
    3581              : 
    3582       173593 :   tree eval, jmp_target = NULL_TREE;
    3583       173593 :   if (!evaluated)
    3584              :     {
    3585       173593 :       if (!potential_rvalue_constant_expression (arg))
    3586           16 :         return true;
    3587              : 
    3588       173577 :       constexpr_ctx new_ctx = *ctx;
    3589       173577 :       new_ctx.quiet = true;
    3590       173577 :       bool new_non_constant_p = false, new_overflow_p = false;
    3591              :       /* Avoid modification of existing values.  */
    3592       173577 :       modifiable_tracker ms (new_ctx.global);
    3593       173577 :       eval = cxx_eval_constant_expression (&new_ctx, arg, vc_prvalue,
    3594              :                                            &new_non_constant_p,
    3595              :                                            &new_overflow_p, &jmp_target);
    3596       173577 :     }
    3597              :   else
    3598            0 :     eval = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    3599              :                                          non_constant_p,
    3600              :                                          overflow_p, &jmp_target);
    3601       173577 :   if (jmp_target)
    3602              :     return true;
    3603              : 
    3604       173577 :   if (!*non_constant_p && integer_zerop (eval))
    3605              :     {
    3606           42 :       if (!ctx->quiet)
    3607              :         {
    3608              :           /* See if we can find which clause was failing
    3609              :              (for logical AND).  */
    3610           13 :           tree bad = find_failing_clause (ctx, arg);
    3611              :           /* If not, or its location is unusable, fall back to the
    3612              :              previous location.  */
    3613           13 :           location_t cloc = cp_expr_loc_or_loc (bad, loc);
    3614              : 
    3615              :           /* Report the error. */
    3616           13 :           auto_diagnostic_group d;
    3617           13 :           error_at (cloc, msg);
    3618           13 :           diagnose_failing_condition (bad, cloc, true, ctx);
    3619           13 :           return bad;
    3620           13 :         }
    3621           29 :       *non_constant_p = true;
    3622           29 :       return false;
    3623              :     }
    3624              : 
    3625              :   return true;
    3626              : }
    3627              : 
    3628              : /* Evaluate a call T to a GCC internal function when possible and return
    3629              :    the evaluated result or, under the control of CTX, give an error, set
    3630              :    NON_CONSTANT_P, and return the unevaluated call T otherwise.  */
    3631              : 
    3632              : static tree
    3633       388244 : cxx_eval_internal_function (const constexpr_ctx *ctx, tree t,
    3634              :                             value_cat lval,
    3635              :                             bool *non_constant_p, bool *overflow_p,
    3636              :                             tree *jump_target)
    3637              : {
    3638       388244 :   enum tree_code opcode = ERROR_MARK;
    3639              : 
    3640       388244 :   switch (CALL_EXPR_IFN (t))
    3641              :     {
    3642          166 :     case IFN_UBSAN_NULL:
    3643          166 :     case IFN_UBSAN_BOUNDS:
    3644          166 :     case IFN_UBSAN_VPTR:
    3645          166 :     case IFN_FALLTHROUGH:
    3646          166 :       return void_node;
    3647              : 
    3648       173593 :     case IFN_ASSUME:
    3649       173593 :       if (!cxx_eval_assert (ctx, CALL_EXPR_ARG (t, 0),
    3650              :                             G_("failed %<assume%> attribute assumption"),
    3651       173593 :                             EXPR_LOCATION (t), /*eval*/false,
    3652              :                             non_constant_p, overflow_p))
    3653              :         return t;
    3654       173564 :       return void_node;
    3655              : 
    3656              :     case IFN_ADD_OVERFLOW:
    3657              :       opcode = PLUS_EXPR;
    3658              :       break;
    3659          385 :     case IFN_SUB_OVERFLOW:
    3660          385 :       opcode = MINUS_EXPR;
    3661          385 :       break;
    3662       206750 :     case IFN_MUL_OVERFLOW:
    3663       206750 :       opcode = MULT_EXPR;
    3664       206750 :       break;
    3665              : 
    3666           96 :     case IFN_LAUNDER:
    3667           96 :       return cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
    3668              :                                            vc_prvalue, non_constant_p,
    3669           96 :                                            overflow_p, jump_target);
    3670              : 
    3671            0 :     case IFN_DEFERRED_INIT:
    3672            0 :       return build_clobber (TREE_TYPE (t), CLOBBER_OBJECT_BEGIN);
    3673              : 
    3674          120 :     case IFN_BSWAP:
    3675          120 :     case IFN_BITREVERSE:
    3676          120 :       {
    3677          120 :         tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
    3678              :                                                  vc_prvalue, non_constant_p,
    3679              :                                                  overflow_p, jump_target);
    3680          120 :         if (*jump_target)
    3681              :           return NULL_TREE;
    3682          120 :         if (*non_constant_p)
    3683              :           return t;
    3684           60 :         location_t loc = cp_expr_loc_or_input_loc (t);
    3685           60 :         if (TREE_CODE (arg) != INTEGER_CST
    3686           60 :             || !INTEGRAL_TYPE_P (TREE_TYPE (arg))
    3687           60 :             || !TYPE_UNSIGNED (TREE_TYPE (arg))
    3688          120 :             || (CALL_EXPR_IFN (t) == IFN_BSWAP
    3689           30 :                 && (TYPE_PRECISION (TREE_TYPE (arg)) % 8) != 0))
    3690              :           {
    3691            0 :             if (!ctx->quiet)
    3692            0 :               error_at (loc, "call to internal function %qE", t);
    3693            0 :             *non_constant_p = true;
    3694            0 :             return t;
    3695              :           }
    3696           60 :         return fold_build_builtin_bswapg_bitreverseg (loc, CALL_EXPR_IFN (t),
    3697           60 :                                                       arg);
    3698              :       }
    3699              : 
    3700         6634 :     case IFN_VEC_CONVERT:
    3701         6634 :       {
    3702         6634 :         tree arg = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0),
    3703              :                                                  vc_prvalue, non_constant_p,
    3704              :                                                  overflow_p, jump_target);
    3705         6634 :         if (*jump_target)
    3706              :           return NULL_TREE;
    3707         6634 :         if (TREE_CODE (arg) == VECTOR_CST)
    3708         6237 :           if (tree r = fold_const_call (CFN_VEC_CONVERT, TREE_TYPE (t), arg))
    3709              :             return r;
    3710              :       }
    3711              :       /* FALLTHRU */
    3712              : 
    3713          402 :     default:
    3714          402 :       if (!ctx->quiet)
    3715            0 :         error_at (cp_expr_loc_or_input_loc (t),
    3716              :                   "call to internal function %qE", t);
    3717          402 :       *non_constant_p = true;
    3718          402 :       return t;
    3719              :     }
    3720              : 
    3721              :   /* Evaluate constant arguments using OPCODE and return a complex
    3722              :      number containing the result and the overflow bit.  */
    3723       207635 :   tree arg0 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 0), lval,
    3724              :                                             non_constant_p, overflow_p,
    3725              :                                             jump_target);
    3726       207635 :   tree arg1 = cxx_eval_constant_expression (ctx, CALL_EXPR_ARG (t, 1), lval,
    3727              :                                             non_constant_p, overflow_p,
    3728              :                                             jump_target);
    3729       207635 :   if (*jump_target)
    3730              :     return NULL_TREE;
    3731       207635 :   if (TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
    3732              :     {
    3733            2 :       location_t loc = cp_expr_loc_or_input_loc (t);
    3734            2 :       tree type = TREE_TYPE (TREE_TYPE (t));
    3735            2 :       tree result = fold_binary_loc (loc, opcode, type,
    3736              :                                      fold_convert_loc (loc, type, arg0),
    3737              :                                      fold_convert_loc (loc, type, arg1));
    3738            2 :       tree ovf
    3739            2 :         = build_int_cst (type, arith_overflowed_p (opcode, type, arg0, arg1));
    3740              :       /* Reset TREE_OVERFLOW to avoid warnings for the overflow.  */
    3741            2 :       if (TREE_OVERFLOW (result))
    3742            0 :         TREE_OVERFLOW (result) = 0;
    3743              : 
    3744            2 :       return build_complex (TREE_TYPE (t), result, ovf);
    3745              :     }
    3746              : 
    3747       207633 :   *non_constant_p = true;
    3748       207633 :   return t;
    3749              : }
    3750              : 
    3751              : /* Clean CONSTRUCTOR_NO_CLEARING from CTOR and its sub-aggregates.  */
    3752              : 
    3753              : static void
    3754      6001400 : clear_no_implicit_zero (tree ctor)
    3755              : {
    3756      6001400 :   if (CONSTRUCTOR_NO_CLEARING (ctor))
    3757              :     {
    3758      1746046 :       CONSTRUCTOR_NO_CLEARING (ctor) = false;
    3759      7392032 :       for (auto &e: CONSTRUCTOR_ELTS (ctor))
    3760      2322106 :         if (TREE_CODE (e.value) == CONSTRUCTOR)
    3761       731036 :           clear_no_implicit_zero (e.value);
    3762              :     }
    3763      6001400 : }
    3764              : 
    3765              : /* Complain about a const object OBJ being modified in a constant expression.
    3766              :    EXPR is the MODIFY_EXPR expression performing the modification.  */
    3767              : 
    3768              : static void
    3769           65 : modifying_const_object_error (tree expr, tree obj)
    3770              : {
    3771           65 :   location_t loc = cp_expr_loc_or_input_loc (expr);
    3772           65 :   auto_diagnostic_group d;
    3773          130 :   error_at (loc, "modifying a const object %qE is not allowed in "
    3774           65 :             "a constant expression", TREE_OPERAND (expr, 0));
    3775              : 
    3776              :   /* Find the underlying object that was declared as const.  */
    3777           65 :   location_t decl_loc = UNKNOWN_LOCATION;
    3778          207 :   for (tree probe = obj; decl_loc == UNKNOWN_LOCATION; )
    3779           77 :     switch (TREE_CODE (probe))
    3780              :       {
    3781           39 :       case BIT_FIELD_REF:
    3782           39 :       case COMPONENT_REF:
    3783           39 :         {
    3784           39 :           tree elt = TREE_OPERAND (probe, 1);
    3785           39 :           if (CP_TYPE_CONST_P (TREE_TYPE (elt)))
    3786           27 :             decl_loc = DECL_SOURCE_LOCATION (elt);
    3787           39 :           probe = TREE_OPERAND (probe, 0);
    3788              :         }
    3789           39 :         break;
    3790              : 
    3791            0 :       case ARRAY_REF:
    3792            0 :       case REALPART_EXPR:
    3793            0 :       case IMAGPART_EXPR:
    3794            0 :         probe = TREE_OPERAND (probe, 0);
    3795            0 :         break;
    3796              : 
    3797           38 :       default:
    3798           38 :         decl_loc = location_of (probe);
    3799           38 :         break;
    3800              :       }
    3801           65 :   inform (decl_loc, "originally declared %<const%> here");
    3802           65 : }
    3803              : 
    3804              : /* Return true if FNDECL is a replaceable global allocation function that
    3805              :    should be usable during constant expression evaluation.  */
    3806              : 
    3807              : static inline bool
    3808     38721576 : cxx_replaceable_global_alloc_fn (tree fndecl)
    3809              : {
    3810     38721576 :   return (cxx_dialect >= cxx20
    3811     36657186 :           && IDENTIFIER_NEWDEL_OP_P (DECL_NAME (fndecl))
    3812      2243081 :           && CP_DECL_CONTEXT (fndecl) == global_namespace
    3813     40964272 :           && (DECL_IS_REPLACEABLE_OPERATOR_NEW_P (fndecl)
    3814       928120 :               || DECL_IS_OPERATOR_DELETE_P (fndecl)));
    3815              : }
    3816              : 
    3817              : /* Return true if FNDECL is a placement new function that should be
    3818              :    usable during constant expression evaluation of std::construct_at.  */
    3819              : 
    3820              : static inline bool
    3821     37239772 : cxx_placement_new_fn (tree fndecl)
    3822              : {
    3823     37239772 :   return (cxx_dialect >= cxx20 && std_placement_new_fn_p (fndecl));
    3824              : }
    3825              : 
    3826              : /* Return true if FNDECL is std::construct_at.  */
    3827              : 
    3828              : static inline bool
    3829      2369048 : is_std_construct_at (tree fndecl)
    3830              : {
    3831      2369048 :   if (!decl_in_std_namespace_p (fndecl))
    3832              :     return false;
    3833              : 
    3834      2324880 :   tree name = DECL_NAME (fndecl);
    3835      2324880 :   return name && id_equal (name, "construct_at");
    3836              : }
    3837              : 
    3838              : /* Overload for the above taking constexpr_call*.  */
    3839              : 
    3840              : static inline bool
    3841      2128054 : is_std_construct_at (const constexpr_call *call)
    3842              : {
    3843      2128054 :   return (call
    3844      1966051 :           && call->fundef
    3845      4094105 :           && is_std_construct_at (call->fundef->decl));
    3846              : }
    3847              : 
    3848              : /* True if CTX is an instance of std::NAME class.  */
    3849              : 
    3850              : bool
    3851     12368687 : is_std_class (tree ctx, const char *name)
    3852              : {
    3853     12368687 :   if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
    3854              :     return false;
    3855              : 
    3856     12368065 :   tree decl = TYPE_MAIN_DECL (ctx);
    3857     12368065 :   tree dname = DECL_NAME (decl);
    3858     12368065 :   if (dname == NULL_TREE || !id_equal (dname, name))
    3859              :     return false;
    3860              : 
    3861       884531 :   return decl_in_std_namespace_p (decl);
    3862              : }
    3863              : 
    3864              : /* True if CTX is an instance of std::allocator.  */
    3865              : 
    3866              : bool
    3867       719751 : is_std_allocator (tree ctx)
    3868              : {
    3869       719751 :   return is_std_class (ctx, "allocator");
    3870              : }
    3871              : 
    3872              : /* Return true if FNDECL is std::allocator<T>::allocate.  */
    3873              : 
    3874              : static bool
    3875       108512 : is_std_allocator_allocate (tree fndecl)
    3876              : {
    3877       108512 :   tree name = DECL_NAME (fndecl);
    3878       108512 :   if (name == NULL_TREE || !id_equal (name, "allocate"))
    3879              :     return false;
    3880              : 
    3881        99967 :   return is_std_allocator (DECL_CONTEXT (fndecl));
    3882              : }
    3883              : 
    3884              : /* Overload for the above taking constexpr_call*.  */
    3885              : 
    3886              : static inline bool
    3887       119140 : is_std_allocator_allocate (const constexpr_call *call)
    3888              : {
    3889       119140 :   return (call
    3890       108512 :           && call->fundef
    3891       227652 :           && is_std_allocator_allocate (call->fundef->decl));
    3892              : }
    3893              : 
    3894              : /* Return true if FNDECL is std::allocator<T>::{,de}allocate.  */
    3895              : 
    3896              : static bool
    3897       664934 : is_std_allocator_allocate_deallocate (tree fndecl)
    3898              : {
    3899       664934 :   tree name = DECL_NAME (fndecl);
    3900       664934 :   if (name == NULL_TREE
    3901       664934 :       || !(id_equal (name, "allocate") || id_equal (name, "deallocate")))
    3902              :     return false;
    3903              : 
    3904       618156 :   return is_std_allocator (DECL_CONTEXT (fndecl));
    3905              : }
    3906              : 
    3907              : /* Overload for the above taking constexpr_call*.  */
    3908              : 
    3909              : static inline bool
    3910       499300 : is_std_allocator_allocate_deallocate (const constexpr_call *call)
    3911              : {
    3912       499300 :   return (call
    3913       302144 :           && call->fundef
    3914       801444 :           && is_std_allocator_allocate_deallocate (call->fundef->decl));
    3915              : }
    3916              : 
    3917              : /* Return true if FNDECL is std::source_location::current.  */
    3918              : 
    3919              : static inline bool
    3920        58342 : is_std_source_location_current (tree fndecl)
    3921              : {
    3922        58342 :   if (!decl_in_std_namespace_p (fndecl))
    3923              :     return false;
    3924              : 
    3925        39155 :   tree name = DECL_NAME (fndecl);
    3926        39155 :   if (name == NULL_TREE || !id_equal (name, "current"))
    3927              :     return false;
    3928              : 
    3929          159 :   tree ctx = DECL_CONTEXT (fndecl);
    3930          159 :   if (ctx == NULL_TREE || !CLASS_TYPE_P (ctx) || !TYPE_MAIN_DECL (ctx))
    3931              :     return false;
    3932              : 
    3933          159 :   name = DECL_NAME (TYPE_MAIN_DECL (ctx));
    3934          159 :   return name && id_equal (name, "source_location");
    3935              : }
    3936              : 
    3937              : /* Overload for the above taking constexpr_call*.  */
    3938              : 
    3939              : static inline bool
    3940        85560 : is_std_source_location_current (const constexpr_call *call)
    3941              : {
    3942        85560 :   return (call
    3943        58342 :           && call->fundef
    3944       143902 :           && is_std_source_location_current (call->fundef->decl));
    3945              : }
    3946              : 
    3947              : /* Return true if FNDECL is __dynamic_cast.  */
    3948              : 
    3949              : static inline bool
    3950     36928918 : cxx_dynamic_cast_fn_p (tree fndecl)
    3951              : {
    3952     36928918 :   return (cxx_dialect >= cxx20
    3953     34864523 :           && id_equal (DECL_NAME (fndecl), "__dynamic_cast")
    3954         6788 :           && CP_DECL_CONTEXT (fndecl) == abi_node
    3955              :           /* Only consider implementation-detail __dynamic_cast calls that
    3956              :              correspond to a dynamic_cast, and ignore direct calls to
    3957              :              abi::__dynamic_cast.  */
    3958     36935706 :           && DECL_ARTIFICIAL (fndecl));
    3959              : }
    3960              : 
    3961              : /* Often, we have an expression in the form of address + offset, e.g.
    3962              :    "&_ZTV1A + 16".  Extract the object from it, i.e. "_ZTV1A".  */
    3963              : 
    3964              : static tree
    3965         5840 : extract_obj_from_addr_offset (tree expr)
    3966              : {
    3967         5840 :   if (TREE_CODE (expr) == POINTER_PLUS_EXPR)
    3968         2786 :     expr = TREE_OPERAND (expr, 0);
    3969         5840 :   STRIP_NOPS (expr);
    3970         5840 :   if (TREE_CODE (expr) == ADDR_EXPR)
    3971         5829 :     expr = TREE_OPERAND (expr, 0);
    3972         5840 :   return expr;
    3973              : }
    3974              : 
    3975              : /* Given a PATH like
    3976              : 
    3977              :      g.D.2181.D.2154.D.2102.D.2093
    3978              : 
    3979              :    find a component with type TYPE.  Return NULL_TREE if not found, and
    3980              :    error_mark_node if the component is not accessible.  If STOP is non-null,
    3981              :    this function will return NULL_TREE if STOP is found before TYPE.  */
    3982              : 
    3983              : static tree
    3984         2831 : get_component_with_type (tree path, tree type, tree stop)
    3985              : {
    3986         7921 :   while (true)
    3987              :     {
    3988         5376 :       if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path), type))
    3989              :         /* Found it.  */
    3990              :         return path;
    3991         3761 :       else if (stop
    3992         3761 :                && (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (path),
    3993              :                                                               stop)))
    3994              :         return NULL_TREE;
    3995         3716 :       else if (TREE_CODE (path) == COMPONENT_REF
    3996         3716 :                && DECL_FIELD_IS_BASE (TREE_OPERAND (path, 1)))
    3997              :         {
    3998              :           /* We need to check that the component we're accessing is in fact
    3999              :              accessible.  */
    4000         3716 :           if (TREE_PRIVATE (TREE_OPERAND (path, 1))
    4001         3716 :               || TREE_PROTECTED (TREE_OPERAND (path, 1)))
    4002         1171 :             return error_mark_node;
    4003         2545 :           path = TREE_OPERAND (path, 0);
    4004              :         }
    4005              :       else
    4006              :         return NULL_TREE;
    4007              :     }
    4008              : }
    4009              : 
    4010              : /* Evaluate a call to __dynamic_cast (permitted by P1327R1).
    4011              : 
    4012              :    The declaration of __dynamic_cast is:
    4013              : 
    4014              :    void* __dynamic_cast (const void* __src_ptr,
    4015              :                          const __class_type_info* __src_type,
    4016              :                          const __class_type_info* __dst_type,
    4017              :                          ptrdiff_t __src2dst);
    4018              : 
    4019              :    where src2dst has the following possible values
    4020              : 
    4021              :    >-1: src_type is a unique public non-virtual base of dst_type
    4022              :         dst_ptr + src2dst == src_ptr
    4023              :    -1: unspecified relationship
    4024              :    -2: src_type is not a public base of dst_type
    4025              :    -3: src_type is a multiple public non-virtual base of dst_type  */
    4026              : 
    4027              : static tree
    4028         3173 : cxx_eval_dynamic_cast_fn (const constexpr_ctx *ctx, tree call,
    4029              :                           bool *non_constant_p, bool *overflow_p,
    4030              :                           tree *jump_target)
    4031              : {
    4032              :   /* T will be something like
    4033              :       __dynamic_cast ((B*) b, &_ZTI1B, &_ZTI1D, 8)
    4034              :      dismantle it.  */
    4035         3173 :   gcc_assert (call_expr_nargs (call) == 4);
    4036         3173 :   tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
    4037         3173 :   tree obj = CALL_EXPR_ARG (call, 0);
    4038         3173 :   tree type = CALL_EXPR_ARG (call, 2);
    4039         3173 :   HOST_WIDE_INT hint = int_cst_value (CALL_EXPR_ARG (call, 3));
    4040         3173 :   location_t loc = cp_expr_loc_or_input_loc (call);
    4041              : 
    4042              :   /* Get the target type of the dynamic_cast.  */
    4043         3173 :   gcc_assert (TREE_CODE (type) == ADDR_EXPR);
    4044         3173 :   type = TREE_OPERAND (type, 0);
    4045         3173 :   type = TREE_TYPE (DECL_NAME (type));
    4046              : 
    4047              :   /* TYPE can only be either T* or T&.  We can't know which of these it
    4048              :      is by looking at TYPE, but OBJ will be "(T*) x" in the first case,
    4049              :      and something like "(T*)(T&)(T*) x" in the second case.
    4050              :      This is true for the reference cases in C++ < 26 or when exceptions
    4051              :      aren't enabled, in that case we should diagnose errors.  For C++26
    4052              :      with exceptions we should silently evaluate to null pointer and
    4053              :      let the callers call __cxa_bad_cast () later to throw an exception.  */
    4054         3173 :   bool fail_for_non_constant_p = false;
    4055        12899 :   while (CONVERT_EXPR_P (obj) || TREE_CODE (obj) == SAVE_EXPR)
    4056              :     {
    4057         9726 :       if (cxx_dialect < cxx26 || !flag_exceptions)
    4058         5557 :         fail_for_non_constant_p |= TYPE_REF_P (TREE_TYPE (obj));
    4059         9726 :       obj = TREE_OPERAND (obj, 0);
    4060              :     }
    4061              : 
    4062              :   /* Evaluate the object so that we know its dynamic type.  */
    4063         3173 :   obj = cxx_eval_constant_expression (ctx, obj, vc_prvalue, non_constant_p,
    4064              :                                       overflow_p, jump_target);
    4065         3173 :   if (*non_constant_p)
    4066              :     return call;
    4067         3054 :   if (*jump_target)
    4068              :     return NULL_TREE;
    4069              : 
    4070              :   /* For dynamic_cast from classes with virtual bases we can get something
    4071              :      like (virt_base *)(&d + 16) as OBJ.  Try to convert that into
    4072              :      d.D.1234 using cxx_fold_indirect_ref.  */
    4073         3054 :   if (cxx_dialect >= cxx26 && CONVERT_EXPR_P (obj))
    4074              :     {
    4075         1206 :       tree objo = obj;
    4076         1206 :       STRIP_NOPS (objo);
    4077         1206 :       if (TREE_CODE (objo) == POINTER_PLUS_EXPR)
    4078              :         {
    4079         1152 :           objo = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (TREE_TYPE (obj)),
    4080              :                                         obj, NULL, jump_target);
    4081         1152 :           if (objo)
    4082         1152 :             obj = build_fold_addr_expr (objo);
    4083              :         }
    4084              :     }
    4085              : 
    4086              :   /* We expect OBJ to be in form of &d.D.2102 when HINT == 0,
    4087              :      but when HINT is > 0, it can also be something like
    4088              :      &d.D.2102 + 18446744073709551608, which includes the BINFO_OFFSET.  */
    4089         3054 :   obj = extract_obj_from_addr_offset (obj);
    4090         3054 :   const tree objtype = TREE_TYPE (obj);
    4091              :   /* If OBJ doesn't refer to a base field, we're done.  */
    4092         6029 :   if (tree t = (TREE_CODE (obj) == COMPONENT_REF
    4093         3054 :                 ? TREE_OPERAND (obj, 1) : obj))
    4094         3054 :     if (TREE_CODE (t) != FIELD_DECL || !DECL_FIELD_IS_BASE (t))
    4095              :       {
    4096           79 :         if (fail_for_non_constant_p)
    4097              :           {
    4098           55 :             if (!ctx->quiet)
    4099              :               {
    4100            2 :                 auto_diagnostic_group d;
    4101            2 :                 error_at (loc, "reference %<dynamic_cast%> failed");
    4102            2 :                 inform (loc, "dynamic type %qT of its operand does "
    4103              :                         "not have a base class of type %qT",
    4104              :                         objtype, type);
    4105            2 :               }
    4106           55 :             *non_constant_p = true;
    4107              :           }
    4108           79 :         return integer_zero_node;
    4109              :       }
    4110              : 
    4111              :   /* [class.cdtor] When a dynamic_cast is used in a constructor ...
    4112              :      or in a destructor ... if the operand of the dynamic_cast refers
    4113              :      to the object under construction or destruction, this object is
    4114              :      considered to be a most derived object that has the type of the
    4115              :      constructor or destructor's class.  */
    4116         2975 :   tree vtable = build_vfield_ref (obj, objtype);
    4117         2975 :   vtable = cxx_eval_constant_expression (ctx, vtable, vc_prvalue,
    4118              :                                          non_constant_p, overflow_p,
    4119              :                                          jump_target);
    4120         2975 :   if (*non_constant_p)
    4121              :     return call;
    4122         2798 :   if (*jump_target)
    4123              :     return NULL_TREE;
    4124              :   /* With -fsanitize=vptr, we initialize all vtable pointers to null,
    4125              :      so it's possible that we got a null pointer now.  */
    4126         2798 :   if (integer_zerop (vtable))
    4127              :     {
    4128           12 :       if (!ctx->quiet)
    4129            3 :         error_at (loc, "virtual table pointer is used uninitialized");
    4130           12 :       *non_constant_p = true;
    4131           12 :       return integer_zero_node;
    4132              :     }
    4133              :   /* VTABLE will be &_ZTV1A + 16 or similar, get _ZTV1A.  */
    4134         2786 :   vtable = extract_obj_from_addr_offset (vtable);
    4135         2786 :   const tree mdtype = DECL_CONTEXT (vtable);
    4136              : 
    4137              :   /* Given dynamic_cast<T>(v),
    4138              : 
    4139              :      [expr.dynamic.cast] If C is the class type to which T points or refers,
    4140              :      the runtime check logically executes as follows:
    4141              : 
    4142              :      If, in the most derived object pointed (referred) to by v, v points
    4143              :      (refers) to a public base class subobject of a C object, and if only
    4144              :      one object of type C is derived from the subobject pointed (referred)
    4145              :      to by v the result points (refers) to that C object.
    4146              : 
    4147              :      In this case, HINT >= 0 or -3.  */
    4148         2786 :   if (hint >= 0 || hint == -3)
    4149              :     {
    4150              :       /* Look for a component with type TYPE.  */
    4151          687 :       tree t = get_component_with_type (obj, type, mdtype);
    4152              :       /* If not accessible, give an error.  */
    4153          687 :       if (t == error_mark_node)
    4154              :         {
    4155          198 :           if (fail_for_non_constant_p)
    4156              :             {
    4157          108 :               if (!ctx->quiet)
    4158              :                 {
    4159           12 :                   auto_diagnostic_group d;
    4160           12 :                   error_at (loc, "reference %<dynamic_cast%> failed");
    4161           12 :                   inform (loc, "static type %qT of its operand is a "
    4162              :                           "non-public base class of dynamic type %qT",
    4163              :                           objtype, type);
    4164              : 
    4165           12 :                 }
    4166          108 :               *non_constant_p = true;
    4167              :             }
    4168          198 :           return integer_zero_node;
    4169              :         }
    4170          489 :       else if (t)
    4171              :         /* The result points to the TYPE object.  */
    4172          444 :         return cp_build_addr_expr (t, complain);
    4173              :       /* Else, TYPE was not found, because the HINT turned out to be wrong.
    4174              :          Fall through to the normal processing.  */
    4175              :     }
    4176              : 
    4177              :   /* Otherwise, if v points (refers) to a public base class subobject of the
    4178              :      most derived object, and the type of the most derived object has a base
    4179              :      class, of type C, that is unambiguous and public, the result points
    4180              :      (refers) to the C subobject of the most derived object.
    4181              : 
    4182              :      But it can also be an invalid case.  */
    4183              : 
    4184              :   /* Get the most derived object.  */
    4185         2144 :   obj = get_component_with_type (obj, mdtype, NULL_TREE);
    4186         2144 :   if (obj == error_mark_node)
    4187              :     {
    4188          973 :       if (fail_for_non_constant_p)
    4189              :         {
    4190          350 :           if (!ctx->quiet)
    4191              :             {
    4192           38 :               auto_diagnostic_group d;
    4193           38 :               error_at (loc, "reference %<dynamic_cast%> failed");
    4194           38 :               inform (loc, "static type %qT of its operand is a non-public"
    4195              :                       " base class of dynamic type %qT", objtype, mdtype);
    4196           38 :             }
    4197          350 :           *non_constant_p = true;
    4198              :         }
    4199          973 :       return integer_zero_node;
    4200              :     }
    4201              :   else
    4202         1171 :     gcc_assert (obj);
    4203              : 
    4204              :   /* Check that the type of the most derived object has a base class
    4205              :      of type TYPE that is unambiguous and public.  */
    4206         1171 :   base_kind b_kind;
    4207         1171 :   tree binfo = lookup_base (mdtype, type, ba_check, &b_kind, tf_none);
    4208         1171 :   if (!binfo || binfo == error_mark_node)
    4209              :     {
    4210          441 :       if (fail_for_non_constant_p)
    4211              :         {
    4212          134 :           if (!ctx->quiet)
    4213              :             {
    4214           16 :               auto_diagnostic_group d;
    4215           16 :               error_at (loc, "reference %<dynamic_cast%> failed");
    4216           16 :               if (b_kind == bk_ambig)
    4217            6 :                 inform (loc, "%qT is an ambiguous base class of dynamic "
    4218              :                         "type %qT of its operand", type, mdtype);
    4219              :               else
    4220           10 :                 inform (loc, "dynamic type %qT of its operand does not "
    4221              :                         "have an unambiguous public base class %qT",
    4222              :                         mdtype, type);
    4223           16 :             }
    4224          134 :           *non_constant_p = true;
    4225              :         }
    4226          441 :       return integer_zero_node;
    4227              :     }
    4228              :   /* If so, return the TYPE subobject of the most derived object.  */
    4229          730 :   obj = convert_to_base_statically (obj, binfo);
    4230          730 :   return cp_build_addr_expr (obj, complain);
    4231              : }
    4232              : 
    4233              : /* Data structure used by replace_decl and replace_decl_r.  */
    4234              : 
    4235              : struct replace_decl_data
    4236              : {
    4237              :   /* The _DECL we want to replace.  */
    4238              :   tree decl;
    4239              :   /* The replacement for DECL.  */
    4240              :   tree replacement;
    4241              :   /* Trees we've visited.  */
    4242              :   hash_set<tree> *pset;
    4243              :   /* Whether we've performed any replacements.  */
    4244              :   bool changed;
    4245              : };
    4246              : 
    4247              : /* Helper function for replace_decl, called through cp_walk_tree.  */
    4248              : 
    4249              : static tree
    4250     17066293 : replace_decl_r (tree *tp, int *walk_subtrees, void *data)
    4251              : {
    4252     17066293 :   replace_decl_data *d = (replace_decl_data *) data;
    4253              : 
    4254              :   /* We could be replacing
    4255              :        &<retval>.bar -> &foo.bar
    4256              :      where foo is a static VAR_DECL, so we need to recompute TREE_CONSTANT
    4257              :      on the ADDR_EXPR around it.  */
    4258     17066293 :   if (TREE_CODE (*tp) == ADDR_EXPR)
    4259              :     {
    4260      1539069 :       d->pset->add (*tp);
    4261      1539069 :       auto save_changed = d->changed;
    4262      1539069 :       d->changed = false;
    4263      1539069 :       cp_walk_tree (&TREE_OPERAND (*tp, 0), replace_decl_r, d, nullptr);
    4264      1539069 :       if (d->changed)
    4265              :         {
    4266         1855 :           cxx_mark_addressable (*tp);
    4267         1855 :           recompute_tree_invariant_for_addr_expr (*tp);
    4268              :         }
    4269              :       else
    4270      1537214 :         d->changed = save_changed;
    4271      1539069 :       *walk_subtrees = 0;
    4272              :     }
    4273     15527224 :   else if (*tp == d->decl)
    4274              :     {
    4275         2095 :       *tp = unshare_expr (d->replacement);
    4276         2095 :       d->changed = true;
    4277         2095 :       *walk_subtrees = 0;
    4278              :     }
    4279     15525129 :   else if (TYPE_P (*tp)
    4280     15525129 :            || d->pset->add (*tp))
    4281      2835310 :     *walk_subtrees = 0;
    4282              : 
    4283     17066293 :   return NULL_TREE;
    4284              : }
    4285              : 
    4286              : /* Replace every occurrence of DECL with (an unshared copy of)
    4287              :    REPLACEMENT within the expression *TP.  Returns true iff a
    4288              :    replacement was performed.  */
    4289              : 
    4290              : bool
    4291      2274915 : replace_decl (tree *tp, tree decl, tree replacement)
    4292              : {
    4293      2274915 :   gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
    4294              :                        (TREE_TYPE (decl), TREE_TYPE (replacement)));
    4295      2274915 :   hash_set<tree> pset;
    4296      2274915 :   replace_decl_data data = { decl, replacement, &pset, false };
    4297      2274915 :   cp_walk_tree (tp, replace_decl_r, &data, NULL);
    4298      2274915 :   return data.changed;
    4299      2274915 : }
    4300              : 
    4301              : /* Evaluate the call T to virtual function thunk THUNK_FNDECL.  */
    4302              : 
    4303              : static tree
    4304           44 : cxx_eval_thunk_call (const constexpr_ctx *ctx, tree t, tree thunk_fndecl,
    4305              :                      value_cat lval,
    4306              :                      bool *non_constant_p, bool *overflow_p, tree *jump_target)
    4307              : {
    4308           44 :   tree function = THUNK_TARGET (thunk_fndecl);
    4309              : 
    4310           44 :   if (THUNK_VIRTUAL_OFFSET (thunk_fndecl))
    4311              :     {
    4312           13 :       if (!ctx->quiet)
    4313              :         {
    4314            3 :           if (!DECL_DECLARED_CONSTEXPR_P (function))
    4315              :             {
    4316            0 :               error ("call to non-%<constexpr%> function %qD", function);
    4317            0 :               explain_invalid_constexpr_fn (function);
    4318              :             }
    4319              :           else
    4320              :             /* virtual_offset is only set for virtual bases, which make the
    4321              :                class non-literal, so we don't need to handle it here.  */
    4322            3 :             error ("calling constexpr member function %qD through virtual "
    4323              :                    "base subobject", function);
    4324              :         }
    4325           13 :       *non_constant_p = true;
    4326           13 :       return t;
    4327              :     }
    4328              : 
    4329           31 :   tree new_call = copy_node (t);
    4330           31 :   CALL_EXPR_FN (new_call) = function;
    4331           31 :   TREE_TYPE (new_call) = TREE_TYPE (TREE_TYPE (function));
    4332              : 
    4333           31 :   tree offset = size_int (THUNK_FIXED_OFFSET (thunk_fndecl));
    4334              : 
    4335           31 :   if (DECL_THIS_THUNK_P (thunk_fndecl))
    4336              :     {
    4337              :       /* 'this'-adjusting thunk.  */
    4338           19 :       tree this_arg = CALL_EXPR_ARG (t, 0);
    4339           19 :       this_arg = build2 (POINTER_PLUS_EXPR, TREE_TYPE (this_arg),
    4340              :                          this_arg, offset);
    4341           19 :       CALL_EXPR_ARG (new_call, 0) = this_arg;
    4342              :     }
    4343              :   else
    4344              :     {
    4345              :       /* Return-adjusting thunk.  As in expand_thunk, adjust a pointer only
    4346              :          if it is non-null.  */
    4347           12 :       tree call = new_call;
    4348           12 :       if (TYPE_PTR_P (TREE_TYPE (call)))
    4349           12 :         call = save_expr (call);
    4350           12 :       new_call = build2 (POINTER_PLUS_EXPR, TREE_TYPE (call), call, offset);
    4351           12 :       if (TYPE_PTR_P (TREE_TYPE (call)))
    4352           12 :         new_call = build_if_nonnull (call, new_call, tf_none);
    4353              :     }
    4354              : 
    4355           31 :   tree result = cxx_eval_constant_expression (ctx, new_call, lval,
    4356              :                                                non_constant_p, overflow_p,
    4357              :                                                jump_target);
    4358           31 :   if (!*non_constant_p
    4359           27 :       && !*overflow_p
    4360           27 :       && !*jump_target
    4361           27 :       && result != void_node
    4362           27 :       && INDIRECT_TYPE_P (TREE_TYPE (t))
    4363           55 :       && !(same_type_ignoring_top_level_qualifiers_p
    4364           24 :            (TREE_TYPE (result), TREE_TYPE (t))))
    4365           15 :     result = adjust_temp_type (TREE_TYPE (t), result);
    4366              :   return result;
    4367              : }
    4368              : 
    4369              : /* If OBJECT is of const class type, evaluate it to a CONSTRUCTOR and set
    4370              :    its TREE_READONLY flag according to READONLY_P.  Used for constexpr
    4371              :    'tors to detect modifying const objects in a constexpr context.  */
    4372              : 
    4373              : static void
    4374     11185101 : cxx_set_object_constness (const constexpr_ctx *ctx, tree object,
    4375              :                           bool readonly_p, bool *non_constant_p,
    4376              :                           bool *overflow_p, tree *jump_target)
    4377              : {
    4378     22370202 :   if (CLASS_TYPE_P (TREE_TYPE (object))
    4379     22370202 :       && CP_TYPE_CONST_P (TREE_TYPE (object)))
    4380              :     {
    4381              :       /* Subobjects might not be stored in ctx->global->values but we
    4382              :          can get its CONSTRUCTOR by evaluating *this.  */
    4383      1042148 :       tree e = cxx_eval_constant_expression (ctx, object, vc_prvalue,
    4384              :                                              non_constant_p, overflow_p,
    4385              :                                              jump_target);
    4386      1042148 :       if (!*non_constant_p
    4387     12185564 :           && !throws (jump_target)
    4388      2042611 :           && TREE_CODE (e) == CONSTRUCTOR)
    4389      1000463 :         TREE_READONLY (e) = readonly_p;
    4390              :     }
    4391     11185101 : }
    4392              : 
    4393              : /* Allocate an exception for OBJECT and throw it.  */
    4394              : 
    4395              : tree
    4396         3164 : cxa_allocate_and_throw_exception (location_t loc, const constexpr_ctx *ctx,
    4397              :                                   tree object)
    4398              : {
    4399         3164 :   tree type = TREE_TYPE (object);
    4400              :   /* This simulates a call to __cxa_allocate_exception.  We need
    4401              :      (struct exception *) &heap -- memory on the heap so that
    4402              :      it can survive the stack being unwound.  */
    4403         3164 :   tree arr = build_array_of_n_type (type, 1);
    4404         3164 :   tree var = cxa_allocate_exception (loc, ctx, arr, size_zero_node);
    4405         3164 :   DECL_NAME (var) = heap_identifier;
    4406         3164 :   ctx->global->put_value (var, NULL_TREE);
    4407              : 
    4408              :   /* *(struct exception *) &heap  = exc{ ... }  */
    4409         3164 :   tree ptr = build_nop (build_pointer_type (type), build_address (var));
    4410         3164 :   object = cp_build_init_expr (cp_build_fold_indirect_ref (ptr), object);
    4411         3164 :   bool non_constant_p = false, overflow_p = false;
    4412         3164 :   tree jump_target = NULL_TREE;
    4413         3164 :   cxx_eval_constant_expression (ctx, object, vc_prvalue, &non_constant_p,
    4414              :                                 &overflow_p, &jump_target);
    4415         3164 :   if (non_constant_p)
    4416              :     {
    4417            0 :       if (!ctx->quiet)
    4418            0 :         error_at (loc, "couldn%'t throw %qT", type);
    4419              :       return NULL_TREE;
    4420              :     }
    4421              : 
    4422              :   /* Now we can __cxa_throw.  */
    4423         3164 :   DECL_EXCEPTION_REFCOUNT (var)
    4424         3164 :     = size_binop (PLUS_EXPR, DECL_EXCEPTION_REFCOUNT (var), size_one_node);
    4425         3164 :   ++ctx->global->uncaught_exceptions;
    4426              : 
    4427         3164 :   return var;
    4428              : }
    4429              : 
    4430              : /* Subroutine of cxx_eval_constant_expression.
    4431              :    Evaluate the call expression tree T in the context of OLD_CALL expression
    4432              :    evaluation.  */
    4433              : 
    4434              : static tree
    4435    206993461 : cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
    4436              :                           value_cat lval,
    4437              :                           bool *non_constant_p, bool *overflow_p,
    4438              :                           tree *jump_target)
    4439              : {
    4440    206993461 :   location_t loc = cp_expr_loc_or_input_loc (t);
    4441    206993461 :   tree fun = get_function_named_in_call (t);
    4442              : 
    4443    206993461 :   if (fun == NULL_TREE)
    4444       388244 :     return cxx_eval_internal_function (ctx, t, lval,
    4445              :                                        non_constant_p, overflow_p,
    4446       388244 :                                        jump_target);
    4447              : 
    4448    206605217 :   if (TREE_CODE (fun) != FUNCTION_DECL)
    4449              :     {
    4450              :       /* Might be a constexpr function pointer.  */
    4451       419654 :       fun = cxx_eval_constant_expression (ctx, fun, vc_prvalue,
    4452              :                                           non_constant_p, overflow_p,
    4453              :                                           jump_target);
    4454       419654 :       if (*jump_target)
    4455              :         return NULL_TREE;
    4456       419654 :       STRIP_NOPS (fun);
    4457       419654 :       if (TREE_CODE (fun) == ADDR_EXPR)
    4458        31303 :         fun = TREE_OPERAND (fun, 0);
    4459              :       /* For TARGET_VTABLE_USES_DESCRIPTORS targets, there is no
    4460              :          indirection, the called expression is a pointer into the
    4461              :          virtual table which should contain FDESC_EXPR.  Extract the
    4462              :          FUNCTION_DECL from there.  */
    4463              :       else if (TARGET_VTABLE_USES_DESCRIPTORS
    4464              :                && TREE_CODE (fun) == POINTER_PLUS_EXPR
    4465              :                && TREE_CODE (TREE_OPERAND (fun, 0)) == ADDR_EXPR
    4466              :                && TREE_CODE (TREE_OPERAND (fun, 1)) == INTEGER_CST)
    4467              :         {
    4468              :           tree d = TREE_OPERAND (TREE_OPERAND (fun, 0), 0);
    4469              :           if (VAR_P (d)
    4470              :               && DECL_VTABLE_OR_VTT_P (d)
    4471              :               && TREE_CODE (TREE_TYPE (d)) == ARRAY_TYPE
    4472              :               && TREE_TYPE (TREE_TYPE (d)) == vtable_entry_type
    4473              :               && DECL_INITIAL (d)
    4474              :               && TREE_CODE (DECL_INITIAL (d)) == CONSTRUCTOR)
    4475              :             {
    4476              :               tree i = int_const_binop (TRUNC_DIV_EXPR, TREE_OPERAND (fun, 1),
    4477              :                                         TYPE_SIZE_UNIT (vtable_entry_type));
    4478              :               HOST_WIDE_INT idx = find_array_ctor_elt (DECL_INITIAL (d), i);
    4479              :               if (idx >= 0)
    4480              :                 {
    4481              :                   tree fdesc
    4482              :                     = (*CONSTRUCTOR_ELTS (DECL_INITIAL (d)))[idx].value;
    4483              :                   if (TREE_CODE (fdesc) == FDESC_EXPR
    4484              :                       && integer_zerop (TREE_OPERAND (fdesc, 1)))
    4485              :                     fun = TREE_OPERAND (fdesc, 0);
    4486              :                 }
    4487              :             }
    4488              :         }
    4489              :     }
    4490    206605217 :   if (TREE_CODE (fun) != FUNCTION_DECL)
    4491              :     {
    4492       388351 :       if (!ctx->quiet && !*non_constant_p)
    4493            0 :         error_at (loc, "expression %qE does not designate a %<constexpr%> "
    4494              :                   "function", fun);
    4495       388351 :       *non_constant_p = true;
    4496       388351 :       return t;
    4497              :     }
    4498    206216866 :   tree orig_fun = fun;
    4499    206216866 :   if (DECL_CLONED_FUNCTION_P (fun) && !DECL_DELETING_DESTRUCTOR_P (fun))
    4500     24582036 :     fun = DECL_CLONED_FUNCTION (fun);
    4501              : 
    4502    206216866 :   if (is_ubsan_builtin_p (fun))
    4503           58 :     return void_node;
    4504              : 
    4505    206216808 :   if (fndecl_built_in_p (fun))
    4506     20742282 :     return cxx_eval_builtin_function_call (ctx, t, fun,
    4507              :                                            lval, non_constant_p, overflow_p,
    4508     20742280 :                                            jump_target);
    4509    185474526 :   if (DECL_THUNK_P (fun))
    4510           44 :     return cxx_eval_thunk_call (ctx, t, fun, lval, non_constant_p, overflow_p,
    4511           44 :                                 jump_target);
    4512    185474482 :   if (metafunction_p (fun))
    4513              :     {
    4514              :       /* To be able to evaluate a metafunction, we may have to instantiate
    4515              :          constexpr functions.  If we're not allowed to instantiate, leave
    4516              :          this for later.  Don't evaluate metafunctions at all when mce_unknown,
    4517              :          otherwise we might fold those prematurely.  See
    4518              :          g++.dg/reflect/p2996-17.C.  */
    4519        82942 :       if (uid_sensitive_constexpr_evaluation_p ()
    4520        82380 :           || ctx->manifestly_const_eval == mce_unknown)
    4521              :         {
    4522        20924 :           *non_constant_p = true;
    4523        20924 :           return t;
    4524              :         }
    4525        62018 :       ctx->global->state_dependent = true;
    4526        62018 :       tree e = process_metafunction (ctx, fun, t, non_constant_p, overflow_p,
    4527              :                                      jump_target);
    4528        62018 :       if (*jump_target)
    4529              :         return NULL_TREE;
    4530        58842 :       if (*non_constant_p)
    4531              :         return t;
    4532        57774 :       e = cxx_eval_constant_expression (ctx, e, vc_prvalue,
    4533              :                                         non_constant_p, overflow_p,
    4534              :                                         jump_target);
    4535        57774 :       if (*jump_target)
    4536              :         return NULL_TREE;
    4537        57774 :       if (*non_constant_p)
    4538              :         return t;
    4539        57768 :       return e;
    4540              :     }
    4541    185391540 :   bool non_constexpr_call = false;
    4542    185391540 :   if (!maybe_constexpr_fn (fun))
    4543              :     {
    4544       905842 :       if (TREE_CODE (t) == CALL_EXPR
    4545       898285 :           && cxx_replaceable_global_alloc_fn (fun)
    4546      1571555 :           && (CALL_FROM_NEW_OR_DELETE_P (t)
    4547       331656 :               || is_std_allocator_allocate_deallocate (ctx->call)))
    4548              :         {
    4549       495775 :           const bool new_op_p = IDENTIFIER_NEW_OP_P (DECL_NAME (fun));
    4550       495775 :           const int nargs = call_expr_nargs (t);
    4551       495775 :           tree arg0 = NULL_TREE;
    4552       787137 :           for (int i = 0; i < nargs; ++i)
    4553              :             {
    4554       496844 :               tree arg = CALL_EXPR_ARG (t, i);
    4555       496844 :               arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    4556              :                                                   non_constant_p, overflow_p,
    4557              :                                                   jump_target);
    4558       496844 :               if (*jump_target)
    4559              :                 return NULL_TREE;
    4560              :               /* Deleting a non-constant pointer has a better error message
    4561              :                  below.  */
    4562       496834 :               if (new_op_p || i != 0)
    4563       416215 :                 VERIFY_CONSTANT (arg);
    4564       210743 :               if (i == 0)
    4565              :                 arg0 = arg;
    4566              :             }
    4567       290293 :           gcc_assert (arg0);
    4568       290293 :           if (new_op_p)
    4569              :             {
    4570       209674 :               if (!tree_fits_uhwi_p (arg0))
    4571              :                 {
    4572              :                   /* We should not get here; the VERIFY_CONSTANT above
    4573              :                      should have already caught it.  */
    4574            0 :                   gcc_checking_assert (false);
    4575              :                   if (!ctx->quiet)
    4576              :                     error_at (loc, "cannot allocate array: size not constant");
    4577              :                   *non_constant_p = true;
    4578              :                   return t;
    4579              :                 }
    4580       419348 :               tree type = build_array_type_nelts (char_type_node,
    4581       209674 :                                                   tree_to_uhwi (arg0));
    4582       209674 :               tree var = build_decl (loc, VAR_DECL,
    4583       209674 :                                      (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
    4584              :                                       & OVL_OP_FLAG_VEC)
    4585              :                                      ? heap_vec_uninit_identifier
    4586              :                                      : heap_uninit_identifier,
    4587       209674 :                                      type);
    4588       209674 :               DECL_ARTIFICIAL (var) = 1;
    4589       209674 :               ctx->global->heap_vars.safe_push (var);
    4590       209674 :               ctx->global->put_value (var, NULL_TREE);
    4591       209674 :               return fold_convert (ptr_type_node, build_address (var));
    4592              :             }
    4593              :           else
    4594              :             {
    4595        80619 :               STRIP_NOPS (arg0);
    4596        80619 :               if (TREE_CODE (arg0) == ADDR_EXPR
    4597        80619 :                   && VAR_P (TREE_OPERAND (arg0, 0)))
    4598              :                 {
    4599        80619 :                   tree var = TREE_OPERAND (arg0, 0);
    4600        80619 :                   if (DECL_NAME (var) == heap_uninit_identifier
    4601        80619 :                       || DECL_NAME (var) == heap_identifier)
    4602              :                     {
    4603        80445 :                       if (IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
    4604              :                           & OVL_OP_FLAG_VEC)
    4605              :                         {
    4606            9 :                           if (!ctx->quiet)
    4607              :                             {
    4608            3 :                               auto_diagnostic_group d;
    4609            3 :                               error_at (loc, "array deallocation of object "
    4610              :                                              "allocated with non-array "
    4611              :                                              "allocation");
    4612            3 :                               inform (DECL_SOURCE_LOCATION (var),
    4613              :                                       "allocation performed here");
    4614            3 :                             }
    4615            9 :                           *non_constant_p = true;
    4616            9 :                           return t;
    4617              :                         }
    4618        80436 :                       DECL_NAME (var) = heap_deleted_identifier;
    4619        80436 :                       ctx->global->destroy_value (var);
    4620        80436 :                       ctx->global->heap_dealloc_count++;
    4621        80436 :                       return void_node;
    4622              :                     }
    4623          174 :                   else if (DECL_NAME (var) == heap_vec_uninit_identifier
    4624          174 :                            || DECL_NAME (var) == heap_vec_identifier)
    4625              :                     {
    4626          150 :                       if ((IDENTIFIER_OVL_OP_FLAGS (DECL_NAME (fun))
    4627              :                            & OVL_OP_FLAG_VEC) == 0)
    4628              :                         {
    4629            9 :                           if (!ctx->quiet)
    4630              :                             {
    4631            3 :                               auto_diagnostic_group d;
    4632            3 :                               error_at (loc, "non-array deallocation of "
    4633              :                                              "object allocated with array "
    4634              :                                              "allocation");
    4635            3 :                               inform (DECL_SOURCE_LOCATION (var),
    4636              :                                       "allocation performed here");
    4637            3 :                             }
    4638            9 :                           *non_constant_p = true;
    4639            9 :                           return t;
    4640              :                         }
    4641          141 :                       DECL_NAME (var) = heap_deleted_identifier;
    4642          141 :                       ctx->global->destroy_value (var);
    4643          141 :                       ctx->global->heap_dealloc_count++;
    4644          141 :                       return void_node;
    4645              :                     }
    4646           24 :                   else if (DECL_NAME (var) == heap_deleted_identifier)
    4647              :                     {
    4648           15 :                       if (!ctx->quiet)
    4649            6 :                         error_at (loc, "deallocation of already deallocated "
    4650              :                                        "storage");
    4651           15 :                       *non_constant_p = true;
    4652           15 :                       return t;
    4653              :                     }
    4654              :                 }
    4655            9 :               if (!ctx->quiet)
    4656            3 :                 error_at (loc, "deallocation of storage that was "
    4657              :                                "not previously allocated");
    4658            9 :               *non_constant_p = true;
    4659            9 :               return t;
    4660              :             }
    4661              :         }
    4662              :       /* Allow placement new in std::construct_at, just return the second
    4663              :          argument.  */
    4664       410067 :       if (TREE_CODE (t) == CALL_EXPR
    4665       402510 :           && cxx_placement_new_fn (fun)
    4666       590871 :           && is_std_construct_at (ctx->call))
    4667              :         {
    4668        45973 :           const int nargs = call_expr_nargs (t);
    4669        45973 :           tree arg1 = NULL_TREE;
    4670       137919 :           for (int i = 0; i < nargs; ++i)
    4671              :             {
    4672        91946 :               tree arg = CALL_EXPR_ARG (t, i);
    4673        91946 :               arg = cxx_eval_constant_expression (ctx, arg, vc_prvalue,
    4674              :                                                   non_constant_p, overflow_p,
    4675              :                                                   jump_target);
    4676        91946 :               if (*jump_target)
    4677              :                 return NULL_TREE;
    4678        91946 :               if (i == 1)
    4679              :                 arg1 = arg;
    4680              :               else
    4681        91946 :                 VERIFY_CONSTANT (arg);
    4682              :             }
    4683        45973 :           gcc_assert (arg1);
    4684              :           return arg1;
    4685              :         }
    4686       364094 :       else if (cxx_dynamic_cast_fn_p (fun))
    4687         3173 :         return cxx_eval_dynamic_cast_fn (ctx, t, non_constant_p, overflow_p,
    4688         3173 :                                          jump_target);
    4689       360921 :       else if (enum cxa_builtin kind = cxx_cxa_builtin_fn_p (fun))
    4690        27937 :         return cxx_eval_cxa_builtin_fn (ctx, t, kind, fun,
    4691              :                                         non_constant_p, overflow_p,
    4692        27937 :                                         jump_target);
    4693              : 
    4694              :       /* Calls to non-constexpr functions can be diagnosed right away
    4695              :          before C++26, though in C++26 evaluation of the arguments might
    4696              :          throw and if caught it could be still constant expression.
    4697              :          So for C++26 this is diagnosed only after
    4698              :          cxx_bind_parameters_in_call.  */
    4699       332984 :       if (cxx_dialect >= cxx26)
    4700              :         non_constexpr_call = true;
    4701              :       else
    4702              :         {
    4703       292307 :           if (!ctx->quiet)
    4704              :             {
    4705          208 :               if (!lambda_static_thunk_p (fun))
    4706          208 :                 error_at (loc, "call to non-%<constexpr%> function %qD", fun);
    4707          208 :               explain_invalid_constexpr_fn (fun);
    4708              :             }
    4709       292307 :           *non_constant_p = true;
    4710       292307 :           return t;
    4711              :         }
    4712              :     }
    4713              : 
    4714    184526375 :   constexpr_ctx new_ctx = *ctx;
    4715    184526375 :   ctx = &new_ctx;
    4716    207618947 :   if (DECL_CONSTRUCTOR_P (fun) && !ctx->object
    4717    188519984 :       && TREE_CODE (t) == AGGR_INIT_EXPR)
    4718              :     {
    4719              :       /* We want to have an initialization target for an AGGR_INIT_EXPR.
    4720              :          If we don't already have one in CTX, use the AGGR_INIT_EXPR_SLOT.  */
    4721         2809 :       new_ctx.object = AGGR_INIT_EXPR_SLOT (t);
    4722         2809 :       tree ctor = new_ctx.ctor = build_constructor (DECL_CONTEXT (fun), NULL);
    4723         2809 :       CONSTRUCTOR_NO_CLEARING (ctor) = true;
    4724         2809 :       ctx->global->put_value (new_ctx.object, ctor);
    4725              :     }
    4726              :   /* An immediate invocation is manifestly constant evaluated including the
    4727              :      arguments of the call, so use mce_true even for the argument
    4728              :      evaluation.  */
    4729    369052750 :   if (DECL_IMMEDIATE_FUNCTION_P (fun))
    4730      4774412 :     new_ctx.manifestly_const_eval = mce_true;
    4731              : 
    4732              :   /* We used to shortcut trivial constructor/op= here, but nowadays
    4733              :      we can only get a trivial function here with -fno-elide-constructors.  */
    4734    184526511 :   gcc_checking_assert (!trivial_fn_p (fun)
    4735              :                        || !flag_elide_constructors
    4736              :                        /* Or it's a call from maybe_thunk_body (111075).  */
    4737              :                        || (TREE_CODE (t) == CALL_EXPR ? CALL_FROM_THUNK_P (t)
    4738              :                            : AGGR_INIT_FROM_THUNK_P (t))
    4739              :                        /* We don't elide constructors when processing
    4740              :                           a noexcept-expression.  */
    4741              :                        || cp_noexcept_operand);
    4742              : 
    4743    184526375 :   bool non_constant_args = false;
    4744    184526375 :   constexpr_call new_call;
    4745    184526375 :   new_call.bindings
    4746    184526375 :     = cxx_bind_parameters_in_call (ctx, t, fun, orig_fun, non_constant_p,
    4747              :                                    overflow_p, &non_constant_args,
    4748              :                                    jump_target);
    4749              : 
    4750              :   /* We build up the bindings list before we know whether we already have this
    4751              :      call cached.  If we don't end up saving these bindings, ggc_free them when
    4752              :      this function exits.  */
    4753    184526375 :   class free_bindings
    4754              :   {
    4755              :     tree *bindings;
    4756              :   public:
    4757    184526375 :     free_bindings (tree &b): bindings (&b) { }
    4758    184526371 :     ~free_bindings () { if (bindings) ggc_free (*bindings); }
    4759      4658176 :     void preserve () { bindings = NULL; }
    4760    184526375 :   } fb (new_call.bindings);
    4761              : 
    4762    184526375 :   if (*jump_target)
    4763              :     return NULL_TREE;
    4764    184526291 :   if (*non_constant_p)
    4765              :     return t;
    4766    110149998 :   if (non_constexpr_call)
    4767              :     {
    4768         6367 :       if (!ctx->quiet)
    4769              :         {
    4770          436 :           if (!lambda_static_thunk_p (fun))
    4771          436 :             error_at (loc, "call to non-%<constexpr%> function %qD", fun);
    4772          436 :           explain_invalid_constexpr_fn (fun);
    4773              :         }
    4774         6367 :       *non_constant_p = true;
    4775         6367 :       return t;
    4776              :     }
    4777              : 
    4778              :   /* We can't defer instantiating the function any longer.  */
    4779    110143631 :   if (!DECL_INITIAL (fun)
    4780      3143497 :       && (DECL_TEMPLOID_INSTANTIATION (fun) || DECL_DEFAULTED_FN (fun))
    4781    110143631 :       && !uid_sensitive_constexpr_evaluation_p ())
    4782              :     {
    4783      2900614 :       location_t save_loc = input_location;
    4784      2900614 :       input_location = loc;
    4785      2900614 :       ++function_depth;
    4786      2900614 :       if (ctx->manifestly_const_eval == mce_true)
    4787       369836 :         FNDECL_MANIFESTLY_CONST_EVALUATED (fun) = true;
    4788      2900614 :       if (DECL_TEMPLOID_INSTANTIATION (fun))
    4789      2900600 :         instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false);
    4790              :       else
    4791           14 :         synthesize_method (fun);
    4792      2900614 :       --function_depth;
    4793      2900614 :       input_location = save_loc;
    4794              :     }
    4795              : 
    4796              :   /* If in direct recursive call, optimize definition search.  */
    4797    110143631 :   if (ctx && ctx->call && ctx->call->fundef && ctx->call->fundef->decl == fun)
    4798        29271 :     new_call.fundef = ctx->call->fundef;
    4799              :   else
    4800              :     {
    4801    110114360 :       new_call.fundef = retrieve_constexpr_fundef (fun);
    4802    110114360 :       if (new_call.fundef == NULL || new_call.fundef->body == NULL
    4803    109542861 :           || new_call.fundef->result == error_mark_node
    4804    109527236 :           || fun == current_function_decl)
    4805              :         {
    4806       587130 :           if (!ctx->quiet)
    4807              :             {
    4808              :               /* We need to check for current_function_decl here in case we're
    4809              :                  being called during cp_fold_function, because at that point
    4810              :                  DECL_INITIAL is set properly and we have a fundef but we
    4811              :                  haven't lowered invisirefs yet (c++/70344).  */
    4812          187 :               if (DECL_INITIAL (fun) == error_mark_node
    4813          187 :                   || fun == current_function_decl)
    4814           15 :                 error_at (loc, "%qD called in a constant expression before its "
    4815              :                           "definition is complete", fun);
    4816          172 :               else if (DECL_INITIAL (fun))
    4817              :                 {
    4818              :                   /* The definition of fun was somehow unsuitable.  But pretend
    4819              :                      that lambda static thunks don't exist.  */
    4820          134 :                   if (!lambda_static_thunk_p (fun))
    4821          122 :                     error_at (loc, "%qD called in a constant expression", fun);
    4822          134 :                   explain_invalid_constexpr_fn (fun);
    4823              :                 }
    4824              :               else
    4825           38 :                 error_at (loc, "%qD used before its definition", fun);
    4826              :             }
    4827       587130 :           *non_constant_p = true;
    4828       587130 :           return t;
    4829              :         }
    4830              :     }
    4831              : 
    4832              :   /* Don't complain about problems evaluating an ill-formed function.  */
    4833    109556501 :   if (function *f = DECL_STRUCT_FUNCTION (fun))
    4834    109556501 :     if (f->language->erroneous)
    4835          976 :       new_ctx.quiet = true;
    4836              : 
    4837    109556501 :   int depth_ok = push_cx_call_context (t);
    4838              : 
    4839              :   /* Remember the object we are constructing or destructing.  */
    4840    109556501 :   tree new_obj = NULL_TREE;
    4841    219113002 :   if (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))
    4842              :     {
    4843              :       /* In a cdtor, it should be the first `this' argument.
    4844              :          At this point it has already been evaluated in the call
    4845              :          to cxx_bind_parameters_in_call.  */
    4846     13814828 :       new_obj = TREE_VEC_ELT (new_call.bindings, 0);
    4847     13814828 :       bool empty_base = false;
    4848     13814828 :       new_obj = cxx_fold_indirect_ref (ctx, loc, DECL_CONTEXT (fun), new_obj,
    4849              :                                        &empty_base, jump_target);
    4850     13814828 :       if (*jump_target)
    4851            0 :         return NULL_TREE;
    4852              :       /* If we're initializing an empty class, don't set constness, because
    4853              :          cxx_fold_indirect_ref will return the wrong object to set constness
    4854              :          of.  */
    4855     13814828 :       if (empty_base)
    4856              :         new_obj = NULL_TREE;
    4857      6903595 :       else if (ctx->call && ctx->call->fundef
    4858     25050454 :                && DECL_CONSTRUCTOR_P (ctx->call->fundef->decl))
    4859              :         {
    4860      3608695 :           tree cur_obj = TREE_VEC_ELT (ctx->call->bindings, 0);
    4861      3608695 :           STRIP_NOPS (cur_obj);
    4862      3608695 :           if (TREE_CODE (cur_obj) == ADDR_EXPR)
    4863      3606190 :             cur_obj = TREE_OPERAND (cur_obj, 0);
    4864      3608695 :           if (new_obj == cur_obj)
    4865              :             /* We're calling the target constructor of a delegating
    4866              :                constructor, or accessing a base subobject through a
    4867              :                NOP_EXPR as part of a call to a base constructor, so
    4868              :                there is no new (sub)object.  */
    4869     13814828 :             new_obj = NULL_TREE;
    4870              :         }
    4871              :     }
    4872              : 
    4873    109556501 :   tree result = NULL_TREE;
    4874              : 
    4875    109556501 :   constexpr_call *entry = NULL;
    4876    109556501 :   if (depth_ok && !non_constant_args && ctx->strict)
    4877              :     {
    4878     36959086 :       new_call.hash = constexpr_fundef_hasher::hash (new_call.fundef);
    4879     36959086 :       new_call.hash
    4880     36959086 :         = iterative_hash_template_arg (new_call.bindings, new_call.hash);
    4881              : 
    4882              :       /* If we have seen this call before, we are done.  */
    4883     36959086 :       maybe_initialize_constexpr_call_table ();
    4884     36959086 :       bool insert = depth_ok < constexpr_cache_depth;
    4885     36959086 :       constexpr_call **slot
    4886     50185796 :         = constexpr_call_table->find_slot (&new_call,
    4887              :                                            insert ? INSERT : NO_INSERT);
    4888     36959086 :       entry = slot ? *slot : NULL;
    4889     32580215 :       if (entry == NULL)
    4890              :         {
    4891              :           /* Only cache up to constexpr_cache_depth to limit memory use.  */
    4892      9037047 :           if (insert)
    4893              :             {
    4894              :               /* We need to keep a pointer to the entry, not just the slot, as
    4895              :                  the slot can move during evaluation of the body.  */
    4896      4658176 :               *slot = entry = ggc_alloc<constexpr_call> ();
    4897      4658176 :               *entry = new_call;
    4898      4658176 :               entry->result (ctx->manifestly_const_eval) = unknown_type_node;
    4899      4658176 :               fb.preserve ();
    4900              : 
    4901              :               /* Unshare args going into the hash table to separate them
    4902              :                  from the caller's context, for better GC and to avoid
    4903              :                  problems with verify_gimple.  */
    4904      4658176 :               tree bound = new_call.bindings;
    4905      7533612 :               for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
    4906              :                 {
    4907      2875436 :                   tree &arg = TREE_VEC_ELT (bound, i);
    4908      2875436 :                   arg = unshare_expr_without_location (arg);
    4909              :                 }
    4910              :             }
    4911              :         }
    4912              :       /* Calls that are in progress have their result set to unknown_type_node,
    4913              :          so that we can detect circular dependencies.  Now that we only cache
    4914              :          up to constexpr_cache_depth this won't catch circular dependencies that
    4915              :          start deeper, but they'll hit the recursion or ops limit.  */
    4916     27922039 :       else if (entry->result (ctx->manifestly_const_eval) == unknown_type_node)
    4917              :         {
    4918            6 :           if (!ctx->quiet)
    4919            0 :             error ("call has circular dependency");
    4920            6 :           *non_constant_p = true;
    4921            6 :           entry->result (ctx->manifestly_const_eval) = result = error_mark_node;
    4922              :         }
    4923              :       else
    4924     27922033 :         result = entry->result (ctx->manifestly_const_eval);
    4925              :     }
    4926              : 
    4927    109556468 :   if (!depth_ok)
    4928              :     {
    4929           33 :       if (!ctx->quiet)
    4930            3 :         error ("%<constexpr%> evaluation depth exceeds maximum of %d (use "
    4931              :                "%<-fconstexpr-depth=%> to increase the maximum)",
    4932              :                max_constexpr_depth);
    4933           33 :       *non_constant_p = true;
    4934           33 :       result = error_mark_node;
    4935              :     }
    4936              :   else
    4937              :     {
    4938    109556468 :       bool cacheable = !!entry;
    4939    109556468 :       if (result && result != error_mark_node)
    4940              :         /* OK */;
    4941     86767136 :       else if (!DECL_SAVED_TREE (fun))
    4942              :         {
    4943              :           /* When at_eof >= 3, cgraph has started throwing away
    4944              :              DECL_SAVED_TREE, so fail quietly.  FIXME we get here because of
    4945              :              late code generation for VEC_INIT_EXPR, which needs to be
    4946              :              completely reconsidered.  */
    4947            0 :           gcc_assert (at_eof >= 3 && ctx->quiet);
    4948            0 :           *non_constant_p = true;
    4949              :         }
    4950     86767136 :       else if (tree copy = get_fundef_copy (new_call.fundef))
    4951              :         {
    4952     86767127 :           tree body, parms, res;
    4953     86767127 :           releasing_vec ctors;
    4954              : 
    4955              :           /* Reuse or create a new unshared copy of this function's body.  */
    4956     86767127 :           body = TREE_PURPOSE (copy);
    4957     86767127 :           parms = TREE_VALUE (copy);
    4958     86767127 :           res = TREE_TYPE (copy);
    4959              : 
    4960              :           /* Associate the bindings with the remapped parms.  */
    4961     86767127 :           tree bound = new_call.bindings;
    4962     86767127 :           tree remapped = parms;
    4963    212349131 :           for (int i = 0; i < TREE_VEC_LENGTH (bound); ++i)
    4964              :             {
    4965    125582004 :               tree arg = TREE_VEC_ELT (bound, i);
    4966    125582004 :               if (entry)
    4967              :                 {
    4968              :                   /* Unshare again so the callee doesn't change the
    4969              :                      argument values in the hash table. XXX Could we unshare
    4970              :                      lazily in cxx_eval_store_expression?  */
    4971      3116230 :                   arg = unshare_constructor (arg);
    4972      3116230 :                   if (TREE_CODE (arg) == CONSTRUCTOR)
    4973       881138 :                     vec_safe_push (ctors, arg);
    4974              :                 }
    4975    125582004 :               ctx->global->put_value (remapped, arg);
    4976    125582004 :               remapped = DECL_CHAIN (remapped);
    4977              :             }
    4978     86767127 :           if (remapped)
    4979              :             {
    4980              :               /* We shouldn't have any parms without args, but fail gracefully
    4981              :                  in error recovery.  */
    4982            6 :               gcc_checking_assert (seen_error ());
    4983            6 :               *non_constant_p = true;
    4984              :             }
    4985              :           /* Add the RESULT_DECL to the values map, too.  */
    4986     86767127 :           gcc_assert (!DECL_BY_REFERENCE (res));
    4987     86767127 :           ctx->global->put_value (res, NULL_TREE);
    4988              : 
    4989              :           /* Remember the current call we're evaluating.  */
    4990     86767127 :           constexpr_ctx call_ctx = *ctx;
    4991     86767127 :           call_ctx.call = &new_call;
    4992     86767127 :           unsigned save_heap_alloc_count = ctx->global->heap_vars.length ();
    4993     86767127 :           unsigned save_heap_dealloc_count = ctx->global->heap_dealloc_count;
    4994     86767127 :           bool save_state_dependent = ctx->global->state_dependent;
    4995              : 
    4996              :           /* Make sure we fold std::is_constant_evaluated to true in an
    4997              :              immediate function.  */
    4998    173534254 :           if (DECL_IMMEDIATE_FUNCTION_P (fun))
    4999      2759416 :             call_ctx.manifestly_const_eval = mce_true;
    5000              : 
    5001              :           /* If this is a constexpr destructor, the object's const and volatile
    5002              :              semantics are no longer in effect; see [class.dtor]p5.  */
    5003     97952228 :           if (new_obj && DECL_DESTRUCTOR_P (fun))
    5004      1254021 :             cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/false,
    5005              :                                       non_constant_p, overflow_p, jump_target);
    5006              : 
    5007              :           /* If this is a constructor, we are beginning the lifetime of the
    5008              :              object we are initializing.  */
    5009     86767127 :           if (new_obj
    5010     22370202 :               && DECL_CONSTRUCTOR_P (fun)
    5011      9931080 :               && TREE_CODE (new_obj) == COMPONENT_REF
    5012     89604661 :               && TREE_CODE (TREE_TYPE (TREE_OPERAND (new_obj, 0))) == UNION_TYPE)
    5013              :             {
    5014         8212 :               tree ctor = build_constructor (TREE_TYPE (new_obj), NULL);
    5015         8212 :               CONSTRUCTOR_NO_CLEARING (ctor) = true;
    5016         8212 :               tree activate = build2 (INIT_EXPR, TREE_TYPE (new_obj),
    5017              :                                       new_obj, ctor);
    5018         8212 :               cxx_eval_constant_expression (ctx, activate,
    5019              :                                             lval, non_constant_p, overflow_p,
    5020              :                                             jump_target);
    5021         8212 :               ggc_free (activate);
    5022         8212 :               if (*jump_target)
    5023            0 :                 return NULL_TREE;
    5024              :             }
    5025              : 
    5026     86767127 :           ctx->global->state_dependent = false;
    5027              : 
    5028     86767127 :           tree jmp_target = NULL_TREE;
    5029     86767127 :           cxx_eval_constant_expression (&call_ctx, body,
    5030              :                                         vc_discard, non_constant_p, overflow_p,
    5031              :                                         &jmp_target);
    5032              : 
    5033     86767123 :           if (!*non_constant_p && throws (&jmp_target))
    5034              :             {
    5035         3683 :               result = NULL_TREE;
    5036         3683 :               cacheable = false;
    5037         3683 :               *jump_target = jmp_target;
    5038              :             }
    5039     86763440 :           else if (!*non_constant_p && TREE_THIS_VOLATILE (fun))
    5040              :             {
    5041              :               /* Return from a [[noreturn]] function.  */
    5042           11 :               if (!ctx->quiet)
    5043            5 :                 error ("%<[[noreturn]]%> call returns");
    5044           11 :               *non_constant_p = true;
    5045              :             }
    5046    173526858 :           else if (DECL_CONSTRUCTOR_P (fun))
    5047              :             /* This can be null for a subobject constructor call, in
    5048              :                which case what we care about is the initialization
    5049              :                side-effects rather than the value.  We could get at the
    5050              :                value by evaluating *this, but we don't bother; there's
    5051              :                no need to put such a call in the hash table.  */
    5052     12390892 :             result = lval ? ctx->object : ctx->ctor;
    5053     74372537 :           else if (VOID_TYPE_P (TREE_TYPE (res)))
    5054      7384043 :             result = void_node;
    5055              :           else
    5056              :             {
    5057     66988494 :               result = ctx->global->get_value (res);
    5058     10974969 :               if (result == NULL_TREE && !*non_constant_p
    5059     66988714 :                   && !DECL_DESTRUCTOR_P (fun))
    5060              :                 {
    5061          110 :                   if (!ctx->quiet)
    5062            6 :                     error ("%<constexpr%> call flows off the end "
    5063              :                            "of the function");
    5064          110 :                   *non_constant_p = true;
    5065              :                 }
    5066              :             }
    5067              : 
    5068     86767123 :           if (ctx->global->state_dependent)
    5069        65830 :             cacheable = false;
    5070     86767123 :           ctx->global->state_dependent |= save_state_dependent;
    5071              : 
    5072              :           /* At this point, the object's constructor will have run, so
    5073              :              the object is no longer under construction, and its possible
    5074              :              'const' semantics now apply.  Make a note of this fact by
    5075              :              marking the CONSTRUCTOR TREE_READONLY.  */
    5076     97952224 :           if (new_obj && DECL_CONSTRUCTOR_P (fun))
    5077      9931080 :             cxx_set_object_constness (ctx, new_obj, /*readonly_p=*/true,
    5078              :                                       non_constant_p, overflow_p, jump_target);
    5079              : 
    5080              :           /* Remove the parms/result from the values map.  */
    5081     86767123 :           destroy_value_checked (ctx, res, non_constant_p);
    5082    299116254 :           for (tree parm = parms; parm; parm = TREE_CHAIN (parm))
    5083    125582008 :             destroy_value_checked (ctx, parm, non_constant_p);
    5084              : 
    5085              :           /* Free any parameter CONSTRUCTORs we aren't returning directly.  */
    5086     87648261 :           while (!ctors->is_empty ())
    5087              :             {
    5088       881138 :               tree c = ctors->pop ();
    5089       881138 :               if (c != result)
    5090       881138 :                 free_constructor (c);
    5091              :             }
    5092              : 
    5093              :           /* Make the unshared function copy we used available for re-use.  */
    5094     86767123 :           save_fundef_copy (fun, copy);
    5095              : 
    5096              :           /* If the call allocated some heap object that hasn't been
    5097              :              deallocated during the call, or if it deallocated some heap
    5098              :              object it has not allocated, the call isn't really stateless
    5099              :              for the constexpr evaluation and should not be cached.
    5100              :              It is fine if the call allocates something and deallocates it
    5101              :              too.  */
    5102     86767123 :           if (cacheable
    5103     96553095 :               && (save_heap_alloc_count != ctx->global->heap_vars.length ()
    5104      9781471 :                   || (save_heap_dealloc_count
    5105      9781471 :                       != ctx->global->heap_dealloc_count)))
    5106              :             {
    5107         4501 :               tree heap_var;
    5108         4501 :               unsigned int i;
    5109         4501 :               if ((ctx->global->heap_vars.length ()
    5110         4501 :                    - ctx->global->heap_dealloc_count)
    5111         4501 :                   != save_heap_alloc_count - save_heap_dealloc_count)
    5112              :                 cacheable = false;
    5113              :               else
    5114       139075 :                 FOR_EACH_VEC_ELT_FROM (ctx->global->heap_vars, i, heap_var,
    5115              :                                        save_heap_alloc_count)
    5116       136450 :                   if (DECL_NAME (heap_var) != heap_deleted_identifier)
    5117              :                     {
    5118              :                       cacheable = false;
    5119              :                       break;
    5120              :                     }
    5121              :             }
    5122              : 
    5123              :             /* Rewrite all occurrences of the function's RESULT_DECL with the
    5124              :                current object under construction.  */
    5125     86767123 :             if (!*non_constant_p
    5126     72100313 :                 && ctx->object
    5127     17241441 :                 && CLASS_TYPE_P (TREE_TYPE (res))
    5128     89966962 :                 && !is_empty_class (TREE_TYPE (res)))
    5129              :               {
    5130      2274769 :                 if (!same_type_ignoring_top_level_qualifiers_p
    5131      2274769 :                     (TREE_TYPE (res), TREE_TYPE (ctx->object)))
    5132            0 :                   *non_constant_p = true;
    5133      2274769 :                 else if (replace_decl (&result, res, ctx->object))
    5134              :                   {
    5135         1791 :                     cacheable = false;
    5136         1791 :                     result = cxx_eval_constant_expression (ctx, result, lval,
    5137              :                                                            non_constant_p,
    5138              :                                                            overflow_p,
    5139              :                                                            jump_target);
    5140         1791 :                     if (*jump_target)
    5141              :                       {
    5142            0 :                         cacheable = false;
    5143            0 :                         result = NULL_TREE;
    5144              :                       }
    5145              :                   }
    5146              :               }
    5147              : 
    5148              :           /* Only cache a permitted result of a constant expression.  */
    5149     86765332 :           if (cacheable && !reduced_constant_expression_p (result))
    5150              :             cacheable = false;
    5151              : 
    5152              :           /* Only cache a result without contract violations.  */
    5153     81725805 :           if (cacheable && ctx->global->contract_statement)
    5154     82024834 :             cacheable = false;
    5155     86767123 :         }
    5156              :       else
    5157              :         /* Couldn't get a function copy to evaluate.  */
    5158            9 :         *non_constant_p = true;
    5159              : 
    5160    109556464 :       if (result == error_mark_node)
    5161            6 :         *non_constant_p = true;
    5162    109556464 :       if (*non_constant_p || *overflow_p)
    5163     14666975 :         result = error_mark_node;
    5164     94889489 :       else if (!result)
    5165      3951004 :         result = void_node;
    5166    109556464 :       if (entry)
    5167              :         {
    5168     65160426 :           entry->result (ctx->manifestly_const_eval)
    5169     32580213 :             = cacheable ? result : error_mark_node;
    5170              : 
    5171     32580213 :           if (result != error_mark_node
    5172     27605778 :               && ctx->manifestly_const_eval == mce_unknown)
    5173              :             {
    5174              :               /* Evaluation succeeded and was independent of whether we're in a
    5175              :                  manifestly constant-evaluated context, so we can also reuse
    5176              :                  this result when evaluating this call with a fixed context.  */
    5177      1923899 :               if (!entry->result (mce_true))
    5178       714459 :                 entry->result (mce_true) = entry->result (mce_unknown);
    5179      1923899 :               if (!entry->result (mce_false))
    5180       681280 :                 entry->result (mce_false) = entry->result (mce_unknown);
    5181              :             }
    5182              :         }
    5183              :     }
    5184              : 
    5185              :   /* The result of a constexpr function must be completely initialized.
    5186              : 
    5187              :      However, in C++20, a constexpr constructor doesn't necessarily have
    5188              :      to initialize all the fields, so we don't clear CONSTRUCTOR_NO_CLEARING
    5189              :      in order to detect reading an uninitialized object in constexpr instead
    5190              :      of value-initializing it.  (reduced_constant_expression_p is expected to
    5191              :      take care of clearing the flag.)  */
    5192    109556497 :   if (TREE_CODE (result) == CONSTRUCTOR
    5193    109556497 :       && (cxx_dialect < cxx20
    5194     21479634 :           || !DECL_CONSTRUCTOR_P (fun)))
    5195      5270364 :     clear_no_implicit_zero (result);
    5196              : 
    5197    109556497 :   pop_cx_call_context ();
    5198              : 
    5199              :   /* A virtual call with a zero-offset covariant return needs no thunk, so
    5200              :      constant evaluation can evaluate the final overrider directly.  The
    5201              :      result then has the overrider's return type rather than the static type
    5202              :      of the call.  Adjust after caching so a direct call can reuse the result
    5203              :      with its original type.  */
    5204    109556497 :   if (!*non_constant_p
    5205     94889645 :       && !*overflow_p
    5206     94889489 :       && !*jump_target
    5207     94885806 :       && DECL_VIRTUAL_P (fun)
    5208        26460 :       && result != void_node
    5209         2173 :       && INDIRECT_TYPE_P (TREE_TYPE (t))
    5210    109557506 :       && !(same_type_ignoring_top_level_qualifiers_p
    5211         1009 :            (TREE_TYPE (result), TREE_TYPE (t))))
    5212           11 :     result = adjust_temp_type (TREE_TYPE (t), result);
    5213              : 
    5214    109556497 :   return result;
    5215    184526371 : }
    5216              : 
    5217              : /* Return true if T is a valid constant initializer.  If a CONSTRUCTOR
    5218              :    initializes all the members, the CONSTRUCTOR_NO_CLEARING flag will be
    5219              :    cleared.  If called recursively on a FIELD_DECL's CONSTRUCTOR, SZ
    5220              :    is DECL_SIZE of the FIELD_DECL, otherwise NULL.
    5221              :    UNION_ELEMENTAL_SUBOBJECT is true when recursing on union elemental
    5222              :    subobjects.
    5223              :    FIXME speed this up, it's taking 16% of compile time on sieve testcase.  */
    5224              : 
    5225              : bool
    5226   1246709405 : reduced_constant_expression_p (tree t, tree sz /* = NULL_TREE */,
    5227              :                                bool union_elemental_subobject /* = false */)
    5228              : {
    5229   1246709405 :   if (t == NULL_TREE)
    5230              :     return false;
    5231              : 
    5232   1241740204 :   switch (TREE_CODE (t))
    5233              :     {
    5234              :     case PTRMEM_CST:
    5235              :     case REFLECT_EXPR:
    5236              :       /* Even if we can't lower this yet, it's constant.  */
    5237              :       return true;
    5238              : 
    5239              :     case OMP_DECLARE_MAPPER:
    5240              :       return true;
    5241              : 
    5242     64025448 :     case CONSTRUCTOR:
    5243              :       /* And we need to handle PTRMEM_CST wrapped in a CONSTRUCTOR.  */
    5244     64025448 :       tree field;
    5245     64025448 :       if (!AGGREGATE_TYPE_P (TREE_TYPE (t)))
    5246              :         /* A constant vector would be folded to VECTOR_CST.
    5247              :            A CONSTRUCTOR of scalar type means uninitialized.  */
    5248              :         return false;
    5249     64008871 :       if (CONSTRUCTOR_NO_CLEARING (t))
    5250              :         {
    5251      3509532 :           if (union_elemental_subobject
    5252         5261 :               && cxx_dialect >= cxx26
    5253         1954 :               && TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
    5254      3510734 :               && CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (t))
    5255              :             field = NULL_TREE;
    5256      3509164 :           else if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
    5257              :             {
    5258              :               /* There must be a valid constant initializer at every array
    5259              :                  index.  */
    5260         6089 :               tree min = TYPE_MIN_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
    5261         6089 :               tree max = TYPE_MAX_VALUE (TYPE_DOMAIN (TREE_TYPE (t)));
    5262         6089 :               tree cursor = min;
    5263        96687 :               for (auto &e: CONSTRUCTOR_ELTS (t))
    5264              :                 {
    5265        78639 :                   if (!reduced_constant_expression_p
    5266        78639 :                         (e.value, NULL_TREE, union_elemental_subobject))
    5267              :                     return false;
    5268        78480 :                   if (array_index_cmp (cursor, e.index) != 0)
    5269              :                     return false;
    5270        78420 :                   if (TREE_CODE (e.index) == RANGE_EXPR)
    5271            0 :                     cursor = TREE_OPERAND (e.index, 1);
    5272        78420 :                   if (TREE_CODE (e.value) == RAW_DATA_CST)
    5273            0 :                     cursor
    5274            0 :                       = int_const_binop (PLUS_EXPR, cursor,
    5275            0 :                                          size_int (RAW_DATA_LENGTH (e.value)));
    5276              :                   else
    5277        78420 :                     cursor = int_const_binop (PLUS_EXPR, cursor,
    5278        78420 :                                               size_one_node);
    5279              :                 }
    5280         5870 :               if (find_array_ctor_elt (t, max) == -1)
    5281              :                 return false;
    5282         5599 :               goto ok;
    5283              :             }
    5284      3503075 :           else if (cxx_dialect >= cxx20
    5285      3503075 :                    && TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
    5286              :             {
    5287              :               /* A union can have at most one active member.  A union with no
    5288              :                  active member has no constituent values, so all constituent
    5289              :                  values are constant.  */
    5290              :               field = NULL_TREE;
    5291              :               union_elemental_subobject = true;
    5292              :             }
    5293              :           else
    5294              :             {
    5295      3499499 :               field = next_subobject_field (TYPE_FIELDS (TREE_TYPE (t)));
    5296      3499499 :               union_elemental_subobject = false;
    5297              :             }
    5298              :         }
    5299              :       else
    5300              :         {
    5301     60499339 :           field = NULL_TREE;
    5302     60499339 :           if (TREE_CODE (TREE_TYPE (t)) == UNION_TYPE)
    5303              :             union_elemental_subobject = true;
    5304     59541486 :           else if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE)
    5305     56800890 :             union_elemental_subobject = false;
    5306              :         }
    5307    602778228 :       for (auto &e: CONSTRUCTOR_ELTS (t))
    5308              :         {
    5309              :           /* If VAL is null, we're in the middle of initializing this
    5310              :              element.  */
    5311    470816723 :           if (!reduced_constant_expression_p (e.value,
    5312    470816723 :                                               (e.index
    5313    470816687 :                                                && (TREE_CODE (e.index)
    5314              :                                                    == FIELD_DECL))
    5315     59491690 :                                               ? DECL_SIZE (e.index)
    5316              :                                               : NULL_TREE,
    5317              :                                               union_elemental_subobject))
    5318              :             return false;
    5319              :           /* We want to remove initializers for empty fields in a struct to
    5320              :              avoid confusing output_constructor.  */
    5321    470239772 :           if (is_empty_field (e.index)
    5322    470239772 :               && TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
    5323              :             return false;
    5324              :           /* Check for non-empty fields between initialized fields when
    5325              :              CONSTRUCTOR_NO_CLEARING.  */
    5326    469115664 :           for (; field && e.index != field;
    5327       384210 :                field = next_subobject_field (DECL_CHAIN (field)))
    5328       388958 :             if (!is_really_empty_class (TREE_TYPE (field),
    5329              :                                         /*ignore_vptr*/false))
    5330              :               return false;
    5331    468726706 :           if (field)
    5332      3989644 :             field = next_subobject_field (DECL_CHAIN (field));
    5333              :         }
    5334              :       /* There could be a non-empty field at the end.  */
    5335     62199739 :       for (; field; field = next_subobject_field (DECL_CHAIN (field)))
    5336       293806 :         if (!is_really_empty_class (TREE_TYPE (field), /*ignore_vptr*/false))
    5337              :           {
    5338              :             /* Ignore FIELD_DECLs with bit positions beyond DECL_SIZE of
    5339              :                the parent FIELD_DECL (if any) for classes with virtual
    5340              :                bases.  */
    5341         6832 :             if (cxx_dialect >= cxx26
    5342         4334 :                 && sz
    5343         7352 :                 && tree_int_cst_le (sz, bit_position (field)))
    5344              :               break;
    5345              :             return false;
    5346              :           }
    5347     61905933 : ok:
    5348     61911924 :       if (CONSTRUCTOR_NO_CLEARING (t))
    5349              :         /* All the fields are initialized.  */
    5350      3376157 :         CONSTRUCTOR_NO_CLEARING (t) = false;
    5351              :       return true;
    5352              : 
    5353   1177394826 :     default:
    5354              :       /* FIXME are we calling this too much?  */
    5355   1177394826 :       return initializer_constant_valid_p (t, TREE_TYPE (t)) != NULL_TREE;
    5356              :     }
    5357              : }
    5358              : 
    5359              : /* *TP was not deemed constant by reduced_constant_expression_p.  Explain
    5360              :    why and suggest what could be done about it.  */
    5361              : 
    5362              : static tree
    5363         1602 : verify_constant_explain_r (tree *tp, int *walk_subtrees, void *)
    5364              : {
    5365         1602 :   bool ref_p = false;
    5366              : 
    5367              :   /* No need to look into types or unevaluated operands.  */
    5368         1602 :   if (TYPE_P (*tp) || unevaluated_p (TREE_CODE (*tp)))
    5369              :     {
    5370            0 :       *walk_subtrees = false;
    5371            0 :       return NULL_TREE;
    5372              :     }
    5373              : 
    5374         1602 :   switch (TREE_CODE (*tp))
    5375              :     {
    5376          104 :     CASE_CONVERT:
    5377          104 :       if (TREE_CODE (TREE_OPERAND (*tp, 0)) != ADDR_EXPR)
    5378              :         break;
    5379           85 :       ref_p = TYPE_REF_P (TREE_TYPE (*tp));
    5380           85 :       *tp = TREE_OPERAND (*tp, 0);
    5381          217 :       gcc_fallthrough ();
    5382          217 :     case ADDR_EXPR:
    5383          217 :       {
    5384          217 :         tree op = TREE_OPERAND (*tp, 0);
    5385          217 :         if (VAR_P (op)
    5386          116 :             && DECL_DECLARED_CONSTEXPR_P (op)
    5387           39 :             && !TREE_STATIC (op)
    5388              :             /* ??? We should also say something about temporaries.  */
    5389          253 :             && !DECL_ARTIFICIAL (op))
    5390              :           {
    5391           33 :             if (ref_p)
    5392           12 :               inform (location_of (*tp), "reference to %qD is not a constant "
    5393              :                       "expression", op);
    5394              :             else
    5395           21 :               inform (location_of (*tp), "pointer to %qD is not a constant "
    5396              :                       "expression", op);
    5397           33 :             const location_t op_loc = DECL_SOURCE_LOCATION (op);
    5398           33 :             rich_location richloc (line_table, op_loc);
    5399           33 :             richloc.add_fixit_insert_before (op_loc, "static ");
    5400           33 :             inform (&richloc,
    5401              :                     "address of non-static constexpr variable %qD may differ on "
    5402              :                     "each invocation of the enclosing function; add %<static%> "
    5403              :                     "to give it a constant address", op);
    5404           33 :           }
    5405              :         break;
    5406              :       }
    5407              :     default:
    5408              :       break;
    5409              :     }
    5410              : 
    5411              :   return NULL_TREE;
    5412              : }
    5413              : 
    5414              : /* Some expressions may have constant operands but are not constant
    5415              :    themselves, such as 1/0.  Call this function to check for that
    5416              :    condition.
    5417              : 
    5418              :    We only call this in places that require an arithmetic constant, not in
    5419              :    places where we might have a non-constant expression that can be a
    5420              :    component of a constant expression, such as the address of a constexpr
    5421              :    variable that might be dereferenced later.  */
    5422              : 
    5423              : static bool
    5424    674183100 : verify_constant (tree t, bool allow_non_constant, bool *non_constant_p,
    5425              :                  bool *overflow_p)
    5426              : {
    5427    661167717 :   if (!*non_constant_p && !reduced_constant_expression_p (t)
    5428    677123315 :       && t != void_node)
    5429              :     {
    5430      2939780 :       if (!allow_non_constant)
    5431              :         {
    5432          422 :           auto_diagnostic_group d;
    5433          577 :           error_at (cp_expr_loc_or_input_loc (t),
    5434              :                     "%q+E is not a constant expression", t);
    5435          422 :           cp_walk_tree_without_duplicates (&t, verify_constant_explain_r,
    5436              :                                            nullptr);
    5437          422 :         }
    5438      2939780 :       *non_constant_p = true;
    5439              :     }
    5440    674183100 :   if (TREE_OVERFLOW_P (t))
    5441              :     {
    5442          678 :       if (!allow_non_constant)
    5443              :         {
    5444          155 :           permerror (input_location, "overflow in constant expression");
    5445              :           /* If we're being permissive (and are in an enforcing
    5446              :              context), ignore the overflow.  */
    5447          155 :           if (flag_permissive)
    5448           75 :             return *non_constant_p;
    5449              :         }
    5450          603 :       *overflow_p = true;
    5451              :     }
    5452    674183025 :   return *non_constant_p;
    5453              : }
    5454              : 
    5455              : /* Check whether the shift operation with code CODE and type TYPE on LHS
    5456              :    and RHS is undefined.  If it is, give an error with an explanation,
    5457              :    and return true; return false otherwise.  */
    5458              : 
    5459              : static bool
    5460     80284515 : cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
    5461              :                         enum tree_code code, tree type, tree lhs, tree rhs)
    5462              : {
    5463     80284515 :   if ((code != LSHIFT_EXPR && code != RSHIFT_EXPR)
    5464      5581639 :       || TREE_CODE (lhs) != INTEGER_CST
    5465      5581363 :       || TREE_CODE (rhs) != INTEGER_CST)
    5466              :     return false;
    5467              : 
    5468      5581363 :   tree lhstype = TREE_TYPE (lhs);
    5469      5581363 :   unsigned HOST_WIDE_INT uprec = TYPE_PRECISION (TREE_TYPE (lhs));
    5470              : 
    5471              :   /* [expr.shift] The behavior is undefined if the right operand
    5472              :      is negative, or greater than or equal to the length in bits
    5473              :      of the promoted left operand.  */
    5474      5581363 :   if (tree_int_cst_sgn (rhs) == -1)
    5475              :     {
    5476          126 :       if (!ctx->quiet)
    5477           35 :         permerror (loc, "right operand of shift expression %q+E is negative",
    5478              :                    build2_loc (loc, code, type, lhs, rhs));
    5479          126 :       return (!flag_permissive || ctx->quiet);
    5480              :     }
    5481      5581237 :   if (compare_tree_int (rhs, uprec) >= 0)
    5482              :     {
    5483          200 :       if (!ctx->quiet)
    5484           34 :         permerror (loc, "right operand of shift expression %q+E is greater "
    5485              :                    "than or equal to the precision %wu of the left operand",
    5486              :                    build2_loc (loc, code, type, lhs, rhs), uprec);
    5487          200 :       return (!flag_permissive || ctx->quiet);
    5488              :     }
    5489              : 
    5490              :   /* The value of E1 << E2 is E1 left-shifted E2 bit positions; [...]
    5491              :      if E1 has a signed type and non-negative value, and E1x2^E2 is
    5492              :      representable in the corresponding unsigned type of the result type,
    5493              :      then that value, converted to the result type, is the resulting value;
    5494              :      otherwise, the behavior is undefined.
    5495              :      For C++20:
    5496              :      The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
    5497              :      2^N, where N is the range exponent of the type of the result.  */
    5498      5581037 :   if (code == LSHIFT_EXPR
    5499      4667605 :       && !TYPE_OVERFLOW_WRAPS (lhstype)
    5500      2199705 :       && cxx_dialect >= cxx11
    5501      7760565 :       && cxx_dialect < cxx20)
    5502              :     {
    5503        54036 :       if (tree_int_cst_sgn (lhs) == -1)
    5504              :         {
    5505           74 :           if (!ctx->quiet)
    5506           18 :             permerror (loc,
    5507              :                        "left operand of shift expression %q+E is negative",
    5508              :                        build2_loc (loc, code, type, lhs, rhs));
    5509           74 :           return (!flag_permissive || ctx->quiet);
    5510              :         }
    5511              :       /* For signed x << y the following:
    5512              :          (unsigned) x >> ((prec (lhs) - 1) - y)
    5513              :          if > 1, is undefined.  The right-hand side of this formula
    5514              :          is the highest bit of the LHS that can be set (starting from 0),
    5515              :          so that the shift doesn't overflow.  We then right-shift the LHS
    5516              :          to see whether any other bit is set making the original shift
    5517              :          undefined -- the result is not representable in the corresponding
    5518              :          unsigned type.  */
    5519        53962 :       tree t = build_int_cst (unsigned_type_node, uprec - 1);
    5520        53962 :       t = fold_build2 (MINUS_EXPR, unsigned_type_node, t, rhs);
    5521        53962 :       tree ulhs = fold_convert (unsigned_type_for (lhstype), lhs);
    5522        53962 :       t = fold_build2 (RSHIFT_EXPR, TREE_TYPE (ulhs), ulhs, t);
    5523        53962 :       if (tree_int_cst_lt (integer_one_node, t))
    5524              :         {
    5525           41 :           if (!ctx->quiet)
    5526            7 :             permerror (loc, "shift expression %q+E overflows",
    5527              :                        build2_loc (loc, code, type, lhs, rhs));
    5528           41 :           return (!flag_permissive || ctx->quiet);
    5529              :         }
    5530              :     }
    5531              :   return false;
    5532              : }
    5533              : 
    5534              : /* Subroutine of cxx_eval_constant_expression.
    5535              :    Attempt to reduce the unary expression tree T to a compile time value.
    5536              :    If successful, return the value.  Otherwise issue a diagnostic
    5537              :    and return error_mark_node.  */
    5538              : 
    5539              : static tree
    5540     25813295 : cxx_eval_unary_expression (const constexpr_ctx *ctx, tree t,
    5541              :                            bool /*lval*/,
    5542              :                            bool *non_constant_p, bool *overflow_p,
    5543              :                            tree *jump_target)
    5544              : {
    5545     25813295 :   tree r;
    5546     25813295 :   tree orig_arg = TREE_OPERAND (t, 0);
    5547     25813295 :   tree arg = cxx_eval_constant_expression (ctx, orig_arg, vc_prvalue,
    5548              :                                            non_constant_p, overflow_p,
    5549              :                                            jump_target);
    5550     25813293 :   if (*jump_target)
    5551              :     return NULL_TREE;
    5552     25813291 :   VERIFY_CONSTANT (arg);
    5553     20555997 :   location_t loc = EXPR_LOCATION (t);
    5554     20555997 :   enum tree_code code = TREE_CODE (t);
    5555     20555997 :   tree type = TREE_TYPE (t);
    5556     20555997 :   r = fold_unary_loc (loc, code, type, arg);
    5557     20555997 :   if (r == NULL_TREE)
    5558              :     {
    5559           17 :       if (arg == orig_arg)
    5560              :         r = t;
    5561              :       else
    5562           13 :         r = build1_loc (loc, code, type, arg);
    5563              :     }
    5564     20555997 :   VERIFY_CONSTANT (r);
    5565              :   return r;
    5566              : }
    5567              : 
    5568              : /* Helper function for cxx_eval_binary_expression.  Try to optimize
    5569              :    original POINTER_PLUS_EXPR T, LHS p+ RHS, return NULL_TREE if the
    5570              :    generic folding should be used.  */
    5571              : 
    5572              : static tree
    5573     10848221 : cxx_fold_pointer_plus_expression (const constexpr_ctx *ctx, tree t,
    5574              :                                   tree lhs, tree rhs, bool *non_constant_p,
    5575              :                                   bool *overflow_p, tree *jump_target)
    5576              : {
    5577     10848221 :   STRIP_NOPS (lhs);
    5578     10848221 :   if (TREE_CODE (lhs) != ADDR_EXPR)
    5579              :     return NULL_TREE;
    5580              : 
    5581      9979693 :   lhs = TREE_OPERAND (lhs, 0);
    5582              : 
    5583              :   /* &A[i] p+ j => &A[i + j] */
    5584      9979693 :   if (TREE_CODE (lhs) == ARRAY_REF
    5585       208338 :       && TREE_CODE (TREE_OPERAND (lhs, 1)) == INTEGER_CST
    5586       208338 :       && TREE_CODE (rhs) == INTEGER_CST
    5587       208338 :       && TYPE_SIZE_UNIT (TREE_TYPE (lhs))
    5588     10188031 :       && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
    5589              :     {
    5590       208338 :       tree orig_type = TREE_TYPE (t);
    5591       208338 :       location_t loc = EXPR_LOCATION (t);
    5592       208338 :       tree type = TREE_TYPE (lhs);
    5593              : 
    5594       208338 :       t = fold_convert_loc (loc, ssizetype, TREE_OPERAND (lhs, 1));
    5595       208338 :       tree nelts = array_type_nelts_top (TREE_TYPE (TREE_OPERAND (lhs, 0)));
    5596       208338 :       nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
    5597              :                                             non_constant_p, overflow_p,
    5598              :                                             jump_target);
    5599       208338 :       if (*non_constant_p)
    5600              :         return NULL_TREE;
    5601       208326 :       if (*jump_target)
    5602              :         return NULL_TREE;
    5603              :       /* Don't fold an out-of-bound access.  */
    5604       208326 :       if (!tree_int_cst_le (t, nelts))
    5605              :         return NULL_TREE;
    5606       208326 :       rhs = cp_fold_convert (ssizetype, rhs);
    5607              :       /* Don't fold if rhs can't be divided exactly by TYPE_SIZE_UNIT.
    5608              :          constexpr int A[1]; ... (char *)&A[0] + 1 */
    5609       208326 :       if (!integer_zerop (fold_build2_loc (loc, TRUNC_MOD_EXPR, sizetype,
    5610       208326 :                                            rhs, TYPE_SIZE_UNIT (type))))
    5611              :         return NULL_TREE;
    5612              :       /* Make sure to treat the second operand of POINTER_PLUS_EXPR
    5613              :          as signed.  */
    5614       208294 :       rhs = fold_build2_loc (loc, EXACT_DIV_EXPR, ssizetype, rhs,
    5615       208294 :                              TYPE_SIZE_UNIT (type));
    5616       208294 :       t = size_binop_loc (loc, PLUS_EXPR, rhs, t);
    5617       208294 :       t = build4_loc (loc, ARRAY_REF, type, TREE_OPERAND (lhs, 0),
    5618              :                       t, NULL_TREE, NULL_TREE);
    5619       208294 :       t = cp_build_addr_expr (t, tf_warning_or_error);
    5620       208294 :       t = cp_fold_convert (orig_type, t);
    5621       208294 :       return cxx_eval_constant_expression (ctx, t, vc_prvalue,
    5622              :                                            non_constant_p, overflow_p,
    5623       208294 :                                            jump_target);
    5624              :     }
    5625              : 
    5626              :   return NULL_TREE;
    5627              : }
    5628              : 
    5629              : /* Try to fold expressions like
    5630              :    (struct S *) (&a[0].D.2378 + 12)
    5631              :    into
    5632              :    &MEM <struct T> [(void *)&a + 12B]
    5633              :    This is something normally done by gimple_fold_stmt_to_constant_1
    5634              :    on GIMPLE, but is undesirable on GENERIC if we are e.g. going to
    5635              :    dereference the address because some details are lost.
    5636              :    For pointer comparisons we want such folding though so that
    5637              :    match.pd address_compare optimization works.  */
    5638              : 
    5639              : static tree
    5640     12042380 : cxx_maybe_fold_addr_pointer_plus (tree t)
    5641              : {
    5642     24084766 :   while (CONVERT_EXPR_P (t)
    5643     12755041 :          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
    5644       712655 :     t = TREE_OPERAND (t, 0);
    5645     12042380 :   if (TREE_CODE (t) != POINTER_PLUS_EXPR)
    5646              :     return NULL_TREE;
    5647     10332931 :   tree op0 = TREE_OPERAND (t, 0);
    5648     10332931 :   tree op1 = TREE_OPERAND (t, 1);
    5649     10332931 :   if (TREE_CODE (op1) != INTEGER_CST)
    5650              :     return NULL_TREE;
    5651     10332931 :   while (CONVERT_EXPR_P (op0)
    5652     20662314 :          && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (op0, 0))))
    5653     10329383 :     op0 = TREE_OPERAND (op0, 0);
    5654     10332931 :   if (TREE_CODE (op0) != ADDR_EXPR)
    5655              :     return NULL_TREE;
    5656     10332931 :   op1 = fold_convert (ptr_type_node, op1);
    5657     10332931 :   tree r = fold_build2 (MEM_REF, TREE_TYPE (TREE_TYPE (op0)), op0, op1);
    5658     10332931 :   return build1_loc (EXPR_LOCATION (t), ADDR_EXPR, TREE_TYPE (op0), r);
    5659              : }
    5660              : 
    5661              : /* Subroutine of cxx_eval_constant_expression.
    5662              :    Like cxx_eval_unary_expression, except for binary expressions.  */
    5663              : 
    5664              : static tree
    5665    112345121 : cxx_eval_binary_expression (const constexpr_ctx *ctx, tree t,
    5666              :                             value_cat lval,
    5667              :                             bool *non_constant_p, bool *overflow_p,
    5668              :                             tree *jump_target)
    5669              : {
    5670    112345121 :   tree r = NULL_TREE;
    5671    112345121 :   tree orig_lhs = TREE_OPERAND (t, 0);
    5672    112345121 :   tree orig_rhs = TREE_OPERAND (t, 1);
    5673    112345121 :   tree lhs, rhs;
    5674              : 
    5675    112345121 :   if (TREE_CODE (t) == POINTER_PLUS_EXPR
    5676     12625627 :       && CONVERT_EXPR_P (orig_lhs)
    5677      6626580 :       && (lhs = TREE_OPERAND (orig_lhs, 0))
    5678      6626580 :       && INDIRECT_TYPE_P (TREE_TYPE (lhs))
    5679      6626580 :       && (TREE_CODE (orig_lhs) != NOP_EXPR || !REINTERPRET_CAST_P (orig_lhs))
    5680    118971672 :       && is_properly_derived_from (TREE_TYPE (TREE_TYPE (orig_lhs)),
    5681      6626551 :                                    TREE_TYPE (TREE_TYPE (lhs))))
    5682              :     /* fold_unary_loc and match.pd can optimize
    5683              :        (type *) (ptr p+ off) into ((type *) ptr) p+ off, which can break
    5684              :        static_cast constexpr diagnostics, because ptr before the p+
    5685              :        cast to type * can be invalid while the original valid.
    5686              :        Evaluate it as (type *) (ptr p+ off) instead.  */
    5687              :     {
    5688           42 :       tree cast = copy_node (orig_lhs);
    5689           42 :       tree pplus = copy_node (t);
    5690           42 :       TREE_OPERAND (cast, 0) = pplus;
    5691           42 :       TREE_OPERAND (pplus, 0) = lhs;
    5692           42 :       TREE_TYPE (pplus) = TREE_TYPE (lhs);
    5693           42 :       lhs = cxx_eval_constant_expression (ctx, cast, vc_prvalue,
    5694              :                                           non_constant_p, overflow_p,
    5695              :                                           jump_target);
    5696           42 :       if (lhs != cast)
    5697              :         {
    5698           24 :           ggc_free (cast);
    5699           24 :           ggc_free (pplus);
    5700              :         }
    5701           42 :       if (*non_constant_p)
    5702              :         return t;
    5703           42 :       return lhs;
    5704              :     }
    5705              : 
    5706    112345079 :   lhs = cxx_eval_constant_expression (ctx, orig_lhs, vc_prvalue,
    5707              :                                       non_constant_p, overflow_p,
    5708              :                                       jump_target);
    5709              :   /* Don't VERIFY_CONSTANT here, it's unnecessary and will break pointer
    5710              :      subtraction.  */
    5711    112345077 :   if (*non_constant_p)
    5712              :     return t;
    5713     90450300 :   if (*jump_target)
    5714              :     return NULL_TREE;
    5715     90450205 :   rhs = cxx_eval_constant_expression (ctx, orig_rhs, vc_prvalue,
    5716              :                                       non_constant_p, overflow_p,
    5717              :                                       jump_target);
    5718     90450205 :   if (*non_constant_p)
    5719              :     return t;
    5720     89283766 :   if (*jump_target)
    5721              :     return NULL_TREE;
    5722              : 
    5723     89283760 :   location_t loc = EXPR_LOCATION (t);
    5724     89283760 :   enum tree_code code = TREE_CODE (t);
    5725     89283760 :   tree type = TREE_TYPE (t);
    5726              : 
    5727     89283760 :   if (code == EQ_EXPR || code == NE_EXPR)
    5728              :     {
    5729     18244545 :       bool is_code_eq = (code == EQ_EXPR);
    5730              : 
    5731     18244545 :       if (TREE_CODE (lhs) == PTRMEM_CST
    5732          217 :           && TREE_CODE (rhs) == PTRMEM_CST)
    5733              :         {
    5734           76 :           tree lmem = PTRMEM_CST_MEMBER (lhs);
    5735           76 :           tree rmem = PTRMEM_CST_MEMBER (rhs);
    5736           76 :           bool eq;
    5737           76 :           if (TREE_CODE (lmem) == TREE_CODE (rmem)
    5738           76 :               && TREE_CODE (lmem) == FIELD_DECL
    5739           76 :               && TREE_CODE (DECL_CONTEXT (lmem)) == UNION_TYPE
    5740          103 :               && same_type_p (DECL_CONTEXT (lmem),
    5741              :                               DECL_CONTEXT (rmem)))
    5742              :             /* If both refer to (possibly different) members of the same union
    5743              :                (12.3), they compare equal. */
    5744              :             eq = true;
    5745              :           else
    5746           49 :             eq = cp_tree_equal (lhs, rhs);
    5747           76 :           r = constant_boolean_node (eq == is_code_eq, type);
    5748           76 :         }
    5749     18244469 :       else if ((TREE_CODE (lhs) == PTRMEM_CST
    5750     18244328 :                 || TREE_CODE (rhs) == PTRMEM_CST)
    5751     18244469 :                && (null_member_pointer_value_p (lhs)
    5752          141 :                    || null_member_pointer_value_p (rhs)))
    5753          141 :         r = constant_boolean_node (!is_code_eq, type);
    5754     18244328 :       else if (TREE_CODE (lhs) == PTRMEM_CST)
    5755            0 :         lhs = cplus_expand_constant (lhs);
    5756     18244328 :       else if (TREE_CODE (rhs) == PTRMEM_CST)
    5757            0 :         rhs = cplus_expand_constant (rhs);
    5758     18244328 :       else if (REFLECT_EXPR_P (lhs) && REFLECT_EXPR_P (rhs))
    5759              :         {
    5760         3926 :           const bool eq = compare_reflections (lhs, rhs);
    5761         3926 :           r = constant_boolean_node (eq == is_code_eq, type);
    5762              :         }
    5763              :     }
    5764            0 :   if (r == NULL_TREE
    5765     89279617 :       && TREE_CODE_CLASS (code) == tcc_comparison
    5766     39127482 :       && POINTER_TYPE_P (TREE_TYPE (lhs)))
    5767              :     {
    5768      6021190 :       if (tree lhso = cxx_maybe_fold_addr_pointer_plus (lhs))
    5769      5018685 :         lhs = fold_convert (TREE_TYPE (lhs), lhso);
    5770      6021190 :       if (tree rhso = cxx_maybe_fold_addr_pointer_plus (rhs))
    5771      5314246 :         rhs = fold_convert (TREE_TYPE (rhs), rhso);
    5772              :     }
    5773     10848376 :   if (code == POINTER_PLUS_EXPR && !*non_constant_p
    5774    100132136 :       && integer_zerop (lhs) && !integer_zerop (rhs))
    5775              :     {
    5776          155 :       if (!ctx->quiet)
    5777           45 :         error ("arithmetic involving a null pointer in %qE", lhs);
    5778          155 :       *non_constant_p = true;
    5779          155 :       return t;
    5780              :     }
    5781     89283605 :   else if (code == POINTER_PLUS_EXPR)
    5782              :     {
    5783     10848221 :       r = cxx_fold_pointer_plus_expression (ctx, t, lhs, rhs, non_constant_p,
    5784              :                                             overflow_p, jump_target);
    5785     10848221 :       if (*jump_target)
    5786              :         return NULL_TREE;
    5787              :     }
    5788     78435384 :   else if (code == SPACESHIP_EXPR)
    5789              :     {
    5790        27365 :       r = genericize_spaceship (loc, type, lhs, rhs);
    5791        27365 :       return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
    5792        27365 :                                            overflow_p, jump_target);
    5793              :     }
    5794              : 
    5795     89256240 :   if (r == NULL_TREE)
    5796              :     {
    5797     89043803 :       if (ctx->manifestly_const_eval == mce_true
    5798     68045300 :           && (flag_constexpr_fp_except
    5799     68045297 :               || TREE_CODE (type) != REAL_TYPE))
    5800              :         {
    5801     67991582 :           auto ofcc = make_temp_override (folding_cxx_constexpr, true);
    5802     67991582 :           r = fold_binary_initializer_loc (loc, code, type, lhs, rhs);
    5803     67991582 :         }
    5804              :       else
    5805     21052221 :         r = fold_binary_loc (loc, code, type, lhs, rhs);
    5806              :     }
    5807              : 
    5808     89043803 :   if (r == NULL_TREE
    5809      8971823 :       && (code == LSHIFT_EXPR || code == RSHIFT_EXPR)
    5810          100 :       && TREE_CODE (lhs) == INTEGER_CST
    5811           98 :       && TREE_CODE (rhs) == INTEGER_CST
    5812     98228063 :       && wi::neg_p (wi::to_wide (rhs)))
    5813              :     {
    5814              :       /* For diagnostics and -fpermissive emulate previous behavior of
    5815              :          handling shifts by negative amount.  */
    5816           98 :       tree nrhs = const_unop (NEGATE_EXPR, TREE_TYPE (rhs), rhs);
    5817           98 :       if (nrhs)
    5818          119 :         r = fold_binary_loc (loc,
    5819              :                              code == LSHIFT_EXPR ? RSHIFT_EXPR : LSHIFT_EXPR,
    5820              :                              type, lhs, nrhs);
    5821              :     }
    5822              : 
    5823     89256240 :   if (r == NULL_TREE)
    5824              :     {
    5825      8971725 :       if (lhs == orig_lhs && rhs == orig_rhs)
    5826              :         r = t;
    5827              :       else
    5828      3152255 :         r = build2_loc (loc, code, type, lhs, rhs);
    5829              :     }
    5830     80284515 :   else if (cxx_eval_check_shift_p (loc, ctx, code, type, lhs, rhs))
    5831          433 :     *non_constant_p = true;
    5832              :   /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
    5833              :      a local array in a constexpr function.  */
    5834     89256240 :   bool ptr = INDIRECT_TYPE_P (TREE_TYPE (lhs));
    5835     71698318 :   if (!ptr)
    5836     71698318 :     VERIFY_CONSTANT (r);
    5837              :   return r;
    5838              : }
    5839              : 
    5840              : /* Subroutine of cxx_eval_constant_expression.
    5841              :    Attempt to evaluate condition expressions.  */
    5842              : 
    5843              : static tree
    5844     39283619 : cxx_eval_conditional_expression (const constexpr_ctx *ctx, tree t,
    5845              :                                  value_cat lval,
    5846              :                                  bool *non_constant_p, bool *overflow_p,
    5847              :                                  tree *jump_target)
    5848              : {
    5849     39283619 :   tree val = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
    5850              :                                            vc_prvalue,
    5851              :                                            non_constant_p, overflow_p,
    5852              :                                            jump_target);
    5853     39283619 :   if (*jump_target)
    5854              :     return NULL_TREE;
    5855     39283595 :   VERIFY_CONSTANT (val);
    5856     36974701 :   if (TREE_CODE (t) == IF_STMT && IF_STMT_CONSTEVAL_P (t))
    5857              :     {
    5858              :       /* Evaluate the condition as if it was
    5859              :          if (__builtin_is_constant_evaluated ()), i.e. defer it if not
    5860              :          ctx->manifestly_const_eval (as sometimes we try to constant evaluate
    5861              :          without manifestly_const_eval even expressions or parts thereof which
    5862              :          will later be manifestly const_eval evaluated), otherwise fold it to
    5863              :          true.  */
    5864      1069011 :       if (ctx->manifestly_const_eval == mce_unknown)
    5865              :         {
    5866       965285 :           *non_constant_p = true;
    5867       965285 :           return t;
    5868              :         }
    5869       103726 :       val = constant_boolean_node (ctx->manifestly_const_eval == mce_true,
    5870              :                                    boolean_type_node);
    5871              :     }
    5872              :   /* Don't VERIFY_CONSTANT the other operands.  */
    5873     36009416 :   const bool zero_p = integer_zerop (val);
    5874     36009416 :   if (zero_p)
    5875     22879923 :     val = TREE_OPERAND (t, 2);
    5876              :   else
    5877     13129493 :     val = TREE_OPERAND (t, 1);
    5878     36009416 :   if (TREE_CODE (t) == IF_STMT && !val)
    5879      9949698 :     val = void_node;
    5880              : 
    5881              :   /* P2564: If we aren't in immediate function context (including a manifestly
    5882              :      constant-evaluated expression), check any uses of immediate functions in
    5883              :      the arm we're discarding.  But don't do this inside a call; we already
    5884              :      checked when parsing the function.  */
    5885     36009416 :   if (ctx->manifestly_const_eval != mce_true
    5886      5085655 :       && !in_immediate_context ()
    5887      4988063 :       && !ctx->call
    5888     36818118 :       && cp_fold_immediate (&TREE_OPERAND (t, zero_p ? 1 : 2),
    5889       808702 :                             ctx->manifestly_const_eval))
    5890              :     {
    5891            7 :       *non_constant_p = true;
    5892            7 :       return t;
    5893              :     }
    5894              : 
    5895              :   /* A TARGET_EXPR may be nested inside another TARGET_EXPR, but still
    5896              :      serve as the initializer for the same object as the outer TARGET_EXPR,
    5897              :      as in
    5898              :        A a = true ? A{} : A{};
    5899              :      so strip the inner TARGET_EXPR so we don't materialize a temporary.  */
    5900     36009409 :   if (TREE_CODE (val) == TARGET_EXPR)
    5901         5341 :     val = TARGET_EXPR_INITIAL (val);
    5902     36009409 :   return cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
    5903     36009409 :                                        overflow_p, jump_target);
    5904              : }
    5905              : 
    5906              : /* Subroutine of cxx_eval_constant_expression.
    5907              :    Attempt to evaluate vector condition expressions.  Unlike
    5908              :    cxx_eval_conditional_expression, VEC_COND_EXPR acts like a normal
    5909              :    ternary arithmetics operation, where all 3 arguments have to be
    5910              :    evaluated as constants and then folding computes the result from
    5911              :    them.  */
    5912              : 
    5913              : static tree
    5914        11755 : cxx_eval_vector_conditional_expression (const constexpr_ctx *ctx, tree t,
    5915              :                                         bool *non_constant_p, bool *overflow_p,
    5916              :                                         tree *jump_target)
    5917              : {
    5918        11755 :   tree arg1 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
    5919              :                                             vc_prvalue,
    5920              :                                             non_constant_p, overflow_p,
    5921              :                                             jump_target);
    5922        11755 :   if (*jump_target)
    5923              :     return NULL_TREE;
    5924        11755 :   VERIFY_CONSTANT (arg1);
    5925         8227 :   tree arg2 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
    5926              :                                             vc_prvalue,
    5927              :                                             non_constant_p, overflow_p,
    5928              :                                             jump_target);
    5929         8227 :   if (*jump_target)
    5930              :     return NULL_TREE;
    5931         8227 :   VERIFY_CONSTANT (arg2);
    5932         7097 :   tree arg3 = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 2),
    5933              :                                             vc_prvalue,
    5934              :                                             non_constant_p, overflow_p,
    5935              :                                             jump_target);
    5936         7097 :   if (*jump_target)
    5937              :     return NULL_TREE;
    5938         7097 :   VERIFY_CONSTANT (arg3);
    5939         7097 :   location_t loc = EXPR_LOCATION (t);
    5940         7097 :   tree type = TREE_TYPE (t);
    5941         7097 :   tree r = fold_ternary_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
    5942         7097 :   if (r == NULL_TREE)
    5943              :     {
    5944            0 :       if (arg1 == TREE_OPERAND (t, 0)
    5945            0 :           && arg2 == TREE_OPERAND (t, 1)
    5946            0 :           && arg3 == TREE_OPERAND (t, 2))
    5947              :         r = t;
    5948              :       else
    5949            0 :         r = build3_loc (loc, VEC_COND_EXPR, type, arg1, arg2, arg3);
    5950              :     }
    5951         7097 :   VERIFY_CONSTANT (r);
    5952              :   return r;
    5953              : }
    5954              : 
    5955              : /* Returns less than, equal to, or greater than zero if KEY is found to be
    5956              :    less than, to match, or to be greater than the constructor_elt's INDEX.  */
    5957              : 
    5958              : static int
    5959       439901 : array_index_cmp (tree key, tree index)
    5960              : {
    5961       439901 :   gcc_assert (TREE_CODE (key) == INTEGER_CST);
    5962              : 
    5963       439901 :   switch (TREE_CODE (index))
    5964              :     {
    5965       436963 :     case INTEGER_CST:
    5966       436963 :       return tree_int_cst_compare (key, index);
    5967         2938 :     case RANGE_EXPR:
    5968         2938 :       {
    5969         2938 :         tree lo = TREE_OPERAND (index, 0);
    5970         2938 :         tree hi = TREE_OPERAND (index, 1);
    5971         2938 :         if (tree_int_cst_lt (key, lo))
    5972              :           return -1;
    5973         2642 :         else if (tree_int_cst_lt (hi, key))
    5974              :           return 1;
    5975              :         else
    5976         2642 :           return 0;
    5977              :       }
    5978            0 :     default:
    5979            0 :       gcc_unreachable ();
    5980              :     }
    5981              : }
    5982              : 
    5983              : /* Extract a single INTEGER_CST from RAW_DATA_CST RAW_DATA at
    5984              :    relative index OFF.  */
    5985              : 
    5986              : static tree
    5987        29559 : raw_data_cst_elt (tree raw_data, unsigned int off)
    5988              : {
    5989        29559 :   return build_int_cst (TREE_TYPE (raw_data),
    5990        29559 :                         TYPE_UNSIGNED (TREE_TYPE (raw_data))
    5991        59118 :                         ? (HOST_WIDE_INT)
    5992        29073 :                           RAW_DATA_UCHAR_ELT (raw_data, off)
    5993              :                         : (HOST_WIDE_INT)
    5994          486 :                           RAW_DATA_SCHAR_ELT (raw_data, off));
    5995              : }
    5996              : 
    5997              : /* Returns the index of the constructor_elt of ARY which matches DINDEX, or -1
    5998              :    if none.  If INSERT is true, insert a matching element rather than fail.  */
    5999              : 
    6000              : static HOST_WIDE_INT
    6001     12443315 : find_array_ctor_elt (tree ary, tree dindex, bool insert)
    6002              : {
    6003     12443315 :   if (tree_int_cst_sgn (dindex) < 0)
    6004              :     return -1;
    6005              : 
    6006     12443315 :   unsigned HOST_WIDE_INT i = tree_to_uhwi (dindex);
    6007     12443315 :   vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ary);
    6008     12443315 :   unsigned HOST_WIDE_INT len = vec_safe_length (elts);
    6009              : 
    6010     16717152 :   unsigned HOST_WIDE_INT end = len;
    6011     16717152 :   unsigned HOST_WIDE_INT begin = 0;
    6012              : 
    6013              :   /* If the last element of the CONSTRUCTOR has its own index, we can assume
    6014              :      that the same is true of the other elements and index directly.  */
    6015     11885620 :   if (end > 0)
    6016              :     {
    6017     11656669 :       tree cindex = (*elts)[end - 1].index;
    6018     11656669 :       if (cindex == NULL_TREE)
    6019              :         {
    6020              :           /* Verify that if the last index is missing, all indexes
    6021              :              are missing and there is no RAW_DATA_CST.  */
    6022        21794 :           if (flag_checking)
    6023       220133 :             for (unsigned int j = 0; j < len - 1; ++j)
    6024       198339 :               gcc_assert ((*elts)[j].index == NULL_TREE
    6025              :                           && TREE_CODE ((*elts)[j].value) != RAW_DATA_CST);
    6026        21794 :           if (i < end)
    6027        21794 :             return i;
    6028              :           else
    6029              :             {
    6030            0 :               begin = end;
    6031            0 :               if (i == end)
    6032              :                 /* If the element is to be added right at the end,
    6033              :                    make sure it is added with cleared index too.  */
    6034      4831532 :                 dindex = NULL_TREE;
    6035            0 :               else if (insert)
    6036              :                 /* Otherwise, in order not to break the assumption
    6037              :                    that CONSTRUCTOR either has all indexes or none,
    6038              :                    we need to add indexes to all elements.  */
    6039            0 :                 for (unsigned int j = 0; j < len; ++j)
    6040            0 :                   (*elts)[j].index = build_int_cst (TREE_TYPE (dindex), j);
    6041              :             }
    6042              :         }
    6043     11634875 :       else if (TREE_CODE (cindex) == INTEGER_CST
    6044     11634875 :                && compare_tree_int (cindex, end - 1) == 0)
    6045              :         {
    6046     11424081 :           tree value = (*elts)[end - 1].value;
    6047     11424081 :           if (i < end)
    6048              :             {
    6049      7590079 :               if (i == end - 1 && TREE_CODE (value) == RAW_DATA_CST)
    6050              :                 begin = end - 1;
    6051              :               else
    6052      7589989 :                 return i;
    6053              :             }
    6054      3834002 :           else if (TREE_CODE (value) == RAW_DATA_CST
    6055      3866158 :                    && wi::to_offset (dindex) < (wi::to_offset (cindex)
    6056        32156 :                                                 + RAW_DATA_LENGTH (value)))
    6057        16078 :             begin = end - 1;
    6058              :           else
    6059      3817924 :             begin = end;
    6060              :         }
    6061              :     }
    6062              : 
    6063              :   /* Otherwise, find a matching index by means of a binary search.  */
    6064      5036311 :   while (begin != end)
    6065              :     {
    6066       361418 :       unsigned HOST_WIDE_INT middle = (begin + end) / 2;
    6067       361418 :       constructor_elt &elt = (*elts)[middle];
    6068       361418 :       tree idx = elt.index;
    6069              : 
    6070       361418 :       int cmp = array_index_cmp (dindex, idx);
    6071       361418 :       if (cmp > 0
    6072        66757 :           && TREE_CODE (elt.value) == RAW_DATA_CST
    6073       445226 :           && wi::to_offset (dindex) < (wi::to_offset (idx)
    6074        83808 :                                        + RAW_DATA_LENGTH (elt.value)))
    6075        29417 :         cmp = 0;
    6076       361418 :       if (cmp < 0)
    6077              :         end = middle;
    6078       193979 :       else if (cmp > 0)
    6079        37340 :         begin = middle + 1;
    6080              :       else
    6081              :         {
    6082       156639 :           if (insert && TREE_CODE (elt.value) == RAW_DATA_CST)
    6083              :             {
    6084              :               /* We need to split the RAW_DATA_CST elt.  */
    6085          122 :               constructor_elt e;
    6086          122 :               gcc_checking_assert (TREE_CODE (idx) != RANGE_EXPR);
    6087          244 :               unsigned int off = (wi::to_offset (dindex)
    6088          244 :                                   - wi::to_offset (idx)).to_uhwi ();
    6089          122 :               tree value = elt.value;
    6090          122 :               unsigned int len = RAW_DATA_LENGTH (value);
    6091          122 :               if (off > 1 && len >= off + 3)
    6092           22 :                 value = copy_node (elt.value);
    6093          122 :               if (off)
    6094              :                 {
    6095           33 :                   if (off > 1)
    6096           33 :                     RAW_DATA_LENGTH (elt.value) = off;
    6097              :                   else
    6098            0 :                     elt.value = raw_data_cst_elt (elt.value, 0);
    6099           33 :                   e.index = size_binop (PLUS_EXPR, elt.index,
    6100              :                                         build_int_cst (TREE_TYPE (elt.index),
    6101              :                                                        off));
    6102           33 :                   e.value = NULL_TREE;
    6103           33 :                   ++middle;
    6104           33 :                   vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
    6105              :                 }
    6106          122 :               (*elts)[middle].value = raw_data_cst_elt (value, off);
    6107          122 :               if (len >= off + 2)
    6108              :                 {
    6109          111 :                   e.index = (*elts)[middle].index;
    6110          111 :                   e.index = size_binop (PLUS_EXPR, e.index,
    6111              :                                         build_one_cst (TREE_TYPE (e.index)));
    6112          111 :                   if (len >= off + 3)
    6113              :                     {
    6114          111 :                       RAW_DATA_LENGTH (value) -= off + 1;
    6115          111 :                       RAW_DATA_POINTER (value) += off + 1;
    6116          111 :                       e.value = value;
    6117              :                     }
    6118              :                   else
    6119            0 :                     e.value = raw_data_cst_elt (value, off + 1);
    6120          111 :                   vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
    6121              :                 }
    6122          122 :               return middle;
    6123              :             }
    6124        35871 :           if (insert && TREE_CODE (idx) == RANGE_EXPR)
    6125              :             {
    6126              :               /* We need to split the range.  */
    6127          361 :               constructor_elt e;
    6128          361 :               tree lo = TREE_OPERAND (idx, 0);
    6129          361 :               tree hi = TREE_OPERAND (idx, 1);
    6130          361 :               tree value = elt.value;
    6131          361 :               dindex = fold_convert (sizetype, dindex);
    6132          361 :               if (tree_int_cst_lt (lo, dindex))
    6133              :                 {
    6134              :                   /* There are still some lower elts; shorten the range.  */
    6135          194 :                   tree new_hi = int_const_binop (MINUS_EXPR, dindex,
    6136           97 :                                                  size_one_node);
    6137           97 :                   if (tree_int_cst_equal (lo, new_hi))
    6138              :                     /* Only one element left, no longer a range.  */
    6139           42 :                     elt.index = lo;
    6140              :                   else
    6141           55 :                     TREE_OPERAND (idx, 1) = new_hi;
    6142              :                   /* Append the element we want to insert.  */
    6143           97 :                   ++middle;
    6144           97 :                   e.index = dindex;
    6145           97 :                   e.value = unshare_constructor (value);
    6146           97 :                   vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle, e);
    6147              :                 }
    6148              :               else
    6149              :                 /* No lower elts, the range elt is now ours.  */
    6150          264 :                 elt.index = dindex;
    6151              : 
    6152          361 :               if (tree_int_cst_lt (dindex, hi))
    6153              :                 {
    6154              :                   /* There are still some higher elts; append a range.  */
    6155          506 :                   tree new_lo = int_const_binop (PLUS_EXPR, dindex,
    6156          253 :                                                  size_one_node);
    6157          253 :                   if (tree_int_cst_equal (new_lo, hi))
    6158              :                     e.index = hi;
    6159              :                   else
    6160          153 :                     e.index = build2 (RANGE_EXPR, sizetype, new_lo, hi);
    6161          253 :                   e.value = unshare_constructor (value);
    6162          253 :                   vec_safe_insert (CONSTRUCTOR_ELTS (ary), middle + 1, e);
    6163              :                 }
    6164              :             }
    6165       156517 :           return middle;
    6166              :         }
    6167              :     }
    6168              : 
    6169      4674893 :   if (insert)
    6170              :     {
    6171      4544241 :       constructor_elt e = { dindex, NULL_TREE };
    6172      4544241 :       vec_safe_insert (CONSTRUCTOR_ELTS (ary), end, e);
    6173      4544241 :       return end;
    6174              :     }
    6175              : 
    6176              :   return -1;
    6177              : }
    6178              : 
    6179              : /* Return a pointer to the constructor_elt of CTOR which matches INDEX.  If no
    6180              :    matching constructor_elt exists, then add one to CTOR.
    6181              : 
    6182              :    As an optimization, if POS_HINT is non-negative then it is used as a guess
    6183              :    for the (integer) index of the matching constructor_elt within CTOR.
    6184              : 
    6185              :    If POS_HINT is -2, it means do not insert.  */
    6186              : 
    6187              : static constructor_elt *
    6188     42688981 : get_or_insert_ctor_field (tree ctor, tree index, int pos_hint = -1)
    6189              : {
    6190              :   /* Check the hint first.  */
    6191      4629497 :   if (pos_hint >= 0 && (unsigned)pos_hint < CONSTRUCTOR_NELTS (ctor)
    6192     47318478 :       && CONSTRUCTOR_ELT (ctor, pos_hint)->index == index)
    6193              :     return CONSTRUCTOR_ELT (ctor, pos_hint);
    6194              : 
    6195     38059496 :   bool insertp = (pos_hint != -2);
    6196     38059496 :   tree type = TREE_TYPE (ctor);
    6197     38059496 :   if (TREE_CODE (type) == VECTOR_TYPE && index == NULL_TREE)
    6198              :     {
    6199        27296 :       gcc_assert (insertp);
    6200        27296 :       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (ctor), index, NULL_TREE);
    6201        27296 :       return &CONSTRUCTOR_ELTS (ctor)->last();
    6202              :     }
    6203     38032200 :   else if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
    6204              :     {
    6205      6243922 :       if (TREE_CODE (index) == RANGE_EXPR)
    6206              :         {
    6207              :           /* Support for RANGE_EXPR index lookups is currently limited to
    6208              :              accessing an existing element via POS_HINT, or appending a new
    6209              :              element to the end of CTOR.  ??? Support for other access
    6210              :              patterns may also be needed.  */
    6211            3 :           vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (ctor);
    6212            3 :           if (vec_safe_length (elts))
    6213              :             {
    6214            3 :               tree lo = TREE_OPERAND (index, 0);
    6215            3 :               gcc_assert (array_index_cmp (elts->last().index, lo) < 0);
    6216              :             }
    6217            3 :           gcc_assert (insertp);
    6218            3 :           CONSTRUCTOR_APPEND_ELT (elts, index, NULL_TREE);
    6219            3 :           return &elts->last();
    6220              :         }
    6221              : 
    6222      6243919 :       HOST_WIDE_INT i = find_array_ctor_elt (ctor, index, insertp);
    6223      6243919 :       if (i < 0)
    6224              :         {
    6225         2711 :           gcc_assert (!insertp);
    6226              :           return nullptr;
    6227              :         }
    6228      6241208 :       constructor_elt *cep = CONSTRUCTOR_ELT (ctor, i);
    6229      6241208 :       if (!insertp && cep->index && TREE_CODE (cep->index) == RANGE_EXPR)
    6230              :         {
    6231              :           /* Split a range even if we aren't inserting new entries.  */
    6232            0 :           gcc_assert (!insertp);
    6233            0 :           i = find_array_ctor_elt (ctor, index, /*insert*/true);
    6234            0 :           gcc_assert (i >= 0);
    6235            0 :           cep = CONSTRUCTOR_ELT (ctor, i);
    6236              :         }
    6237      6241208 :       gcc_assert (cep->index == NULL_TREE
    6238              :                   || TREE_CODE (cep->index) != RANGE_EXPR);
    6239              :       return cep;
    6240              :     }
    6241              :   else
    6242              :     {
    6243     31788278 :       gcc_assert (TREE_CODE (index) == FIELD_DECL
    6244              :                   && (same_type_ignoring_top_level_qualifiers_p
    6245              :                       (DECL_CONTEXT (index), TREE_TYPE (ctor))));
    6246              : 
    6247              :       /* We must keep the CONSTRUCTOR's ELTS in FIELD order.
    6248              :          Usually we meet initializers in that order, but it is
    6249              :          possible for base types to be placed not in program
    6250              :          order.  */
    6251     31788278 :       tree fields = TYPE_FIELDS (DECL_CONTEXT (index));
    6252     31788278 :       unsigned HOST_WIDE_INT idx = 0;
    6253     31788278 :       constructor_elt *cep = NULL;
    6254              : 
    6255              :       /* Check if we're changing the active member of a union.  */
    6256       584383 :       if (TREE_CODE (type) == UNION_TYPE && CONSTRUCTOR_NELTS (ctor)
    6257     32168077 :           && CONSTRUCTOR_ELT (ctor, 0)->index != index)
    6258        12483 :         vec_safe_truncate (CONSTRUCTOR_ELTS (ctor), 0);
    6259              :       /* If the bit offset of INDEX is larger than that of the last
    6260              :          constructor_elt, then we can just immediately append a new
    6261              :          constructor_elt to the end of CTOR.  */
    6262     48422474 :       else if (CONSTRUCTOR_NELTS (ctor)
    6263     44581454 :                && tree_int_cst_compare (bit_position (index),
    6264     43614120 :                                         bit_position (CONSTRUCTOR_ELTS (ctor)
    6265     21807060 :                                                       ->last().index)) > 0)
    6266              :         {
    6267      6140198 :           idx = CONSTRUCTOR_NELTS (ctor);
    6268      6140198 :           goto insert;
    6269              :         }
    6270              : 
    6271              :       /* Otherwise, we need to iterate over CTOR to find or insert INDEX
    6272              :          appropriately.  */
    6273              : 
    6274     30444966 :       for (; vec_safe_iterate (CONSTRUCTOR_ELTS (ctor), idx, &cep);
    6275      4796886 :            idx++, fields = DECL_CHAIN (fields))
    6276              :         {
    6277     20463748 :           if (index == cep->index)
    6278     15624936 :             goto found;
    6279              : 
    6280              :           /* The field we're initializing must be on the field
    6281              :              list.  Look to see if it is present before the
    6282              :              field the current ELT initializes.  */
    6283     51214328 :           for (; fields != cep->index; fields = DECL_CHAIN (fields))
    6284     46417442 :             if (index == fields)
    6285        41926 :               goto insert;
    6286              :         }
    6287              :       /* We fell off the end of the CONSTRUCTOR, so insert a new
    6288              :          entry at the end.  */
    6289              : 
    6290     16163342 :     insert:
    6291     16163342 :       if (!insertp)
    6292              :         return nullptr;
    6293              : 
    6294     16163339 :       {
    6295     16163339 :         constructor_elt ce = { index, NULL_TREE };
    6296              : 
    6297     16163339 :         vec_safe_insert (CONSTRUCTOR_ELTS (ctor), idx, ce);
    6298     16163339 :         cep = CONSTRUCTOR_ELT (ctor, idx);
    6299              :       }
    6300     42688981 :     found:;
    6301              : 
    6302              :       return cep;
    6303              :     }
    6304              : }
    6305              : 
    6306              : /* Under the control of CTX, issue a detailed diagnostic for
    6307              :    an out-of-bounds subscript INDEX into the expression ARRAY.  */
    6308              : 
    6309              : static void
    6310          601 : diag_array_subscript (location_t loc, const constexpr_ctx *ctx, tree array, tree index)
    6311              : {
    6312          601 :   if (!ctx->quiet)
    6313              :     {
    6314          120 :       tree arraytype = TREE_TYPE (array);
    6315              : 
    6316              :       /* Convert the unsigned array subscript to a signed integer to avoid
    6317              :          printing huge numbers for small negative values.  */
    6318          120 :       tree sidx = fold_convert (ssizetype, index);
    6319          120 :       STRIP_ANY_LOCATION_WRAPPER (array);
    6320          120 :       if (DECL_P (array))
    6321              :         {
    6322           79 :           auto_diagnostic_group d;
    6323           79 :           if (TYPE_DOMAIN (arraytype))
    6324           73 :             error_at (loc, "array subscript value %qE is outside the bounds "
    6325              :                       "of array %qD of type %qT", sidx, array, arraytype);
    6326              :           else
    6327            6 :             error_at (loc, "nonzero array subscript %qE is used with array %qD of "
    6328              :                       "type %qT with unknown bounds", sidx, array, arraytype);
    6329           79 :           inform (DECL_SOURCE_LOCATION (array), "declared here");
    6330           79 :         }
    6331           41 :       else if (TYPE_DOMAIN (arraytype))
    6332           38 :         error_at (loc, "array subscript value %qE is outside the bounds "
    6333              :                   "of array type %qT", sidx, arraytype);
    6334              :       else
    6335            3 :         error_at (loc, "nonzero array subscript %qE is used with array of type %qT "
    6336              :                   "with unknown bounds", sidx, arraytype);
    6337              :     }
    6338          601 : }
    6339              : 
    6340              : /* Return the number of elements for TYPE (which is an ARRAY_TYPE or
    6341              :    a VECTOR_TYPE).  */
    6342              : 
    6343              : static tree
    6344     21009824 : get_array_or_vector_nelts (const constexpr_ctx *ctx, tree type,
    6345              :                            bool *non_constant_p, bool *overflow_p,
    6346              :                            tree *jump_target)
    6347              : {
    6348     21009824 :   tree nelts;
    6349     21009824 :   if (TREE_CODE (type) == ARRAY_TYPE)
    6350              :     {
    6351     21009824 :       if (TYPE_DOMAIN (type))
    6352     21009564 :         nelts = array_type_nelts_top (type);
    6353              :       else
    6354          260 :         nelts = size_zero_node;
    6355              :     }
    6356            0 :   else if (VECTOR_TYPE_P (type))
    6357            0 :     nelts = size_int (TYPE_VECTOR_SUBPARTS (type));
    6358              :   else
    6359            0 :     gcc_unreachable ();
    6360              : 
    6361              :   /* For VLAs, the number of elements won't be an integer constant.  */
    6362     21009824 :   nelts = cxx_eval_constant_expression (ctx, nelts, vc_prvalue,
    6363              :                                         non_constant_p, overflow_p,
    6364              :                                         jump_target);
    6365     21009824 :   return nelts;
    6366              : }
    6367              : 
    6368              : /* Extract element INDEX consisting of CHARS_PER_ELT chars from
    6369              :    STRING_CST STRING.  */
    6370              : 
    6371              : static tree
    6372      1975077 : extract_string_elt (tree string, unsigned chars_per_elt, unsigned index)
    6373              : {
    6374      1975077 :   tree type = cv_unqualified (TREE_TYPE (TREE_TYPE (string)));
    6375      1975077 :   tree r;
    6376              : 
    6377      1975077 :   if (chars_per_elt == 1)
    6378      1760338 :     r = build_int_cst (type, TREE_STRING_POINTER (string)[index]);
    6379              :   else
    6380              :     {
    6381       214739 :       const unsigned char *ptr
    6382       214739 :         = ((const unsigned char *)TREE_STRING_POINTER (string)
    6383       214739 :            + index * chars_per_elt);
    6384       214739 :       r = native_interpret_expr (type, ptr, chars_per_elt);
    6385              :     }
    6386      1975077 :   return r;
    6387              : }
    6388              : 
    6389              : /* Subroutine of cxx_eval_array_reference.  T is an ARRAY_REF; evaluate the
    6390              :    subscript, diagnose any problems with it, and return the result.  */
    6391              : 
    6392              : static tree
    6393     21210497 : eval_and_check_array_index (const constexpr_ctx *ctx,
    6394              :                             tree t, bool allow_one_past,
    6395              :                             bool *non_constant_p, bool *overflow_p,
    6396              :                             tree *jump_target)
    6397              : {
    6398     21210497 :   location_t loc = cp_expr_loc_or_input_loc (t);
    6399     21210497 :   tree ary = TREE_OPERAND (t, 0);
    6400     21210497 :   t = TREE_OPERAND (t, 1);
    6401     21210497 :   tree index = cxx_eval_constant_expression (ctx, t, vc_prvalue,
    6402              :                                              non_constant_p, overflow_p,
    6403              :                                              jump_target);
    6404     21210497 :   if (*jump_target)
    6405              :     return NULL_TREE;
    6406     21210497 :   VERIFY_CONSTANT (index);
    6407              : 
    6408     21009032 :   if (!tree_fits_shwi_p (index)
    6409     21009032 :       || tree_int_cst_sgn (index) < 0)
    6410              :     {
    6411          112 :       diag_array_subscript (loc, ctx, ary, index);
    6412          112 :       *non_constant_p = true;
    6413          112 :       return t;
    6414              :     }
    6415              : 
    6416     21008920 :   tree nelts = get_array_or_vector_nelts (ctx, TREE_TYPE (ary), non_constant_p,
    6417              :                                           overflow_p, jump_target);
    6418     21008920 :   if (*jump_target)
    6419              :     return NULL_TREE;
    6420     21008920 :   VERIFY_CONSTANT (nelts);
    6421     21008836 :   if (allow_one_past
    6422     21008836 :       ? !tree_int_cst_le (index, nelts)
    6423     14196660 :       : !tree_int_cst_lt (index, nelts))
    6424              :     {
    6425          489 :       diag_array_subscript (loc, ctx, ary, index);
    6426          489 :       *non_constant_p = true;
    6427          489 :       return t;
    6428              :     }
    6429              : 
    6430              :   return index;
    6431              : }
    6432              : 
    6433              : /* Subroutine of cxx_eval_constant_expression.
    6434              :    Attempt to reduce a reference to an array slot.  */
    6435              : 
    6436              : static tree
    6437     15557274 : cxx_eval_array_reference (const constexpr_ctx *ctx, tree t,
    6438              :                           value_cat lval,
    6439              :                           bool *non_constant_p, bool *overflow_p,
    6440              :                           tree *jump_target)
    6441              : {
    6442     15557274 :   tree oldary = TREE_OPERAND (t, 0);
    6443     15557274 :   tree ary = cxx_eval_constant_expression (ctx, oldary,
    6444              :                                            lval,
    6445              :                                            non_constant_p, overflow_p,
    6446              :                                            jump_target);
    6447     15557274 :   if (*non_constant_p)
    6448              :     return t;
    6449     15314933 :   if (*jump_target)
    6450              :     return NULL_TREE;
    6451     15314933 :   if (!lval
    6452      8501310 :       && TREE_CODE (ary) == VIEW_CONVERT_EXPR
    6453       144212 :       && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (ary, 0)))
    6454     15459145 :       && (TYPE_MAIN_VARIANT (TREE_TYPE (t))
    6455       144212 :           == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (TREE_OPERAND (ary, 0))))))
    6456       144212 :     ary = TREE_OPERAND (ary, 0);
    6457              : 
    6458     15314933 :   tree oldidx = TREE_OPERAND (t, 1);
    6459     15314933 :   tree index = eval_and_check_array_index (ctx, t, lval,
    6460              :                                            non_constant_p, overflow_p,
    6461              :                                            jump_target);
    6462     15314933 :   if (*non_constant_p)
    6463              :     return t;
    6464     15112864 :   if (*jump_target)
    6465              :     return NULL_TREE;
    6466              : 
    6467     15112864 :   if (lval && ary == oldary && index == oldidx)
    6468              :     return t;
    6469     10071596 :   else if (lval == vc_discard)
    6470              :     return t;
    6471     10071596 :   else if (lval)
    6472      1770654 :     return build4 (ARRAY_REF, TREE_TYPE (t), ary, index, NULL, NULL);
    6473              : 
    6474      8300942 :   unsigned len = 0, elem_nchars = 1;
    6475      8300942 :   tree elem_type = TREE_TYPE (TREE_TYPE (ary));
    6476      8300942 :   if (TREE_CODE (ary) == CONSTRUCTOR)
    6477      6192802 :     len = CONSTRUCTOR_NELTS (ary);
    6478      2108140 :   else if (TREE_CODE (ary) == STRING_CST)
    6479              :     {
    6480      1963942 :       elem_nchars = (TYPE_PRECISION (elem_type)
    6481      1963942 :                      / TYPE_PRECISION (char_type_node));
    6482      1963942 :       len = (unsigned) TREE_STRING_LENGTH (ary) / elem_nchars;
    6483              :     }
    6484       144198 :   else if (TREE_CODE (ary) == VECTOR_CST)
    6485              :     /* We don't create variable-length VECTOR_CSTs.  */
    6486       144198 :     len = VECTOR_CST_NELTS (ary).to_constant ();
    6487              :   else
    6488              :     {
    6489              :       /* We can't do anything with other tree codes, so use
    6490              :          VERIFY_CONSTANT to complain and fail.  */
    6491            0 :       VERIFY_CONSTANT (ary);
    6492            0 :       gcc_unreachable ();
    6493              :     }
    6494              : 
    6495      8300942 :   bool found;
    6496      8300942 :   HOST_WIDE_INT i = 0;
    6497      8300942 :   if (TREE_CODE (ary) == CONSTRUCTOR)
    6498              :     {
    6499      6192802 :       HOST_WIDE_INT ix = find_array_ctor_elt (ary, index);
    6500      6192802 :       found = (ix >= 0);
    6501      6192802 :       if (found)
    6502      6065516 :         i = ix;
    6503              :     }
    6504              :   else
    6505              :     {
    6506      2108140 :       i = tree_to_shwi (index);
    6507      2108140 :       found = (i < len);
    6508              :     }
    6509              : 
    6510      8300942 :   if (found)
    6511              :     {
    6512      8173205 :       tree r;
    6513      8173205 :       if (TREE_CODE (ary) == CONSTRUCTOR)
    6514              :         {
    6515      6065516 :           r = (*CONSTRUCTOR_ELTS (ary))[i].value;
    6516      6065516 :           if (TREE_CODE (r) == RAW_DATA_CST)
    6517              :             {
    6518        29437 :               tree ridx = (*CONSTRUCTOR_ELTS (ary))[i].index;
    6519        29437 :               gcc_checking_assert (ridx);
    6520        29437 :               unsigned int off
    6521        29437 :                 = (wi::to_offset (index) - wi::to_offset (ridx)).to_uhwi ();
    6522        29437 :               r = raw_data_cst_elt (r, off);
    6523              :             }
    6524              :         }
    6525      2107689 :       else if (TREE_CODE (ary) == VECTOR_CST)
    6526       144198 :         r = VECTOR_CST_ELT (ary, i);
    6527              :       else
    6528      1963491 :         r = extract_string_elt (ary, elem_nchars, i);
    6529              : 
    6530      2137126 :       if (r)
    6531              :         /* Don't VERIFY_CONSTANT here.  */
    6532              :         return r;
    6533              : 
    6534              :       /* Otherwise the element doesn't have a value yet.  */
    6535              :     }
    6536              : 
    6537              :   /* Not found.  */
    6538              : 
    6539       127737 :   if (is_really_empty_class (elem_type, /*ignore_vptr*/false))
    6540           90 :     return build_constructor (elem_type, NULL);
    6541              : 
    6542       127647 :   if (TREE_CODE (ary) == CONSTRUCTOR
    6543       127647 :       && CONSTRUCTOR_NO_CLEARING (ary))
    6544              :     {
    6545              :       /* 'ary' is part of the aggregate initializer we're currently
    6546              :          building; if there's no initializer for this element yet,
    6547              :          that's an error.  */
    6548           51 :       if (!ctx->quiet)
    6549           16 :         error ("accessing uninitialized array element");
    6550           51 :       *non_constant_p = true;
    6551           51 :       return t;
    6552              :     }
    6553              : 
    6554              :   /* If it's within the array bounds but doesn't have an explicit
    6555              :      initializer, it's initialized from {}.  But use build_value_init
    6556              :      directly for non-aggregates to avoid creating a garbage CONSTRUCTOR.  */
    6557       127596 :   tree val;
    6558       127596 :   constexpr_ctx new_ctx;
    6559       127596 :   if (CP_AGGREGATE_TYPE_P (elem_type))
    6560              :     {
    6561          500 :       tree empty_ctor = build_constructor (init_list_type_node, NULL);
    6562          500 :       val = digest_init (elem_type, empty_ctor, tf_warning_or_error);
    6563              :     }
    6564              :   else
    6565       127096 :     val = build_value_init (elem_type, tf_warning_or_error);
    6566              : 
    6567              :   /* Create a new constructor only if we don't already have a suitable one.  */
    6568       127596 :   const bool new_ctor = (!SCALAR_TYPE_P (elem_type)
    6569       128122 :                          && (!ctx->ctor
    6570           45 :                              || !same_type_ignoring_top_level_qualifiers_p
    6571           45 :                                   (elem_type, TREE_TYPE (ctx->ctor))));
    6572              :   if (new_ctor)
    6573              :     {
    6574          517 :       new_ctx = *ctx;
    6575              :       /* We clear the object here.  We used to replace it with T, but that
    6576              :          caused problems (101371, 108158); and anyway, T is the initializer,
    6577              :          not the target object.  */
    6578          517 :       new_ctx.object = NULL_TREE;
    6579          517 :       new_ctx.ctor = build_constructor (elem_type, NULL);
    6580          517 :       ctx = &new_ctx;
    6581              :     }
    6582       127596 :   t = cxx_eval_constant_expression (ctx, val, lval, non_constant_p,
    6583              :                                     overflow_p, jump_target);
    6584       127596 :   if (new_ctor && t != ctx->ctor)
    6585          496 :     free_constructor (ctx->ctor);
    6586              :   return t;
    6587              : }
    6588              : 
    6589              : /* Subroutine of cxx_eval_constant_expression.
    6590              :    Attempt to reduce a field access of a value of class type.  */
    6591              : 
    6592              : static tree
    6593    116103042 : cxx_eval_component_reference (const constexpr_ctx *ctx, tree t,
    6594              :                               value_cat lval,
    6595              :                               bool *non_constant_p, bool *overflow_p,
    6596              :                               tree *jump_target)
    6597              : {
    6598    116103042 :   unsigned HOST_WIDE_INT i;
    6599    116103042 :   tree field;
    6600    116103042 :   tree value;
    6601    116103042 :   tree part = TREE_OPERAND (t, 1);
    6602    116103042 :   tree orig_whole = TREE_OPERAND (t, 0);
    6603    116103042 :   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
    6604              :                                              lval,
    6605              :                                              non_constant_p, overflow_p,
    6606              :                                              jump_target);
    6607    116103042 :   if (*non_constant_p)
    6608              :     return t;
    6609     90048146 :   if (*jump_target)
    6610              :     return NULL_TREE;
    6611     90048140 :   if (INDIRECT_REF_P (whole)
    6612     90048140 :       && integer_zerop (TREE_OPERAND (whole, 0)))
    6613              :     {
    6614          177 :       if (!ctx->quiet)
    6615           39 :         error ("dereferencing a null pointer in %qE", orig_whole);
    6616          177 :       *non_constant_p = true;
    6617          177 :       return t;
    6618              :     }
    6619              : 
    6620     90047963 :   if (TREE_CODE (whole) == PTRMEM_CST)
    6621         1651 :     whole = cplus_expand_constant (whole);
    6622     90047963 :   if (whole == orig_whole)
    6623              :     return t;
    6624     60968950 :   if (lval == vc_discard)
    6625              :     return t;
    6626     60968926 :   if (lval)
    6627     21630899 :     return fold_build3 (COMPONENT_REF, TREE_TYPE (t),
    6628              :                         whole, part, NULL_TREE);
    6629              :   /* Don't VERIFY_CONSTANT here; we only want to check that we got a
    6630              :      CONSTRUCTOR.  */
    6631     39338027 :   if (TREE_CODE (whole) != CONSTRUCTOR)
    6632              :     {
    6633            0 :       if (!ctx->quiet)
    6634            0 :         error ("%qE is not a constant expression", orig_whole);
    6635            0 :       *non_constant_p = true;
    6636            0 :       return t;
    6637              :     }
    6638     39336533 :   if ((cxx_dialect < cxx14 || CONSTRUCTOR_MUTABLE_POISON (whole))
    6639     39339703 :       && DECL_MUTABLE_P (part))
    6640              :     {
    6641          144 :       if (!ctx->quiet)
    6642           16 :         error ("mutable %qD is not usable in a constant expression", part);
    6643          144 :       *non_constant_p = true;
    6644          144 :       return t;
    6645              :     }
    6646              : 
    6647     39337883 :   bool pmf = TYPE_PTRMEMFUNC_P (TREE_TYPE (whole));
    6648     59174381 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
    6649              :     {
    6650              :       /* Use name match for PMF fields, as a variant will have a
    6651              :          different FIELD_DECL with a different type.  */
    6652     58948506 :       if (pmf ? DECL_NAME (field) == DECL_NAME (part)
    6653              :           : field == part)
    6654              :         {
    6655     39112008 :           if (value == void_node)
    6656            6 :             goto uninit;
    6657     39112002 :           if (value)
    6658              :             {
    6659     39111984 :               STRIP_ANY_LOCATION_WRAPPER (value);
    6660     39111984 :               return value;
    6661              :             }
    6662              :           else
    6663              :             /* We're in the middle of initializing it.  */
    6664              :             break;
    6665              :         }
    6666              :     }
    6667       225893 :   if (TREE_CODE (TREE_TYPE (whole)) == UNION_TYPE)
    6668              :     {
    6669          112 :       if (CONSTRUCTOR_NELTS (whole) > 0)
    6670              :         {
    6671              :           /* DR 1188 says we don't have to deal with this.  */
    6672           97 :           if (!ctx->quiet)
    6673              :             {
    6674           20 :               constructor_elt *cep = CONSTRUCTOR_ELT (whole, 0);
    6675           20 :               if (cep->value == NULL_TREE)
    6676            9 :                 error ("accessing uninitialized member %qD", part);
    6677              :               else
    6678           11 :                 error ("accessing %qD member instead of active %qD member "
    6679              :                        "in constant expression", part, cep->index);
    6680              :             }
    6681           97 :           *non_constant_p = true;
    6682           97 :           return t;
    6683              :         }
    6684           15 :       else if (!CONSTRUCTOR_NO_CLEARING (whole))
    6685              :         {
    6686              :           /* Value-initialized union, check if looking at the first member.  */
    6687           12 :           tree first = next_aggregate_field (TYPE_FIELDS (TREE_TYPE (whole)));
    6688           12 :           if (first != part)
    6689              :             {
    6690            9 :               if (!ctx->quiet)
    6691            3 :                 error ("accessing %qD member instead of initialized %qD "
    6692              :                        "member in constant expression", part, first);
    6693            9 :               *non_constant_p = true;
    6694            9 :               return t;
    6695              :             }
    6696              :         }
    6697              :     }
    6698              : 
    6699              :   /* We only create a CONSTRUCTOR for a subobject when we modify it, so empty
    6700              :      classes never get represented; throw together a value now.  */
    6701       225787 :   if (is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
    6702       209209 :     return build_constructor (TREE_TYPE (t), NULL);
    6703              : 
    6704        16578 :   gcc_assert (DECL_CONTEXT (part) == TYPE_MAIN_VARIANT (TREE_TYPE (whole)));
    6705              : 
    6706        16578 :   if (CONSTRUCTOR_NO_CLEARING (whole))
    6707              :     {
    6708          112 :     uninit:
    6709              :       /* 'whole' is part of the aggregate initializer we're currently
    6710              :          building; if there's no initializer for this member yet, that's an
    6711              :          error.  */
    6712          118 :       if (!ctx->quiet)
    6713           23 :         error ("accessing uninitialized member %qD", part);
    6714          118 :       *non_constant_p = true;
    6715          118 :       return t;
    6716              :     }
    6717              : 
    6718              :   /* If there's no explicit init for this field, it's value-initialized.  */
    6719              : 
    6720        16466 :   if (AGGREGATE_TYPE_P (TREE_TYPE (t)))
    6721              :     {
    6722              :       /* As in cxx_eval_store_expression, insert an empty CONSTRUCTOR
    6723              :          and copy the flags.  */
    6724        15869 :       constructor_elt *e = get_or_insert_ctor_field (whole, part);
    6725        15869 :       e->value = value = build_constructor (TREE_TYPE (part), NULL);
    6726        15869 :       CONSTRUCTOR_ZERO_PADDING_BITS (value)
    6727        15869 :         = CONSTRUCTOR_ZERO_PADDING_BITS (whole);
    6728        15869 :       return value;
    6729              :     }
    6730              : 
    6731          597 :   value = build_value_init (TREE_TYPE (t), tf_warning_or_error);
    6732          597 :   return cxx_eval_constant_expression (ctx, value,
    6733              :                                        lval,
    6734              :                                        non_constant_p, overflow_p,
    6735          597 :                                        jump_target);
    6736              : }
    6737              : 
    6738              : /* Subroutine of cxx_eval_constant_expression.
    6739              :    Attempt to reduce a field access of a value of class type that is
    6740              :    expressed as a BIT_FIELD_REF.  */
    6741              : 
    6742              : static tree
    6743        40745 : cxx_eval_bit_field_ref (const constexpr_ctx *ctx, tree t,
    6744              :                         value_cat lval,
    6745              :                         bool *non_constant_p, bool *overflow_p,
    6746              :                         tree *jump_target)
    6747              : {
    6748        40745 :   tree orig_whole = TREE_OPERAND (t, 0);
    6749        40745 :   tree retval, fldval, utype, mask;
    6750        40745 :   bool fld_seen = false;
    6751        40745 :   HOST_WIDE_INT istart, isize;
    6752        40745 :   tree whole = cxx_eval_constant_expression (ctx, orig_whole,
    6753              :                                              lval,
    6754              :                                              non_constant_p, overflow_p,
    6755              :                                              jump_target);
    6756        40745 :   tree start, field, value;
    6757        40745 :   unsigned HOST_WIDE_INT i;
    6758              : 
    6759        40745 :   if (*jump_target)
    6760              :     return NULL_TREE;
    6761        40745 :   if (whole == orig_whole)
    6762              :     return t;
    6763              :   /* Don't VERIFY_CONSTANT here; we only want to check that we got a
    6764              :      CONSTRUCTOR.  */
    6765        40596 :   if (!*non_constant_p
    6766        40596 :       && TREE_CODE (whole) != VECTOR_CST
    6767            0 :       && TREE_CODE (whole) != CONSTRUCTOR)
    6768              :     {
    6769            0 :       if (!ctx->quiet)
    6770            0 :         error ("%qE is not a constant expression", orig_whole);
    6771            0 :       *non_constant_p = true;
    6772              :     }
    6773        40596 :   if (*non_constant_p)
    6774              :     return t;
    6775              : 
    6776        40596 :   if (TREE_CODE (whole) == VECTOR_CST || !INTEGRAL_TYPE_P (TREE_TYPE (t)))
    6777              :     {
    6778        40596 :       if (tree r = fold_ternary (BIT_FIELD_REF, TREE_TYPE (t), whole,
    6779              :                                  TREE_OPERAND (t, 1), TREE_OPERAND (t, 2)))
    6780              :         return r;
    6781            0 :       if (!ctx->quiet)
    6782            0 :         error ("%qE is not a constant expression", orig_whole);
    6783            0 :       *non_constant_p = true;
    6784            0 :       return t;
    6785              :     }
    6786              : 
    6787            0 :   start = TREE_OPERAND (t, 2);
    6788            0 :   istart = tree_to_shwi (start);
    6789            0 :   isize = tree_to_shwi (TREE_OPERAND (t, 1));
    6790            0 :   utype = TREE_TYPE (t);
    6791            0 :   if (!TYPE_UNSIGNED (utype))
    6792            0 :     utype = build_nonstandard_integer_type (TYPE_PRECISION (utype), 1);
    6793            0 :   retval = build_int_cst (utype, 0);
    6794            0 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (whole), i, field, value)
    6795              :     {
    6796            0 :       tree bitpos = bit_position (field);
    6797            0 :       STRIP_ANY_LOCATION_WRAPPER (value);
    6798            0 :       if (bitpos == start && DECL_SIZE (field) == TREE_OPERAND (t, 1))
    6799              :         return value;
    6800            0 :       if (TREE_CODE (TREE_TYPE (field)) == INTEGER_TYPE
    6801            0 :           && TREE_CODE (value) == INTEGER_CST
    6802            0 :           && tree_fits_shwi_p (bitpos)
    6803            0 :           && tree_fits_shwi_p (DECL_SIZE (field)))
    6804              :         {
    6805            0 :           HOST_WIDE_INT bit = tree_to_shwi (bitpos);
    6806            0 :           HOST_WIDE_INT sz = tree_to_shwi (DECL_SIZE (field));
    6807            0 :           HOST_WIDE_INT shift;
    6808            0 :           if (bit >= istart && bit + sz <= istart + isize)
    6809              :             {
    6810            0 :               fldval = fold_convert (utype, value);
    6811            0 :               mask = build_int_cst_type (utype, -1);
    6812            0 :               mask = fold_build2 (LSHIFT_EXPR, utype, mask,
    6813              :                                   size_int (TYPE_PRECISION (utype) - sz));
    6814            0 :               mask = fold_build2 (RSHIFT_EXPR, utype, mask,
    6815              :                                   size_int (TYPE_PRECISION (utype) - sz));
    6816            0 :               fldval = fold_build2 (BIT_AND_EXPR, utype, fldval, mask);
    6817            0 :               shift = bit - istart;
    6818            0 :               if (BYTES_BIG_ENDIAN)
    6819              :                 shift = TYPE_PRECISION (utype) - shift - sz;
    6820            0 :               fldval = fold_build2 (LSHIFT_EXPR, utype, fldval,
    6821              :                                     size_int (shift));
    6822            0 :               retval = fold_build2 (BIT_IOR_EXPR, utype, retval, fldval);
    6823            0 :               fld_seen = true;
    6824              :             }
    6825              :         }
    6826              :     }
    6827            0 :   if (fld_seen)
    6828            0 :     return fold_convert (TREE_TYPE (t), retval);
    6829            0 :   gcc_unreachable ();
    6830              :   return error_mark_node;
    6831              : }
    6832              : 
    6833              : /* Helper for cxx_eval_bit_cast.
    6834              :    Check [bit.cast]/3 rules, bit_cast is constexpr only if the To and From
    6835              :    types and types of all subobjects have is_union_v<T>, is_pointer_v<T>,
    6836              :    is_member_pointer_v<T>, is_volatile_v<T> false and has no non-static
    6837              :    data members of reference type.  */
    6838              : 
    6839              : static bool
    6840        56278 : check_bit_cast_type (const constexpr_ctx *ctx, location_t loc, tree type,
    6841              :                      tree orig_type)
    6842              : {
    6843        57278 :   if (TREE_CODE (type) == UNION_TYPE)
    6844              :     {
    6845           63 :       if (!ctx->quiet)
    6846              :         {
    6847           21 :           if (type == orig_type)
    6848            6 :             error_at (loc, "%qs is not a constant expression because %qT is "
    6849              :                            "a union type", "__builtin_bit_cast", type);
    6850              :           else
    6851           15 :             error_at (loc, "%qs is not a constant expression because %qT "
    6852              :                            "contains a union type", "__builtin_bit_cast",
    6853              :                       orig_type);
    6854              :         }
    6855              :       return true;
    6856              :     }
    6857              :   if (TREE_CODE (type) == POINTER_TYPE)
    6858              :     {
    6859           57 :       if (!ctx->quiet)
    6860              :         {
    6861           18 :           if (type == orig_type)
    6862            6 :             error_at (loc, "%qs is not a constant expression because %qT is "
    6863              :                            "a pointer type", "__builtin_bit_cast", type);
    6864              :           else
    6865           12 :             error_at (loc, "%qs is not a constant expression because %qT "
    6866              :                            "contains a pointer type", "__builtin_bit_cast",
    6867              :                       orig_type);
    6868              :         }
    6869              :       return true;
    6870              :     }
    6871              :   if (TREE_CODE (type) == REFERENCE_TYPE)
    6872              :     {
    6873            0 :       if (!ctx->quiet)
    6874              :         {
    6875            0 :           if (type == orig_type)
    6876            0 :             error_at (loc, "%qs is not a constant expression because %qT is "
    6877              :                            "a reference type", "__builtin_bit_cast", type);
    6878              :           else
    6879            0 :             error_at (loc, "%qs is not a constant expression because %qT "
    6880              :                            "contains a reference type", "__builtin_bit_cast",
    6881              :                       orig_type);
    6882              :         }
    6883              :       return true;
    6884              :     }
    6885        39310 :   if (TYPE_PTRMEM_P (type))
    6886              :     {
    6887           36 :       if (!ctx->quiet)
    6888              :         {
    6889           12 :           if (type == orig_type)
    6890           12 :             error_at (loc, "%qs is not a constant expression because %qT is "
    6891              :                            "a pointer to member type", "__builtin_bit_cast",
    6892              :                       type);
    6893              :           else
    6894            0 :             error_at (loc, "%qs is not a constant expression because %qT "
    6895              :                            "contains a pointer to member type",
    6896              :                       "__builtin_bit_cast", orig_type);
    6897              :         }
    6898              :       return true;
    6899              :     }
    6900        57122 :   if (TYPE_VOLATILE (type))
    6901              :     {
    6902            0 :       if (!ctx->quiet)
    6903              :         {
    6904            0 :           if (type == orig_type)
    6905            0 :             error_at (loc, "%qs is not a constant expression because %qT is "
    6906              :                            "volatile", "__builtin_bit_cast", type);
    6907              :           else
    6908            0 :             error_at (loc, "%qs is not a constant expression because %qT "
    6909              :                            "contains a volatile subobject",
    6910              :                       "__builtin_bit_cast", orig_type);
    6911              :         }
    6912              :       return true;
    6913              :     }
    6914        57122 :   if (TREE_CODE (type) == RECORD_TYPE)
    6915      2294014 :     for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    6916      2254812 :       if (TREE_CODE (field) == FIELD_DECL
    6917      2254812 :           && check_bit_cast_type (ctx, loc, TREE_TYPE (field), orig_type))
    6918              :         return true;
    6919        57032 :   if (TREE_CODE (type) == ARRAY_TYPE)
    6920         1000 :     return check_bit_cast_type (ctx, loc, TREE_TYPE (type), orig_type);
    6921              :   return false;
    6922              : }
    6923              : 
    6924              : /* Helper function for cxx_eval_bit_cast.  For unsigned char or
    6925              :    std::byte members of CONSTRUCTOR (recursively) if they contain
    6926              :    some indeterminate bits (as set in MASK), remove the ctor elts,
    6927              :    mark the CONSTRUCTOR as CONSTRUCTOR_NO_CLEARING and clear the
    6928              :    bits in MASK.  */
    6929              : 
    6930              : static void
    6931         9631 : clear_uchar_or_std_byte_in_mask (location_t loc, tree t, unsigned char *mask)
    6932              : {
    6933         9631 :   if (TREE_CODE (t) != CONSTRUCTOR)
    6934              :     return;
    6935              : 
    6936              :   unsigned i, j = 0;
    6937              :   tree index, value;
    6938        23564 :   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t), i, index, value)
    6939              :     {
    6940        13933 :       tree type = TREE_TYPE (value);
    6941        13933 :       if (TREE_CODE (TREE_TYPE (t)) != ARRAY_TYPE
    6942        27427 :           && DECL_BIT_FIELD_TYPE (index) != NULL_TREE)
    6943              :         {
    6944          270 :           if (is_byte_access_type_not_plain_char (DECL_BIT_FIELD_TYPE (index)))
    6945              :             {
    6946          135 :               HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (index));
    6947          135 :               gcc_assert (fldsz != 0);
    6948          135 :               HOST_WIDE_INT pos = int_byte_position (index);
    6949          135 :               HOST_WIDE_INT bpos
    6950          135 :                 = tree_to_uhwi (DECL_FIELD_BIT_OFFSET (index));
    6951          135 :               bpos %= BITS_PER_UNIT;
    6952          135 :               HOST_WIDE_INT end
    6953          135 :                 = ROUND_UP (bpos + fldsz, BITS_PER_UNIT) / BITS_PER_UNIT;
    6954          135 :               gcc_assert (end == 1 || end == 2);
    6955          135 :               unsigned char *p = mask + pos;
    6956          135 :               unsigned char mask_save[2];
    6957          135 :               mask_save[0] = mask[pos];
    6958          135 :               mask_save[1] = end == 2 ? mask[pos + 1] : 0;
    6959          135 :               if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN)
    6960              :                 sorry_at (loc, "PDP11 bit-field handling unsupported"
    6961              :                                " in %qs", "__builtin_bit_cast");
    6962          135 :               else if (BYTES_BIG_ENDIAN)
    6963              :                 {
    6964              :                   /* Big endian.  */
    6965              :                   if (bpos + fldsz <= BITS_PER_UNIT)
    6966              :                     *p &= ~(((1 << fldsz) - 1)
    6967              :                             << (BITS_PER_UNIT - bpos - fldsz));
    6968              :                   else
    6969              :                     {
    6970              :                       gcc_assert (bpos);
    6971              :                       *p &= ~(((1U << BITS_PER_UNIT) - 1) >> bpos);
    6972              :                       p++;
    6973              :                       fldsz -= BITS_PER_UNIT - bpos;
    6974              :                       gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
    6975              :                       *p &= ((1U << BITS_PER_UNIT) - 1) >> fldsz;
    6976              :                     }
    6977              :                 }
    6978              :               else
    6979              :                 {
    6980              :                   /* Little endian.  */
    6981          135 :                   if (bpos + fldsz <= BITS_PER_UNIT)
    6982          135 :                     *p &= ~(((1 << fldsz) - 1) << bpos);
    6983              :                   else
    6984              :                     {
    6985            0 :                       gcc_assert (bpos);
    6986            0 :                       *p &= ~(((1 << BITS_PER_UNIT) - 1) << bpos);
    6987            0 :                       p++;
    6988            0 :                       fldsz -= BITS_PER_UNIT - bpos;
    6989            0 :                       gcc_assert (fldsz && fldsz < BITS_PER_UNIT);
    6990            0 :                       *p &= ~((1 << fldsz) - 1);
    6991              :                     }
    6992              :                 }
    6993          135 :               if (mask_save[0] != mask[pos]
    6994           99 :                   || (end == 2 && mask_save[1] != mask[pos + 1]))
    6995              :                 {
    6996           36 :                   CONSTRUCTOR_NO_CLEARING (t) = 1;
    6997           36 :                   continue;
    6998              :                 }
    6999              :             }
    7000              :         }
    7001        13663 :       else if (is_byte_access_type_not_plain_char (type))
    7002              :         {
    7003          228 :           HOST_WIDE_INT pos;
    7004          228 :           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
    7005          132 :             pos = tree_to_shwi (index);
    7006              :           else
    7007           96 :             pos = int_byte_position (index);
    7008          228 :           if (mask[pos])
    7009              :             {
    7010           48 :               CONSTRUCTOR_NO_CLEARING (t) = 1;
    7011           48 :               mask[pos] = 0;
    7012           48 :               continue;
    7013              :             }
    7014              :         }
    7015        13849 :       if (TREE_CODE (value) == CONSTRUCTOR)
    7016              :         {
    7017         7292 :           HOST_WIDE_INT pos;
    7018         7292 :           if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
    7019          144 :             pos = tree_to_shwi (index)
    7020           72 :                   * tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (TREE_TYPE (t))));
    7021              :           else
    7022         7220 :             pos = int_byte_position (index);
    7023         7292 :           clear_uchar_or_std_byte_in_mask (loc, value, mask + pos);
    7024              :         }
    7025        13849 :       if (i != j)
    7026              :         {
    7027          180 :           CONSTRUCTOR_ELT (t, j)->index = index;
    7028          180 :           CONSTRUCTOR_ELT (t, j)->value = value;
    7029              :         }
    7030        13849 :       ++j;
    7031              :     }
    7032        19262 :   if (CONSTRUCTOR_NELTS (t) != j)
    7033           84 :     vec_safe_truncate (CONSTRUCTOR_ELTS (t), j);
    7034              : }
    7035              : 
    7036              : /* Subroutine of cxx_eval_constant_expression.
    7037              :    Attempt to evaluate a BIT_CAST_EXPR.  */
    7038              : 
    7039              : static tree
    7040         4025 : cxx_eval_bit_cast (const constexpr_ctx *ctx, tree t, bool *non_constant_p,
    7041              :                    bool *overflow_p, tree *jump_target)
    7042              : {
    7043         4025 :   if (check_bit_cast_type (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
    7044         4025 :                            TREE_TYPE (t))
    7045        12733 :       || check_bit_cast_type (ctx, cp_expr_loc_or_loc (TREE_OPERAND (t, 0),
    7046         3944 :                                                        EXPR_LOCATION (t)),
    7047         3944 :                               TREE_TYPE (TREE_OPERAND (t, 0)),
    7048         3944 :                               TREE_TYPE (TREE_OPERAND (t, 0))))
    7049              :     {
    7050          156 :       *non_constant_p = true;
    7051          156 :       return t;
    7052              :     }
    7053              : 
    7054         3869 :   tree op = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_prvalue,
    7055              :                                           non_constant_p, overflow_p,
    7056              :                                           jump_target);
    7057         3869 :   if (*non_constant_p)
    7058              :     return t;
    7059         2820 :   if (*jump_target)
    7060              :     return NULL_TREE;
    7061              : 
    7062         2820 :   location_t loc = EXPR_LOCATION (t);
    7063         2820 :   if (BITS_PER_UNIT != 8 || CHAR_BIT != 8)
    7064              :     {
    7065              :       if (!ctx->quiet)
    7066              :         sorry_at (loc, "%qs cannot be constant evaluated on the target",
    7067              :                        "__builtin_bit_cast");
    7068              :       *non_constant_p = true;
    7069              :       return t;
    7070              :     }
    7071              : 
    7072         2820 :   if (!tree_fits_shwi_p (TYPE_SIZE_UNIT (TREE_TYPE (t))))
    7073              :     {
    7074            0 :       if (!ctx->quiet)
    7075            0 :         sorry_at (loc, "%qs cannot be constant evaluated because the "
    7076              :                        "type is too large", "__builtin_bit_cast");
    7077            0 :       *non_constant_p = true;
    7078            0 :       return t;
    7079              :     }
    7080              : 
    7081         2820 :   HOST_WIDE_INT len = tree_to_shwi (TYPE_SIZE_UNIT (TREE_TYPE (t)));
    7082         2820 :   if (len < 0 || (int) len != len)
    7083              :     {
    7084            0 :       if (!ctx->quiet)
    7085            0 :         sorry_at (loc, "%qs cannot be constant evaluated because the "
    7086              :                        "type is too large", "__builtin_bit_cast");
    7087            0 :       *non_constant_p = true;
    7088            0 :       return t;
    7089              :     }
    7090              : 
    7091         2820 :   unsigned char buf[64];
    7092         2820 :   unsigned char *ptr, *mask;
    7093         2820 :   size_t alen = (size_t) len * 2;
    7094         2820 :   if (alen <= sizeof (buf))
    7095              :     ptr = buf;
    7096              :   else
    7097          329 :     ptr = XNEWVEC (unsigned char, alen);
    7098         2820 :   mask = ptr + (size_t) len;
    7099              :   /* At the beginning consider everything indeterminate.  */
    7100         2820 :   memset (mask, ~0, (size_t) len);
    7101              : 
    7102         2820 :   if (native_encode_initializer (op, ptr, len, 0, mask) != len)
    7103              :     {
    7104            0 :       if (!ctx->quiet)
    7105            0 :         sorry_at (loc, "%qs cannot be constant evaluated because the "
    7106              :                        "argument cannot be encoded", "__builtin_bit_cast");
    7107            0 :       *non_constant_p = true;
    7108            0 :       if (ptr != buf)
    7109            0 :         XDELETE (ptr);
    7110              :       return t;
    7111              :     }
    7112              : 
    7113         2820 :   tree r = NULL_TREE;
    7114         2820 :   if (can_native_interpret_type_p (TREE_TYPE (t)))
    7115              :     {
    7116          481 :       r = native_interpret_expr (TREE_TYPE (t), ptr, len);
    7117          481 :       if (is_byte_access_type_not_plain_char (TREE_TYPE (t)))
    7118              :         {
    7119           52 :           gcc_assert (len == 1);
    7120           52 :           if (mask[0])
    7121              :             {
    7122           27 :               memset (mask, 0, len);
    7123           27 :               r = build_constructor (TREE_TYPE (r), NULL);
    7124           27 :               CONSTRUCTOR_NO_CLEARING (r) = 1;
    7125              :             }
    7126              :         }
    7127              :     }
    7128         2339 :   else if (TREE_CODE (TREE_TYPE (t)) == RECORD_TYPE)
    7129              :     {
    7130         2339 :       r = native_interpret_aggregate (TREE_TYPE (t), ptr, 0, len);
    7131         2339 :       if (r != NULL_TREE)
    7132              :         {
    7133         2339 :           clear_type_padding_in_mask (TREE_TYPE (t), mask);
    7134         2339 :           clear_uchar_or_std_byte_in_mask (loc, r, mask);
    7135         2339 :           if (CHECKING_P)
    7136              :             {
    7137         2339 :               tree e = cxx_eval_bare_aggregate (ctx, r, vc_prvalue,
    7138              :                                                 non_constant_p, overflow_p,
    7139              :                                                 jump_target);
    7140         2339 :               gcc_checking_assert (e == r && !*jump_target);
    7141              :               r = e;
    7142              :             }
    7143              :         }
    7144              :     }
    7145              : 
    7146         2820 :   if (r != NULL_TREE)
    7147              :     {
    7148        92041 :       for (int i = 0; i < len; i++)
    7149        89311 :         if (mask[i])
    7150              :           {
    7151           90 :             if (!ctx->quiet)
    7152           30 :               error_at (loc, "%qs accessing uninitialized byte at offset %d",
    7153              :                              "__builtin_bit_cast", i);
    7154           90 :             *non_constant_p = true;
    7155           90 :             r = t;
    7156           90 :             break;
    7157              :           }
    7158         2820 :       if (ptr != buf)
    7159          329 :         XDELETE (ptr);
    7160              :       return r;
    7161              :     }
    7162              : 
    7163            0 :   if (!ctx->quiet)
    7164            0 :     sorry_at (loc, "%qs cannot be constant evaluated because the "
    7165              :                    "argument cannot be interpreted", "__builtin_bit_cast");
    7166            0 :   *non_constant_p = true;
    7167            0 :   if (ptr != buf)
    7168            0 :     XDELETE (ptr);
    7169              :   return t;
    7170              : }
    7171              : 
    7172              : /* Subroutine of cxx_eval_constant_expression.
    7173              :    Evaluate a short-circuited logical expression T in the context
    7174              :    of a given constexpr CALL.  BAILOUT_VALUE is the value for
    7175              :    early return.  CONTINUE_VALUE is used here purely for
    7176              :    sanity check purposes.  */
    7177              : 
    7178              : static tree
    7179     18483962 : cxx_eval_logical_expression (const constexpr_ctx *ctx, tree t,
    7180              :                              tree bailout_value, tree continue_value,
    7181              :                              bool *non_constant_p, bool *overflow_p,
    7182              :                              tree *jump_target)
    7183              : {
    7184     18483962 :   tree r;
    7185     18483962 :   tree lhs = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
    7186              :                                            vc_prvalue, non_constant_p,
    7187              :                                            overflow_p, jump_target);
    7188     18483960 :   if (*jump_target)
    7189              :     return NULL_TREE;
    7190     18483951 :   VERIFY_CONSTANT (lhs);
    7191     13696833 :   if (tree_int_cst_equal (lhs, bailout_value))
    7192              :     return lhs;
    7193     11660270 :   gcc_assert (tree_int_cst_equal (lhs, continue_value));
    7194     11660270 :   r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
    7195              :                                     vc_prvalue, non_constant_p,
    7196              :                                     overflow_p, jump_target);
    7197     11660270 :   if (*jump_target)
    7198              :     return NULL_TREE;
    7199     11660270 :   VERIFY_CONSTANT (r);
    7200              :   return r;
    7201              : }
    7202              : 
    7203              : /* REF is a COMPONENT_REF designating a particular field.  V is a vector of
    7204              :    CONSTRUCTOR elements to initialize (part of) an object containing that
    7205              :    field.  Return a pointer to the constructor_elt corresponding to the
    7206              :    initialization of the field.  */
    7207              : 
    7208              : static constructor_elt *
    7209            0 : base_field_constructor_elt (vec<constructor_elt, va_gc> *v, tree ref)
    7210              : {
    7211            0 :   tree aggr = TREE_OPERAND (ref, 0);
    7212            0 :   tree field = TREE_OPERAND (ref, 1);
    7213            0 :   HOST_WIDE_INT i;
    7214            0 :   constructor_elt *ce;
    7215              : 
    7216            0 :   gcc_assert (TREE_CODE (ref) == COMPONENT_REF);
    7217              : 
    7218            0 :   if (TREE_CODE (aggr) == COMPONENT_REF)
    7219              :     {
    7220            0 :       constructor_elt *base_ce
    7221            0 :         = base_field_constructor_elt (v, aggr);
    7222            0 :       v = CONSTRUCTOR_ELTS (base_ce->value);
    7223              :     }
    7224              : 
    7225            0 :   for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
    7226            0 :     if (ce->index == field)
    7227            0 :       return ce;
    7228              : 
    7229            0 :   gcc_unreachable ();
    7230              :   return NULL;
    7231              : }
    7232              : 
    7233              : /* Some of the expressions fed to the constexpr mechanism are calls to
    7234              :    constructors, which have type void.  In that case, return the type being
    7235              :    initialized by the constructor.  */
    7236              : 
    7237              : static tree
    7238    610082107 : initialized_type (tree t)
    7239              : {
    7240    611746188 :   if (TYPE_P (t))
    7241              :     return t;
    7242    611745724 :   tree type = TREE_TYPE (t);
    7243    611745724 :   if (TREE_CODE (t) == CALL_EXPR)
    7244              :     {
    7245              :       /* A constructor call has void type, so we need to look deeper.  */
    7246     74131355 :       tree fn = get_function_named_in_call (t);
    7247     74124876 :       if (fn && TREE_CODE (fn) == FUNCTION_DECL
    7248    148129738 :           && DECL_CXX_CONSTRUCTOR_P (fn))
    7249      4097008 :         type = DECL_CONTEXT (fn);
    7250              :     }
    7251    537614369 :   else if (TREE_CODE (t) == COMPOUND_EXPR)
    7252      1664081 :     return initialized_type (TREE_OPERAND (t, 1));
    7253    535950288 :   else if (TREE_CODE (t) == AGGR_INIT_EXPR)
    7254       883071 :     type = TREE_TYPE (AGGR_INIT_EXPR_SLOT (t));
    7255    610081643 :   return cv_unqualified (type);
    7256              : }
    7257              : 
    7258              : /* We're about to initialize element INDEX of an array or class from VALUE.
    7259              :    Set up NEW_CTX appropriately by adjusting .object to refer to the
    7260              :    subobject and creating a new CONSTRUCTOR if the element is itself
    7261              :    a class or array.  */
    7262              : 
    7263              : static void
    7264      4200518 : init_subob_ctx (const constexpr_ctx *ctx, constexpr_ctx &new_ctx,
    7265              :                tree index, tree &value)
    7266              : {
    7267      4200518 :   new_ctx = *ctx;
    7268              : 
    7269      4200518 :   if (index && TREE_CODE (index) != INTEGER_CST
    7270      3763260 :       && TREE_CODE (index) != FIELD_DECL
    7271            3 :       && TREE_CODE (index) != RANGE_EXPR)
    7272              :     /* This won't have an element in the new CONSTRUCTOR.  */
    7273              :     return;
    7274              : 
    7275      4200518 :   tree type = initialized_type (value);
    7276      4200518 :   if (!AGGREGATE_TYPE_P (type) && !VECTOR_TYPE_P (type))
    7277              :     /* A non-aggregate member doesn't get its own CONSTRUCTOR.  */
    7278              :     return;
    7279              : 
    7280      1696095 :   tree ctxtype = NULL_TREE;
    7281      1696095 :   if (ctx->ctor)
    7282      1696078 :     ctxtype = TREE_TYPE (ctx->ctor);
    7283           17 :   else if (ctx->object)
    7284           14 :     ctxtype = TREE_TYPE (ctx->object);
    7285              :   else
    7286              :     {
    7287              :       /* This can happen if the enclosing object is also an empty subobject
    7288              :          (c++/125315).  */
    7289            3 :       gcc_checking_assert (is_empty_field (index));
    7290              :       return;
    7291              :     }
    7292              : 
    7293      1696092 :   if (VECTOR_TYPE_P (type)
    7294         7417 :       && VECTOR_TYPE_P (ctxtype)
    7295         2596 :       && index == NULL_TREE)
    7296              :     /* A vector inside of a vector CONSTRUCTOR, e.g. when a larger
    7297              :        vector is constructed from smaller vectors, doesn't get its own
    7298              :        CONSTRUCTOR either.  */
    7299              :     return;
    7300              : 
    7301              :   /* The sub-aggregate initializer might contain a placeholder;
    7302              :      update object to refer to the subobject and ctor to refer to
    7303              :      the (newly created) sub-initializer.  */
    7304      1693496 :   if (ctx->object)
    7305              :     {
    7306      1530867 :       if (index == NULL_TREE || TREE_CODE (index) == RANGE_EXPR)
    7307              :         /* There's no well-defined subobject for this index.  */
    7308            3 :         new_ctx.object = NULL_TREE;
    7309              :       else
    7310      1530864 :         new_ctx.object = build_ctor_subob_ref (index, type, ctx->object);
    7311              :     }
    7312              : 
    7313      1693496 :   if (is_empty_field (index)
    7314      1693496 :       && TREE_CODE (ctxtype) != UNION_TYPE)
    7315              :     /* Leave ctor null for an empty subobject of a non-union class, they aren't
    7316              :        represented in the result of evaluation.  */
    7317      1518130 :     new_ctx.ctor = NULL_TREE;
    7318              :   else
    7319              :     {
    7320       175366 :       tree elt = build_constructor (type, NULL);
    7321       175366 :       CONSTRUCTOR_NO_CLEARING (elt) = true;
    7322       175366 :       new_ctx.ctor = elt;
    7323              :     }
    7324              : 
    7325      1693496 :   if (TREE_CODE (value) == TARGET_EXPR)
    7326              :     /* Avoid creating another CONSTRUCTOR when we expand the TARGET_EXPR.  */
    7327       120255 :     value = TARGET_EXPR_INITIAL (value);
    7328              : }
    7329              : 
    7330              : /* We're about to process an initializer for a class or array TYPE.  Make
    7331              :    sure that CTX is set up appropriately.  */
    7332              : 
    7333              : static void
    7334      3390722 : verify_ctor_sanity (const constexpr_ctx *ctx, tree type)
    7335              : {
    7336              :   /* We don't bother building a ctor for an empty base subobject.  */
    7337      3390722 :   if (is_empty_class (type))
    7338              :     return;
    7339              : 
    7340              :   /* We're in the middle of an initializer that might involve placeholders;
    7341              :      our caller should have created a CONSTRUCTOR for us to put the
    7342              :      initializer into.  We will either return that constructor or T.  */
    7343      1890823 :   gcc_assert (ctx->ctor);
    7344      1890823 :   gcc_assert (same_type_ignoring_top_level_qualifiers_p
    7345              :               (type, TREE_TYPE (ctx->ctor)));
    7346              :   /* We used to check that ctx->ctor was empty, but that isn't the case when
    7347              :      the object is zero-initialized before calling the constructor.  */
    7348      1890823 :   if (ctx->object)
    7349              :     {
    7350      1675681 :       tree otype = TREE_TYPE (ctx->object);
    7351      1675681 :       gcc_assert (same_type_ignoring_top_level_qualifiers_p (type, otype)
    7352              :                   /* Handle flexible array members.  */
    7353              :                   || (TREE_CODE (otype) == ARRAY_TYPE
    7354              :                       && TYPE_DOMAIN (otype) == NULL_TREE
    7355              :                       && TREE_CODE (type) == ARRAY_TYPE
    7356              :                       && (same_type_ignoring_top_level_qualifiers_p
    7357              :                           (TREE_TYPE (type), TREE_TYPE (otype)))));
    7358              :     }
    7359      1890823 :   gcc_assert (!ctx->object || !DECL_P (ctx->object)
    7360              :               || ctx->global->get_value (ctx->object) == ctx->ctor);
    7361              : }
    7362              : 
    7363              : /* Subroutine of cxx_eval_constant_expression.
    7364              :    The expression tree T denotes a C-style array or a C-style
    7365              :    aggregate.  Reduce it to a constant expression.  */
    7366              : 
    7367              : static tree
    7368      3389818 : cxx_eval_bare_aggregate (const constexpr_ctx *ctx, tree t,
    7369              :                          value_cat lval,
    7370              :                          bool *non_constant_p, bool *overflow_p,
    7371              :                          tree *jump_target)
    7372              : {
    7373      3389818 :   vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
    7374      3389818 :   bool changed = false;
    7375      3389818 :   gcc_assert (!BRACE_ENCLOSED_INITIALIZER_P (t));
    7376      3389818 :   tree type = TREE_TYPE (t);
    7377              : 
    7378      3389818 :   constexpr_ctx new_ctx;
    7379      3389818 :   if (TYPE_PTRMEMFUNC_P (type) || VECTOR_TYPE_P (type))
    7380              :     {
    7381              :       /* We don't really need the ctx->ctor business for a PMF or
    7382              :          vector, but it's simpler to use the same code.  */
    7383        56001 :       new_ctx = *ctx;
    7384        56001 :       new_ctx.ctor = build_constructor (type, NULL);
    7385        56001 :       new_ctx.object = NULL_TREE;
    7386        56001 :       ctx = &new_ctx;
    7387      3389818 :     };
    7388      3389818 :   verify_ctor_sanity (ctx, type);
    7389      3389818 :   vec<constructor_elt, va_gc> **p = nullptr;
    7390      3389818 :   if (ctx->ctor)
    7391              :     {
    7392      3389801 :       p = &CONSTRUCTOR_ELTS (ctx->ctor);
    7393      6776153 :       vec_alloc (*p, vec_safe_length (v));
    7394      3389801 :       if (CONSTRUCTOR_PLACEHOLDER_BOUNDARY (t))
    7395        16083 :         CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor) = 1;
    7396              :     }
    7397              : 
    7398      3389818 :   unsigned i;
    7399      3389818 :   tree index, value;
    7400      3389818 :   bool constant_p = true;
    7401      3389818 :   bool side_effects_p = false;
    7402      6859275 :   FOR_EACH_CONSTRUCTOR_ELT (v, i, index, value)
    7403              :     {
    7404      4194081 :       tree orig_value = value;
    7405      4194081 :       init_subob_ctx (ctx, new_ctx, index, value);
    7406              :       /* Like in cxx_eval_store_expression, omit entries for empty fields.  */
    7407      4194081 :       bool no_slot = new_ctx.ctor == NULL_TREE;
    7408      4194081 :       int pos_hint = -1;
    7409      4194081 :       if (!ctx->ctor)
    7410              :         /* The enclosing object could be an empty subobject so we have no
    7411              :            CONSTRUCTOR (c++/125336).  */
    7412           17 :         gcc_checking_assert (is_empty_class (type));
    7413      4194064 :       else if (new_ctx.ctor != ctx->ctor && !no_slot)
    7414              :         {
    7415              :           /* If we built a new CONSTRUCTOR, attach it now so that other
    7416              :              initializers can refer to it.  */
    7417       169228 :           constructor_elt *cep = get_or_insert_ctor_field (ctx->ctor, index);
    7418       169228 :           cep->value = new_ctx.ctor;
    7419       169228 :           pos_hint = cep - (*p)->begin();
    7420       169228 :         }
    7421      4024836 :       else if (TREE_CODE (type) == UNION_TYPE)
    7422              :         /* Otherwise if we're constructing a non-aggregate union member, set
    7423              :            the active union member now so that we can later detect and diagnose
    7424              :            if its initializer attempts to activate another member.  */
    7425         1089 :         get_or_insert_ctor_field (ctx->ctor, index);
    7426      4194081 :       tree elt = cxx_eval_constant_expression (&new_ctx, value,
    7427              :                                                lval,
    7428              :                                                non_constant_p, overflow_p,
    7429              :                                                jump_target);
    7430      4194081 :       if (*jump_target)
    7431              :         return NULL_TREE;
    7432              :       /* Don't VERIFY_CONSTANT here.  */
    7433      4194075 :       if (ctx->quiet && *non_constant_p)
    7434              :         break;
    7435      3469457 :       if (elt != orig_value)
    7436      1245240 :         changed = true;
    7437              : 
    7438      3469457 :       if (!TREE_CONSTANT (elt))
    7439       955753 :         constant_p = false;
    7440      3469457 :       if (TREE_SIDE_EFFECTS (elt))
    7441          281 :         side_effects_p = true;
    7442      3469457 :       if (index && TREE_CODE (index) == COMPONENT_REF)
    7443              :         {
    7444              :           /* This is an initialization of a vfield inside a base
    7445              :              subaggregate that we already initialized; push this
    7446              :              initialization into the previous initialization.  */
    7447            0 :           constructor_elt *inner = base_field_constructor_elt (*p, index);
    7448            0 :           inner->value = elt;
    7449            0 :           changed = true;
    7450            0 :         }
    7451      3469457 :       else if (no_slot)
    7452              :         /* This is an initializer for an empty field; now that we've
    7453              :            checked that it's constant, we can ignore it.  */
    7454              :         changed = true;
    7455      1952493 :       else if (ctx->ctor)
    7456              :         {
    7457      1952493 :           if (TREE_CODE (type) == UNION_TYPE
    7458      1952493 :               && (*p)->last().index != index)
    7459              :             /* The initializer erroneously changed the active union member that
    7460              :                we're initializing.  */
    7461            7 :             gcc_assert (*non_constant_p);
    7462              :           else
    7463              :             {
    7464              :               /* The initializer might have mutated the underlying CONSTRUCTOR,
    7465              :                  so recompute the location of the target constructer_elt.  */
    7466      1952486 :               constructor_elt *cep
    7467      1952486 :                 = get_or_insert_ctor_field (ctx->ctor, index, pos_hint);
    7468      1952486 :               cep->value = elt;
    7469              :             }
    7470              : 
    7471              :           /* Adding or replacing an element might change the ctor's flags.  */
    7472      1952493 :           TREE_CONSTANT (ctx->ctor) = constant_p;
    7473      1952493 :           TREE_SIDE_EFFECTS (ctx->ctor) = side_effects_p;
    7474              :         }
    7475              :     }
    7476      3389812 :   if (*non_constant_p)
    7477              :     return t;
    7478      2665127 :   if (!changed)
    7479              :     {
    7480       267697 :       if (VECTOR_TYPE_P (type))
    7481        14408 :         t = fold (t);
    7482              :       return t;
    7483              :     }
    7484      2397430 :   t = ctx->ctor;
    7485      2397430 :   if (!t)
    7486            8 :     t = build_constructor (type, NULL);
    7487              :   /* We're done building this CONSTRUCTOR, so now we can interpret an
    7488              :      element without an explicit initializer as value-initialized.  */
    7489      2397430 :   CONSTRUCTOR_NO_CLEARING (t) = false;
    7490      2397430 :   TREE_CONSTANT (t) = constant_p;
    7491      2397430 :   TREE_SIDE_EFFECTS (t) = side_effects_p;
    7492      2397430 :   if (VECTOR_TYPE_P (type))
    7493        11444 :     t = fold (t);
    7494              :   return t;
    7495              : }
    7496              : 
    7497              : /* Subroutine of cxx_eval_constant_expression.
    7498              :    The expression tree T is a VEC_INIT_EXPR which denotes the desired
    7499              :    initialization of a non-static data member of array type.  Reduce it to a
    7500              :    CONSTRUCTOR.
    7501              : 
    7502              :    Note that apart from value-initialization (when VALUE_INIT is true),
    7503              :    this is only intended to support value-initialization and the
    7504              :    initializations done by defaulted constructors for classes with
    7505              :    non-static data members of array type.  In this case, VEC_INIT_EXPR_INIT
    7506              :    will either be NULL_TREE for the default constructor, or a COMPONENT_REF
    7507              :    for the copy/move constructor.  */
    7508              : 
    7509              : static tree
    7510          904 : cxx_eval_vec_init_1 (const constexpr_ctx *ctx, tree atype, tree init,
    7511              :                      bool value_init, value_cat lval,
    7512              :                      bool *non_constant_p, bool *overflow_p,
    7513              :                      tree *jump_target)
    7514              : {
    7515          904 :   tree elttype = TREE_TYPE (atype);
    7516          904 :   verify_ctor_sanity (ctx, atype);
    7517          904 :   vec<constructor_elt, va_gc> **p = &CONSTRUCTOR_ELTS (ctx->ctor);
    7518          904 :   bool pre_init = false;
    7519          904 :   unsigned HOST_WIDE_INT i;
    7520          904 :   tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
    7521              : 
    7522          904 :   if (init && TREE_CODE (init) == CONSTRUCTOR)
    7523            0 :     return cxx_eval_bare_aggregate (ctx, init, lval,
    7524            0 :                                     non_constant_p, overflow_p, jump_target);
    7525              : 
    7526              :   /* We already checked access when building the VEC_INIT_EXPR.  */
    7527          904 :   deferring_access_check_sentinel acs (dk_deferred);
    7528              : 
    7529              :   /* For the default constructor, build up a call to the default
    7530              :      constructor of the element type.  We only need to handle class types
    7531              :      here, as for a constructor to be constexpr, all members must be
    7532              :      initialized, which for a defaulted default constructor means they must
    7533              :      be of a class type with a constexpr default constructor.  */
    7534          904 :   if (TREE_CODE (elttype) == ARRAY_TYPE)
    7535              :     /* We only do this at the lowest level.  */;
    7536          850 :   else if (value_init)
    7537              :     {
    7538          336 :       init = build_value_init (elttype, complain);
    7539          336 :       pre_init = true;
    7540              :     }
    7541          514 :   else if (!init)
    7542              :     {
    7543          402 :       releasing_vec argvec;
    7544          402 :       init = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    7545              :                                         &argvec, elttype, LOOKUP_NORMAL,
    7546              :                                         complain);
    7547          402 :       init = build_aggr_init_expr (elttype, init);
    7548          402 :       pre_init = true;
    7549          402 :     }
    7550              : 
    7551          904 :   bool zeroed_out = false;
    7552          904 :   if (!CONSTRUCTOR_NO_CLEARING (ctx->ctor))
    7553              :     {
    7554              :       /* We're initializing an array object that had been zero-initialized
    7555              :          earlier.  Truncate ctx->ctor, and propagate its zeroed state by
    7556              :          clearing CONSTRUCTOR_NO_CLEARING on each of the aggregate element
    7557              :          initializers we append to it.  */
    7558          156 :       gcc_checking_assert (initializer_zerop (ctx->ctor));
    7559          156 :       zeroed_out = true;
    7560          156 :       vec_safe_truncate (*p, 0);
    7561              :     }
    7562              : 
    7563          904 :   tree nelts = get_array_or_vector_nelts (ctx, atype, non_constant_p,
    7564              :                                           overflow_p, jump_target);
    7565          904 :   if (*jump_target)
    7566              :     return NULL_TREE;
    7567          904 :   unsigned HOST_WIDE_INT max = tree_to_uhwi (nelts);
    7568         6674 :   for (i = 0; i < max; ++i)
    7569              :     {
    7570         6437 :       tree idx = build_int_cst (size_type_node, i);
    7571         6437 :       tree eltinit;
    7572         6437 :       bool reuse = false;
    7573         6437 :       constexpr_ctx new_ctx;
    7574         6901 :       init_subob_ctx (ctx, new_ctx, idx, pre_init ? init : elttype);
    7575         6437 :       bool no_slot = new_ctx.ctor == NULL_TREE;
    7576         6437 :       if (new_ctx.ctor != ctx->ctor && !no_slot)
    7577              :         {
    7578         6138 :           if (zeroed_out)
    7579         5445 :             CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = false;
    7580         6138 :           CONSTRUCTOR_APPEND_ELT (*p, idx, new_ctx.ctor);
    7581              :         }
    7582         6437 :       if (TREE_CODE (elttype) == ARRAY_TYPE)
    7583              :         {
    7584              :           /* A multidimensional array; recurse.  */
    7585          186 :           if (value_init || init == NULL_TREE)
    7586              :             {
    7587          176 :               eltinit = NULL_TREE;
    7588          176 :               reuse = i == 0;
    7589              :             }
    7590              :           else
    7591           10 :             eltinit = cp_build_array_ref (input_location, init, idx, complain);
    7592          186 :           eltinit = cxx_eval_vec_init_1 (&new_ctx, elttype, eltinit,
    7593              :                                          value_init, lval, non_constant_p,
    7594              :                                          overflow_p, jump_target);
    7595              :         }
    7596         6251 :       else if (pre_init)
    7597              :         {
    7598              :           /* Initializing an element using value or default initialization
    7599              :              we just pre-built above.  */
    7600         5973 :           if (init == void_node)
    7601              :             /* Trivial default-init, don't do anything to the CONSTRUCTOR.  */
    7602           10 :             return ctx->ctor;
    7603         5963 :           eltinit = init;
    7604         5963 :           if (CLASS_TYPE_P (elttype) && new_ctx.object)
    7605              :             /* Clarify what object is being initialized (118285).  */
    7606         5665 :             eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
    7607         5963 :           eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
    7608              :                                                   non_constant_p, overflow_p,
    7609              :                                                   jump_target);
    7610         5963 :           reuse = i == 0;
    7611              :         }
    7612              :       else
    7613              :         {
    7614              :           /* Copying an element.  */
    7615          278 :           eltinit = cp_build_array_ref (input_location, init, idx, complain);
    7616          278 :           if (!lvalue_p (init))
    7617          232 :             eltinit = move (eltinit);
    7618          278 :           eltinit = (perform_implicit_conversion_flags
    7619          278 :                      (elttype, eltinit, complain,
    7620              :                       LOOKUP_IMPLICIT|LOOKUP_NO_NARROWING));
    7621          271 :           if (CLASS_TYPE_P (elttype)
    7622          271 :               && new_ctx.object
    7623          526 :               && !error_operand_p (eltinit))
    7624              :             /* Clarify what object is being initialized (118285).  */
    7625          244 :             eltinit = build2 (INIT_EXPR, elttype, new_ctx.object, eltinit);
    7626          278 :           eltinit = cxx_eval_constant_expression (&new_ctx, eltinit, lval,
    7627              :                                                   non_constant_p, overflow_p,
    7628              :                                                   jump_target);
    7629              :         }
    7630         6427 :       if (*jump_target)
    7631              :         return NULL_TREE;
    7632         6427 :       if (*non_constant_p)
    7633              :         break;
    7634         6249 :       if (no_slot)
    7635              :         {
    7636              :           /* This is an initializer for an empty subobject; now that we've
    7637              :              checked that it's constant, we can ignore it.  */
    7638            0 :           gcc_checking_assert (i == 0);
    7639              :           break;
    7640              :         }
    7641         6249 :       else if (new_ctx.ctor != ctx->ctor)
    7642              :         {
    7643              :           /* We appended this element above; update the value.  */
    7644         5957 :           gcc_assert ((*p)->last().index == idx);
    7645         5957 :           (*p)->last().value = eltinit;
    7646              :         }
    7647              :       else
    7648          292 :         CONSTRUCTOR_APPEND_ELT (*p, idx, eltinit);
    7649              :       /* Reuse the result of cxx_eval_constant_expression call
    7650              :          from the first iteration to all others if it is a constant
    7651              :          initializer that doesn't require relocations.  */
    7652         6249 :       if (reuse
    7653         6249 :           && max > 1
    7654         6249 :           && (eltinit == NULL_TREE
    7655          632 :               || (initializer_constant_valid_p (eltinit, TREE_TYPE (eltinit))
    7656          632 :                   == null_pointer_node)))
    7657              :         {
    7658          479 :           if (new_ctx.ctor != ctx->ctor)
    7659          201 :             eltinit = new_ctx.ctor;
    7660          479 :           tree range = build2 (RANGE_EXPR, size_type_node,
    7661              :                                build_int_cst (size_type_node, 1),
    7662          479 :                                build_int_cst (size_type_node, max - 1));
    7663          479 :           CONSTRUCTOR_APPEND_ELT (*p, range, unshare_constructor (eltinit));
    7664          479 :           break;
    7665              :         }
    7666         5770 :       else if (i == 0)
    7667          234 :         vec_safe_reserve (*p, max);
    7668              :     }
    7669              : 
    7670          894 :   if (!*non_constant_p)
    7671              :     {
    7672          716 :       init = ctx->ctor;
    7673          716 :       CONSTRUCTOR_NO_CLEARING (init) = false;
    7674              :     }
    7675          894 :   return init;
    7676              : }
    7677              : 
    7678              : static tree
    7679          790 : cxx_eval_vec_init (const constexpr_ctx *ctx, tree t,
    7680              :                    value_cat lval,
    7681              :                    bool *non_constant_p, bool *overflow_p, tree *jump_target)
    7682              : {
    7683          790 :   tree atype = TREE_TYPE (t);
    7684          790 :   tree init = VEC_INIT_EXPR_INIT (t);
    7685          790 :   bool value_init = VEC_INIT_EXPR_VALUE_INIT (t);
    7686          790 :   if (!init || !BRACE_ENCLOSED_INITIALIZER_P (init))
    7687              :     ;
    7688           83 :   else if (CONSTRUCTOR_NELTS (init) == 0
    7689           83 :            && !CP_AGGREGATE_TYPE_P (strip_array_types (atype)))
    7690              :     {
    7691              :       /* Handle {} as value-init.  */
    7692              :       init = NULL_TREE;
    7693              :       value_init = true;
    7694              :     }
    7695              :   else
    7696              :     {
    7697              :       /* This is a more complicated case, like needing to loop over trailing
    7698              :          elements; call build_vec_init and evaluate the result.  */
    7699           72 :       tsubst_flags_t complain = ctx->quiet ? tf_none : tf_warning_or_error;
    7700           72 :       constexpr_ctx new_ctx = *ctx;
    7701           72 :       if (!ctx->object)
    7702              :         {
    7703              :           /* We want to have an initialization target for an VEC_INIT_EXPR.
    7704              :              If we don't already have one in CTX, use the VEC_INIT_EXPR_SLOT.  */
    7705           57 :           new_ctx.object = VEC_INIT_EXPR_SLOT (t);
    7706           57 :           tree ctor = new_ctx.ctor = build_constructor (atype, NULL);
    7707           57 :           CONSTRUCTOR_NO_CLEARING (ctor) = true;
    7708           57 :           ctx->global->put_value (new_ctx.object, ctor);
    7709           57 :           ctx = &new_ctx;
    7710              :         }
    7711           72 :       init = expand_vec_init_expr (ctx->object, t, complain);
    7712           72 :       return cxx_eval_constant_expression (ctx, init, lval, non_constant_p,
    7713              :                                            overflow_p, jump_target);
    7714              :     }
    7715          718 :   tree r = cxx_eval_vec_init_1 (ctx, atype, init, value_init,
    7716              :                                 lval, non_constant_p, overflow_p, jump_target);
    7717          718 :   if (*non_constant_p)
    7718              :     return t;
    7719              :   else
    7720          566 :     return r;
    7721              : }
    7722              : 
    7723              : /* Like same_type_ignoring_top_level_qualifiers_p, but also handle the case
    7724              :    where the desired type is an array of unknown bounds because the variable
    7725              :    has had its bounds deduced since the wrapping expression was created.  */
    7726              : 
    7727              : static bool
    7728    445601775 : same_type_ignoring_tlq_and_bounds_p (tree type1, tree type2)
    7729              : {
    7730    445601775 :   while (TREE_CODE (type1) == ARRAY_TYPE
    7731       144752 :          && TREE_CODE (type2) == ARRAY_TYPE
    7732    445601779 :          && (!TYPE_DOMAIN (type1) || !TYPE_DOMAIN (type2)))
    7733              :     {
    7734            2 :       type1 = TREE_TYPE (type1);
    7735            2 :       type2 = TREE_TYPE (type2);
    7736              :     }
    7737    445601775 :   return same_type_ignoring_top_level_qualifiers_p (type1, type2);
    7738              : }
    7739              : 
    7740              : /* Try to determine the currently active union member for an expression
    7741              :    with UNION_TYPE.  If it can be determined, return the FIELD_DECL,
    7742              :    otherwise return NULL_TREE.  */
    7743              : 
    7744              : static tree
    7745           86 : cxx_union_active_member (const constexpr_ctx *ctx, tree t, tree *jump_target)
    7746              : {
    7747           86 :   constexpr_ctx new_ctx = *ctx;
    7748           86 :   new_ctx.quiet = true;
    7749           86 :   bool non_constant_p = false, overflow_p = false;
    7750           86 :   tree ctor = cxx_eval_constant_expression (&new_ctx, t, vc_prvalue,
    7751              :                                             &non_constant_p,
    7752              :                                             &overflow_p, jump_target);
    7753           86 :   if (*jump_target)
    7754              :     return NULL_TREE;
    7755           86 :   if (TREE_CODE (ctor) == CONSTRUCTOR
    7756           32 :       && CONSTRUCTOR_NELTS (ctor) == 1
    7757           20 :       && CONSTRUCTOR_ELT (ctor, 0)->index
    7758          106 :       && TREE_CODE (CONSTRUCTOR_ELT (ctor, 0)->index) == FIELD_DECL)
    7759              :     return CONSTRUCTOR_ELT (ctor, 0)->index;
    7760              :   return NULL_TREE;
    7761              : }
    7762              : 
    7763              : /* Helper function for cxx_fold_indirect_ref_1, called recursively.  */
    7764              : 
    7765              : static tree
    7766     15257535 : cxx_fold_indirect_ref_1 (const constexpr_ctx *ctx, location_t loc, tree type,
    7767              :                          tree op, unsigned HOST_WIDE_INT off, bool *empty_base,
    7768              :                          tree *jump_target)
    7769              : {
    7770     24734527 :   tree optype = TREE_TYPE (op);
    7771     24734527 :   unsigned HOST_WIDE_INT const_nunits;
    7772     24734527 :   if (off == 0 && similar_type_p (optype, type))
    7773              :     return op;
    7774     15252791 :   else if (cxx_dialect >= cxx26
    7775      9344423 :            && VAR_P (op)
    7776      5326992 :            && DECL_VTABLE_OR_VTT_P (op)
    7777        15646 :            && same_type_ignoring_top_level_qualifiers_p (type,
    7778              :                                                          ptrdiff_type_node)
    7779     15254136 :            && POINTER_TYPE_P (strip_array_types (optype)))
    7780              :     {
    7781              :       /* We often read some virtual table elements using ptrdiff_t rather
    7782              :          than pointer type.  */
    7783         1345 :       if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc,
    7784              :                                               strip_array_types (optype),
    7785              :                                               op, off, empty_base,
    7786              :                                               jump_target))
    7787         1345 :         return fold_convert (type, ret);
    7788              :     }
    7789     15251446 :   else if (TREE_CODE (optype) == COMPLEX_TYPE
    7790     15251446 :            && similar_type_p (type, TREE_TYPE (optype)))
    7791              :     {
    7792              :       /* *(foo *)&complexfoo => __real__ complexfoo */
    7793            0 :       if (off == 0)
    7794            0 :         return build1_loc (loc, REALPART_EXPR, type, op);
    7795              :       /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */
    7796            0 :       else if (tree_to_uhwi (TYPE_SIZE_UNIT (type)) == off)
    7797            0 :         return build1_loc (loc, IMAGPART_EXPR, type, op);
    7798              :     }
    7799              :   /* ((foo*)&vectorfoo)[x] => BIT_FIELD_REF<vectorfoo,...> */
    7800     15251446 :   else if (VECTOR_TYPE_P (optype)
    7801            0 :            && similar_type_p (type, TREE_TYPE (optype))
    7802     15251446 :            && TYPE_VECTOR_SUBPARTS (optype).is_constant (&const_nunits))
    7803              :     {
    7804            0 :       unsigned HOST_WIDE_INT part_width = tree_to_uhwi (TYPE_SIZE_UNIT (type));
    7805            0 :       unsigned HOST_WIDE_INT max_offset = part_width * const_nunits;
    7806            0 :       if (off < max_offset && off % part_width == 0)
    7807              :         {
    7808            0 :           tree index = bitsize_int (off * BITS_PER_UNIT);
    7809            0 :           return build3_loc (loc, BIT_FIELD_REF, type, op,
    7810            0 :                              TYPE_SIZE (type), index);
    7811              :         }
    7812              :     }
    7813              :   /* ((foo *)&fooarray)[x] => fooarray[x] */
    7814     15251446 :   else if (TREE_CODE (optype) == ARRAY_TYPE
    7815      9476992 :            && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (optype)))
    7816     24728438 :            && !integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (optype))))
    7817              :     {
    7818      9476992 :       tree type_domain = TYPE_DOMAIN (optype);
    7819      9476992 :       tree min_val = size_zero_node;
    7820      9476992 :       if (type_domain && TYPE_MIN_VALUE (type_domain))
    7821      9476787 :         min_val = TYPE_MIN_VALUE (type_domain);
    7822      9476992 :       unsigned HOST_WIDE_INT el_sz
    7823      9476992 :         = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (optype)));
    7824      9476992 :       unsigned HOST_WIDE_INT idx = off / el_sz;
    7825      9476992 :       unsigned HOST_WIDE_INT rem = off % el_sz;
    7826      9476992 :       if (tree_fits_uhwi_p (min_val))
    7827              :         {
    7828      9476992 :           tree index = size_int (idx + tree_to_uhwi (min_val));
    7829      9476992 :           op = build4_loc (loc, ARRAY_REF, TREE_TYPE (optype), op, index,
    7830              :                            NULL_TREE, NULL_TREE);
    7831      9476992 :           return cxx_fold_indirect_ref_1 (ctx, loc, type, op, rem,
    7832      9476992 :                                           empty_base, jump_target);
    7833              :         }
    7834              :     }
    7835              :   /* ((foo *)&struct_with_foo_field)[x] => COMPONENT_REF */
    7836      5774454 :   else if (TREE_CODE (optype) == RECORD_TYPE
    7837      5774454 :            || TREE_CODE (optype) == UNION_TYPE)
    7838              :     {
    7839      5766127 :       if (TREE_CODE (optype) == UNION_TYPE)
    7840              :         /* For unions prefer the currently active member.  */
    7841           86 :         if (tree field = cxx_union_active_member (ctx, op, jump_target))
    7842              :           {
    7843           20 :             unsigned HOST_WIDE_INT el_sz
    7844           20 :               = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
    7845           20 :             if (off < el_sz)
    7846              :               {
    7847           20 :                 tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
    7848              :                                    op, field, NULL_TREE);
    7849           20 :                 if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
    7850              :                                                         off, empty_base,
    7851              :                                                         jump_target))
    7852              :                   return ret;
    7853              :               }
    7854              :           }
    7855              : 
    7856              :       /* Handle conversion to "as base" type.  */
    7857      5766113 :       if (CLASS_TYPE_P (optype)
    7858     11532062 :           && CLASSTYPE_AS_BASE (optype) == type)
    7859              :         return op;
    7860              : 
    7861              :       /* Handle conversion to an empty base class, which is represented with a
    7862              :          NOP_EXPR.  Do this before spelunking into the non-empty subobjects,
    7863              :          which is likely to be a waste of time (109678).  */
    7864      5760033 :       if (is_empty_class (type)
    7865      5418832 :           && CLASS_TYPE_P (optype)
    7866     11178859 :           && lookup_base (optype, type, ba_any, NULL, tf_none, off))
    7867              :         {
    7868      2634119 :           if (empty_base)
    7869      2634119 :             *empty_base = true;
    7870              :           return op;
    7871              :         }
    7872              : 
    7873      3125914 :       for (tree field = TYPE_FIELDS (optype);
    7874     44745146 :            field; field = DECL_CHAIN (field))
    7875     44697561 :         if (TREE_CODE (field) == FIELD_DECL
    7876      3138496 :             && TREE_TYPE (field) != error_mark_node
    7877     47836057 :             && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (field))))
    7878              :           {
    7879      3138492 :             tree pos = byte_position (field);
    7880      3138492 :             if (!tree_fits_uhwi_p (pos))
    7881            0 :               continue;
    7882      3138492 :             unsigned HOST_WIDE_INT upos = tree_to_uhwi (pos);
    7883      3138492 :             unsigned HOST_WIDE_INT el_sz;
    7884      3138492 :             if (DECL_FIELD_IS_BASE (field)
    7885       787684 :                 && CLASS_TYPE_P (optype)
    7886      3926176 :                 && CLASSTYPE_VBASECLASSES (optype))
    7887         7765 :               el_sz = tree_to_uhwi (DECL_SIZE_UNIT (field));
    7888              :             else
    7889      3130727 :               el_sz = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (field)));
    7890      3138492 :             if (upos <= off && off < upos + el_sz)
    7891              :               {
    7892      3125765 :                 tree cop = build3 (COMPONENT_REF, TREE_TYPE (field),
    7893              :                                    op, field, NULL_TREE);
    7894      3125765 :                 if (tree ret = cxx_fold_indirect_ref_1 (ctx, loc, type, cop,
    7895              :                                                         off - upos,
    7896              :                                                         empty_base,
    7897              :                                                         jump_target))
    7898              :                   return ret;
    7899              :               }
    7900              :           }
    7901              :     }
    7902              : 
    7903              :   return NULL_TREE;
    7904              : }
    7905              : 
    7906              : /* A less strict version of fold_indirect_ref_1, which requires cv-quals to
    7907              :    match.  We want to be less strict for simple *& folding; if we have a
    7908              :    non-const temporary that we access through a const pointer, that should
    7909              :    work.  We handle this here rather than change fold_indirect_ref_1
    7910              :    because we're dealing with things like ADDR_EXPR of INTEGER_CST which
    7911              :    don't really make sense outside of constant expression evaluation.  Also
    7912              :    we want to allow folding to COMPONENT_REF, which could cause trouble
    7913              :    with TBAA in fold_indirect_ref_1.  */
    7914              : 
    7915              : static tree
    7916    196569904 : cxx_fold_indirect_ref (const constexpr_ctx *ctx, location_t loc, tree type,
    7917              :                        tree op0, bool *empty_base, tree *jump_target)
    7918              : {
    7919    196569904 :   tree sub = op0;
    7920    196569904 :   tree subtype;
    7921              : 
    7922              :   /* STRIP_NOPS, but stop if REINTERPRET_CAST_P.  */
    7923    405094773 :   while (CONVERT_EXPR_P (sub) || TREE_CODE (sub) == NON_LVALUE_EXPR
    7924    529099867 :          || TREE_CODE (sub) == VIEW_CONVERT_EXPR)
    7925              :     {
    7926    133468847 :       if (TREE_CODE (sub) == NOP_EXPR
    7927    133468847 :           && REINTERPRET_CAST_P (sub))
    7928              :         return NULL_TREE;
    7929    133468847 :       sub = TREE_OPERAND (sub, 0);
    7930              :     }
    7931              : 
    7932    196569904 :   subtype = TREE_TYPE (sub);
    7933    196569904 :   if (!INDIRECT_TYPE_P (subtype))
    7934              :     return NULL_TREE;
    7935              : 
    7936              :   /* Canonicalizes the given OBJ/OFF pair by iteratively absorbing
    7937              :      the innermost component into the offset until it would make the
    7938              :      offset positive, so that cxx_fold_indirect_ref_1 can identify
    7939              :      more folding opportunities.  */
    7940    208700260 :   auto canonicalize_obj_off = [] (tree& obj, tree& off) {
    7941     12130405 :     if (cxx_dialect >= cxx26)
    7942              :       {
    7943              :         /* For C++26, we need to fold *(B *)(&x.D.1234 + 32) used
    7944              :            to access virtual base members.  */
    7945      7261537 :         tree nobj = obj;
    7946      7261537 :         while (TREE_CODE (nobj) == COMPONENT_REF
    7947      7298046 :                && DECL_FIELD_IS_BASE (TREE_OPERAND (nobj, 1)))
    7948        36509 :           nobj = TREE_OPERAND (nobj, 0);
    7949      7261537 :         if (nobj != obj
    7950        28612 :             && CLASS_TYPE_P (TREE_TYPE (nobj))
    7951      7290149 :             && CLASSTYPE_VBASECLASSES (TREE_TYPE (nobj)))
    7952         2537 :           while (obj != nobj)
    7953              :             {
    7954         1424 :               tree field = TREE_OPERAND (obj, 1);
    7955         1424 :               tree pos = byte_position (field);
    7956         1424 :               off = int_const_binop (PLUS_EXPR, off, pos);
    7957         1424 :               obj = TREE_OPERAND (obj, 0);
    7958              :             }
    7959              :       }
    7960     15244439 :     while (TREE_CODE (obj) == COMPONENT_REF
    7961              :            /* We need to preserve union member accesses so that we can
    7962              :               later properly diagnose accessing the wrong member.  */
    7963      6442039 :            && TREE_CODE (TREE_TYPE (TREE_OPERAND (obj, 0))) == RECORD_TYPE
    7964     21461769 :            && (tree_int_cst_sign_bit (off) || integer_zerop (off)))
    7965              :       {
    7966      3303042 :         tree field = TREE_OPERAND (obj, 1);
    7967      3303042 :         tree pos = byte_position (field);
    7968      3303042 :         if (integer_zerop (off) && integer_nonzerop (pos))
    7969              :           /* If the offset is already 0, keep going as long as the
    7970              :              component is at position 0.  */
    7971              :           break;
    7972      3114034 :         off = int_const_binop (PLUS_EXPR, off, pos);
    7973      3114034 :         obj = TREE_OPERAND (obj, 0);
    7974              :       }
    7975     12130405 :   };
    7976              : 
    7977    196569855 :   if (TREE_CODE (sub) == ADDR_EXPR)
    7978              :     {
    7979     87825217 :       tree op = TREE_OPERAND (sub, 0);
    7980     87825217 :       tree optype = TREE_TYPE (op);
    7981              : 
    7982              :       /* *&CONST_DECL -> to the value of the const decl.  */
    7983     87825217 :       if (TREE_CODE (op) == CONST_DECL)
    7984            0 :         return DECL_INITIAL (op);
    7985              :       /* *&p => p;  make sure to handle *&"str"[cst] here.  */
    7986     87825217 :       if (similar_type_p (optype, type))
    7987              :         {
    7988     83908020 :           tree fop = fold_read_from_constant_string (op);
    7989     83908020 :           if (fop)
    7990              :             return fop;
    7991              :           else
    7992     83700345 :             return op;
    7993              :         }
    7994              :       else
    7995              :         {
    7996      3917197 :           tree off = integer_zero_node;
    7997      3917197 :           canonicalize_obj_off (op, off);
    7998      3917197 :           return cxx_fold_indirect_ref_1 (ctx, loc, type, op,
    7999              :                                           tree_to_uhwi (off), empty_base,
    8000              :                                           jump_target);
    8001              :         }
    8002              :     }
    8003    108744638 :   else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
    8004    108744638 :            && tree_fits_uhwi_p (TREE_OPERAND (sub, 1)))
    8005              :     {
    8006      8810883 :       tree op00 = TREE_OPERAND (sub, 0);
    8007      8810883 :       tree off = TREE_OPERAND (sub, 1);
    8008              : 
    8009      8810883 :       STRIP_NOPS (op00);
    8010      8810883 :       if (TREE_CODE (op00) == ADDR_EXPR)
    8011              :         {
    8012      8213208 :           tree obj = TREE_OPERAND (op00, 0);
    8013      8213208 :           canonicalize_obj_off (obj, off);
    8014      8213208 :           return cxx_fold_indirect_ref_1 (ctx, loc, type, obj,
    8015              :                                           tree_to_uhwi (off), empty_base,
    8016              :                                           jump_target);
    8017              :         }
    8018              :     }
    8019              :   /* *(foo *)fooarrptr => (*fooarrptr)[0] */
    8020     99933755 :   else if (TREE_CODE (TREE_TYPE (subtype)) == ARRAY_TYPE
    8021     99933755 :            && similar_type_p (type, TREE_TYPE (TREE_TYPE (subtype))))
    8022              :     {
    8023            0 :       tree type_domain;
    8024            0 :       tree min_val = size_zero_node;
    8025            0 :       tree newsub
    8026            0 :         = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (subtype), sub, NULL,
    8027              :                                  jump_target);
    8028            0 :       if (*jump_target)
    8029              :         return NULL_TREE;
    8030            0 :       if (newsub)
    8031              :         sub = newsub;
    8032              :       else
    8033            0 :         sub = build1_loc (loc, INDIRECT_REF, TREE_TYPE (subtype), sub);
    8034            0 :       type_domain = TYPE_DOMAIN (TREE_TYPE (sub));
    8035            0 :       if (type_domain && TYPE_MIN_VALUE (type_domain))
    8036            0 :         min_val = TYPE_MIN_VALUE (type_domain);
    8037            0 :       return build4_loc (loc, ARRAY_REF, type, sub, min_val, NULL_TREE,
    8038            0 :                          NULL_TREE);
    8039              :     }
    8040              : 
    8041              :   return NULL_TREE;
    8042              : }
    8043              : 
    8044              : static tree
    8045    103846674 : cxx_eval_indirect_ref (const constexpr_ctx *ctx, tree t,
    8046              :                        value_cat lval,
    8047              :                        bool *non_constant_p, bool *overflow_p,
    8048              :                        tree *jump_target)
    8049              : {
    8050    103846674 :   tree orig_op0 = TREE_OPERAND (t, 0);
    8051    103846674 :   bool empty_base = false;
    8052              : 
    8053              :   /* We can handle a MEM_REF like an INDIRECT_REF, if MEM_REF's second
    8054              :      operand is an integer-zero.  Otherwise reject the MEM_REF for now.  */
    8055              : 
    8056    103846674 :   if (TREE_CODE (t) == MEM_REF
    8057    103846674 :       && (!TREE_OPERAND (t, 1) || !integer_zerop (TREE_OPERAND (t, 1))))
    8058              :     {
    8059            9 :       gcc_assert (ctx->quiet);
    8060            9 :       *non_constant_p = true;
    8061            9 :       return t;
    8062              :     }
    8063              : 
    8064              :   /* First try to simplify it directly.  */
    8065    103846665 :   tree r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t),
    8066              :                                   orig_op0, &empty_base, jump_target);
    8067    103846665 :   if (*jump_target)
    8068              :     return NULL_TREE;
    8069    103846665 :   if (!r)
    8070              :     {
    8071              :       /* If that didn't work, evaluate the operand first.  */
    8072     99835946 :       tree op0 = cxx_eval_constant_expression (ctx, orig_op0,
    8073              :                                                vc_prvalue, non_constant_p,
    8074              :                                                overflow_p, jump_target);
    8075     99835946 :       if (*jump_target)
    8076              :         return NULL_TREE;
    8077              :       /* Don't VERIFY_CONSTANT here.  */
    8078     99835934 :       if (*non_constant_p)
    8079              :         return t;
    8080              : 
    8081     78868712 :       if (!lval && integer_zerop (op0))
    8082              :         {
    8083           73 :           if (!ctx->quiet)
    8084           12 :             error ("dereferencing a null pointer");
    8085           73 :           *non_constant_p = true;
    8086           73 :           return t;
    8087              :         }
    8088              : 
    8089     78868639 :       r = cxx_fold_indirect_ref (ctx, EXPR_LOCATION (t), TREE_TYPE (t), op0,
    8090              :                                  &empty_base, jump_target);
    8091     78868639 :       if (*jump_target)
    8092              :         return NULL_TREE;
    8093     78868639 :       if (r == NULL_TREE)
    8094              :         {
    8095              :           /* We couldn't fold to a constant value.  Make sure it's not
    8096              :              something we should have been able to fold.  */
    8097       703745 :           tree sub = op0;
    8098       703745 :           STRIP_NOPS (sub);
    8099       703745 :           if (TREE_CODE (sub) == ADDR_EXPR)
    8100              :             {
    8101         4034 :               gcc_assert (!similar_type_p
    8102              :                           (TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t)));
    8103              :               /* DR 1188 says we don't have to deal with this.  */
    8104         4034 :               if (!ctx->quiet)
    8105              :                 {
    8106            9 :                   auto_diagnostic_group d;
    8107           15 :                   error_at (cp_expr_loc_or_input_loc (t),
    8108              :                             "accessing value of %qT object through a %qT "
    8109              :                             "glvalue in a constant expression",
    8110            9 :                             TREE_TYPE (TREE_TYPE (sub)), TREE_TYPE (t));
    8111            9 :                   tree ob = build_fold_indirect_ref (sub);
    8112            9 :                   if (DECL_P (ob))
    8113              :                     {
    8114            9 :                       if (DECL_ARTIFICIAL (ob))
    8115            2 :                         inform (DECL_SOURCE_LOCATION (ob),
    8116            2 :                                 "%qT object created here", TREE_TYPE (ob));
    8117              :                       else
    8118            7 :                         inform (DECL_SOURCE_LOCATION (ob),
    8119              :                                 "%q#D declared here", ob);
    8120              :                     }
    8121            9 :                 }
    8122         4034 :               *non_constant_p = true;
    8123         4034 :               return t;
    8124              :             }
    8125              : 
    8126       699711 :           if (lval == vc_glvalue && op0 != orig_op0)
    8127        84261 :             return build1 (INDIRECT_REF, TREE_TYPE (t), op0);
    8128       615450 :           if (!lval)
    8129       500586 :             VERIFY_CONSTANT (t);
    8130              :           return t;
    8131              :         }
    8132              :     }
    8133              : 
    8134     82175613 :   r = cxx_eval_constant_expression (ctx, r,
    8135              :                                     lval, non_constant_p, overflow_p,
    8136              :                                     jump_target);
    8137     82175611 :   if (*jump_target)
    8138              :     return NULL_TREE;
    8139     82175611 :   if (*non_constant_p)
    8140              :     return t;
    8141              : 
    8142              :   /* If we're pulling out the value of an empty base, just return an empty
    8143              :      CONSTRUCTOR.  */
    8144     73119044 :   if (empty_base && !lval)
    8145              :     {
    8146        19629 :       r = build_constructor (TREE_TYPE (t), NULL);
    8147        19629 :       TREE_CONSTANT (r) = true;
    8148              :     }
    8149              : 
    8150              :   return r;
    8151              : }
    8152              : 
    8153              : /* Complain about R, a DECL that is accessed outside its lifetime.  */
    8154              : 
    8155              : static void
    8156           45 : outside_lifetime_error (location_t loc, tree r)
    8157              : {
    8158           45 :   auto_diagnostic_group d;
    8159           45 :   if (DECL_NAME (r) == heap_deleted_identifier)
    8160              :     {
    8161              :       /* Provide a more accurate message for deleted variables.  */
    8162           14 :       error_at (loc, "use of allocated storage after deallocation "
    8163              :                 "in a constant expression");
    8164           14 :       inform (DECL_SOURCE_LOCATION (r), "allocated here");
    8165              :     }
    8166              :   else
    8167              :     {
    8168           31 :       error_at (loc, "accessing %qE outside its lifetime", r);
    8169           31 :       inform (DECL_SOURCE_LOCATION (r), "declared here");
    8170              :     }
    8171           45 : }
    8172              : 
    8173              : /* Complain about R, a VAR_DECL, not being usable in a constant expression.
    8174              :    FUNDEF_P is true if we're checking a constexpr function body.
    8175              :    Shared between potential_constant_expression and
    8176              :    cxx_eval_constant_expression.  */
    8177              : 
    8178              : static void
    8179          354 : non_const_var_error (location_t loc, tree r, bool fundef_p)
    8180              : {
    8181          354 :   auto_diagnostic_group d;
    8182          354 :   tree type = TREE_TYPE (r);
    8183          354 :   if (DECL_NAME (r) == heap_uninit_identifier
    8184          354 :       || DECL_NAME (r) == heap_identifier
    8185          351 :       || DECL_NAME (r) == heap_vec_uninit_identifier
    8186          705 :       || DECL_NAME (r) == heap_vec_identifier)
    8187              :     {
    8188            3 :       if (constexpr_error (loc, fundef_p, "the content of uninitialized "
    8189              :                            "storage is not usable in a constant expression"))
    8190            3 :         inform (DECL_SOURCE_LOCATION (r), "allocated here");
    8191              :       return;
    8192              :     }
    8193          351 :   if (DECL_NAME (r) == heap_deleted_identifier)
    8194              :     {
    8195            0 :       if (constexpr_error (loc, fundef_p, "use of allocated storage after "
    8196              :                            "deallocation in a constant expression"))
    8197            0 :         inform (DECL_SOURCE_LOCATION (r), "allocated here");
    8198              :       return;
    8199              :     }
    8200          351 :   if (!constexpr_error (loc, fundef_p, "the value of %qD is not usable in "
    8201              :                         "a constant expression", r))
    8202              :     return;
    8203              :   /* Avoid error cascade.  */
    8204          344 :   if (DECL_INITIAL (r) == error_mark_node)
    8205              :     return;
    8206          330 :   if (DECL_DECLARED_CONSTEXPR_P (r))
    8207            3 :     inform (DECL_SOURCE_LOCATION (r),
    8208              :             "%qD used in its own initializer", r);
    8209          327 :   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (type))
    8210              :     {
    8211          225 :       if (!CP_TYPE_CONST_P (type))
    8212          196 :         inform (DECL_SOURCE_LOCATION (r),
    8213              :                 "%q#D is not const", r);
    8214           29 :       else if (CP_TYPE_VOLATILE_P (type))
    8215            0 :         inform (DECL_SOURCE_LOCATION (r),
    8216              :                 "%q#D is volatile", r);
    8217           29 :       else if (!DECL_INITIAL (r)
    8218            9 :                || !TREE_CONSTANT (DECL_INITIAL (r))
    8219           37 :                || !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (r))
    8220           29 :         inform (DECL_SOURCE_LOCATION (r),
    8221              :                 "%qD was not initialized with a constant "
    8222              :                 "expression", r);
    8223              :       else
    8224            0 :         gcc_unreachable ();
    8225              :     }
    8226          102 :   else if (TYPE_REF_P (type))
    8227            9 :     inform (DECL_SOURCE_LOCATION (r),
    8228              :             "%qD was not initialized with a constant "
    8229              :             "expression", r);
    8230              :   else
    8231              :     {
    8232           93 :       if (cxx_dialect >= cxx11 && !DECL_DECLARED_CONSTEXPR_P (r))
    8233           93 :         inform (DECL_SOURCE_LOCATION (r),
    8234              :                 "%qD was not declared %<constexpr%>", r);
    8235              :       else
    8236            0 :         inform (DECL_SOURCE_LOCATION (r),
    8237              :                 "%qD does not have integral or enumeration type",
    8238              :                 r);
    8239              :     }
    8240          354 : }
    8241              : 
    8242              : /* Subroutine of cxx_eval_constant_expression.
    8243              :    Like cxx_eval_unary_expression, except for trinary expressions.  */
    8244              : 
    8245              : static tree
    8246        43640 : cxx_eval_trinary_expression (const constexpr_ctx *ctx, tree t,
    8247              :                              value_cat lval,
    8248              :                              bool *non_constant_p, bool *overflow_p,
    8249              :                              tree *jump_target)
    8250              : {
    8251        43640 :   int i;
    8252        43640 :   tree args[3];
    8253        43640 :   tree val;
    8254              : 
    8255       168053 :   for (i = 0; i < 3; i++)
    8256              :     {
    8257       126582 :       args[i] = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, i),
    8258              :                                               lval,
    8259              :                                               non_constant_p, overflow_p,
    8260              :                                               jump_target);
    8261       126582 :       if (*jump_target)
    8262              :         return NULL_TREE;
    8263       126582 :       VERIFY_CONSTANT (args[i]);
    8264              :     }
    8265              : 
    8266        41471 :   val = fold_ternary_loc (EXPR_LOCATION (t), TREE_CODE (t), TREE_TYPE (t),
    8267              :                           args[0], args[1], args[2]);
    8268        41471 :   if (val == NULL_TREE)
    8269              :     return t;
    8270        41471 :   VERIFY_CONSTANT (val);
    8271              :   return val;
    8272              : }
    8273              : 
    8274              : /* True if T was declared in a function declared to be constexpr, and
    8275              :    therefore potentially constant in C++14.  */
    8276              : 
    8277              : bool
    8278     89642652 : var_in_constexpr_fn (tree t)
    8279              : {
    8280     89642652 :   tree ctx = DECL_CONTEXT (t);
    8281     89642652 :   return (ctx && TREE_CODE (ctx) == FUNCTION_DECL
    8282    170744484 :           && DECL_DECLARED_CONSTEXPR_P (ctx));
    8283              : }
    8284              : 
    8285              : /* True if a function might be constexpr: either a function that was
    8286              :    declared constexpr, or a C++17 lambda op().  */
    8287              : 
    8288              : bool
    8289    736898679 : maybe_constexpr_fn (tree t)
    8290              : {
    8291    736898679 :   return (DECL_DECLARED_CONSTEXPR_P (t)
    8292    225844181 :           || (cxx_dialect >= cxx17 && LAMBDA_FUNCTION_P (t))
    8293    954129459 :           || (flag_implicit_constexpr
    8294           96 :               && DECL_DECLARED_INLINE_P (STRIP_TEMPLATE (t))));
    8295              : }
    8296              : 
    8297              : /* True if T was declared in a function that might be constexpr: either a
    8298              :    function that was declared constexpr, or a C++17 lambda op().  */
    8299              : 
    8300              : bool
    8301     66844144 : var_in_maybe_constexpr_fn (tree t)
    8302              : {
    8303    133687641 :   return (DECL_FUNCTION_SCOPE_P (t)
    8304    122161151 :           && maybe_constexpr_fn (DECL_CONTEXT (t)));
    8305              : }
    8306              : 
    8307              : /* We're assigning INIT to TARGET.  In do_build_copy_constructor and
    8308              :    build_over_call we implement trivial copy of a class with tail padding using
    8309              :    assignment of character arrays, which is valid in normal code, but not in
    8310              :    constexpr evaluation.  We don't need to worry about clobbering tail padding
    8311              :    in constexpr evaluation, so strip the type punning.  */
    8312              : 
    8313              : static void
    8314    103531991 : maybe_simplify_trivial_copy (tree &target, tree &init)
    8315              : {
    8316    103531991 :   if (TREE_CODE (target) == MEM_REF
    8317        36160 :       && TREE_CODE (init) == MEM_REF
    8318        35992 :       && TREE_TYPE (target) == TREE_TYPE (init)
    8319        35992 :       && TREE_CODE (TREE_TYPE (target)) == ARRAY_TYPE
    8320    103567983 :       && TREE_TYPE (TREE_TYPE (target)) == unsigned_char_type_node)
    8321              :     {
    8322        35992 :       target = build_fold_indirect_ref (TREE_OPERAND (target, 0));
    8323        35992 :       init = build_fold_indirect_ref (TREE_OPERAND (init, 0));
    8324              :     }
    8325    103531991 : }
    8326              : 
    8327              : /* Returns true if REF, which is a COMPONENT_REF, has any fields
    8328              :    of constant type.  This does not check for 'mutable', so the
    8329              :    caller is expected to be mindful of that.  */
    8330              : 
    8331              : static bool
    8332          419 : cref_has_const_field (tree ref)
    8333              : {
    8334          488 :   while (TREE_CODE (ref) == COMPONENT_REF)
    8335              :     {
    8336          479 :       if (CP_TYPE_CONST_P (TREE_TYPE (TREE_OPERAND (ref, 1))))
    8337              :        return true;
    8338           69 :       ref = TREE_OPERAND (ref, 0);
    8339              :     }
    8340              :   return false;
    8341              : }
    8342              : 
    8343              : /* Return true if we are modifying something that is const during constant
    8344              :    expression evaluation.  CODE is the code of the statement, OBJ is the
    8345              :    object in question, MUTABLE_P is true if one of the subobjects were
    8346              :    declared mutable.  */
    8347              : 
    8348              : static bool
    8349    107275982 : modifying_const_object_p (tree_code code, tree obj, bool mutable_p)
    8350              : {
    8351              :   /* If this is initialization, there's no problem.  */
    8352    107275982 :   if (code == INIT_EXPR)
    8353              :     return false;
    8354              : 
    8355              :   /* [basic.type.qualifier] "A const object is an object of type
    8356              :      const T or a non-mutable subobject of a const object."  */
    8357     30009029 :   if (mutable_p)
    8358              :     return false;
    8359              : 
    8360     30008287 :   if (TREE_READONLY (obj))
    8361              :     return true;
    8362              : 
    8363     29953590 :   if (CP_TYPE_CONST_P (TREE_TYPE (obj)))
    8364              :     {
    8365              :       /* Although a COMPONENT_REF may have a const type, we should
    8366              :          only consider it modifying a const object when any of the
    8367              :          field components is const.  This can happen when using
    8368              :          constructs such as const_cast<const T &>(m), making something
    8369              :          const even though it wasn't declared const.  */
    8370        33749 :       if (TREE_CODE (obj) == COMPONENT_REF)
    8371          419 :         return cref_has_const_field (obj);
    8372              :       else
    8373              :         return true;
    8374              :     }
    8375              : 
    8376              :   return false;
    8377              : }
    8378              : 
    8379              : /* Evaluate an INIT_EXPR or MODIFY_EXPR or MODOP_EXPR.  MODOP_EXPR means
    8380              :    we are evaluating __builtin_start_lifetime (init is in the second
    8381              :    operand rather than third, like for INIT_EXPR and MODIFY_EXPR).  */
    8382              : 
    8383              : static tree
    8384    103531991 : cxx_eval_store_expression (const constexpr_ctx *ctx, tree t,
    8385              :                            value_cat lval,
    8386              :                            bool *non_constant_p, bool *overflow_p,
    8387              :                            tree *jump_target)
    8388              : {
    8389    103531991 :   constexpr_ctx new_ctx = *ctx;
    8390              : 
    8391    103531991 :   tree init = TREE_OPERAND (t, 1);
    8392              : 
    8393              :   /* First we figure out where we're storing to.  */
    8394    103531991 :   tree target = TREE_OPERAND (t, 0);
    8395              : 
    8396    103531991 :   maybe_simplify_trivial_copy (target, init);
    8397              : 
    8398    103531991 :   tree type = TREE_TYPE (target);
    8399    103531991 :   bool preeval = SCALAR_TYPE_P (type) || TREE_CODE (t) != INIT_EXPR;
    8400     72679587 :   if (preeval && !TREE_CLOBBER_P (init) && TREE_CODE (t) != MODOP_EXPR)
    8401              :     {
    8402              :       /* Ignore var = .DEFERRED_INIT (); for now, until PR121965 is fixed.  */
    8403     71612621 :       if (flag_auto_var_init > AUTO_INIT_UNINITIALIZED
    8404     41740733 :           && TREE_CODE (init) == CALL_EXPR
    8405      6802994 :           && CALL_EXPR_FN (init) == NULL_TREE
    8406     71612629 :           && CALL_EXPR_IFN (init) == IFN_DEFERRED_INIT)
    8407            8 :         return void_node;
    8408              : 
    8409              :       /* Evaluate the value to be stored without knowing what object it will be
    8410              :          stored in, so that any side-effects happen first.  */
    8411     71612613 :       if (!SCALAR_TYPE_P (type))
    8412       205685 :         new_ctx.ctor = new_ctx.object = NULL_TREE;
    8413     71612613 :       init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
    8414              :                                            non_constant_p, overflow_p,
    8415              :                                            jump_target);
    8416     71612609 :       if (*jump_target)
    8417              :         return NULL_TREE;
    8418     71612341 :       if (*non_constant_p)
    8419              :         return t;
    8420              :     }
    8421              : 
    8422     94357462 :   bool evaluated = false;
    8423     94357462 :   if (lval == vc_glvalue)
    8424              :     {
    8425              :       /* If we want to return a reference to the target, we need to evaluate it
    8426              :          as a whole; otherwise, only evaluate the innermost piece to avoid
    8427              :          building up unnecessary *_REFs.  */
    8428            0 :       target = cxx_eval_constant_expression (ctx, target, lval,
    8429              :                                              non_constant_p, overflow_p,
    8430              :                                              jump_target);
    8431            0 :       evaluated = true;
    8432            0 :       if (*jump_target)
    8433              :         return NULL_TREE;
    8434            0 :       if (*non_constant_p)
    8435              :         return t;
    8436              :     }
    8437              : 
    8438              :   /* Find the underlying variable.  */
    8439     94357462 :   releasing_vec refs;
    8440     94357462 :   tree object = NULL_TREE;
    8441              :   /* If we're modifying a const object, save it.  */
    8442     94357462 :   tree const_object_being_modified = NULL_TREE;
    8443     94357462 :   bool mutable_p = false;
    8444              :   /* If we see a union, we can't ignore clobbers.  */
    8445     94357462 :   int seen_union = 0;
    8446    319463841 :   for (tree probe = target; object == NULL_TREE; )
    8447              :     {
    8448    225106834 :       switch (TREE_CODE (probe))
    8449              :         {
    8450     36392236 :         case BIT_FIELD_REF:
    8451     36392236 :         case COMPONENT_REF:
    8452     36392236 :         case ARRAY_REF:
    8453     36392236 :           {
    8454     36392236 :             tree ob = TREE_OPERAND (probe, 0);
    8455     36392236 :             tree elt = TREE_OPERAND (probe, 1);
    8456     36392236 :             if (TREE_CODE (elt) == FIELD_DECL && DECL_MUTABLE_P (elt))
    8457              :               mutable_p = true;
    8458     36392236 :             if (TREE_CODE (probe) == ARRAY_REF)
    8459              :               {
    8460      5894819 :                 elt = eval_and_check_array_index (ctx, probe, false,
    8461              :                                                   non_constant_p, overflow_p,
    8462              :                                                   jump_target);
    8463      5894819 :                 if (*jump_target)
    8464           69 :                   return NULL_TREE;
    8465      5894819 :                 if (*non_constant_p)
    8466              :                   return t;
    8467              :               }
    8468              :             /* We don't check modifying_const_object_p for ARRAY_REFs.  Given
    8469              :                "int a[10]", an ARRAY_REF "a[2]" can be "const int", even though
    8470              :                the array isn't const.  Instead, check "a" in the next iteration;
    8471              :                that will detect modifying "const int a[10]".  */
    8472     30497417 :             else if (evaluated
    8473     12918975 :                      && modifying_const_object_p (TREE_CODE (t), probe,
    8474              :                                                   mutable_p)
    8475     30498031 :                      && const_object_being_modified == NULL_TREE)
    8476              :               const_object_being_modified = probe;
    8477              : 
    8478              :             /* Track named member accesses for unions to validate modifications
    8479              :                that change active member.  */
    8480     36392167 :             if (!evaluated && TREE_CODE (probe) == COMPONENT_REF)
    8481     17578442 :               vec_safe_push (refs, probe);
    8482              :             else
    8483     18813725 :               vec_safe_push (refs, NULL_TREE);
    8484              : 
    8485     36392167 :             vec_safe_push (refs, elt);
    8486     36392167 :             vec_safe_push (refs, TREE_TYPE (probe));
    8487     36392167 :             probe = ob;
    8488     36392167 :             if (TREE_CODE (TREE_TYPE (ob)) == UNION_TYPE)
    8489       585736 :               ++seen_union;
    8490              :           }
    8491     36392167 :           break;
    8492              : 
    8493           30 :         case REALPART_EXPR:
    8494           30 :           gcc_assert (refs->is_empty ());
    8495           30 :           vec_safe_push (refs, NULL_TREE);
    8496           30 :           vec_safe_push (refs, probe);
    8497           30 :           vec_safe_push (refs, TREE_TYPE (probe));
    8498           30 :           probe = TREE_OPERAND (probe, 0);
    8499           30 :           break;
    8500              : 
    8501           31 :         case IMAGPART_EXPR:
    8502           31 :           gcc_assert (refs->is_empty ());
    8503           31 :           vec_safe_push (refs, NULL_TREE);
    8504           31 :           vec_safe_push (refs, probe);
    8505           31 :           vec_safe_push (refs, TREE_TYPE (probe));
    8506           31 :           probe = TREE_OPERAND (probe, 0);
    8507           31 :           break;
    8508              : 
    8509    188714537 :         default:
    8510    188714537 :           if (evaluated)
    8511              :             object = probe;
    8512              :           else
    8513              :             {
    8514     94357530 :               tree pvar = tree_strip_any_location_wrapper (probe);
    8515     94357530 :               if (VAR_P (pvar) && DECL_ANON_UNION_VAR_P (pvar))
    8516              :                 {
    8517              :                   /* Stores to DECL_ANON_UNION_VAR_P var are allowed to change
    8518              :                      active union member.  */
    8519          101 :                   probe = DECL_VALUE_EXPR (pvar);
    8520          101 :                   break;
    8521              :                 }
    8522     94357429 :               probe = cxx_eval_constant_expression (ctx, probe, vc_glvalue,
    8523              :                                                     non_constant_p, overflow_p,
    8524              :                                                     jump_target);
    8525     94357429 :               evaluated = true;
    8526     94357429 :               if (*jump_target)
    8527              :                 return NULL_TREE;
    8528     94357429 :               if (*non_constant_p)
    8529              :                 return t;
    8530              :             }
    8531              :           break;
    8532              :         }
    8533              :     }
    8534              : 
    8535     94357007 :   if (modifying_const_object_p (TREE_CODE (t), object, mutable_p)
    8536     94357007 :       && const_object_being_modified == NULL_TREE)
    8537     94357007 :     const_object_being_modified = object;
    8538              : 
    8539     94357007 :   if (DECL_P (object)
    8540     94355121 :       && TREE_CLOBBER_P (init)
    8541     95446532 :       && DECL_NAME (object) == heap_deleted_identifier)
    8542              :     /* Ignore clobbers of deleted allocations for now; we'll get a better error
    8543              :        message later when operator delete is called.  */
    8544           15 :     return void_node;
    8545              : 
    8546              :   /* And then find/build up our initializer for the path to the subobject
    8547              :      we're initializing.  */
    8548     94356992 :   tree *valp;
    8549     94356992 :   if (DECL_P (object))
    8550     94355106 :     valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
    8551              :   else
    8552              :     valp = NULL;
    8553     94356992 :   if (!valp)
    8554              :     {
    8555              :       /* A constant-expression cannot modify objects from outside the
    8556              :          constant-expression.  */
    8557        11466 :       if (!ctx->quiet)
    8558              :         {
    8559           31 :           auto_diagnostic_group d;
    8560           31 :           if (DECL_P (object) && DECL_NAME (object) == heap_deleted_identifier)
    8561              :             {
    8562            0 :               error ("modification of allocated storage after deallocation "
    8563              :                      "is not a constant expression");
    8564            0 :               inform (DECL_SOURCE_LOCATION (object), "allocated here");
    8565              :             }
    8566           31 :           else if (DECL_P (object) && ctx->global->is_outside_lifetime (object))
    8567              :             {
    8568           14 :               if (TREE_CLOBBER_P (init))
    8569            6 :                 error ("destroying %qE outside its lifetime", object);
    8570              :               else
    8571            8 :                 error ("modification of %qE outside its lifetime "
    8572              :                        "is not a constant expression", object);
    8573           14 :               inform (DECL_SOURCE_LOCATION (object), "declared here");
    8574              :             }
    8575              :           else
    8576              :             {
    8577           17 :               if (TREE_CLOBBER_P (init))
    8578            6 :                 error ("destroying %qE from outside current evaluation "
    8579              :                        "is not a constant expression", object);
    8580              :               else
    8581           11 :                 error ("modification of %qE from outside current evaluation "
    8582              :                        "is not a constant expression", object);
    8583              :             }
    8584           31 :         }
    8585        11466 :       *non_constant_p = true;
    8586        11466 :       return t;
    8587              :     }
    8588              : 
    8589              :   /* Handle explicit end-of-lifetime.  */
    8590     94345526 :   if (TREE_CLOBBER_P (init))
    8591              :     {
    8592      1089459 :       if (CLOBBER_KIND (init) >= CLOBBER_OBJECT_END
    8593      1089459 :           && refs->is_empty ())
    8594              :         {
    8595       303811 :           ctx->global->destroy_value (object, (CLOBBER_KIND (init)
    8596              :                                                > CLOBBER_OBJECT_END));
    8597       303811 :           return void_node;
    8598              :         }
    8599              : 
    8600       771512 :       if (!seen_union && !*valp
    8601       796046 :           && CLOBBER_KIND (init) < CLOBBER_OBJECT_END)
    8602        10363 :         return void_node;
    8603              : 
    8604              :       /* Ending the lifetime of a const object is OK.  */
    8605              :       const_object_being_modified = NULL_TREE;
    8606              :     }
    8607              : 
    8608     94031352 :   type = TREE_TYPE (object);
    8609     94031352 :   bool no_zero_init = true;
    8610     94031352 :   bool zero_padding_bits = false;
    8611              : 
    8612    188062704 :   auto_vec<tree *> ctors;
    8613    188062704 :   releasing_vec indexes;
    8614    188062704 :   auto_vec<int> index_pos_hints;
    8615     94031352 :   bool activated_union_member_p = false;
    8616     94031352 :   bool empty_base = false;
    8617    130101076 :   while (!refs->is_empty ())
    8618              :     {
    8619     36361449 :       if (*valp == NULL_TREE)
    8620              :         {
    8621      2943817 :           *valp = build_constructor (type, NULL);
    8622      2943817 :           CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
    8623      2943817 :           CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
    8624              :         }
    8625     33417632 :       else if (STRIP_ANY_LOCATION_WRAPPER (*valp),
    8626     33417632 :                TREE_CODE (*valp) == STRING_CST)
    8627              :         {
    8628              :           /* An array was initialized with a string constant, and now
    8629              :              we're writing into one of its elements.  Explode the
    8630              :              single initialization into a set of element
    8631              :              initializations.  */
    8632        11432 :           gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
    8633              : 
    8634        11432 :           tree string = *valp;
    8635        11432 :           tree elt_type = TREE_TYPE (type);
    8636        11432 :           unsigned chars_per_elt = (TYPE_PRECISION (elt_type)
    8637        11432 :                                     / TYPE_PRECISION (char_type_node));
    8638        11432 :           unsigned num_elts = TREE_STRING_LENGTH (string) / chars_per_elt;
    8639        11432 :           tree ary_ctor = build_constructor (type, NULL);
    8640              : 
    8641        11432 :           vec_safe_reserve (CONSTRUCTOR_ELTS (ary_ctor), num_elts);
    8642        34450 :           for (unsigned ix = 0; ix != num_elts; ix++)
    8643              :             {
    8644        11586 :               constructor_elt elt =
    8645              :                 {
    8646        11586 :                   build_int_cst (size_type_node, ix),
    8647        11586 :                   extract_string_elt (string, chars_per_elt, ix)
    8648        11586 :                 };
    8649        11586 :               CONSTRUCTOR_ELTS (ary_ctor)->quick_push (elt);
    8650              :             }
    8651              : 
    8652        11432 :           *valp = ary_ctor;
    8653              :         }
    8654              : 
    8655     36361449 :       enum tree_code code = TREE_CODE (type);
    8656     36361449 :       tree reftype = refs->pop();
    8657     36361449 :       tree index = refs->pop();
    8658     36361449 :       bool is_access_expr = refs->pop() != NULL_TREE;
    8659              : 
    8660     36361449 :       if (code == COMPLEX_TYPE)
    8661              :         {
    8662           61 :           if (TREE_CODE (*valp) == COMPLEX_CST)
    8663           51 :             *valp = build2 (COMPLEX_EXPR, type, TREE_REALPART (*valp),
    8664           51 :                             TREE_IMAGPART (*valp));
    8665           10 :           else if (TREE_CODE (*valp) == CONSTRUCTOR
    8666            2 :                    && CONSTRUCTOR_NELTS (*valp) == 0
    8667           12 :                    && CONSTRUCTOR_NO_CLEARING (*valp))
    8668              :             {
    8669            2 :               tree r = build_constructor (reftype, NULL);
    8670            2 :               CONSTRUCTOR_NO_CLEARING (r) = 1;
    8671            2 :               *valp = build2 (COMPLEX_EXPR, type, r, r);
    8672              :             }
    8673           61 :           gcc_assert (TREE_CODE (*valp) == COMPLEX_EXPR);
    8674           61 :           ctors.safe_push (valp);
    8675           61 :           vec_safe_push (indexes, index);
    8676           61 :           valp = &TREE_OPERAND (*valp, TREE_CODE (index) == IMAGPART_EXPR);
    8677           61 :           gcc_checking_assert (refs->is_empty ());
    8678              :           type = reftype;
    8679       287033 :           break;
    8680              :         }
    8681              : 
    8682              :       /* If the value of object is already zero-initialized, any new ctors for
    8683              :          subobjects will also be zero-initialized.  Similarly with zeroing of
    8684              :          padding bits.  */
    8685     36361388 :       no_zero_init = CONSTRUCTOR_NO_CLEARING (*valp);
    8686     36361388 :       zero_padding_bits = CONSTRUCTOR_ZERO_PADDING_BITS (*valp);
    8687              : 
    8688     36361388 :       if (code == RECORD_TYPE && is_empty_field (index))
    8689              :         /* Don't build a sub-CONSTRUCTOR for an empty base or field, as they
    8690              :            have no data and might have an offset lower than previously declared
    8691              :            fields, which confuses the middle-end.  The code below will notice
    8692              :            that we don't have a CONSTRUCTOR for our inner target and just
    8693              :            return init.  */
    8694              :         {
    8695              :           empty_base = true;
    8696              :           break;
    8697              :         }
    8698              : 
    8699              :       /* If a union is zero-initialized, its first non-static named data member
    8700              :          is zero-initialized (and therefore active).  */
    8701     36074416 :       if (code == UNION_TYPE
    8702     36074416 :           && !no_zero_init
    8703     36074416 :           && CONSTRUCTOR_NELTS (*valp) == 0)
    8704         4079 :         if (tree first = next_aggregate_field (TYPE_FIELDS (type)))
    8705         4079 :           CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (*valp), first, NULL_TREE);
    8706              : 
    8707              :       /* Check for implicit change of active member for a union.  */
    8708              : 
    8709              :       /* LWG3436, CWG2675, c++/121068: The array object model is confused.  For
    8710              :          now allow initializing an array element to activate the array.  */
    8711     36126765 :       auto only_array_refs = [](const releasing_vec &refs)
    8712              :       {
    8713        52354 :         for (unsigned i = 1; i < refs->length(); i += 3)
    8714           35 :           if (TREE_CODE ((*refs)[i]) != INTEGER_CST)
    8715              :             return false;
    8716              :         return true;
    8717              :       };
    8718              : 
    8719     36074416 :       if (code == UNION_TYPE
    8720       584222 :           && (CONSTRUCTOR_NELTS (*valp) == 0
    8721       381748 :               || CONSTRUCTOR_ELT (*valp, 0)->index != index)
    8722              :           /* An INIT_EXPR of the last member in an access chain is always OK,
    8723              :              but still check implicit change of members earlier on; see
    8724              :              cpp2a/constexpr-union6.C.  */
    8725     36289367 :           && !(TREE_CODE (t) == INIT_EXPR && only_array_refs (refs)))
    8726              :         {
    8727       162632 :           bool has_active_member = CONSTRUCTOR_NELTS (*valp) != 0;
    8728       162632 :           tree inner = strip_array_types (reftype);
    8729              : 
    8730       162632 :           if (has_active_member && cxx_dialect < cxx20)
    8731              :             {
    8732           58 :               if (!ctx->quiet)
    8733           19 :                 error_at (cp_expr_loc_or_input_loc (t),
    8734              :                           "change of the active member of a union "
    8735              :                           "from %qD to %qD is not a constant expression "
    8736              :                           "before C++20",
    8737           19 :                           CONSTRUCTOR_ELT (*valp, 0)->index,
    8738              :                           index);
    8739           58 :               *non_constant_p = true;
    8740              :             }
    8741       162574 :           else if ((!is_access_expr
    8742        47066 :                     || (TREE_CLOBBER_P (init)
    8743            0 :                         && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
    8744        47066 :                     || (TREE_CODE (t) != INIT_EXPR
    8745        47054 :                         && CLASS_TYPE_P (inner)
    8746          479 :                         && !type_has_non_deleted_trivial_default_ctor (inner)))
    8747       162659 :                    && TREE_CODE (t) != MODOP_EXPR)
    8748              :             {
    8749              :               /* Diagnose changing active union member after initialization
    8750              :                  without a valid member access expression, as described in
    8751              :                  [class.union.general] p5.  */
    8752       115517 :               if (!ctx->quiet)
    8753              :                 {
    8754           33 :                   auto_diagnostic_group d;
    8755           33 :                   if (has_active_member)
    8756           24 :                     error_at (cp_expr_loc_or_input_loc (t),
    8757              :                               "accessing %qD member instead of initialized "
    8758              :                               "%qD member in constant expression",
    8759           24 :                               index, CONSTRUCTOR_ELT (*valp, 0)->index);
    8760              :                   else
    8761            9 :                     error_at (cp_expr_loc_or_input_loc (t),
    8762              :                               "accessing uninitialized member %qD",
    8763              :                               index);
    8764           33 :                   if (is_access_expr)
    8765            3 :                     inform (DECL_SOURCE_LOCATION (index),
    8766              :                             "%qD does not implicitly begin its lifetime "
    8767              :                             "because %qT does not have a non-deleted "
    8768              :                             "trivial default constructor, use "
    8769              :                             "%<std::construct_at%> instead",
    8770              :                             index, inner);
    8771              :                   else
    8772           30 :                     inform (DECL_SOURCE_LOCATION (index),
    8773              :                             "initializing %qD requires a member access "
    8774              :                             "expression as the left operand of the assignment",
    8775              :                             index);
    8776           33 :                 }
    8777       115517 :               *non_constant_p = true;
    8778              :             }
    8779        47057 :           else if (has_active_member && CONSTRUCTOR_NO_CLEARING (*valp))
    8780              :             {
    8781              :               /* Diagnose changing the active union member while the union
    8782              :                  is in the process of being initialized.  */
    8783           18 :               if (!ctx->quiet)
    8784            6 :                 error_at (cp_expr_loc_or_input_loc (t),
    8785              :                           "change of the active member of a union "
    8786              :                           "from %qD to %qD during initialization",
    8787            6 :                           CONSTRUCTOR_ELT (*valp, 0)->index,
    8788              :                           index);
    8789           18 :               *non_constant_p = true;
    8790              :             }
    8791              :           no_zero_init = true;
    8792              :         }
    8793              : 
    8794              :       /* Ending the lifetime of the active union member means the union no
    8795              :          longer has an active member.  */
    8796       584222 :       if (code == UNION_TYPE && refs->is_empty ()
    8797       100427 :           && TREE_CLOBBER_P (init)
    8798     36082470 :           && CLOBBER_KIND (init) >= CLOBBER_OBJECT_END)
    8799              :         {
    8800         1978 :           vec_safe_truncate (CONSTRUCTOR_ELTS (*valp), 0);
    8801         4692 :           return void_node;
    8802              :         }
    8803              : 
    8804     36072438 :       ctors.safe_push (valp);
    8805     36072438 :       vec_safe_push (indexes, index);
    8806              : 
    8807              :       /* Avoid adding an _elt for a clobber when the whole CONSTRUCTOR is
    8808              :          uninitialized.  */
    8809     34160574 :       int pos = (!seen_union && TREE_CLOBBER_P (init)
    8810      1775203 :                  && CONSTRUCTOR_NO_CLEARING (*valp)
    8811     37653687 :                  && CLOBBER_KIND (init) < CLOBBER_OBJECT_END) ? -2 : -1;
    8812     36072438 :       constructor_elt *cep
    8813     36072438 :         = get_or_insert_ctor_field (*valp, index, pos);
    8814     36072438 :       if (cep == nullptr)
    8815         2714 :         return void_node;
    8816     36069724 :       index_pos_hints.safe_push (cep - CONSTRUCTOR_ELTS (*valp)->begin());
    8817              : 
    8818     36069724 :       if (code == UNION_TYPE)
    8819              :         {
    8820       582244 :           activated_union_member_p = true;
    8821       582244 :           --seen_union;
    8822              :         }
    8823              : 
    8824     36069724 :       valp = &cep->value;
    8825     36069724 :       type = reftype;
    8826              :     }
    8827              : 
    8828              :   /* Change an "as-base" clobber to the real type;
    8829              :      we don't need to worry about padding in constexpr.  */
    8830     94026660 :   tree itype = initialized_type (init);
    8831     94026660 :   if (IS_FAKE_BASE_TYPE (itype))
    8832         5058 :     itype = TYPE_CONTEXT (itype);
    8833              : 
    8834              :   /* For initialization of an empty base, the original target will be
    8835              :      *(base*)this, evaluation of which resolves to the object
    8836              :      argument, which has the derived type rather than the base type.  */
    8837    187766348 :   if (!empty_base && !(same_type_ignoring_top_level_qualifiers_p
    8838     93739688 :                        (itype, type)))
    8839              :     {
    8840        19002 :       gcc_assert (is_empty_class (TREE_TYPE (target)));
    8841              :       empty_base = true;
    8842              :     }
    8843              : 
    8844              :   /* For __builtin_start_lifetime, if it is already within lifetime,
    8845              :      don't do anything.  */
    8846     94026660 :   if (TREE_CODE (t) == MODOP_EXPR && *valp != NULL_TREE && *valp != void_node)
    8847              :     return void_node;
    8848              : 
    8849              :   /* Detect modifying a constant object in constexpr evaluation.
    8850              :      We have found a const object that is being modified.  Figure out
    8851              :      if we need to issue an error.  Consider
    8852              : 
    8853              :      struct A {
    8854              :        int n;
    8855              :        constexpr A() : n(1) { n = 2; } // #1
    8856              :      };
    8857              :      struct B {
    8858              :        const A a;
    8859              :        constexpr B() { a.n = 3; } // #2
    8860              :      };
    8861              :     constexpr B b{};
    8862              : 
    8863              :     #1 is OK, since we're modifying an object under construction, but
    8864              :     #2 is wrong, since "a" is const and has been fully constructed.
    8865              :     To track it, we use the TREE_READONLY bit in the object's CONSTRUCTOR
    8866              :     which means that the object is read-only.  For the example above, the
    8867              :     *ctors stack at the point of #2 will look like:
    8868              : 
    8869              :       ctors[0] = {.a={.n=2}}  TREE_READONLY = 0
    8870              :       ctors[1] = {.n=2}       TREE_READONLY = 1
    8871              : 
    8872              :     and we're modifying "b.a", so we search the stack and see if the
    8873              :     constructor for "b.a" has already run.  */
    8874     94026628 :   if (const_object_being_modified)
    8875              :     {
    8876        86908 :       bool fail = false;
    8877        86908 :       tree const_objtype
    8878        86908 :         = strip_array_types (TREE_TYPE (const_object_being_modified));
    8879        86908 :       if (!CLASS_TYPE_P (const_objtype))
    8880              :         fail = true;
    8881              :       else
    8882              :         {
    8883              :           /* [class.ctor]p5 "A constructor can be invoked for a const,
    8884              :              volatile, or const volatile object.  const and volatile
    8885              :              semantics are not applied on an object under construction.
    8886              :              They come into effect when the constructor for the most
    8887              :              derived object ends."  */
    8888       260923 :           for (tree *elt : ctors)
    8889        87317 :             if (same_type_ignoring_top_level_qualifiers_p
    8890        87317 :                 (TREE_TYPE (const_object_being_modified), TREE_TYPE (*elt)))
    8891              :               {
    8892        86803 :                 fail = TREE_READONLY (*elt);
    8893        86803 :                 break;
    8894              :               }
    8895              :         }
    8896        86803 :       if (fail)
    8897              :         {
    8898          200 :           if (!ctx->quiet)
    8899           65 :             modifying_const_object_error (t, const_object_being_modified);
    8900          200 :           *non_constant_p = true;
    8901          200 :           return t;
    8902              :         }
    8903              :     }
    8904              : 
    8905     94026428 :   if (!preeval)
    8906              :     {
    8907              :       /* We're handling an INIT_EXPR of class type, so the value of the
    8908              :          initializer can depend on the object it's initializing.  */
    8909              : 
    8910              :       /* Create a new CONSTRUCTOR in case evaluation of the initializer
    8911              :          wants to modify it.  */
    8912     30830635 :       if (*valp == NULL_TREE)
    8913              :         {
    8914     29729822 :           *valp = build_constructor (type, NULL);
    8915     29729822 :           CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
    8916     29729822 :           CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
    8917              :         }
    8918     30830635 :       new_ctx.ctor = empty_base ? NULL_TREE : *valp;
    8919     30830635 :       new_ctx.object = target;
    8920              :       /* Avoid temporary materialization when initializing from a TARGET_EXPR.
    8921              :          We don't need to mess with AGGR_EXPR_SLOT/VEC_INIT_EXPR_SLOT because
    8922              :          expansion of those trees uses ctx instead.  */
    8923     30830635 :       if (TREE_CODE (init) == TARGET_EXPR)
    8924      3292049 :         if (tree tinit = TARGET_EXPR_INITIAL (init))
    8925      3292049 :           init = tinit;
    8926     30830635 :       init = cxx_eval_constant_expression (&new_ctx, init, vc_prvalue,
    8927              :                                            non_constant_p, overflow_p,
    8928              :                                            jump_target);
    8929     30830635 :       if (*jump_target)
    8930              :         return NULL_TREE;
    8931              :       /* The hash table might have moved since the get earlier, and the
    8932              :          initializer might have mutated the underlying CONSTRUCTORs, so we must
    8933              :          recompute VALP. */
    8934     30830441 :       valp = ctx->global->get_value_ptr (object, TREE_CODE (t) == INIT_EXPR);
    8935     35308312 :       for (unsigned i = 0; i < vec_safe_length (indexes); i++)
    8936              :         {
    8937      4477871 :           ctors[i] = valp;
    8938      4477871 :           constructor_elt *cep
    8939      4477871 :             = get_or_insert_ctor_field (*valp, indexes[i], index_pos_hints[i]);
    8940      4477871 :           valp = &cep->value;
    8941              :         }
    8942              :     }
    8943              : 
    8944     94026234 :   if (*non_constant_p)
    8945              :     return t;
    8946              : 
    8947              :   /* Don't share a CONSTRUCTOR that might be changed later.  */
    8948     92165652 :   init = unshare_constructor (init);
    8949              : 
    8950     92165652 :   gcc_checking_assert (!*valp
    8951              :                        || *valp == void_node
    8952              :                        || (same_type_ignoring_top_level_qualifiers_p
    8953              :                            (TREE_TYPE (*valp), type)));
    8954     92165652 :   if (empty_base)
    8955              :     {
    8956              :       /* Just evaluate the initializer and return, since there's no actual data
    8957              :          to store, and we didn't build a CONSTRUCTOR.  */
    8958       294504 :       if (!*valp)
    8959              :         {
    8960              :           /* But do make sure we have something in *valp.  */
    8961            0 :           *valp = build_constructor (type, nullptr);
    8962            0 :           CONSTRUCTOR_NO_CLEARING (*valp) = no_zero_init;
    8963            0 :           CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
    8964              :         }
    8965              :     }
    8966     91871148 :   else if (TREE_CLOBBER_P (init))
    8967              :     {
    8968       770593 :       if (AGGREGATE_TYPE_P (type))
    8969              :         {
    8970       542611 :           if (*valp && TREE_CODE (*valp) == CONSTRUCTOR)
    8971       542562 :             CONSTRUCTOR_ELTS (*valp) = nullptr;
    8972              :           else
    8973           49 :             *valp = build_constructor (type, nullptr);
    8974       542611 :           TREE_CONSTANT (*valp) = true;
    8975       542611 :           TREE_SIDE_EFFECTS (*valp) = false;
    8976       542611 :           CONSTRUCTOR_NO_CLEARING (*valp) = true;
    8977       542611 :           CONSTRUCTOR_ZERO_PADDING_BITS (*valp) = zero_padding_bits;
    8978              :         }
    8979              :       else
    8980       227982 :         *valp = void_node;
    8981              :     }
    8982     91100555 :   else if (*valp && TREE_CODE (*valp) == CONSTRUCTOR
    8983     28963933 :            && TREE_CODE (init) == CONSTRUCTOR)
    8984              :     {
    8985              :       /* An outer ctx->ctor might be pointing to *valp, so replace
    8986              :          its contents.  */
    8987      4756417 :       CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init);
    8988      4756417 :       TREE_CONSTANT (*valp) = TREE_CONSTANT (init);
    8989      4756417 :       TREE_SIDE_EFFECTS (*valp) = TREE_SIDE_EFFECTS (init);
    8990     14269251 :       CONSTRUCTOR_NO_CLEARING (*valp)
    8991      4756417 :         = CONSTRUCTOR_NO_CLEARING (init);
    8992     14269251 :       CONSTRUCTOR_ZERO_PADDING_BITS (*valp)
    8993      4756417 :         = CONSTRUCTOR_ZERO_PADDING_BITS (init);
    8994              :     }
    8995              :   else
    8996     86344138 :     *valp = init;
    8997              : 
    8998              :   /* After initialization, 'const' semantics apply to the value of the
    8999              :      object.  Make a note of this fact by marking the CONSTRUCTOR
    9000              :      TREE_READONLY.  */
    9001     92165652 :   if (TREE_CODE (t) == INIT_EXPR
    9002     69665032 :       && !empty_base
    9003     69370528 :       && TREE_CODE (*valp) == CONSTRUCTOR
    9004     96749137 :       && TYPE_READONLY (type))
    9005              :     {
    9006        35990 :       tree target_type = TREE_TYPE (target);
    9007        35990 :       if (IS_FAKE_BASE_TYPE (target_type))
    9008            0 :         target_type = TYPE_CONTEXT (target_type);
    9009        35990 :       if (INDIRECT_REF_P (target)
    9010        51144 :           && (is_this_parameter
    9011        15154 :               (tree_strip_nop_conversions (TREE_OPERAND (target, 0)))))
    9012              :         /* We've just initialized '*this' (perhaps via the target
    9013              :            constructor of a delegating constructor).  Leave it up to the
    9014              :            caller that set 'this' to set TREE_READONLY appropriately.  */
    9015           23 :         gcc_checking_assert (same_type_ignoring_top_level_qualifiers_p
    9016              :                              (target_type, type) || empty_base);
    9017              :       else
    9018        35967 :         TREE_READONLY (*valp) = true;
    9019              :     }
    9020              : 
    9021              :   /* Update TREE_CONSTANT and TREE_SIDE_EFFECTS on enclosing
    9022              :      CONSTRUCTORs, if any.  */
    9023     92165652 :   bool c = TREE_CONSTANT (init);
    9024     92165652 :   bool s = TREE_SIDE_EFFECTS (init);
    9025     92165652 :   if (!indexes->is_empty ())
    9026              :     {
    9027     20447805 :       tree last = indexes->last ();
    9028     20447805 :       if (TREE_CODE (last) == REALPART_EXPR
    9029     20447805 :           || TREE_CODE (last) == IMAGPART_EXPR)
    9030              :         {
    9031              :           /* And canonicalize COMPLEX_EXPR into COMPLEX_CST if
    9032              :              possible.  */
    9033           61 :           tree *cexpr = ctors.last ();
    9034           61 :           if (tree c = const_binop (COMPLEX_EXPR, TREE_TYPE (*cexpr),
    9035           61 :                                     TREE_OPERAND (*cexpr, 0),
    9036           61 :                                     TREE_OPERAND (*cexpr, 1)))
    9037           53 :             *cexpr = c;
    9038              :           else
    9039              :             {
    9040           16 :               TREE_CONSTANT (*cexpr)
    9041            8 :                 = (TREE_CONSTANT (TREE_OPERAND (*cexpr, 0))
    9042            8 :                    & TREE_CONSTANT (TREE_OPERAND (*cexpr, 1)));
    9043           16 :               TREE_SIDE_EFFECTS (*cexpr)
    9044           16 :                 = (TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 0))
    9045            8 :                    | TREE_SIDE_EFFECTS (TREE_OPERAND (*cexpr, 1)));
    9046              :             }
    9047           61 :           c = TREE_CONSTANT (*cexpr);
    9048           61 :           s = TREE_SIDE_EFFECTS (*cexpr);
    9049              :         }
    9050              :     }
    9051     92165652 :   if (!c || s || activated_union_member_p)
    9052     63898525 :     for (tree *elt : ctors)
    9053              :       {
    9054     12545834 :         if (TREE_CODE (*elt) != CONSTRUCTOR)
    9055            0 :           continue;
    9056     12545834 :         if (!c)
    9057     10648433 :           TREE_CONSTANT (*elt) = false;
    9058     12545834 :         if (s)
    9059            0 :           TREE_SIDE_EFFECTS (*elt) = true;
    9060              :         /* Clear CONSTRUCTOR_NO_CLEARING since we've activated a member of
    9061              :            this union.  */
    9062     12545834 :         if (TREE_CODE (TREE_TYPE (*elt)) == UNION_TYPE)
    9063       465865 :           CONSTRUCTOR_NO_CLEARING (*elt) = false;
    9064              :       }
    9065              : 
    9066     92165652 :   if (lval)
    9067              :     return target;
    9068              :   else
    9069       588792 :     return init;
    9070     94357462 : }
    9071              : 
    9072              : /* Evaluate a ++ or -- expression.  */
    9073              : 
    9074              : static tree
    9075      8717186 : cxx_eval_increment_expression (const constexpr_ctx *ctx, tree t,
    9076              :                               value_cat lval,
    9077              :                               bool *non_constant_p, bool *overflow_p,
    9078              :                               tree *jump_target)
    9079              : {
    9080      8717186 :   enum tree_code code = TREE_CODE (t);
    9081      8717186 :   tree type = TREE_TYPE (t);
    9082      8717186 :   tree op = TREE_OPERAND (t, 0);
    9083      8717186 :   tree offset = TREE_OPERAND (t, 1);
    9084      8717186 :   gcc_assert (TREE_CONSTANT (offset));
    9085              : 
    9086              :   /* OFFSET is constant, but perhaps not constant enough.  We need to
    9087              :      e.g. bash FLOAT_EXPRs to REAL_CSTs.  */
    9088      8717186 :   offset = fold_simple (offset);
    9089              : 
    9090              :   /* The operand as an lvalue.  */
    9091      8717186 :   op = cxx_eval_constant_expression (ctx, op, vc_glvalue,
    9092              :                                      non_constant_p, overflow_p,
    9093              :                                      jump_target);
    9094      8717186 :   if (*jump_target)
    9095              :     return NULL_TREE;
    9096              : 
    9097              :   /* The operand as an rvalue.  */
    9098      8717186 :   tree val
    9099      8717186 :     = cxx_eval_constant_expression (ctx, op, vc_prvalue,
    9100              :                                     non_constant_p, overflow_p,
    9101              :                                     jump_target);
    9102      8717186 :   if (*jump_target)
    9103              :     return NULL_TREE;
    9104              :   /* Don't VERIFY_CONSTANT if this might be dealing with a pointer to
    9105              :      a local array in a constexpr function.  */
    9106      8717186 :   bool ptr = INDIRECT_TYPE_P (TREE_TYPE (val));
    9107      3525475 :   if (!ptr)
    9108      3525475 :     VERIFY_CONSTANT (val);
    9109              : 
    9110              :   /* The modified value.  */
    9111      8657826 :   bool inc = (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR);
    9112      8657826 :   tree mod;
    9113      8657826 :   if (INDIRECT_TYPE_P (type))
    9114              :     {
    9115              :       /* The middle end requires pointers to use POINTER_PLUS_EXPR.  */
    9116      5191711 :       offset = convert_to_ptrofftype (offset);
    9117      5191711 :       if (!inc)
    9118        80832 :         offset = fold_build1 (NEGATE_EXPR, TREE_TYPE (offset), offset);
    9119      5191711 :       mod = fold_build2 (POINTER_PLUS_EXPR, type, val, offset);
    9120              :     }
    9121      3466115 :   else if (c_promoting_integer_type_p (type)
    9122        39611 :            && !TYPE_UNSIGNED (type)
    9123      3466325 :            && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))
    9124              :     {
    9125          210 :       offset = fold_convert (integer_type_node, offset);
    9126          210 :       mod = fold_convert (integer_type_node, val);
    9127          241 :       tree t = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, integer_type_node,
    9128              :                             mod, offset);
    9129          210 :       mod = fold_convert (type, t);
    9130          210 :       if (TREE_OVERFLOW_P (mod) && !TREE_OVERFLOW_P (t))
    9131            9 :         TREE_OVERFLOW (mod) = false;
    9132              :     }
    9133              :   else
    9134      3908138 :     mod = fold_build2 (inc ? PLUS_EXPR : MINUS_EXPR, type, val, offset);
    9135      8657826 :   if (!ptr)
    9136      3466115 :     VERIFY_CONSTANT (mod);
    9137              : 
    9138              :   /* Storing the modified value.  */
    9139     14502608 :   tree store = build2_loc (cp_expr_loc_or_loc (t, input_location),
    9140              :                            MODIFY_EXPR, type, op, mod);
    9141      8657826 :   mod = cxx_eval_constant_expression (ctx, store, lval,
    9142              :                                       non_constant_p, overflow_p,
    9143              :                                       jump_target);
    9144      8657826 :   ggc_free (store);
    9145      8657826 :   if (*jump_target)
    9146              :     return NULL_TREE;
    9147      8657826 :   if (*non_constant_p)
    9148              :     return t;
    9149              : 
    9150              :   /* And the value of the expression.  */
    9151      8583724 :   if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR)
    9152              :     /* Prefix ops are lvalues, but the caller might want an rvalue;
    9153              :        lval has already been taken into account in the store above.  */
    9154              :     return mod;
    9155              :   else
    9156              :     /* Postfix ops are rvalues.  */
    9157       420967 :     return val;
    9158              : }
    9159              : 
    9160              : /* Subroutine of cxx_eval_statement_list.  Determine whether the statement
    9161              :    STMT matches *jump_target.  If we're looking for a case label and we see
    9162              :    the default label, note it in ctx->css_state.  */
    9163              : 
    9164              : static bool
    9165       504206 : label_matches (const constexpr_ctx *ctx, tree *jump_target, tree stmt)
    9166              : {
    9167       504206 :   switch (TREE_CODE (*jump_target))
    9168              :     {
    9169          145 :     case LABEL_DECL:
    9170          145 :       if (TREE_CODE (stmt) == LABEL_EXPR
    9171          145 :           && LABEL_EXPR_LABEL (stmt) == *jump_target)
    9172           52 :         return true;
    9173              :       break;
    9174              : 
    9175       502144 :     case INTEGER_CST:
    9176       502144 :       if (TREE_CODE (stmt) == CASE_LABEL_EXPR)
    9177              :         {
    9178       502117 :           gcc_assert (ctx->css_state != NULL);
    9179       502117 :           if (!CASE_LOW (stmt))
    9180              :             {
    9181              :               /* default: should appear just once in a SWITCH_EXPR
    9182              :                  body (excluding nested SWITCH_EXPR).  */
    9183        76278 :               gcc_assert (*ctx->css_state != css_default_seen);
    9184              :               /* When evaluating SWITCH_EXPR body for the second time,
    9185              :                  return true for the default: label.  */
    9186        76278 :               if (*ctx->css_state == css_default_processing)
    9187              :                 return true;
    9188        39015 :               *ctx->css_state = css_default_seen;
    9189              :             }
    9190       425839 :           else if (CASE_HIGH (stmt))
    9191              :             {
    9192           20 :               if (tree_int_cst_le (CASE_LOW (stmt), *jump_target)
    9193           31 :                   && tree_int_cst_le (*jump_target, CASE_HIGH (stmt)))
    9194              :                 return true;
    9195              :             }
    9196       425819 :           else if (tree_int_cst_equal (*jump_target, CASE_LOW (stmt)))
    9197              :             return true;
    9198              :         }
    9199              :       break;
    9200              : 
    9201              :     case BREAK_STMT:
    9202              :     case CONTINUE_STMT:
    9203              :       /* These two are handled directly in cxx_eval_loop_expr by testing
    9204              :          breaks (jump_target) or continues (jump_target).  */
    9205              :       break;
    9206              : 
    9207              :     case VAR_DECL:
    9208              :       /* Uncaught exception.  This is handled by TRY_BLOCK evaluation
    9209              :          and other places by testing throws (jump_target).  */
    9210              :       break;
    9211              : 
    9212            0 :     default:
    9213            0 :       gcc_unreachable ();
    9214              :     }
    9215              :   return false;
    9216              : }
    9217              : 
    9218              : /* Evaluate a STATEMENT_LIST for side-effects.  Handles various jump
    9219              :    semantics, for switch, break, continue, and return.  */
    9220              : 
    9221              : static tree
    9222     48474297 : cxx_eval_statement_list (const constexpr_ctx *ctx, tree t,
    9223              :                          bool *non_constant_p, bool *overflow_p,
    9224              :                          tree *jump_target)
    9225              : {
    9226              :   /* In a statement-expression we want to return the last value.
    9227              :      For empty statement expression return void_node.  */
    9228     48474297 :   tree r = void_node;
    9229    127283594 :   for (tree_stmt_iterator i = tsi_start (t); !tsi_end_p (i); ++i)
    9230              :     {
    9231    104657130 :       tree stmt = *i;
    9232              : 
    9233              :       /* We've found a continue, so skip everything until we reach
    9234              :          the label its jumping to.  */
    9235    104657130 :       if (continues (jump_target))
    9236              :         {
    9237         2062 :           if (label_matches (ctx, jump_target, stmt))
    9238              :             /* Found it.  */
    9239           52 :             *jump_target = NULL_TREE;
    9240              :           else
    9241         2010 :             continue;
    9242              :         }
    9243    104655120 :       if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
    9244     11293105 :         continue;
    9245              : 
    9246     93362015 :       value_cat lval = vc_discard;
    9247              :       /* The result of a statement-expression is not wrapped in EXPR_STMT.  */
    9248    131399872 :       if (tsi_one_before_end_p (i)
    9249     38039095 :           && !VOID_TYPE_P (TREE_TYPE (stmt)))
    9250              :         lval = vc_prvalue;
    9251              : 
    9252     93362015 :       r = cxx_eval_constant_expression (ctx, stmt, lval,
    9253              :                                         non_constant_p, overflow_p,
    9254              :                                         jump_target);
    9255     93362011 :       if (*non_constant_p)
    9256              :         break;
    9257     83344269 :       if (returns (jump_target)
    9258     67603680 :           || breaks (jump_target)
    9259     78809297 :           || throws (jump_target))
    9260              :         break;
    9261              :     }
    9262     48474293 :   return r;
    9263              : }
    9264              : 
    9265              : /* Evaluate a LOOP_EXPR for side-effects.  Handles break and return
    9266              :    semantics; continue semantics are covered by cxx_eval_statement_list.  */
    9267              : 
    9268              : static tree
    9269      6662927 : cxx_eval_loop_expr (const constexpr_ctx *ctx, tree t,
    9270              :                     bool *non_constant_p, bool *overflow_p,
    9271              :                     tree *jump_target)
    9272              : {
    9273      6662927 :   tree body, cond = NULL_TREE, expr = NULL_TREE;
    9274      6662927 :   tree cond_prep = NULL_TREE, cond_cleanup = NULL_TREE;
    9275      6662927 :   unsigned cond_cleanup_depth = 0;
    9276      6662927 :   int count = 0;
    9277      6662927 :   switch (TREE_CODE (t))
    9278              :     {
    9279         3403 :     case LOOP_EXPR:
    9280         3403 :       body = LOOP_EXPR_BODY (t);
    9281         3403 :       break;
    9282      5362684 :     case DO_STMT:
    9283      5362684 :       body = DO_BODY (t);
    9284      5362684 :       cond = DO_COND (t);
    9285      5362684 :       break;
    9286       365919 :     case WHILE_STMT:
    9287       365919 :       body = WHILE_BODY (t);
    9288       365919 :       cond = WHILE_COND (t);
    9289       365919 :       cond_prep = WHILE_COND_PREP (t);
    9290       365919 :       cond_cleanup = WHILE_COND_CLEANUP (t);
    9291       365919 :       count = -1;
    9292       365919 :       break;
    9293       930921 :     case FOR_STMT:
    9294       930921 :       if (FOR_INIT_STMT (t))
    9295            0 :         cxx_eval_constant_expression (ctx, FOR_INIT_STMT (t), vc_discard,
    9296              :                                       non_constant_p, overflow_p, jump_target);
    9297       930921 :       if (*non_constant_p)
    9298              :         return NULL_TREE;
    9299       930921 :       body = FOR_BODY (t);
    9300       930921 :       cond = FOR_COND (t);
    9301       930921 :       expr = FOR_EXPR (t);
    9302       930921 :       cond_prep = FOR_COND_PREP (t);
    9303       930921 :       cond_cleanup = FOR_COND_CLEANUP (t);
    9304       930921 :       count = -1;
    9305       930921 :       break;
    9306            0 :     default:
    9307            0 :       gcc_unreachable ();
    9308              :     }
    9309      6662927 :   if (cond_prep)
    9310           12 :     gcc_assert (TREE_CODE (cond_prep) == BIND_EXPR);
    9311     31409789 :   auto cleanup_cond = [&] {
    9312              :     /* Clean up the condition variable after each iteration.  */
    9313     24746862 :     if (cond_cleanup_depth && !*non_constant_p)
    9314              :       {
    9315          105 :         auto_vec<tree, 4> cleanups (cond_cleanup_depth);
    9316          105 :         tree s = BIND_EXPR_BODY (cond_prep);
    9317          105 :         unsigned i;
    9318          210 :         for (i = cond_cleanup_depth; i; --i)
    9319              :           {
    9320          105 :             tree_stmt_iterator iter = tsi_last (s);
    9321          105 :             s = tsi_stmt (iter);
    9322          105 :             cleanups.quick_push (CLEANUP_EXPR (s));
    9323          105 :             s = CLEANUP_BODY (s);
    9324              :           }
    9325          105 :         tree c;
    9326          420 :         FOR_EACH_VEC_ELT_REVERSE (cleanups, i, c)
    9327          105 :           cxx_eval_constant_expression (ctx, c, vc_discard, non_constant_p,
    9328              :                                         overflow_p, jump_target);
    9329          105 :       }
    9330     24746862 :     if (cond_prep)
    9331          111 :       for (tree decl = BIND_EXPR_VARS (cond_prep);
    9332          222 :            decl; decl = DECL_CHAIN (decl))
    9333          111 :         destroy_value_checked (ctx, decl, non_constant_p);
    9334      6662927 :   };
    9335     19416212 :   do
    9336              :     {
    9337     19416212 :       if (count != -1)
    9338              :         {
    9339     18119372 :           if (body)
    9340     18119372 :             cxx_eval_constant_expression (ctx, body, vc_discard,
    9341              :                                           non_constant_p, overflow_p,
    9342              :                                           jump_target);
    9343     18119372 :           if (breaks (jump_target))
    9344              :             {
    9345        35437 :               *jump_target = NULL_TREE;
    9346        35437 :               break;
    9347              :             }
    9348              : 
    9349     18083935 :           if (TREE_CODE (t) != LOOP_EXPR && continues (jump_target))
    9350          570 :             *jump_target = NULL_TREE;
    9351              : 
    9352     18083935 :           if (expr)
    9353      5464369 :             cxx_eval_constant_expression (ctx, expr, vc_discard,
    9354              :                                           non_constant_p, overflow_p,
    9355              :                                           jump_target);
    9356     18083935 :           cleanup_cond ();
    9357              :         }
    9358              : 
    9359     19380775 :       if (cond_prep)
    9360              :         {
    9361          111 :           for (tree decl = BIND_EXPR_VARS (cond_prep);
    9362          222 :                decl; decl = DECL_CHAIN (decl))
    9363          111 :             ctx->global->clear_value (decl);
    9364          111 :           if (cond_cleanup)
    9365              :             {
    9366              :               /* If COND_CLEANUP is non-NULL, we need to evaluate DEPTH
    9367              :                  nested STATEMENT_LISTs from inside of BIND_EXPR_BODY,
    9368              :                  but defer the evaluation of CLEANUP_EXPRs of CLEANUP_STMT
    9369              :                  at the end of those STATEMENT_LISTs.  */
    9370          111 :               cond_cleanup_depth = 0;
    9371          111 :               tree s = BIND_EXPR_BODY (cond_prep);
    9372          111 :               for (unsigned depth = tree_to_uhwi (cond_cleanup);
    9373          222 :                    depth; --depth)
    9374              :                 {
    9375          111 :                   for (tree_stmt_iterator i = tsi_start (s);
    9376          321 :                        !tsi_end_p (i); ++i)
    9377              :                     {
    9378          321 :                       tree stmt = *i;
    9379          321 :                       if (TREE_CODE (stmt) == DEBUG_BEGIN_STMT)
    9380            0 :                         continue;
    9381          321 :                       if (tsi_one_before_end_p (i))
    9382              :                         {
    9383              :                           /* The last statement in the STATEMENT_LIST
    9384              :                              has to be a CLEANUP_STMT (verified in
    9385              :                              finish_loop_cond_prep).  We want to
    9386              :                              evaluate just its CLEANUP_BODY part but not
    9387              :                              CLEANUP_EXPR part just yet.  */
    9388          105 :                           gcc_assert (TREE_CODE (stmt) == CLEANUP_STMT);
    9389              :                           /* If the CLEANUP_STMT is not actually to be
    9390              :                              evaluated, don't increment cond_cleanup_depth
    9391              :                              so that we don't evaluate the CLEANUP_EXPR
    9392              :                              for it later either.  */
    9393          105 :                           if (*jump_target)
    9394              :                             {
    9395              :                               depth = 1;
    9396              :                               break;
    9397              :                             }
    9398          105 :                           ++cond_cleanup_depth;
    9399              :                           /* If not in the innermost one, next iteration
    9400              :                              will handle CLEANUP_BODY similarly.  */
    9401          105 :                           if (depth > 1)
    9402              :                             {
    9403            0 :                               s = CLEANUP_BODY (stmt);
    9404            0 :                               break;
    9405              :                             }
    9406              :                           /* The innermost one can be evaluated normally.  */
    9407          105 :                           cxx_eval_constant_expression (ctx,
    9408          105 :                                                         CLEANUP_BODY (stmt),
    9409              :                                                         vc_discard,
    9410              :                                                         non_constant_p,
    9411              :                                                         overflow_p,
    9412              :                                                         jump_target);
    9413          105 :                           break;
    9414              :                         }
    9415              :                       /* And so should be evaluated statements which aren't
    9416              :                          last in the STATEMENT_LIST.  */
    9417          216 :                       cxx_eval_constant_expression (ctx, stmt, vc_discard,
    9418              :                                                     non_constant_p, overflow_p,
    9419              :                                                     jump_target);
    9420          216 :                       if (*non_constant_p
    9421          210 :                           || returns (jump_target)
    9422          210 :                           || breaks (jump_target)
    9423          210 :                           || continues (jump_target)
    9424          531 :                           || throws (jump_target))
    9425              :                         {
    9426              :                           depth = 1;
    9427              :                           break;
    9428              :                         }
    9429              :                     }
    9430              :                 }
    9431              :             }
    9432              :           else
    9433            0 :             cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (cond_prep),
    9434              :                                           vc_discard, non_constant_p,
    9435              :                                           overflow_p, jump_target);
    9436              :         }
    9437              : 
    9438     19380775 :       if (cond)
    9439              :         {
    9440     19373257 :           tree res
    9441     19373257 :             = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
    9442              :                                             non_constant_p, overflow_p,
    9443              :                                             jump_target);
    9444     19373257 :           if (res)
    9445              :             {
    9446     19317856 :               if (verify_constant (res, ctx->quiet, non_constant_p,
    9447              :                                    overflow_p))
    9448              :                 break;
    9449     19132202 :               if (integer_zerop (res))
    9450              :                 break;
    9451              :             }
    9452              :           else
    9453        55401 :             gcc_assert (*jump_target);
    9454              :         }
    9455              : 
    9456     12810571 :       if (++count >= constexpr_loop_limit)
    9457              :         {
    9458           27 :           if (!ctx->quiet)
    9459            9 :             error_at (cp_expr_loc_or_input_loc (t),
    9460              :                       "%<constexpr%> loop iteration count exceeds limit of %d "
    9461              :                       "(use %<-fconstexpr-loop-limit=%> to increase the limit)",
    9462              :                       constexpr_loop_limit);
    9463           27 :           *non_constant_p = true;
    9464           27 :           break;
    9465              :         }
    9466              :     }
    9467     38374612 :   while (!returns (jump_target)
    9468     12753524 :          && !breaks (jump_target)
    9469     12753524 :          && !continues (jump_target)
    9470     12753617 :          && (!switches (jump_target) || count == 0)
    9471     12753494 :          && !throws (jump_target)
    9472     25621243 :          && !*non_constant_p);
    9473              : 
    9474      6662927 :   cleanup_cond ();
    9475              : 
    9476      6662927 :   return NULL_TREE;
    9477              : }
    9478              : 
    9479              : /* Evaluate a SWITCH_EXPR for side-effects.  Handles switch and break jump
    9480              :    semantics.  */
    9481              : 
    9482              : static tree
    9483        50118 : cxx_eval_switch_expr (const constexpr_ctx *ctx, tree t,
    9484              :                       bool *non_constant_p, bool *overflow_p,
    9485              :                       tree *jump_target)
    9486              : {
    9487        50118 :   tree cond
    9488        50118 :     = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_COND (t) : SWITCH_COND (t);
    9489        50118 :   cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
    9490              :                                        non_constant_p, overflow_p,
    9491              :                                        jump_target);
    9492        50118 :   if (*jump_target)
    9493              :     return NULL_TREE;
    9494        50118 :   VERIFY_CONSTANT (cond);
    9495        49825 :   if (TREE_CODE (cond) != INTEGER_CST)
    9496              :     {
    9497              :       /* If the condition doesn't reduce to an INTEGER_CST it isn't a usable
    9498              :          switch condition even if it's constant enough for other things
    9499              :          (c++/113545).  */
    9500            0 :       gcc_checking_assert (ctx->quiet);
    9501            0 :       *non_constant_p = true;
    9502            0 :       return t;
    9503              :     }
    9504              : 
    9505        49825 :   *jump_target = cond;
    9506              : 
    9507        49825 :   tree body
    9508        49825 :     = TREE_CODE (t) == SWITCH_STMT ? SWITCH_STMT_BODY (t) : SWITCH_BODY (t);
    9509        49825 :   constexpr_ctx new_ctx = *ctx;
    9510        49825 :   constexpr_switch_state css = css_default_not_seen;
    9511        49825 :   new_ctx.css_state = &css;
    9512        49825 :   cxx_eval_constant_expression (&new_ctx, body, vc_discard,
    9513              :                                 non_constant_p, overflow_p, jump_target);
    9514        87128 :   if (switches (jump_target) && css == css_default_seen)
    9515              :     {
    9516              :       /* If the SWITCH_EXPR body has default: label, process it once again,
    9517              :          this time instructing label_matches to return true for default:
    9518              :          label on switches (jump_target).  */
    9519        37263 :       css = css_default_processing;
    9520        37263 :       cxx_eval_constant_expression (&new_ctx, body, vc_discard,
    9521              :                                     non_constant_p, overflow_p, jump_target);
    9522              :     }
    9523        49825 :   if (breaks (jump_target) || switches (jump_target))
    9524        21437 :     *jump_target = NULL_TREE;
    9525              :   return NULL_TREE;
    9526              : }
    9527              : 
    9528              : /* Find the object of TYPE under initialization in CTX.  */
    9529              : 
    9530              : static tree
    9531        16714 : lookup_placeholder (const constexpr_ctx *ctx, value_cat lval, tree type)
    9532              : {
    9533        16714 :   if (!ctx)
    9534              :     return NULL_TREE;
    9535              : 
    9536              :   /* Prefer the outermost matching object, but don't cross
    9537              :      CONSTRUCTOR_PLACEHOLDER_BOUNDARY constructors.  */
    9538        16318 :   if (ctx->ctor && !CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ctx->ctor))
    9539          574 :     if (tree outer_ob = lookup_placeholder (ctx->parent, lval, type))
    9540              :       return outer_ob;
    9541              : 
    9542              :   /* We could use ctx->object unconditionally, but using ctx->ctor when we
    9543              :      can is a minor optimization.  */
    9544        16140 :   if (!lval && ctx->ctor && same_type_p (TREE_TYPE (ctx->ctor), type))
    9545          300 :     return ctx->ctor;
    9546              : 
    9547        15840 :   if (!ctx->object)
    9548              :     return NULL_TREE;
    9549              : 
    9550              :   /* Since an object cannot have a field of its own type, we can search outward
    9551              :      from ctx->object to find the unique containing object of TYPE.  */
    9552              :   tree ob = ctx->object;
    9553        15816 :   while (ob)
    9554              :     {
    9555        15816 :       if (same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (ob), type))
    9556              :         break;
    9557          219 :       if (handled_component_p (ob))
    9558          217 :         ob = TREE_OPERAND (ob, 0);
    9559              :       else
    9560              :         ob = NULL_TREE;
    9561              :     }
    9562              : 
    9563              :   /* Like in replace_placeholders_r.  */
    9564        15599 :   return unshare_expr (ob);
    9565              : }
    9566              : 
    9567              : /* Complain about an attempt to evaluate inline assembly.  If FUNDEF_P is
    9568              :    true, we're checking a constexpr function body.  */
    9569              : 
    9570              : static void
    9571           35 : inline_asm_in_constexpr_error (location_t loc, bool fundef_p)
    9572              : {
    9573           35 :   auto_diagnostic_group d;
    9574           35 :   if (constexpr_error (loc, fundef_p, "inline assembly is not a "
    9575              :                        "constant expression"))
    9576           35 :     inform (loc, "only unevaluated inline assembly is allowed in a "
    9577              :             "%<constexpr%> function in C++20");
    9578           35 : }
    9579              : 
    9580              : /* We're getting the constant value of DECL in a manifestly constant-evaluated
    9581              :    context; maybe complain about that.  */
    9582              : 
    9583              : static void
    9584     92564772 : maybe_warn_about_constant_value (location_t loc, tree decl)
    9585              : {
    9586     92564772 :   static bool explained = false;
    9587     92564772 :   auto_diagnostic_group d;
    9588     92564772 :   if (cxx_dialect >= cxx17
    9589     92395592 :       && warn_interference_size
    9590     92395592 :       && !OPTION_SET_P (param_destruct_interfere_size)
    9591     92395592 :       && DECL_CONTEXT (decl) == std_node
    9592     19054986 :       && DECL_NAME (decl)
    9593     19054980 :       && id_equal (DECL_NAME (decl), "hardware_destructive_interference_size")
    9594           16 :       && (LOCATION_FILE (input_location) != main_input_filename
    9595           10 :           || module_exporting_p ())
    9596     92564775 :       && warning_at (loc, OPT_Winterference_size, "use of %qD", decl)
    9597     92564781 :       && !explained)
    9598              :     {
    9599            6 :       explained = true;
    9600            6 :       inform (loc, "its value can vary between compiler versions or "
    9601              :               "with different %<-mtune%> or %<-mcpu%> flags");
    9602            6 :       inform (loc, "if this use is part of a public ABI, change it to "
    9603              :               "instead use a constant variable you define");
    9604            6 :       inform (loc, "the default value for the current CPU tuning "
    9605              :               "is %d bytes", param_destruct_interfere_size);
    9606            6 :       inform (loc, "you can stabilize this value with %<--param "
    9607              :               "hardware_destructive_interference_size=%d%>, or disable "
    9608              :               "this warning with %<-Wno-interference-size%>",
    9609              :               param_destruct_interfere_size);
    9610              :     }
    9611     92564772 : }
    9612              : 
    9613              : /* For element type ELT_TYPE, return the appropriate type of the heap object
    9614              :    containing such element(s).  COOKIE_SIZE is NULL or the size of cookie
    9615              :    in bytes.  If COOKIE_SIZE is NULL, return array type
    9616              :    ELT_TYPE[FULL_SIZE / sizeof(ELT_TYPE)], otherwise return
    9617              :    struct { size_t[COOKIE_SIZE/sizeof(size_t)]; ELT_TYPE[N]; }
    9618              :    where N is computed such that the size of the struct fits into FULL_SIZE.
    9619              :    If ARG_SIZE is non-NULL, it is the first argument to the new operator.
    9620              :    It should be passed if ELT_TYPE is zero sized type in which case FULL_SIZE
    9621              :    will be also 0 and so it is not possible to determine the actual array
    9622              :    size.  CTX, NON_CONSTANT_P and OVERFLOW_P are used during constant
    9623              :    expression evaluation of subexpressions of ARG_SIZE.  */
    9624              : 
    9625              : static tree
    9626       119140 : build_new_constexpr_heap_type (const constexpr_ctx *ctx, tree elt_type,
    9627              :                                tree cookie_size, tree full_size, tree arg_size,
    9628              :                                bool *non_constant_p, bool *overflow_p,
    9629              :                                tree *jump_target)
    9630              : {
    9631       119140 :   gcc_assert (cookie_size == NULL_TREE || tree_fits_uhwi_p (cookie_size));
    9632       119140 :   gcc_assert (tree_fits_uhwi_p (full_size));
    9633       119140 :   unsigned HOST_WIDE_INT csz = cookie_size ? tree_to_uhwi (cookie_size) : 0;
    9634       119140 :   if (arg_size)
    9635              :     {
    9636            9 :       STRIP_NOPS (arg_size);
    9637            9 :       if (cookie_size)
    9638              :         {
    9639            0 :           if (TREE_CODE (arg_size) != PLUS_EXPR)
    9640              :             arg_size = NULL_TREE;
    9641            0 :           else if (TREE_CODE (TREE_OPERAND (arg_size, 0)) == INTEGER_CST
    9642            0 :                    && tree_int_cst_equal (cookie_size,
    9643            0 :                                           TREE_OPERAND (arg_size, 0)))
    9644              :             {
    9645            0 :               arg_size = TREE_OPERAND (arg_size, 1);
    9646            0 :               STRIP_NOPS (arg_size);
    9647              :             }
    9648            0 :           else if (TREE_CODE (TREE_OPERAND (arg_size, 1)) == INTEGER_CST
    9649            0 :                    && tree_int_cst_equal (cookie_size,
    9650            0 :                                           TREE_OPERAND (arg_size, 1)))
    9651              :             {
    9652            0 :               arg_size = TREE_OPERAND (arg_size, 0);
    9653            0 :               STRIP_NOPS (arg_size);
    9654              :             }
    9655              :           else
    9656              :             arg_size = NULL_TREE;
    9657              :         }
    9658            9 :       if (arg_size && TREE_CODE (arg_size) == MULT_EXPR)
    9659              :         {
    9660            9 :           tree op0 = TREE_OPERAND (arg_size, 0);
    9661            9 :           tree op1 = TREE_OPERAND (arg_size, 1);
    9662            9 :           if (integer_zerop (op0))
    9663            9 :             arg_size
    9664            9 :               = cxx_eval_constant_expression (ctx, op1, vc_prvalue,
    9665              :                                               non_constant_p, overflow_p,
    9666              :                                               jump_target);
    9667            0 :           else if (integer_zerop (op1))
    9668            0 :             arg_size
    9669            0 :               = cxx_eval_constant_expression (ctx, op0, vc_prvalue,
    9670              :                                               non_constant_p, overflow_p,
    9671              :                                               jump_target);
    9672              :           else
    9673              :             arg_size = NULL_TREE;
    9674            9 :           if (*jump_target)
    9675              :             return NULL_TREE;
    9676              :         }
    9677              :       else
    9678              :         arg_size = NULL_TREE;
    9679              :     }
    9680              : 
    9681            9 :   unsigned HOST_WIDE_INT fsz = tree_to_uhwi (arg_size ? arg_size : full_size);
    9682       119140 :   if (!arg_size)
    9683              :     {
    9684       119131 :       unsigned HOST_WIDE_INT esz = int_size_in_bytes (elt_type);
    9685       119131 :       gcc_assert (fsz >= csz);
    9686       119131 :       fsz -= csz;
    9687       119131 :       if (esz)
    9688       119131 :         fsz /= esz;
    9689              :     }
    9690       119140 :   tree itype2 = build_index_type (size_int (fsz - 1));
    9691       119140 :   if (!cookie_size)
    9692       119131 :     return build_cplus_array_type (elt_type, itype2);
    9693            9 :   return build_new_constexpr_heap_type (elt_type, cookie_size, itype2);
    9694              : }
    9695              : 
    9696              : /* Handle the case when a cleanup of some expression throws.  JMP_TARGET
    9697              :    indicates whether the cleanup threw or not, *JUMP_TARGET indicates whether
    9698              :    the expression which needed the cleanup threw.  If both threw, diagnose
    9699              :    it and return NULL, otherwise return R.  If only the cleanup threw, set
    9700              :    *JUMP_TARGET to the exception object from the cleanup.  */
    9701              : 
    9702              : static tree
    9703      1763411 : merge_jump_target (location_t loc, const constexpr_ctx *ctx, tree r,
    9704              :                    bool *non_constant_p, tree *jump_target, tree jmp_target)
    9705              : {
    9706      1763411 :   if (!throws (&jmp_target))
    9707              :     return r;
    9708           14 :   if (throws (jump_target))
    9709              :     {
    9710              :       /* [except.throw]/9 - If the exception handling mechanism
    9711              :          handling an uncaught exception directly invokes a function
    9712              :          that exits via an exception, the function std::terminate is
    9713              :          invoked.  */
    9714           12 :       if (!ctx->quiet)
    9715              :         {
    9716            4 :           auto_diagnostic_group d;
    9717            4 :           diagnose_std_terminate (loc, ctx, *jump_target);
    9718            4 :           inform (loc, "destructor exited with an exception");
    9719            4 :         }
    9720           12 :       *non_constant_p = true;
    9721           12 :       *jump_target = NULL_TREE;
    9722           12 :       return NULL_TREE;
    9723              :     }
    9724            2 :   *jump_target = jmp_target;
    9725            2 :   return r;
    9726              : }
    9727              : 
    9728              : /* Attempt to reduce the expression T to a constant value.
    9729              :    On failure, issue diagnostic and return error_mark_node.  */
    9730              : /* FIXME unify with c_fully_fold */
    9731              : /* FIXME overflow_p is too global */
    9732              : 
    9733              : tree
    9734   3017915285 : cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t,
    9735              :                               value_cat lval,
    9736              :                               bool *non_constant_p, bool *overflow_p,
    9737              :                               tree *jump_target)
    9738              : {
    9739   3017915285 :   if (*jump_target)
    9740              :     {
    9741              :       /* If we are jumping, ignore all statements/expressions except those
    9742              :          that could have LABEL_EXPR or CASE_LABEL_EXPR in their bodies.  */
    9743      1622781 :       switch (TREE_CODE (t))
    9744              :         {
    9745              :         case BIND_EXPR:
    9746              :         case STATEMENT_LIST:
    9747              :         case LOOP_EXPR:
    9748              :         case COND_EXPR:
    9749              :         case IF_STMT:
    9750              :         case DO_STMT:
    9751              :         case WHILE_STMT:
    9752              :         case FOR_STMT:
    9753              :           break;
    9754       502144 :         case LABEL_EXPR:
    9755       502144 :         case CASE_LABEL_EXPR:
    9756       502144 :           if (label_matches (ctx, jump_target, t))
    9757              :             /* Found it.  */
    9758        49785 :             *jump_target = NULL_TREE;
    9759              :           return NULL_TREE;
    9760              :         default:
    9761              :           return NULL_TREE;
    9762              :         }
    9763              :     }
    9764   3016538339 :   if (error_operand_p (t))
    9765              :     {
    9766          194 :       *non_constant_p = true;
    9767          194 :       return t;
    9768              :     }
    9769              : 
    9770              :   /* Change the input location to the currently processed expression for
    9771              :      better error messages when a subexpression has no location.  */
    9772   3016538145 :   location_t loc = cp_expr_loc_or_input_loc (t);
    9773   6033070858 :   iloc_sentinel sentinel (loc);
    9774              : 
    9775   3016538145 :   STRIP_ANY_LOCATION_WRAPPER (t);
    9776              : 
    9777   3016538145 :   if (CONSTANT_CLASS_P (t))
    9778              :     {
    9779    461498251 :       if (TREE_OVERFLOW (t))
    9780              :         {
    9781           62 :           if (!ctx->quiet)
    9782           15 :             permerror (input_location, "overflow in constant expression");
    9783           62 :           if (!flag_permissive || ctx->quiet)
    9784           59 :             *overflow_p = true;
    9785              :         }
    9786              : 
    9787    461498251 :       if (TREE_CODE (t) == INTEGER_CST
    9788    439087869 :           && TYPE_PTR_P (TREE_TYPE (t))
    9789              :           /* INTEGER_CST with pointer-to-method type is only used
    9790              :              for a virtual method in a pointer to member function.
    9791              :              Don't reject those.  */
    9792      2123290 :           && TREE_CODE (TREE_TYPE (TREE_TYPE (t))) != METHOD_TYPE
    9793    463621217 :           && !integer_zerop (t))
    9794              :         {
    9795            6 :           if (!ctx->quiet)
    9796            0 :             error ("value %qE of type %qT is not a constant expression",
    9797            0 :                    t, TREE_TYPE (t));
    9798            6 :           *non_constant_p = true;
    9799              :         }
    9800              : 
    9801              :       return t;
    9802              :     }
    9803              : 
    9804              :   /* Avoid excessively long constexpr evaluations.  */
    9805   2555039894 :   if (++ctx->global->constexpr_ops_count >= constexpr_ops_limit)
    9806              :     {
    9807            9 :       if (!ctx->quiet)
    9808            3 :         error_at (loc,
    9809              :                   "%<constexpr%> evaluation operation count exceeds limit of "
    9810              :                   "%wd (use %<-fconstexpr-ops-limit=%> to increase the limit)",
    9811              :                   constexpr_ops_limit);
    9812            9 :       ctx->global->constexpr_ops_count = INTTYPE_MINIMUM (HOST_WIDE_INT);
    9813            9 :       *non_constant_p = true;
    9814            9 :       return t;
    9815              :     }
    9816              : 
    9817   2555039885 :   constexpr_ctx new_ctx;
    9818   2555039885 :   tree r = t;
    9819              : 
    9820   2555039885 :   tree_code tcode = TREE_CODE (t);
    9821   2555039885 :   switch (tcode)
    9822              :     {
    9823     59460720 :     case RESULT_DECL:
    9824     59460720 :       if (lval)
    9825              :         return t;
    9826              :       /* We ask for an rvalue for the RESULT_DECL when indirecting
    9827              :          through an invisible reference, or in named return value
    9828              :          optimization.  */
    9829       147136 :       if (tree v = ctx->global->get_value (t))
    9830              :         return v;
    9831              :       else
    9832              :         {
    9833            3 :           if (!ctx->quiet)
    9834            0 :             error ("%qE is not a constant expression", t);
    9835            3 :           *non_constant_p = true;
    9836              :         }
    9837            3 :       break;
    9838              : 
    9839    299246200 :     case VAR_DECL:
    9840    299246200 :       if (DECL_HAS_VALUE_EXPR_P (t))
    9841              :         {
    9842      9235502 :           if (is_normal_capture_proxy (t)
    9843      9235502 :               && current_function_decl == DECL_CONTEXT (t))
    9844              :             {
    9845              :               /* Function parms aren't constexpr within the function
    9846              :                  definition, so don't try to look at the closure.  But if the
    9847              :                  captured variable is constant, try to evaluate it directly. */
    9848       629513 :               r = DECL_CAPTURED_VARIABLE (t);
    9849              :             }
    9850              :           else
    9851      8605989 :             r = DECL_VALUE_EXPR (t);
    9852              : 
    9853      9235502 :           tree type = TREE_TYPE (t);
    9854      9235502 :           if (TYPE_REF_P (type) != TYPE_REF_P (TREE_TYPE (r)))
    9855              :             {
    9856              :               /* Adjust r to match the reference-ness of t.  */
    9857       258367 :               if (TYPE_REF_P (type))
    9858       254176 :                 r = build_address (r);
    9859              :               else
    9860         4191 :                 r = convert_from_reference (r);
    9861              :             }
    9862      9235502 :           return cxx_eval_constant_expression (ctx, r, lval, non_constant_p,
    9863      9235502 :                                                overflow_p, jump_target);
    9864              :         }
    9865              :       /* fall through */
    9866    300777514 :     case CONST_DECL:
    9867              :       /* We used to not check lval for CONST_DECL, but darwin.cc uses
    9868              :          CONST_DECL for aggregate constants.  */
    9869    300777514 :       if (lval)
    9870              :         return t;
    9871    213771013 :       else if (t == ctx->object)
    9872      1025698 :         return ctx->ctor;
    9873    212745315 :       if (VAR_P (t))
    9874              :         {
    9875    201978499 :           if (tree v = ctx->global->get_value (t))
    9876              :             {
    9877              :               r = v;
    9878              :               break;
    9879              :             }
    9880    136712974 :           if (ctx->global->is_outside_lifetime (t))
    9881              :             {
    9882          137 :               if (!ctx->quiet)
    9883           39 :                 outside_lifetime_error (loc, t);
    9884          137 :               *non_constant_p = true;
    9885          137 :               break;
    9886              :             }
    9887              :         }
    9888    147479653 :       if (ctx->manifestly_const_eval == mce_true)
    9889     92564772 :         maybe_warn_about_constant_value (loc, t);
    9890    147479653 :       if (COMPLETE_TYPE_P (TREE_TYPE (t))
    9891    147479653 :           && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
    9892              :         {
    9893              :           /* If the class is empty, we aren't actually loading anything.  */
    9894       253311 :           r = build_constructor (TREE_TYPE (t), NULL);
    9895       253311 :           TREE_CONSTANT (r) = true;
    9896              :         }
    9897    147226342 :       else if (ctx->strict)
    9898    146877256 :         r = decl_really_constant_value (t, /*unshare_p=*/false);
    9899              :       else
    9900       349086 :         r = decl_constant_value (t, /*unshare_p=*/false);
    9901    147476956 :       if (TREE_CODE (r) == TARGET_EXPR
    9902    147476956 :           && TREE_CODE (TARGET_EXPR_INITIAL (r)) == CONSTRUCTOR)
    9903            0 :         r = TARGET_EXPR_INITIAL (r);
    9904    147476956 :       if (DECL_P (r)
    9905              :           /* P2280 allows references to unknown.  */
    9906    147764923 :           && !(p2280_active_p (ctx) && VAR_P (t) && TYPE_REF_P (TREE_TYPE (t))))
    9907              :         {
    9908     34578779 :           if (!ctx->quiet)
    9909          183 :             non_const_var_error (loc, r, /*fundef_p*/false);
    9910     34578779 :           *non_constant_p = true;
    9911              :         }
    9912              :       break;
    9913              : 
    9914              :     case DEBUG_BEGIN_STMT:
    9915              :       /* ??? It might be nice to retain this information somehow, so
    9916              :          as to be able to step into a constexpr function call.  */
    9917              :       /* Fall through.  */
    9918              : 
    9919              :     case FUNCTION_DECL:
    9920              :     case TEMPLATE_DECL:
    9921              :     case LABEL_DECL:
    9922              :     case LABEL_EXPR:
    9923              :     case CASE_LABEL_EXPR:
    9924              :     case PREDICT_EXPR:
    9925              :     case OMP_DECLARE_MAPPER:
    9926              :     case REFLECT_EXPR:
    9927              :       return t;
    9928              : 
    9929    304907038 :     case PARM_DECL:
    9930    304907038 :       if (lval && !TYPE_REF_P (TREE_TYPE (t)))
    9931              :         {
    9932              :           /* glvalue use.  */
    9933     21273391 :           if (TREE_ADDRESSABLE (TREE_TYPE (t)))
    9934       219787 :             if (tree v = ctx->global->get_value (t))
    9935   2055779742 :               r = v;
    9936              :         }
    9937    283633647 :       else if (tree v = ctx->global->get_value (t))
    9938              :         {
    9939    165142711 :           r = v;
    9940    165142711 :           if (TREE_ADDRESSABLE (TREE_TYPE (t)))
    9941        11305 :             r = cxx_eval_constant_expression (ctx, r, vc_prvalue,
    9942              :                                               non_constant_p, overflow_p,
    9943              :                                               jump_target);
    9944    165142711 :           if (*jump_target)
    9945              :             return NULL_TREE;
    9946              :         }
    9947    118490936 :       else if (lval)
    9948              :         /* Defer in case this is only used for its type.  */;
    9949    118490936 :       else if (ctx->global->is_outside_lifetime (t))
    9950              :         {
    9951           18 :           if (!ctx->quiet)
    9952            6 :             outside_lifetime_error (loc, t);
    9953           18 :           *non_constant_p = true;
    9954           18 :           break;
    9955              :         }
    9956    118490918 :       else if (COMPLETE_TYPE_P (TREE_TYPE (t))
    9957    118490918 :                && is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
    9958              :         {
    9959              :           /* If the class is empty, we aren't actually loading anything.  */
    9960        41725 :           r = build_constructor (TREE_TYPE (t), NULL);
    9961        41725 :           TREE_CONSTANT (r) = true;
    9962              :         }
    9963    118449193 :       else if (p2280_active_p (ctx) && TYPE_REF_P (TREE_TYPE (t)))
    9964              :         /* P2280 allows references to unknown...  */;
    9965    118168484 :       else if (p2280_active_p (ctx) && is_this_parameter (t))
    9966              :         /* ...as well as the this pointer.  */;
    9967              :       else
    9968              :         {
    9969    117709753 :           if (!ctx->quiet)
    9970          199 :             error ("%qE is not a constant expression", t);
    9971    117709753 :           *non_constant_p = true;
    9972              :         }
    9973              :       break;
    9974              : 
    9975    206993461 :     case CALL_EXPR:
    9976    206993461 :     case AGGR_INIT_EXPR:
    9977    206993461 :       r = cxx_eval_call_expression (ctx, t, lval,
    9978              :                                     non_constant_p, overflow_p, jump_target);
    9979    206993461 :       break;
    9980              : 
    9981     21533066 :     case DECL_EXPR:
    9982     21533066 :       {
    9983     21533066 :         r = DECL_EXPR_DECL (t);
    9984     21533066 :         if (TREE_CODE (r) == USING_DECL)
    9985              :           {
    9986         9428 :             r = void_node;
    9987         9428 :             break;
    9988              :           }
    9989              : 
    9990     21523638 :         if (VAR_P (r)
    9991     21523638 :             && (TREE_STATIC (r)
    9992     21358526 :                 || (CP_DECL_THREAD_LOCAL_P (r) && !DECL_REALLY_EXTERN (r)))
    9993              :             /* Allow __FUNCTION__ etc.  */
    9994       165112 :             && !DECL_ARTIFICIAL (r)
    9995     21524535 :             && !decl_constant_var_p (r))
    9996              :           {
    9997            7 :             if (!ctx->quiet)
    9998              :               {
    9999            2 :                 if (CP_DECL_THREAD_LOCAL_P (r))
   10000            1 :                   error_at (loc, "control passes through definition of %qD "
   10001              :                                  "with thread storage duration", r);
   10002              :                 else
   10003            1 :                   error_at (loc, "control passes through definition of %qD "
   10004              :                                  "with static storage duration", r);
   10005              :               }
   10006            7 :             *non_constant_p = true;
   10007            7 :             break;
   10008              :           }
   10009              : 
   10010              :         /* make_rtl_for_nonlocal_decl could have deferred emission of
   10011              :            a local static var, but if it appears in a statement expression
   10012              :            which is constant expression evaluated to e.g. just the address
   10013              :            of the variable, its DECL_EXPR will never be seen during
   10014              :            gimple lowering's record_vars_into as the statement expression
   10015              :            will not be in the IL at all.  */
   10016     21523631 :         if (VAR_P (r)
   10017     21523631 :             && TREE_STATIC (r)
   10018       165105 :             && !DECL_REALLY_EXTERN (r)
   10019       165083 :             && DECL_FUNCTION_SCOPE_P (r)
   10020       165083 :             && !var_in_maybe_constexpr_fn (r)
   10021     21523634 :             && decl_constant_var_p (r))
   10022              :           {
   10023            3 :             varpool_node *node = varpool_node::get (r);
   10024            3 :             if (node == NULL || !node->definition)
   10025            3 :               rest_of_decl_compilation (r, 0, at_eof);
   10026              :           }
   10027              : 
   10028     42802484 :         if (AGGREGATE_TYPE_P (TREE_TYPE (r))
   10029     40142112 :             || VECTOR_TYPE_P (TREE_TYPE (r)))
   10030              :           {
   10031      2908114 :             new_ctx = *ctx;
   10032      2908114 :             new_ctx.object = r;
   10033      2908114 :             new_ctx.ctor = build_constructor (TREE_TYPE (r), NULL);
   10034      2908114 :             CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
   10035      2908114 :             ctx->global->put_value (r, new_ctx.ctor);
   10036      2908114 :             ctx = &new_ctx;
   10037              :           }
   10038              : 
   10039     21523631 :         if (tree init = DECL_INITIAL (r))
   10040              :           {
   10041     11243723 :             init = cxx_eval_constant_expression (ctx, init, vc_prvalue,
   10042              :                                                  non_constant_p, overflow_p,
   10043              :                                                  jump_target);
   10044     11243723 :             if (*jump_target)
   10045              :               return NULL_TREE;
   10046              :             /* Don't share a CONSTRUCTOR that might be changed.  */
   10047     11243723 :             init = unshare_constructor (init);
   10048              :             /* Remember that a constant object's constructor has already
   10049              :                run.  */
   10050     22487446 :             if (CLASS_TYPE_P (TREE_TYPE (r))
   10051     11793606 :                 && CP_TYPE_CONST_P (TREE_TYPE (r)))
   10052        71517 :               TREE_READONLY (init) = true;
   10053     11243723 :             ctx->global->put_value (r, init);
   10054              :           }
   10055     10279908 :         else if (ctx == &new_ctx)
   10056              :           /* We gave it a CONSTRUCTOR above.  */;
   10057              :         else
   10058      7998744 :           ctx->global->put_value (r, NULL_TREE);
   10059              :       }
   10060              :       break;
   10061              : 
   10062     27124909 :     case TARGET_EXPR:
   10063     27124909 :       {
   10064     27124909 :         tree type = TREE_TYPE (t);
   10065              : 
   10066     27124909 :         if (!literal_type_p (type))
   10067              :           {
   10068         6597 :             if (!ctx->quiet)
   10069              :               {
   10070            0 :                 auto_diagnostic_group d;
   10071            0 :                 error ("temporary of non-literal type %qT in a "
   10072              :                        "constant expression", type);
   10073            0 :                 explain_non_literal_class (type);
   10074            0 :               }
   10075         6597 :             *non_constant_p = true;
   10076     11824083 :             break;
   10077              :           }
   10078     27118312 :         gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (t));
   10079              :         /* Avoid evaluating a TARGET_EXPR more than once.  */
   10080     27118312 :         tree slot = TARGET_EXPR_SLOT (t);
   10081     27118312 :         if (tree v = ctx->global->get_value (slot))
   10082              :           {
   10083         2136 :             if (lval)
   10084     10985825 :               return slot;
   10085              :             r = v;
   10086              :             break;
   10087              :           }
   10088     27116176 :         if ((AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
   10089              :           {
   10090              :             /* We're being expanded without an explicit target, so start
   10091              :                initializing a new object; expansion with an explicit target
   10092              :                strips the TARGET_EXPR before we get here.  */
   10093     20552092 :             new_ctx = *ctx;
   10094              :             /* Link CTX to NEW_CTX so that lookup_placeholder can resolve
   10095              :                any PLACEHOLDER_EXPR within the initializer that refers to the
   10096              :                former object under construction.  */
   10097     20552092 :             new_ctx.parent = ctx;
   10098     20552092 :             new_ctx.ctor = build_constructor (type, NULL);
   10099     20552092 :             CONSTRUCTOR_NO_CLEARING (new_ctx.ctor) = true;
   10100     20552092 :             new_ctx.object = slot;
   10101     20552092 :             ctx->global->put_value (new_ctx.object, new_ctx.ctor);
   10102     20552092 :             ctx = &new_ctx;
   10103              :           }
   10104              : 
   10105              :         /* If the initializer is complex, evaluate it to initialize slot.  */
   10106     27116176 :         bool is_complex = target_expr_needs_replace (t);
   10107     27116176 :         if (is_complex)
   10108              :           /* In case no initialization actually happens, clear out any
   10109              :              void_node from a previous evaluation.  */
   10110          483 :           ctx->global->put_value (slot, NULL_TREE);
   10111              : 
   10112              :         /* Pass vc_prvalue because this indicates
   10113              :            initialization of a temporary.  */
   10114     27116176 :         r = cxx_eval_constant_expression (ctx, TARGET_EXPR_INITIAL (t),
   10115              :                                           vc_prvalue, non_constant_p,
   10116              :                                           overflow_p, jump_target);
   10117     27116176 :         if (*non_constant_p)
   10118              :           break;
   10119     15299776 :         if (ctx->save_exprs)
   10120     10140359 :           ctx->save_exprs->safe_push (slot);
   10121     15299776 :         if (*jump_target)
   10122              :           {
   10123          669 :             if (!is_complex
   10124          669 :                 && !(AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)))
   10125              :               /* If TARGET_EXPR_INITIAL throws exception and slot's value
   10126              :                  has not been changed yet, CLEANUP_POINT_EXPR handling
   10127              :                  could see there void_node from a previous evaluation
   10128              :                  and complain.  */
   10129            6 :               ctx->global->put_value (slot, NULL_TREE);
   10130              :             return NULL_TREE;
   10131              :           }
   10132     15299107 :         if (!is_complex)
   10133              :           {
   10134     15298702 :             r = unshare_constructor (r);
   10135              :             /* Adjust the type of the result to the type of the temporary.  */
   10136     15298702 :             r = adjust_temp_type (type, r);
   10137     15298702 :             ctx->global->put_value (slot, r);
   10138              :           }
   10139     15299107 :         if (TARGET_EXPR_CLEANUP (t)
   10140     15299107 :             && (!CLEANUP_EH_ONLY (t) || cxx_dialect >= cxx26))
   10141              :           {
   10142      1462256 :             ctx->global->cleanups->safe_push (TARGET_EXPR_CLEANUP (t));
   10143              :             /* Mark CLEANUP_EH_ONLY cleanups by pushing NULL_TREE after
   10144              :                them.  */
   10145      1462256 :             if (CLEANUP_EH_ONLY (t))
   10146         2156 :               ctx->global->cleanups->safe_push (NULL_TREE);
   10147              :           }
   10148     15299107 :         if (lval)
   10149              :           return slot;
   10150      4315001 :         if (is_complex)
   10151            0 :           r = ctx->global->get_value (slot);
   10152              :       }
   10153      4315001 :       break;
   10154              : 
   10155    103530518 :     case INIT_EXPR:
   10156    103530518 :     case MODIFY_EXPR:
   10157    103530518 :       gcc_assert (jump_target == NULL || *jump_target == NULL_TREE);
   10158    103530518 :       r = cxx_eval_store_expression (ctx, t, lval,
   10159              :                                      non_constant_p, overflow_p, jump_target);
   10160    103530518 :       break;
   10161              : 
   10162            0 :     case SCOPE_REF:
   10163            0 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1),
   10164              :                                         lval,
   10165              :                                         non_constant_p, overflow_p,
   10166              :                                         jump_target);
   10167            0 :       break;
   10168              : 
   10169     64414115 :     case RETURN_EXPR:
   10170     64414115 :       if (TREE_OPERAND (t, 0) != NULL_TREE)
   10171     64068720 :         r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
   10172              :                                           lval,
   10173              :                                           non_constant_p, overflow_p,
   10174              :                                           jump_target);
   10175     64414111 :       if (!throws (jump_target))
   10176     64413743 :         *jump_target = t;
   10177              :       break;
   10178        54031 :     case BREAK_STMT:
   10179        54031 :     case CONTINUE_STMT:
   10180        54031 :       *jump_target = t;
   10181        54031 :       break;
   10182              : 
   10183       966788 :     case SAVE_EXPR:
   10184              :       /* Avoid evaluating a SAVE_EXPR more than once.  */
   10185       966788 :       if (tree v = ctx->global->get_value (t))
   10186              :         r = v;
   10187              :       else
   10188              :         {
   10189       944759 :           r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
   10190              :                                             vc_prvalue, non_constant_p,
   10191              :                                             overflow_p, jump_target);
   10192       944759 :           if (*non_constant_p || *jump_target)
   10193              :             break;
   10194        12795 :           ctx->global->put_value (t, r);
   10195        12795 :           if (ctx->save_exprs)
   10196         9259 :             ctx->save_exprs->safe_push (t);
   10197              :         }
   10198              :       break;
   10199              : 
   10200     62878870 :     case NON_LVALUE_EXPR:
   10201     62878870 :     case EXPR_STMT:
   10202     62878870 :     case EH_SPEC_BLOCK:
   10203     62878870 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
   10204              :                                         lval,
   10205              :                                         non_constant_p, overflow_p,
   10206              :                                         jump_target);
   10207     62878870 :       break;
   10208              : 
   10209         9408 :     case TRY_BLOCK:
   10210         9408 :       r = cxx_eval_constant_expression (ctx, TRY_STMTS (t), lval,
   10211              :                                         non_constant_p, overflow_p,
   10212              :                                         jump_target);
   10213         9408 :       if (!*non_constant_p && throws (jump_target))
   10214         3787 :         if (tree h = TRY_HANDLERS (t))
   10215              :           {
   10216         3787 :             tree type = strip_array_types (TREE_TYPE (*jump_target));
   10217         3787 :             if (TREE_CODE (h) == STATEMENT_LIST)
   10218              :               {
   10219          938 :                 for (tree stmt : tsi_range (h))
   10220          904 :                   if (TREE_CODE (stmt) == HANDLER
   10221          904 :                       && handler_match_for_exception_type (stmt, type))
   10222              :                     {
   10223              :                       h = stmt;
   10224              :                       break;
   10225              :                     }
   10226          462 :                 if (TREE_CODE (h) == STATEMENT_LIST)
   10227              :                   h = NULL_TREE;
   10228              :               }
   10229         3325 :             else if (TREE_CODE (h) != HANDLER
   10230         3325 :                      || !handler_match_for_exception_type (h, type))
   10231              :               h = NULL_TREE;
   10232              :             if (h)
   10233              :               {
   10234         3753 :                 gcc_assert (VAR_P (*jump_target));
   10235         3753 :                 ctx->global->caught_exceptions.safe_push (*jump_target);
   10236         3753 :                 ctx->global->caught_exceptions.safe_push (HANDLER_TYPE (h));
   10237         3753 :                 *jump_target = NULL_TREE;
   10238         3753 :                 r = cxx_eval_constant_expression (ctx, HANDLER_BODY (h),
   10239              :                                                   vc_discard, non_constant_p,
   10240              :                                                   overflow_p, jump_target);
   10241              :               }
   10242              :           }
   10243              :       break;
   10244              : 
   10245     91793498 :     case CLEANUP_POINT_EXPR:
   10246     91793498 :       {
   10247     91793498 :         auto_vec<tree, 2> cleanups;
   10248     91793498 :         vec<tree> *prev_cleanups = ctx->global->cleanups;
   10249     91793498 :         ctx->global->cleanups = &cleanups;
   10250              : 
   10251     91793498 :         auto_vec<tree, 10> save_exprs;
   10252     91793498 :         constexpr_ctx new_ctx = *ctx;
   10253     91793498 :         new_ctx.save_exprs = &save_exprs;
   10254              : 
   10255     91793498 :         r = cxx_eval_constant_expression (&new_ctx, TREE_OPERAND (t, 0),
   10256              :                                           lval,
   10257              :                                           non_constant_p, overflow_p,
   10258              :                                           jump_target);
   10259              : 
   10260     91793496 :         ctx->global->cleanups = prev_cleanups;
   10261     91793496 :         unsigned int i;
   10262     91793496 :         tree cleanup, jmp_target = NULL_TREE;
   10263     91793496 :         bool eh = throws (jump_target);
   10264              :         /* Evaluate the cleanups.  */
   10265    184946758 :         FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
   10266      1359766 :           if (cleanup == NULL_TREE)
   10267              :             {
   10268              :               /* NULL_TREE cleanup is a marker that before it is
   10269              :                  CLEANUP_EH_ONLY cleanup.  Skip the cleanup before it
   10270              :                  if the body didn't throw.  */
   10271         2133 :               if (!eh)
   10272         2131 :                 --i;
   10273              :             }
   10274              :           else
   10275      1357633 :             cxx_eval_constant_expression (&new_ctx, cleanup, vc_discard,
   10276              :                                           non_constant_p, overflow_p,
   10277              :                                           &jmp_target);
   10278              : 
   10279              :         /* Forget SAVE_EXPRs and TARGET_EXPRs created by this
   10280              :            full-expression.  */
   10281    285530106 :         for (tree save_expr : save_exprs)
   10282     10149618 :           destroy_value_checked (ctx, save_expr, non_constant_p);
   10283     91793496 :         if (throws (&jmp_target))
   10284            0 :           *jump_target = jmp_target;
   10285     91793496 :       }
   10286     91793496 :       break;
   10287              : 
   10288     58908583 :     case MUST_NOT_THROW_EXPR:
   10289     58908583 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
   10290              :                                         lval,
   10291              :                                         non_constant_p, overflow_p,
   10292              :                                         jump_target);
   10293     58908581 :       if (throws (jump_target))
   10294              :         {
   10295              :           /* [except.handle]/7 - If the search for a handler exits the
   10296              :              function body of a function with a non-throwing exception
   10297              :              specification, the function std::terminate is invoked.  */
   10298           54 :           if (!ctx->quiet)
   10299              :             {
   10300           18 :               auto_diagnostic_group d;
   10301           18 :               diagnose_std_terminate (loc, ctx, *jump_target);
   10302           18 :               if (MUST_NOT_THROW_NOEXCEPT_P (t)
   10303           14 :                   && ctx->call
   10304           32 :                   && ctx->call->fundef)
   10305           14 :                 inform (loc, "uncaught exception exited from %<noexcept%> "
   10306              :                              "function %qD",
   10307              :                         ctx->call->fundef->decl);
   10308            4 :               else if (MUST_NOT_THROW_THROW_P (t))
   10309            2 :                 inform (loc, "destructor exited with an exception after "
   10310              :                              "initializing the exception object");
   10311            2 :               else if (MUST_NOT_THROW_CATCH_P (t))
   10312            2 :                 inform (loc, "constructor exited with another exception while "
   10313              :                              "entering handler");
   10314           18 :             }
   10315           54 :           *non_constant_p = true;
   10316           54 :           *jump_target = NULL_TREE;
   10317           54 :           r = NULL_TREE;
   10318              :         }
   10319              :       break;
   10320              : 
   10321            0 :     case TRY_CATCH_EXPR:
   10322            0 :       if (TREE_OPERAND (t, 0) == NULL_TREE)
   10323              :         {
   10324            0 :           r = void_node;
   10325            0 :           break;
   10326              :         }
   10327            0 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
   10328              :                                         non_constant_p, overflow_p,
   10329              :                                         jump_target);
   10330            0 :       if (!*non_constant_p && throws (jump_target))
   10331              :         {
   10332            0 :           tree jmp_target = NULL_TREE;
   10333            0 :           cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
   10334              :                                         non_constant_p, overflow_p,
   10335              :                                         &jmp_target);
   10336            0 :           r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
   10337              :                                  jmp_target);
   10338              :         }
   10339              :       break;
   10340              : 
   10341          842 :     case TRY_FINALLY_EXPR:
   10342          842 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
   10343              :                                         non_constant_p, overflow_p,
   10344              :                                         jump_target);
   10345          842 :       if (!*non_constant_p)
   10346              :         {
   10347          827 :           tree jmp_target = NULL_TREE;
   10348              :           /* Also evaluate the cleanup.  */
   10349          827 :           if (TREE_CODE (TREE_OPERAND (t, 1)) == EH_ELSE_EXPR
   10350          827 :               && throws (jump_target))
   10351            0 :             cxx_eval_constant_expression (ctx,
   10352            0 :                                           TREE_OPERAND (TREE_OPERAND (t, 1),
   10353              :                                                         1), vc_discard,
   10354              :                                           non_constant_p, overflow_p,
   10355              :                                           &jmp_target);
   10356              :           else
   10357          827 :             cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), vc_discard,
   10358              :                                           non_constant_p, overflow_p,
   10359              :                                           &jmp_target);
   10360          827 :           r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
   10361              :                                  jmp_target);
   10362              :         }
   10363              :       break;
   10364              : 
   10365            0 :     case EH_ELSE_EXPR:
   10366              :       /* Evaluate any cleanup that applies to non-EH exits.  */
   10367            0 :       cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), vc_discard,
   10368              :                                     non_constant_p, overflow_p,
   10369              :                                     jump_target);
   10370              : 
   10371              :       /* The EH path is handled in TRY_FINALLY_EXPR handling above.  */
   10372            0 :       break;
   10373              : 
   10374      3944365 :     case CLEANUP_STMT:
   10375      3944365 :       r = cxx_eval_constant_expression (ctx, CLEANUP_BODY (t), lval,
   10376              :                                         non_constant_p, overflow_p,
   10377              :                                         jump_target);
   10378      3944379 :       if ((!CLEANUP_EH_ONLY (t) || throws (jump_target)) && !*non_constant_p)
   10379              :         {
   10380      1762584 :           iloc_sentinel ils (loc);
   10381      1762584 :           tree jmp_target = NULL_TREE;
   10382              :           /* Also evaluate the cleanup.  */
   10383      1762584 :           cxx_eval_constant_expression (ctx, CLEANUP_EXPR (t), vc_discard,
   10384              :                                         non_constant_p, overflow_p,
   10385              :                                         &jmp_target);
   10386      1762584 :           r = merge_jump_target (loc, ctx, r, non_constant_p, jump_target,
   10387              :                                  jmp_target);
   10388      1762584 :         }
   10389              :       break;
   10390              : 
   10391              :       /* These differ from cxx_eval_unary_expression in that this doesn't
   10392              :          check for a constant operand or result; an address can be
   10393              :          constant without its operand being, and vice versa.  */
   10394    103846674 :     case MEM_REF:
   10395    103846674 :     case INDIRECT_REF:
   10396    103846674 :       r = cxx_eval_indirect_ref (ctx, t, lval,
   10397              :                                  non_constant_p, overflow_p,
   10398              :                                  jump_target);
   10399    103846674 :       break;
   10400              : 
   10401    101356090 :     case ADDR_EXPR:
   10402    101356090 :       {
   10403    101356090 :         tree oldop = TREE_OPERAND (t, 0);
   10404    101356090 :         tree op = cxx_eval_constant_expression (ctx, oldop, vc_glvalue,
   10405              :                                                 non_constant_p, overflow_p,
   10406              :                                                 jump_target);
   10407    101356090 :         if (*jump_target)
   10408              :           return NULL_TREE;
   10409              :         /* Don't VERIFY_CONSTANT here.  */
   10410    101356085 :         if (*non_constant_p)
   10411              :           return t;
   10412     81718208 :         gcc_checking_assert (TREE_CODE (op) != CONSTRUCTOR);
   10413              :         /* This function does more aggressive folding than fold itself.  */
   10414     81718208 :         r = build_fold_addr_expr_with_type (op, TREE_TYPE (t));
   10415     81718208 :         if (TREE_CODE (r) == ADDR_EXPR && TREE_OPERAND (r, 0) == oldop)
   10416              :           {
   10417     56642319 :             ggc_free (r);
   10418     56642319 :             return t;
   10419              :           }
   10420              :         break;
   10421              :       }
   10422              : 
   10423       856895 :     case REALPART_EXPR:
   10424       856895 :     case IMAGPART_EXPR:
   10425       856895 :       if (lval)
   10426              :         {
   10427         1386 :           r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
   10428              :                                             non_constant_p, overflow_p,
   10429              :                                             jump_target);
   10430         1386 :           if (*jump_target)
   10431              :             return NULL_TREE;
   10432         1386 :           if (r == error_mark_node)
   10433              :             ;
   10434         1386 :           else if (r == TREE_OPERAND (t, 0) || lval == vc_discard)
   10435              :             r = t;
   10436              :           else
   10437         1276 :             r = fold_build1 (TREE_CODE (t), TREE_TYPE (t), r);
   10438              :           break;
   10439              :         }
   10440              :       /* FALLTHRU */
   10441     25813295 :     case CONJ_EXPR:
   10442     25813295 :     case FIX_TRUNC_EXPR:
   10443     25813295 :     case FLOAT_EXPR:
   10444     25813295 :     case NEGATE_EXPR:
   10445     25813295 :     case ABS_EXPR:
   10446     25813295 :     case ABSU_EXPR:
   10447     25813295 :     case BIT_NOT_EXPR:
   10448     25813295 :     case TRUTH_NOT_EXPR:
   10449     25813295 :     case FIXED_CONVERT_EXPR:
   10450     25813295 :     case VEC_DUPLICATE_EXPR:
   10451     25813295 :       r = cxx_eval_unary_expression (ctx, t, lval,
   10452              :                                      non_constant_p, overflow_p,
   10453              :                                      jump_target);
   10454     25813295 :       break;
   10455              : 
   10456      9401340 :     case SIZEOF_EXPR:
   10457      9401340 :       r = fold_sizeof_expr (t);
   10458              :       /* In a template, fold_sizeof_expr may merely create a new SIZEOF_EXPR,
   10459              :          which could lead to an infinite recursion.  */
   10460      9401340 :       if (TREE_CODE (r) != SIZEOF_EXPR)
   10461      9401340 :         r = cxx_eval_constant_expression (ctx, r, lval,
   10462              :                                           non_constant_p, overflow_p,
   10463              :                                           jump_target);
   10464              :       else
   10465              :         {
   10466            0 :           *non_constant_p = true;
   10467            0 :           gcc_assert (ctx->quiet);
   10468              :         }
   10469              : 
   10470              :       break;
   10471              : 
   10472     13803720 :     case COMPOUND_EXPR:
   10473     13803720 :       {
   10474              :         /* check_return_expr sometimes wraps a TARGET_EXPR in a
   10475              :            COMPOUND_EXPR; don't get confused.  Also handle EMPTY_CLASS_EXPR
   10476              :            introduced by build_call_a.  */
   10477     13803720 :         tree op0 = TREE_OPERAND (t, 0);
   10478     13803720 :         tree op1 = TREE_OPERAND (t, 1);
   10479     13803720 :         STRIP_NOPS (op1);
   10480      5601701 :         if ((TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
   10481     16440210 :             || TREE_CODE (op1) == EMPTY_CLASS_EXPR)
   10482      6857331 :           r = cxx_eval_constant_expression (ctx, op0,
   10483              :                                             lval, non_constant_p, overflow_p,
   10484              :                                             jump_target);
   10485              :         else
   10486              :           {
   10487              :             /* Check that the LHS is constant and then discard it.  */
   10488      6946389 :             cxx_eval_constant_expression (ctx, op0, vc_discard,
   10489              :                                           non_constant_p, overflow_p,
   10490              :                                           jump_target);
   10491      6946389 :             if (*jump_target)
   10492              :               return NULL_TREE;
   10493      6939178 :             if (*non_constant_p)
   10494              :               return t;
   10495      6660177 :             op1 = TREE_OPERAND (t, 1);
   10496      6660177 :             r = cxx_eval_constant_expression (ctx, op1,
   10497              :                                               lval, non_constant_p, overflow_p,
   10498              :                                               jump_target);
   10499              :           }
   10500              :       }
   10501              :       break;
   10502              : 
   10503    112345121 :     case POINTER_PLUS_EXPR:
   10504    112345121 :     case POINTER_DIFF_EXPR:
   10505    112345121 :     case PLUS_EXPR:
   10506    112345121 :     case MINUS_EXPR:
   10507    112345121 :     case MULT_EXPR:
   10508    112345121 :     case TRUNC_DIV_EXPR:
   10509    112345121 :     case CEIL_DIV_EXPR:
   10510    112345121 :     case FLOOR_DIV_EXPR:
   10511    112345121 :     case ROUND_DIV_EXPR:
   10512    112345121 :     case TRUNC_MOD_EXPR:
   10513    112345121 :     case CEIL_MOD_EXPR:
   10514    112345121 :     case ROUND_MOD_EXPR:
   10515    112345121 :     case RDIV_EXPR:
   10516    112345121 :     case EXACT_DIV_EXPR:
   10517    112345121 :     case MIN_EXPR:
   10518    112345121 :     case MAX_EXPR:
   10519    112345121 :     case LSHIFT_EXPR:
   10520    112345121 :     case RSHIFT_EXPR:
   10521    112345121 :     case LROTATE_EXPR:
   10522    112345121 :     case RROTATE_EXPR:
   10523    112345121 :     case BIT_IOR_EXPR:
   10524    112345121 :     case BIT_XOR_EXPR:
   10525    112345121 :     case BIT_AND_EXPR:
   10526    112345121 :     case TRUTH_XOR_EXPR:
   10527    112345121 :     case LT_EXPR:
   10528    112345121 :     case LE_EXPR:
   10529    112345121 :     case GT_EXPR:
   10530    112345121 :     case GE_EXPR:
   10531    112345121 :     case EQ_EXPR:
   10532    112345121 :     case NE_EXPR:
   10533    112345121 :     case SPACESHIP_EXPR:
   10534    112345121 :     case UNORDERED_EXPR:
   10535    112345121 :     case ORDERED_EXPR:
   10536    112345121 :     case UNLT_EXPR:
   10537    112345121 :     case UNLE_EXPR:
   10538    112345121 :     case UNGT_EXPR:
   10539    112345121 :     case UNGE_EXPR:
   10540    112345121 :     case UNEQ_EXPR:
   10541    112345121 :     case LTGT_EXPR:
   10542    112345121 :     case RANGE_EXPR:
   10543    112345121 :     case COMPLEX_EXPR:
   10544    112345121 :       r = cxx_eval_binary_expression (ctx, t, lval,
   10545              :                                       non_constant_p, overflow_p,
   10546              :                                       jump_target);
   10547    112345121 :       break;
   10548              : 
   10549              :       /* fold can introduce non-IF versions of these; still treat them as
   10550              :          short-circuiting.  */
   10551     15427013 :     case TRUTH_AND_EXPR:
   10552     15427013 :     case TRUTH_ANDIF_EXPR:
   10553     15427013 :       r = cxx_eval_logical_expression (ctx, t, boolean_false_node,
   10554              :                                        boolean_true_node,
   10555              :                                        non_constant_p, overflow_p,
   10556              :                                        jump_target);
   10557     15427013 :       break;
   10558              : 
   10559      3056949 :     case TRUTH_OR_EXPR:
   10560      3056949 :     case TRUTH_ORIF_EXPR:
   10561      3056949 :       r = cxx_eval_logical_expression (ctx, t, boolean_true_node,
   10562              :                                        boolean_false_node,
   10563              :                                        non_constant_p, overflow_p,
   10564              :                                        jump_target);
   10565      3056949 :       break;
   10566              : 
   10567     15557274 :     case ARRAY_REF:
   10568     15557274 :       r = cxx_eval_array_reference (ctx, t, lval,
   10569              :                                     non_constant_p, overflow_p,
   10570              :                                     jump_target);
   10571     15557274 :       break;
   10572              : 
   10573    116103048 :     case COMPONENT_REF:
   10574    116103048 :       if (is_overloaded_fn (t))
   10575              :         {
   10576              :           /* We can only get here in checking mode via
   10577              :              build_non_dependent_expr,  because any expression that
   10578              :              calls or takes the address of the function will have
   10579              :              pulled a FUNCTION_DECL out of the COMPONENT_REF.  */
   10580            6 :           gcc_checking_assert (ctx->quiet || errorcount);
   10581            6 :           *non_constant_p = true;
   10582            6 :           return t;
   10583              :         }
   10584    116103042 :       r = cxx_eval_component_reference (ctx, t, lval,
   10585              :                                         non_constant_p, overflow_p,
   10586              :                                         jump_target);
   10587    116103042 :       break;
   10588              : 
   10589        40745 :     case BIT_FIELD_REF:
   10590        40745 :       r = cxx_eval_bit_field_ref (ctx, t, lval,
   10591              :                                   non_constant_p, overflow_p,
   10592              :                                   jump_target);
   10593        40745 :       break;
   10594              : 
   10595     39435171 :     case COND_EXPR:
   10596     39435171 :     case IF_STMT:
   10597     39435171 :       if (*jump_target)
   10598              :         {
   10599       151552 :           tree orig_jump = *jump_target;
   10600       151552 :           tree arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 1))
   10601       303104 :                       ? TREE_OPERAND (t, 1) : void_node);
   10602              :           /* When jumping to a label, the label might be either in the
   10603              :              then or else blocks, so process then block first in skipping
   10604              :              mode first, and if we are still in the skipping mode at its end,
   10605              :              process the else block too.  */
   10606       151552 :           r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
   10607              :                                             overflow_p, jump_target);
   10608              :           /* It's possible that we found the label in the then block.  But
   10609              :              it could have been followed by another jumping statement, e.g.
   10610              :              say we're looking for case 1:
   10611              :               if (cond)
   10612              :                 {
   10613              :                   // skipped statements
   10614              :                   case 1:; // clears up *jump_target
   10615              :                   return 1; // and sets it to a RETURN_EXPR
   10616              :                 }
   10617              :               else { ... }
   10618              :              in which case we need not go looking to the else block.
   10619              :              (goto is not allowed in a constexpr function.)  */
   10620       151552 :           if (*jump_target == orig_jump)
   10621              :             {
   10622       151609 :               arg = ((TREE_CODE (t) != IF_STMT || TREE_OPERAND (t, 2))
   10623       151609 :                      ? TREE_OPERAND (t, 2) : void_node);
   10624       151514 :               r = cxx_eval_constant_expression (ctx, arg, lval, non_constant_p,
   10625              :                                                 overflow_p, jump_target);
   10626              :             }
   10627              :           break;
   10628              :         }
   10629     39283619 :       r = cxx_eval_conditional_expression (ctx, t, lval,
   10630              :                                            non_constant_p, overflow_p,
   10631              :                                            jump_target);
   10632     39283619 :       break;
   10633        11755 :     case VEC_COND_EXPR:
   10634        11755 :       r = cxx_eval_vector_conditional_expression (ctx, t, non_constant_p,
   10635              :                                                   overflow_p, jump_target);
   10636        11755 :       break;
   10637              : 
   10638     23323902 :     case CONSTRUCTOR:
   10639     23323902 :       if (TREE_CONSTANT (t) && reduced_constant_expression_p (t))
   10640              :         {
   10641              :           /* Don't re-process a constant CONSTRUCTOR.  */
   10642     19936183 :           verify_constructor_flags (t);
   10643     19936183 :           if (TREE_CONSTANT (t))
   10644              :             return t;
   10645              :         }
   10646      3387719 :       if (TREE_CLOBBER_P (t))
   10647              :         {
   10648              :           /* Assignment from a clobber is handled in cxx_eval_store_expression;
   10649              :              a clobber by itself isn't a constant-expression.  */
   10650          240 :           gcc_assert (ctx->quiet);
   10651          240 :           *non_constant_p = true;
   10652          240 :           break;
   10653              :         }
   10654      3387479 :       r = cxx_eval_bare_aggregate (ctx, t, lval,
   10655              :                                    non_constant_p, overflow_p, jump_target);
   10656      3387479 :       break;
   10657              : 
   10658          790 :     case VEC_INIT_EXPR:
   10659              :       /* We can get this in a defaulted constructor for a class with a
   10660              :          non-static data member of array type.  Either the initializer will
   10661              :          be NULL, meaning default-initialization, or it will be an lvalue
   10662              :          or xvalue of the same type, meaning direct-initialization from the
   10663              :          corresponding member.  */
   10664          790 :       r = cxx_eval_vec_init (ctx, t, lval,
   10665              :                              non_constant_p, overflow_p, jump_target);
   10666          790 :       break;
   10667              : 
   10668        43640 :     case VEC_PERM_EXPR:
   10669        43640 :       r = cxx_eval_trinary_expression (ctx, t, lval,
   10670              :                                        non_constant_p, overflow_p,
   10671              :                                        jump_target);
   10672        43640 :       break;
   10673              : 
   10674            7 :     case PAREN_EXPR:
   10675            7 :       gcc_assert (!REF_PARENTHESIZED_P (t));
   10676              :       /* A PAREN_EXPR resulting from __builtin_assoc_barrier has no effect in
   10677              :          constant expressions since it's unaffected by -fassociative-math.  */
   10678            7 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
   10679              :                                         non_constant_p, overflow_p,
   10680              :                                         jump_target);
   10681            7 :       break;
   10682              : 
   10683    441298753 :     case NOP_EXPR:
   10684    441298753 :       if (REINTERPRET_CAST_P (t))
   10685              :         {
   10686          145 :           if (!ctx->quiet)
   10687            6 :             error_at (loc,
   10688              :                       "%<reinterpret_cast%> is not a constant expression");
   10689          145 :           *non_constant_p = true;
   10690          145 :           return t;
   10691              :         }
   10692              :       /* FALLTHROUGH.  */
   10693    552449496 :     case CONVERT_EXPR:
   10694    552449496 :     case VIEW_CONVERT_EXPR:
   10695    552449496 :     case UNARY_PLUS_EXPR:
   10696    552449496 :       {
   10697    552449496 :         tree oldop = TREE_OPERAND (t, 0);
   10698              : 
   10699    552449496 :         tree op = cxx_eval_constant_expression (ctx, oldop,
   10700    552449496 :                                                 VOID_TYPE_P (TREE_TYPE (t))
   10701              :                                                 ? vc_discard
   10702              :                                                 : tcode == VIEW_CONVERT_EXPR
   10703    518691037 :                                                 ? lval : vc_prvalue,
   10704              :                                                 non_constant_p, overflow_p,
   10705              :                                                 jump_target);
   10706    552446797 :         if (*jump_target)
   10707              :           return NULL_TREE;
   10708    552442781 :         if (*non_constant_p)
   10709              :           return t;
   10710    444752833 :         tree type = TREE_TYPE (t);
   10711              : 
   10712    444752833 :         if (VOID_TYPE_P (type))
   10713     32555273 :           return void_node;
   10714              : 
   10715    412197560 :         if (TREE_CODE (t) == CONVERT_EXPR
   10716     59863417 :             && ARITHMETIC_TYPE_P (type)
   10717      5076570 :             && INDIRECT_TYPE_P (TREE_TYPE (op))
   10718    412221077 :             && ctx->strict)
   10719              :           {
   10720        23422 :             if (!ctx->quiet)
   10721           54 :               error_at (loc,
   10722              :                         "conversion from pointer type %qT to arithmetic type "
   10723           54 :                         "%qT in a constant expression", TREE_TYPE (op), type);
   10724        23422 :             *non_constant_p = true;
   10725        23422 :             return t;
   10726              :           }
   10727              : 
   10728              :         /* [expr.const]: a conversion from type cv void* to a pointer-to-object
   10729              :            type cannot be part of a core constant expression as a resolution to
   10730              :            DR 1312.  */
   10731    153002839 :         if (TYPE_PTROB_P (type)
   10732    149586360 :             && TYPE_PTR_P (TREE_TYPE (op))
   10733     94673435 :             && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (op)))
   10734              :             /* Inside a call to std::construct_at,
   10735              :                std::allocator<T>::{,de}allocate, or
   10736              :                std::source_location::current, we permit casting from void*
   10737              :                because that is compiler-generated code.  */
   10738      1947250 :             && !is_std_construct_at (ctx->call)
   10739       167644 :             && !is_std_allocator_allocate_deallocate (ctx->call)
   10740    412259698 :             && !is_std_source_location_current (ctx->call))
   10741              :           {
   10742              :             /* Likewise, don't error when casting from void* when OP is
   10743              :                &heap uninit and similar.  */
   10744        85401 :             tree sop = tree_strip_nop_conversions (op);
   10745        85401 :             tree decl = NULL_TREE;
   10746        85401 :             if (TREE_CODE (sop) == ADDR_EXPR)
   10747        63221 :               decl = TREE_OPERAND (sop, 0);
   10748        63221 :             if (decl
   10749        63221 :                 && VAR_P (decl)
   10750        61793 :                 && DECL_ARTIFICIAL (decl)
   10751       124580 :                 && (DECL_NAME (decl) == heap_identifier
   10752        39408 :                     || DECL_NAME (decl) == heap_uninit_identifier
   10753         4561 :                     || DECL_NAME (decl) == heap_vec_identifier
   10754         2620 :                     || DECL_NAME (decl) == heap_vec_uninit_identifier))
   10755              :               /* OK */;
   10756              :             /* P2738 (C++26): a conversion from a prvalue P of type "pointer to
   10757              :                cv void" to a pointer-to-object type T unless P is a null
   10758              :                pointer value or points to an object whose type is similar to
   10759              :                T.  */
   10760        24453 :             else if (cxx_dialect > cxx23)
   10761              :               {
   10762        24288 :                 if (integer_zerop (sop))
   10763           30 :                   return build_int_cst (type, 0);
   10764        24258 :                 r = cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
   10765              :                                            NULL, jump_target);
   10766        24258 :                 if (*jump_target)
   10767              :                   return NULL_TREE;
   10768        24258 :                 if (r)
   10769              :                   {
   10770        24211 :                     r = build1 (ADDR_EXPR, type, r);
   10771        24211 :                     break;
   10772              :                   }
   10773           47 :                 if (!ctx->quiet)
   10774              :                   {
   10775            5 :                     gcc_assert (TREE_CODE (sop) == ADDR_EXPR);
   10776            5 :                     auto_diagnostic_group d;
   10777            5 :                     error_at (loc, "cast from %qT is not allowed in a "
   10778              :                               "constant expression because "
   10779              :                               "pointed-to type %qT is not similar to %qT",
   10780            5 :                               TREE_TYPE (op), TREE_TYPE (TREE_TYPE (sop)),
   10781            5 :                               TREE_TYPE (type));
   10782            5 :                     tree obj = build_fold_indirect_ref (sop);
   10783            5 :                     if (TREE_CODE (obj) == COMPONENT_REF)
   10784            4 :                       obj = TREE_OPERAND (obj, 1);
   10785            5 :                     if (DECL_P (obj))
   10786            5 :                       inform (DECL_SOURCE_LOCATION (obj),
   10787              :                               "pointed-to object declared here");
   10788            5 :                   }
   10789           47 :                 *non_constant_p = true;
   10790           47 :                 return t;
   10791              :               }
   10792              :             else
   10793              :               {
   10794          165 :                 if (!ctx->quiet)
   10795           26 :                   error_at (loc, "cast from %qT is not allowed in a "
   10796              :                             "constant expression before C++26",
   10797           26 :                             TREE_TYPE (op));
   10798          165 :                 *non_constant_p = true;
   10799          165 :                 return t;
   10800              :               }
   10801              :           }
   10802              : 
   10803              :         /* [expr.static.cast]/10: A prvalue of type "pointer to cv1 B", where
   10804              :            B is a class type, can be converted to a prvalue of type
   10805              :            "pointer to cv2 D", where D is a complete class derived from B, ...
   10806              :            If the prvalue of type "pointer to cv1 B" points to a B that is
   10807              :            actually a base class subobject of an object of type D, the
   10808              :            resulting pointer points to the enclosing object of type D.
   10809              :            Otherwise, the behavior is undefined.
   10810              :            Similarly [expr.static.cast]/2 for references. */
   10811    412149685 :         if (INDIRECT_TYPE_P (type)
   10812    255648903 :             && INDIRECT_TYPE_P (TREE_TYPE (op))
   10813    255513647 :             && COMPLETE_TYPE_P (TREE_TYPE (type))
   10814    252281072 :             && !integer_zerop (op)
   10815    663703702 :             && is_properly_derived_from (TREE_TYPE (type),
   10816    251554017 :                                          TREE_TYPE (TREE_TYPE (op))))
   10817              :           {
   10818        14362 :             tree sop = tree_strip_nop_conversions (op);
   10819        14362 :             if (cxx_fold_indirect_ref (ctx, loc, TREE_TYPE (type), sop,
   10820              :                                        NULL, jump_target) == NULL_TREE)
   10821              :               {
   10822          189 :                 tree dyntype = NULL_TREE;
   10823          189 :                 if (!ctx->quiet && TREE_CODE (sop) == ADDR_EXPR)
   10824              :                   {
   10825           44 :                     sop = TREE_OPERAND (sop, 0);
   10826           44 :                     while (TREE_CODE (sop) == COMPONENT_REF
   10827           59 :                            && DECL_FIELD_IS_BASE (TREE_OPERAND (sop, 1)))
   10828           15 :                       sop = TREE_OPERAND (sop, 0);
   10829           44 :                     dyntype = strip_array_types (TREE_TYPE (sop));
   10830           44 :                     if (same_type_p (dyntype, TREE_TYPE (TREE_TYPE (op))))
   10831          166 :                       dyntype = NULL_TREE;
   10832              :                   }
   10833          189 :                 if (!ctx->quiet)
   10834              :                   {
   10835           53 :                     if (dyntype)
   10836           23 :                       error_at (loc, "%qT operand (of dynamic type %qT) is "
   10837              :                                 "not a base class subobject of a %qT object",
   10838           23 :                                 TREE_TYPE (TREE_TYPE (op)), dyntype,
   10839           23 :                                 TREE_TYPE (type));
   10840              :                     else
   10841           30 :                       error_at (loc, "%qT operand is not a base class "
   10842              :                                 "subobject of a %qT object",
   10843           30 :                                 TREE_TYPE (TREE_TYPE (op)), TREE_TYPE (type));
   10844              :                   }
   10845          189 :                 *non_constant_p = true;
   10846          189 :                 return t;
   10847              :               }
   10848              :           }
   10849              : 
   10850    412149496 :         if (TREE_CODE (op) == PTRMEM_CST && !TYPE_PTRMEM_P (type))
   10851              :           {
   10852         1064 :             op = cplus_expand_constant (op);
   10853         1064 :             if (TREE_CODE (op) == PTRMEM_CST)
   10854              :               {
   10855           21 :                 if (!ctx->quiet)
   10856            3 :                   error_at (loc, "%qE is not a constant expression when the "
   10857              :                             "class %qT is still incomplete", op,
   10858            3 :                             PTRMEM_CST_CLASS (op));
   10859           21 :                 *non_constant_p = true;
   10860           21 :                 return t;
   10861              :               }
   10862              :           }
   10863              : 
   10864    412149475 :         if (TREE_CODE (op) == PTRMEM_CST && tcode == NOP_EXPR)
   10865              :           {
   10866          655 :             if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op))
   10867          655 :                 && !can_convert_qual (type, op))
   10868            6 :               op = cplus_expand_constant (op);
   10869          655 :             return cp_fold_convert (type, op);
   10870              :           }
   10871              : 
   10872    412148820 :         if (INDIRECT_TYPE_P (type) && TREE_CODE (op) == INTEGER_CST)
   10873              :           {
   10874       838502 :             if (integer_zerop (op))
   10875              :               {
   10876       781533 :                 if (TYPE_REF_P (type))
   10877              :                   {
   10878           36 :                     if (!ctx->quiet)
   10879            4 :                       error_at (loc, "dereferencing a null pointer");
   10880           36 :                     *non_constant_p = true;
   10881           36 :                     return t;
   10882              :                   }
   10883              :               }
   10884        56969 :             else if (TYPE_PTR_P (type)
   10885        56969 :                     && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
   10886              :               /* INTEGER_CST with pointer-to-method type is only used
   10887              :                  for a virtual method in a pointer to member function.
   10888              :                  Don't reject those.  */
   10889              :               ;
   10890              :             else
   10891              :               {
   10892              :                 /* This detects for example:
   10893              :                      reinterpret_cast<void*>(sizeof 0)
   10894              :                 */
   10895        56966 :                 if (!ctx->quiet)
   10896           15 :                   error_at (loc, "%<reinterpret_cast<%T>(%E)%> is not "
   10897              :                             "a constant expression",
   10898              :                             type, op);
   10899        56966 :                 *non_constant_p = true;
   10900        56966 :                 return t;
   10901              :               }
   10902              :           }
   10903              : 
   10904    412091818 :         if (INDIRECT_TYPE_P (type)
   10905    255591712 :             && TREE_CODE (op) == NOP_EXPR
   10906    122555889 :             && TREE_TYPE (op) == ptr_type_node
   10907       524568 :             && TREE_CODE (TREE_OPERAND (op, 0)) == ADDR_EXPR
   10908       521404 :             && VAR_P (TREE_OPERAND (TREE_OPERAND (op, 0), 0))
   10909    412500498 :             && (DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
   10910       408680 :                                          0)) == heap_uninit_identifier
   10911       291749 :                 || DECL_NAME (TREE_OPERAND (TREE_OPERAND (op, 0),
   10912       291749 :                                             0)) == heap_vec_uninit_identifier))
   10913              :           {
   10914       119140 :             tree var = TREE_OPERAND (TREE_OPERAND (op, 0), 0);
   10915       119140 :             tree var_size = TYPE_SIZE_UNIT (TREE_TYPE (var));
   10916       119140 :             tree elt_type = TREE_TYPE (type);
   10917       119140 :             tree cookie_size = NULL_TREE;
   10918       119140 :             tree arg_size = NULL_TREE;
   10919       119140 :             if (TREE_CODE (elt_type) == RECORD_TYPE
   10920       119140 :                 && TYPE_IDENTIFIER (elt_type) == heap_identifier)
   10921              :               {
   10922            9 :                 tree fld1 = TYPE_FIELDS (elt_type);
   10923            9 :                 tree fld2 = DECL_CHAIN (fld1);
   10924            9 :                 elt_type = TREE_TYPE (TREE_TYPE (fld2));
   10925            9 :                 cookie_size = TYPE_SIZE_UNIT (TREE_TYPE (fld1));
   10926              :               }
   10927       119140 :             DECL_NAME (var)
   10928       119140 :               = (DECL_NAME (var) == heap_uninit_identifier
   10929       119140 :                  ? heap_identifier : heap_vec_identifier);
   10930              :             /* For zero sized elt_type, try to recover how many outer_nelts
   10931              :                it should have.  */
   10932       119140 :             if ((cookie_size ? tree_int_cst_equal (var_size, cookie_size)
   10933       119131 :                              : integer_zerop (var_size))
   10934          105 :                 && !int_size_in_bytes (elt_type)
   10935            9 :                 && TREE_CODE (oldop) == CALL_EXPR
   10936       119158 :                 && call_expr_nargs (oldop) >= 1)
   10937            9 :               if (tree fun = get_function_named_in_call (oldop))
   10938            9 :                 if (cxx_replaceable_global_alloc_fn (fun)
   10939            9 :                     && IDENTIFIER_NEW_OP_P (DECL_NAME (fun)))
   10940            9 :                   arg_size = CALL_EXPR_ARG (oldop, 0);
   10941       119140 :             tree new_type
   10942       119140 :               = build_new_constexpr_heap_type (ctx, elt_type, cookie_size,
   10943              :                                                var_size, arg_size,
   10944              :                                                non_constant_p, overflow_p,
   10945              :                                                jump_target);
   10946       119140 :             if (*jump_target)
   10947              :               return NULL_TREE;
   10948       119140 :             TREE_TYPE (var) = new_type;
   10949       119140 :             TREE_TYPE (TREE_OPERAND (op, 0))
   10950       119140 :               = build_pointer_type (TREE_TYPE (var));
   10951       119140 :             if (is_std_allocator_allocate (ctx->call))
   10952              :               {
   10953              :                 /* [allocator.members]/5: This function starts the lifetime
   10954              :                    of the array object, but not that of any of the array
   10955              :                    elements.  */
   10956        82084 :                 tree ctor = build_constructor (new_type, NULL);
   10957        82084 :                 CONSTRUCTOR_NO_CLEARING (ctor) = 1;
   10958        82084 :                 CONSTRUCTOR_OMITTED_NOT_WITHIN_LIFETIME_P (ctor) = 1;
   10959        82084 :                 ctx->global->put_value (var, ctor);
   10960              :               }
   10961              :           }
   10962              : 
   10963              :         /* This can happen for std::meta::info(^^int) where the cast has no
   10964              :            meaning.  */
   10965    412091818 :         if (REFLECTION_TYPE_P (type) && REFLECT_EXPR_P (op))
   10966              :           {
   10967              :             r = op;
   10968              :             break;
   10969              :           }
   10970              : 
   10971    411983716 :         if (op == oldop && tcode != UNARY_PLUS_EXPR)
   10972              :           /* We didn't fold at the top so we could check for ptr-int
   10973              :              conversion.  */
   10974     32646389 :           return fold (t);
   10975              : 
   10976    379337327 :         tree sop;
   10977              : 
   10978              :         /* Handle an array's bounds having been deduced after we built
   10979              :            the wrapping expression.  */
   10980    379337327 :         if (same_type_ignoring_tlq_and_bounds_p (type, TREE_TYPE (op)))
   10981              :           r = op;
   10982    165142021 :         else if (sop = tree_strip_nop_conversions (op),
   10983    231406469 :                  sop != op && (same_type_ignoring_tlq_and_bounds_p
   10984     66264448 :                                (type, TREE_TYPE (sop))))
   10985              :           r = sop;
   10986    135968039 :         else if (tcode == UNARY_PLUS_EXPR)
   10987            0 :           r = fold_convert (TREE_TYPE (t), op);
   10988              :         else
   10989    135968039 :           r = fold_build1 (tcode, type, op);
   10990              : 
   10991              :         /* Conversion of an out-of-range value has implementation-defined
   10992              :            behavior; the language considers it different from arithmetic
   10993              :            overflow, which is undefined.  */
   10994    379337327 :         if (TREE_OVERFLOW_P (r) && !TREE_OVERFLOW_P (op))
   10995        13273 :           TREE_OVERFLOW (r) = false;
   10996              :       }
   10997              :       break;
   10998              : 
   10999         9741 :     case EXCESS_PRECISION_EXPR:
   11000         9741 :       {
   11001         9741 :         tree oldop = TREE_OPERAND (t, 0);
   11002              : 
   11003         9741 :         tree op = cxx_eval_constant_expression (ctx, oldop,
   11004              :                                                 lval,
   11005              :                                                 non_constant_p, overflow_p,
   11006              :                                                 jump_target);
   11007         9741 :         if (*jump_target)
   11008              :           return NULL_TREE;
   11009         9741 :         if (*non_constant_p)
   11010              :           return t;
   11011         9735 :         r = fold_convert (TREE_TYPE (t), op);
   11012         9735 :         break;
   11013              :       }
   11014              : 
   11015        64993 :     case EMPTY_CLASS_EXPR:
   11016              :       /* Handle EMPTY_CLASS_EXPR produced by build_call_a by lowering
   11017              :          it to an appropriate CONSTRUCTOR.  */
   11018        64993 :       return build_constructor (TREE_TYPE (t), NULL);
   11019              : 
   11020     48474297 :     case STATEMENT_LIST:
   11021     48474297 :       new_ctx = *ctx;
   11022     48474297 :       new_ctx.ctor = new_ctx.object = NULL_TREE;
   11023     48474297 :       return cxx_eval_statement_list (&new_ctx, t,
   11024     48474293 :                                       non_constant_p, overflow_p, jump_target);
   11025              : 
   11026     33689562 :     case BIND_EXPR:
   11027              :       /* Pre-emptively clear the vars declared by this BIND_EXPR from the value
   11028              :          map, so that when checking whether they're already destroyed later we
   11029              :          don't get confused by remnants of previous calls.  */
   11030     52988137 :       for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
   11031     19298575 :         ctx->global->clear_value (decl);
   11032     33689562 :       r = cxx_eval_constant_expression (ctx, BIND_EXPR_BODY (t),
   11033              :                                         lval,
   11034              :                                         non_constant_p, overflow_p,
   11035              :                                         jump_target);
   11036     52988133 :       for (tree decl = BIND_EXPR_VARS (t); decl; decl = DECL_CHAIN (decl))
   11037     19298573 :         destroy_value_checked (ctx, decl, non_constant_p);
   11038              :       break;
   11039              : 
   11040      8717186 :     case PREINCREMENT_EXPR:
   11041      8717186 :     case POSTINCREMENT_EXPR:
   11042      8717186 :     case PREDECREMENT_EXPR:
   11043      8717186 :     case POSTDECREMENT_EXPR:
   11044      8717186 :       return cxx_eval_increment_expression (ctx, t,
   11045              :                                             lval, non_constant_p, overflow_p,
   11046      8717186 :                                             jump_target);
   11047              : 
   11048         2182 :     case THROW_EXPR:
   11049         2182 :       if (cxx_dialect >= cxx26)
   11050         1855 :         return cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval,
   11051              :                                              non_constant_p, overflow_p,
   11052         1855 :                                              jump_target);
   11053              :       /* FALLTHROUGH */
   11054          335 :     case LAMBDA_EXPR:
   11055          335 :     case NEW_EXPR:
   11056          335 :     case VEC_NEW_EXPR:
   11057          335 :     case DELETE_EXPR:
   11058          335 :     case VEC_DELETE_EXPR:
   11059          335 :     case MODOP_EXPR:
   11060              :       /* GCC internal stuff.  */
   11061          335 :     case VA_ARG_EXPR:
   11062          335 :     case BASELINK:
   11063          335 :     case OFFSET_REF:
   11064          335 :       if (!ctx->quiet)
   11065           86 :         error_at (loc, "expression %qE is not a constant expression", t);
   11066          335 :       *non_constant_p = true;
   11067          335 :       break;
   11068              : 
   11069       406273 :     case OBJ_TYPE_REF:
   11070              :       /* Virtual function lookup.  We don't need to do anything fancy.  */
   11071       406273 :       return cxx_eval_constant_expression (ctx, OBJ_TYPE_REF_EXPR (t),
   11072              :                                            lval, non_constant_p, overflow_p,
   11073       406273 :                                            jump_target);
   11074              : 
   11075        16140 :     case PLACEHOLDER_EXPR:
   11076              :       /* Use of the value or address of the current object.  */
   11077        16140 :       if (tree ctor = lookup_placeholder (ctx, lval, TREE_TYPE (t)))
   11078              :         {
   11079        15897 :           if (TREE_CODE (ctor) == CONSTRUCTOR)
   11080              :             return ctor;
   11081              :           else
   11082        15597 :             return cxx_eval_constant_expression (ctx, ctor, lval,
   11083              :                                                  non_constant_p, overflow_p,
   11084        15597 :                                                  jump_target);
   11085              :         }
   11086              :       /* A placeholder without a referent.  We can get here when
   11087              :          checking whether NSDMIs are noexcept, or in massage_init_elt;
   11088              :          just say it's non-constant for now.  */
   11089          243 :       gcc_assert (ctx->quiet);
   11090          243 :       *non_constant_p = true;
   11091          243 :       break;
   11092              : 
   11093         6921 :     case EXIT_EXPR:
   11094         6921 :       {
   11095         6921 :         tree cond = TREE_OPERAND (t, 0);
   11096         6921 :         cond = cxx_eval_constant_expression (ctx, cond, vc_prvalue,
   11097              :                                              non_constant_p, overflow_p,
   11098              :                                              jump_target);
   11099         6921 :         if (*jump_target)
   11100              :           return NULL_TREE;
   11101         6921 :         VERIFY_CONSTANT (cond);
   11102         6921 :         if (integer_nonzerop (cond))
   11103         3385 :           *jump_target = t;
   11104              :       }
   11105              :       break;
   11106              : 
   11107           83 :     case GOTO_EXPR:
   11108           83 :       if (breaks (&TREE_OPERAND (t, 0))
   11109           83 :           || continues (&TREE_OPERAND (t, 0)))
   11110           64 :         *jump_target = TREE_OPERAND (t, 0);
   11111              :       else
   11112              :         {
   11113           19 :           if (!ctx->quiet)
   11114            1 :             error_at (loc, "%<goto%> is not a constant expression");
   11115           19 :           *non_constant_p = true;
   11116              :         }
   11117              :       break;
   11118              : 
   11119      6662927 :     case LOOP_EXPR:
   11120      6662927 :     case DO_STMT:
   11121      6662927 :     case WHILE_STMT:
   11122      6662927 :     case FOR_STMT:
   11123      6662927 :       cxx_eval_loop_expr (ctx, t,
   11124              :                           non_constant_p, overflow_p, jump_target);
   11125      6662927 :       break;
   11126              : 
   11127        50118 :     case SWITCH_EXPR:
   11128        50118 :     case SWITCH_STMT:
   11129        50118 :       cxx_eval_switch_expr (ctx, t,
   11130              :                             non_constant_p, overflow_p, jump_target);
   11131        50118 :       break;
   11132              : 
   11133          213 :     case REQUIRES_EXPR:
   11134              :       /* It's possible to get a requires-expression in a constant
   11135              :          expression. For example:
   11136              : 
   11137              :              template<typename T> concept bool C() {
   11138              :                return requires (T t) { t; };
   11139              :              }
   11140              : 
   11141              :              template<typename T> requires !C<T>() void f(T);
   11142              : 
   11143              :          Normalization leaves f with the associated constraint
   11144              :          '!requires (T t) { ... }' which is not transformed into
   11145              :          a constraint.  */
   11146          213 :       if (!processing_template_decl)
   11147          213 :         return evaluate_requires_expr (t);
   11148              :       else
   11149            0 :         *non_constant_p = true;
   11150            0 :       return t;
   11151              : 
   11152      1223590 :     case ANNOTATE_EXPR:
   11153      1223590 :       r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0),
   11154              :                                         lval,
   11155              :                                         non_constant_p, overflow_p,
   11156              :                                         jump_target);
   11157      1223590 :       break;
   11158              : 
   11159         9357 :     case USING_STMT:
   11160         9357 :       r = void_node;
   11161         9357 :       break;
   11162              : 
   11163           30 :     case ASSERTION_STMT:
   11164           30 :     case PRECONDITION_STMT:
   11165           30 :     case POSTCONDITION_STMT:
   11166           30 :       {
   11167           30 :         r = void_node;
   11168              :         /* Only record the first fail, and do not go further is the semantic
   11169              :            is 'ignore'.  */
   11170           30 :         if (*non_constant_p || ctx->global->contract_statement
   11171           60 :             || contract_ignored_p (t))
   11172              :           break;
   11173              : 
   11174           30 :         tree cond = CONTRACT_CONDITION (t);
   11175           30 :         if (!potential_rvalue_constant_expression (cond))
   11176              :           {
   11177            6 :             ctx->global->contract_statement = t;
   11178            6 :             ctx->global->contract_condition_non_const = true;
   11179            6 :             break;
   11180              :           }
   11181              : 
   11182              :         /* We need to evaluate and stash the result of this here, since whether
   11183              :            it needs to be reported (and how) depends on whether the containing
   11184              :            expression is otherwise const.  */
   11185           24 :         bool ctrct_non_const_p = false;
   11186           24 :         bool ctrct_overflow_p = false;
   11187           24 :         tree jmp_target = NULL_TREE;
   11188           24 :         constexpr_ctx new_ctx = *ctx;
   11189           24 :         new_ctx.quiet = true;
   11190              :         /* Avoid modification of existing values.  */
   11191           24 :         modifiable_tracker ms (new_ctx.global);
   11192           24 :         tree eval =
   11193           24 :           cxx_eval_constant_expression (&new_ctx, cond, vc_prvalue,
   11194              :                                         &ctrct_non_const_p,
   11195              :                                         &ctrct_overflow_p, &jmp_target);
   11196              :         /* Not a constant.  */
   11197           24 :         if (ctrct_non_const_p)
   11198              :           {
   11199            0 :             ctx->global->contract_statement = t;
   11200            0 :             ctx->global->contract_condition_non_const = true;
   11201            0 :             break;
   11202              :           }
   11203              :         /* Constant, but check failed.  */
   11204           24 :         if (integer_zerop (eval))
   11205           24 :           ctx->global->contract_statement = t;
   11206           24 :       }
   11207           24 :       break;
   11208              : 
   11209      2771600 :     case TEMPLATE_ID_EXPR:
   11210      2771600 :       {
   11211              :         /* We can evaluate template-id that refers to a concept only if
   11212              :            the template arguments are non-dependent.  */
   11213      2771600 :         gcc_assert (concept_check_p (t));
   11214              : 
   11215      2771600 :         if (!value_dependent_expression_p (t)
   11216      2771600 :             && !uid_sensitive_constexpr_evaluation_p ())
   11217      2770677 :           r = evaluate_concept_check (t);
   11218              :         else
   11219          923 :           *non_constant_p = true;
   11220              : 
   11221              :         break;
   11222              :       }
   11223              : 
   11224           51 :     case ASM_EXPR:
   11225           51 :       if (!ctx->quiet)
   11226           29 :         inline_asm_in_constexpr_error (loc, /*constexpr_fundef_p*/false);
   11227           51 :       *non_constant_p = true;
   11228           51 :       return t;
   11229              : 
   11230         4025 :     case BIT_CAST_EXPR:
   11231         4025 :       if (lval)
   11232              :         {
   11233            0 :           if (!ctx->quiet)
   11234            0 :             error_at (EXPR_LOCATION (t),
   11235              :                       "address of a call to %qs is not a constant expression",
   11236              :                       "__builtin_bit_cast");
   11237            0 :           *non_constant_p = true;
   11238            0 :           return t;
   11239              :         }
   11240         4025 :       r = cxx_eval_bit_cast (ctx, t, non_constant_p, overflow_p, jump_target);
   11241         4025 :       break;
   11242              : 
   11243            0 :     case OMP_PARALLEL:
   11244            0 :     case OMP_TASK:
   11245            0 :     case OMP_FOR:
   11246            0 :     case OMP_SIMD:
   11247            0 :     case OMP_DISTRIBUTE:
   11248            0 :     case OMP_TASKLOOP:
   11249            0 :     case OMP_LOOP:
   11250            0 :     case OMP_TEAMS:
   11251            0 :     case OMP_TARGET_DATA:
   11252            0 :     case OMP_TARGET:
   11253            0 :     case OMP_SECTIONS:
   11254            0 :     case OMP_ORDERED:
   11255            0 :     case OMP_CRITICAL:
   11256            0 :     case OMP_SINGLE:
   11257            0 :     case OMP_SCAN:
   11258            0 :     case OMP_SCOPE:
   11259            0 :     case OMP_SECTION:
   11260            0 :     case OMP_STRUCTURED_BLOCK:
   11261            0 :     case OMP_MASTER:
   11262            0 :     case OMP_MASKED:
   11263            0 :     case OMP_TASKGROUP:
   11264            0 :     case OMP_TARGET_UPDATE:
   11265            0 :     case OMP_TARGET_ENTER_DATA:
   11266            0 :     case OMP_TARGET_EXIT_DATA:
   11267            0 :     case OMP_ATOMIC:
   11268            0 :     case OMP_ATOMIC_READ:
   11269            0 :     case OMP_ATOMIC_CAPTURE_OLD:
   11270            0 :     case OMP_ATOMIC_CAPTURE_NEW:
   11271            0 :     case OMP_DEPOBJ:
   11272            0 :     case OACC_PARALLEL:
   11273            0 :     case OACC_KERNELS:
   11274            0 :     case OACC_SERIAL:
   11275            0 :     case OACC_DATA:
   11276            0 :     case OACC_HOST_DATA:
   11277            0 :     case OACC_LOOP:
   11278            0 :     case OACC_CACHE:
   11279            0 :     case OACC_DECLARE:
   11280            0 :     case OACC_ENTER_DATA:
   11281            0 :     case OACC_EXIT_DATA:
   11282            0 :     case OACC_UPDATE:
   11283            0 :       if (!ctx->quiet)
   11284            0 :         error_at (EXPR_LOCATION (t),
   11285              :                   "statement is not a constant expression");
   11286            0 :       *non_constant_p = true;
   11287            0 :       break;
   11288              : 
   11289            0 :     default:
   11290            0 :       if (STATEMENT_CODE_P (TREE_CODE (t)))
   11291              :         {
   11292              :           /* This function doesn't know how to deal with pre-genericize
   11293              :              statements; this can only happen with statement-expressions,
   11294              :              so for now just fail.  */
   11295            0 :           if (!ctx->quiet)
   11296            0 :             error_at (EXPR_LOCATION (t),
   11297              :                       "statement is not a constant expression");
   11298              :         }
   11299            0 :       else if (flag_checking)
   11300            0 :         internal_error ("unexpected expression %qE of kind %s", t,
   11301              :                         get_tree_code_name (TREE_CODE (t)));
   11302            0 :       *non_constant_p = true;
   11303            0 :       break;
   11304              :     }
   11305              : 
   11306   2055779742 :   if (r == error_mark_node)
   11307     14668302 :     *non_constant_p = true;
   11308              : 
   11309    135658028 :   if (r == void_node && lval != vc_discard && !*jump_target
   11310   2055797963 :       && !VOID_TYPE_P (TREE_TYPE (t)))
   11311              :     {
   11312              :       /* For diagnostic quality we should have handled this sooner, where we
   11313              :          can be more specific about the out-of-lifetime object.  But here we
   11314              :          can still be correct.  */
   11315            2 :       gcc_checking_assert (false);
   11316              :       if (!ctx->quiet)
   11317              :         error_at (EXPR_LOCATION (t),
   11318              :                   "%qE accesses an object outside its lifetime", t);
   11319              :       *non_constant_p = true;
   11320              :     }
   11321              : 
   11322   2055779740 :   if (*non_constant_p)
   11323              :     return t;
   11324              :   else
   11325   1632185424 :     return r;
   11326              : }
   11327              : 
   11328              : /* P0859: A function is needed for constant evaluation if it is a constexpr
   11329              :    function that is named by an expression ([basic.def.odr]) that is
   11330              :    potentially constant evaluated.
   11331              : 
   11332              :    So we need to instantiate any constexpr functions mentioned by the
   11333              :    expression even if the definition isn't needed for evaluating the
   11334              :    expression.  */
   11335              : 
   11336              : static tree
   11337    594774668 : instantiate_cx_fn_r (tree *tp, int *walk_subtrees, void */*data*/)
   11338              : {
   11339    594774668 :   if (TREE_CODE (*tp) == FUNCTION_DECL
   11340     12251919 :       && DECL_DECLARED_CONSTEXPR_P (*tp)
   11341     12114373 :       && !DECL_INITIAL (*tp)
   11342      3123082 :       && !trivial_fn_p (*tp)
   11343      3122933 :       && (DECL_TEMPLOID_INSTANTIATION (*tp) || DECL_DEFAULTED_FN (*tp))
   11344    594774668 :       && !uid_sensitive_constexpr_evaluation_p ())
   11345              :     {
   11346      3092791 :       ++function_depth;
   11347      3092791 :       if (DECL_TEMPLOID_INSTANTIATION (*tp))
   11348      3092764 :         instantiate_decl (*tp, /*defer_ok*/false, /*expl_inst*/false);
   11349              :       else
   11350           27 :         synthesize_method (*tp);
   11351      3092791 :       --function_depth;
   11352              :     }
   11353    591681877 :   else if (TREE_CODE (*tp) == CALL_EXPR
   11354    579924895 :            || TREE_CODE (*tp) == AGGR_INIT_EXPR)
   11355              :     {
   11356     12316961 :       if (EXPR_HAS_LOCATION (*tp))
   11357     12310150 :         input_location = EXPR_LOCATION (*tp);
   11358              :     }
   11359              : 
   11360    594774668 :   if (!EXPR_P (*tp))
   11361    340185604 :     *walk_subtrees = 0;
   11362              : 
   11363    594774668 :   return NULL_TREE;
   11364              : }
   11365              : 
   11366              : static void
   11367    290129718 : instantiate_constexpr_fns (tree t)
   11368              : {
   11369    290129718 :   location_t loc = input_location;
   11370    290129718 :   cp_walk_tree_without_duplicates (&t, instantiate_cx_fn_r, NULL);
   11371    290129718 :   input_location = loc;
   11372    290129718 : }
   11373              : 
   11374              : /* Look for heap variables in the expression *TP.  */
   11375              : 
   11376              : static tree
   11377       381494 : find_heap_var_refs (tree *tp, int *walk_subtrees, void */*data*/)
   11378              : {
   11379       381494 :   if (VAR_P (*tp)
   11380       381494 :       && (DECL_NAME (*tp) == heap_uninit_identifier
   11381        10173 :           || DECL_NAME (*tp) == heap_identifier
   11382         3245 :           || DECL_NAME (*tp) == heap_vec_uninit_identifier
   11383         2487 :           || DECL_NAME (*tp) == heap_vec_identifier
   11384          719 :           || DECL_NAME (*tp) == heap_deleted_identifier))
   11385              :     return *tp;
   11386              : 
   11387       267681 :   if (TYPE_P (*tp))
   11388          178 :     *walk_subtrees = 0;
   11389              :   return NULL_TREE;
   11390              : }
   11391              : 
   11392              : /* Find immediate function decls in *TP if any.  */
   11393              : 
   11394              : static tree
   11395    623180191 : find_immediate_fndecl (tree *tp, int *walk_subtrees, void */*data*/)
   11396              : {
   11397    627250917 :   if (TREE_CODE (*tp) == FUNCTION_DECL && DECL_IMMEDIATE_FUNCTION_P (*tp))
   11398              :     return *tp;
   11399    623172733 :   if (TREE_CODE (*tp) == PTRMEM_CST
   11400        29810 :       && TREE_CODE (PTRMEM_CST_MEMBER (*tp)) == FUNCTION_DECL
   11401    623201740 :       && DECL_IMMEDIATE_FUNCTION_P (PTRMEM_CST_MEMBER (*tp)))
   11402              :     return PTRMEM_CST_MEMBER (*tp);
   11403    623172628 :   if (REFLECT_EXPR_P (*tp))
   11404       103748 :     *walk_subtrees = 0;
   11405              :   return NULL_TREE;
   11406              : }
   11407              : 
   11408              : /* T has TREE_CONSTANT set but has been deemed not a valid C++ constant
   11409              :    expression.  Return a version of T that has TREE_CONSTANT cleared.  */
   11410              : 
   11411              : static tree
   11412       148463 : mark_non_constant (tree t)
   11413              : {
   11414       148463 :   gcc_checking_assert (TREE_CONSTANT (t));
   11415              : 
   11416              :   /* This isn't actually constant, so unset TREE_CONSTANT.
   11417              :      Don't clear TREE_CONSTANT on ADDR_EXPR, as the middle-end requires
   11418              :      it to be set if it is invariant address, even when it is not
   11419              :      a valid C++ constant expression.  Wrap it with a NOP_EXPR
   11420              :      instead.  */
   11421       148463 :   if (EXPR_P (t) && TREE_CODE (t) != ADDR_EXPR)
   11422       145621 :     t = copy_node (t);
   11423         2842 :   else if (TREE_CODE (t) == CONSTRUCTOR)
   11424          478 :     t = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (t), t);
   11425              :   else
   11426         2364 :     t = build_nop (TREE_TYPE (t), t);
   11427       148463 :   TREE_CONSTANT (t) = false;
   11428       148463 :   return t;
   11429              : }
   11430              : 
   11431              : /* If we have a successful constant evaluation, now check whether there is
   11432              :    a failed or non-constant contract that would invalidate this.  */
   11433              : 
   11434              : static bool
   11435    568517705 : check_for_failed_contracts (constexpr_ctx *ctx)
   11436              : {
   11437    568517705 :   constexpr_global_ctx *const global_ctx = ctx->global;
   11438    568517705 :   if (!flag_contracts || !global_ctx->contract_statement)
   11439              :     return false;
   11440              : 
   11441           30 :   location_t loc = EXPR_LOCATION (global_ctx->contract_statement);
   11442           30 :   enum diagnostics::kind kind;
   11443           30 :   bool error = false;
   11444              :   /* [intro.compliance.general]/2.3.4. */
   11445              :   /* [basic.contract.eval]/8. */
   11446           30 :   if (ctx->manifestly_const_eval != mce_true)
   11447              :     {
   11448              :       /* When !MCE, silently return not constant.  */
   11449              :       return true;
   11450              :     }
   11451           27 :   else if (contract_terminating_p (global_ctx->contract_statement))
   11452              :     {
   11453              :       kind = diagnostics::kind::error;
   11454              :       error = true;
   11455              :     }
   11456              :   else
   11457            6 :     kind = diagnostics::kind::warning;
   11458              : 
   11459              :   /* [basic.contract.eval]/7.3 */
   11460           27 :   if (global_ctx->contract_condition_non_const)
   11461              :     {
   11462            6 :       emit_diagnostic (kind, loc, 0, "contract condition is not constant");
   11463            6 :       return error;
   11464              :     }
   11465              : 
   11466              :   /* Otherwise, the evaluation was const, but determined to be false.  */
   11467           21 :   emit_diagnostic (kind, loc, 0,
   11468              :                    "contract predicate is false in constant expression");
   11469           21 :   return error;
   11470              : }
   11471              : 
   11472              : /* ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
   11473              :    STRICT has the same sense as for constant_value_1: true if we only allow
   11474              :    conforming C++ constant expressions, or false if we want a constant value
   11475              :    even if it doesn't conform.
   11476              :    MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
   11477              :    per P0595 even when ALLOW_NON_CONSTANT is true.
   11478              :    CONSTEXPR_DTOR is true when evaluating the dtor of a constexpr variable.
   11479              :    OBJECT must be non-NULL in that case.  */
   11480              : 
   11481              : static tree
   11482    578608694 : cxx_eval_outermost_constant_expr (tree t, bool allow_non_constant,
   11483              :                                   bool strict = true,
   11484              :                                   mce_value manifestly_const_eval = mce_unknown,
   11485              :                                   bool constexpr_dtor = false,
   11486              :                                   tree object = NULL_TREE)
   11487              : {
   11488    578608694 :   auto_timevar time (TV_CONSTEXPR);
   11489              : 
   11490    578608694 :   bool non_constant_p = false;
   11491    578608694 :   bool overflow_p = false;
   11492              : 
   11493    578608694 :   if (BRACE_ENCLOSED_INITIALIZER_P (t))
   11494              :     {
   11495            0 :       gcc_checking_assert (allow_non_constant);
   11496              :       return t;
   11497              :     }
   11498              : 
   11499    578608694 :   constexpr_global_ctx global_ctx;
   11500    578608694 :   constexpr_ctx ctx = { &global_ctx, NULL, NULL, NULL, NULL, NULL, NULL,
   11501              :                         allow_non_constant, strict,
   11502    578608694 :                         !allow_non_constant ? mce_true : manifestly_const_eval };
   11503              : 
   11504              :   /* Turn off -frounding-math for manifestly constant evaluation.  */
   11505    578608694 :   warning_sentinel rm (flag_rounding_math,
   11506    578608694 :                        ctx.manifestly_const_eval == mce_true);
   11507    578608694 :   tree type = (object
   11508    578608694 :                ? cv_unqualified (TREE_TYPE (object))
   11509    511854929 :                : initialized_type (t));
   11510    578608694 :   tree r = t;
   11511    578608694 :   bool is_consteval = false;
   11512    578608694 :   if (VOID_TYPE_P (type))
   11513              :     {
   11514     10083246 :       if (!constexpr_dtor)
   11515              :         {
   11516     10083246 :           if (cxx_dialect < cxx20)
   11517              :             return t;
   11518              :           /* We could have a COMPOUND_EXPR here coming from
   11519              :              keep_unused_object_arg.  */
   11520     10072196 :           tree x = extract_call_expr (t);
   11521     10072196 :           if (x == NULL_TREE || x == error_mark_node)
   11522              :             return t;
   11523              :           /* Calls to immediate functions returning void need to be
   11524              :              evaluated.  */
   11525     10072156 :           tree fndecl = cp_get_callee_fndecl_nofold (x);
   11526     20144312 :           if (fndecl == NULL_TREE || !DECL_IMMEDIATE_FUNCTION_P (fndecl))
   11527              :             return t;
   11528              :           else
   11529         1154 :             is_consteval = true;
   11530         1154 :           tree lam;
   11531         1154 :           if (manifestly_const_eval == mce_true
   11532         1693 :               && LAMBDA_FUNCTION_P (fndecl)
   11533          533 :               && (lam = CLASSTYPE_LAMBDA_EXPR (CP_DECL_CONTEXT (fndecl)))
   11534         1687 :               && LAMBDA_EXPR_CONSTEVAL_BLOCK_P (lam))
   11535          516 :             global_ctx.consteval_block = fndecl;
   11536              :         }
   11537              :     }
   11538    568525448 :   else if (cxx_dialect >= cxx20
   11539    559618969 :            && (TREE_CODE (t) == CALL_EXPR
   11540    480740069 :                || TREE_CODE (t) == AGGR_INIT_EXPR
   11541    475620248 :                || TREE_CODE (t) == TARGET_EXPR))
   11542              :     {
   11543     89462686 :       tree x = t;
   11544     89462686 :       if (TREE_CODE (x) == TARGET_EXPR)
   11545      5463965 :         x = TARGET_EXPR_INITIAL (x);
   11546     89462686 :       tree fndecl = cp_get_callee_fndecl_nofold (x);
   11547    176144771 :       if (fndecl && DECL_IMMEDIATE_FUNCTION_P (fndecl))
   11548              :         is_consteval = true;
   11549              :       /* Don't try to evaluate a std::vector constructor taking an integer, it
   11550              :          will fail in the 'if (heap_var)' block below after doing all the work
   11551              :          (c++/113835).  This will need adjustment if P3554 is accepted.  Note
   11552              :          that evaluation of e.g. the vector default constructor can succeed, so
   11553              :          we don't shortcut all vector constructors.  */
   11554    173364170 :       if (fndecl && DECL_CONSTRUCTOR_P (fndecl) && allow_non_constant
   11555     11531821 :           && is_std_class (type, "vector") && call_expr_nargs (x) > 1
   11556     89487216 :           && TREE_CODE (TREE_TYPE (get_nth_callarg (x, 1))) == INTEGER_TYPE)
   11557              :         return t;
   11558              :     }
   11559    568524555 :   if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type))
   11560              :     {
   11561              :       /* In C++14 an NSDMI can participate in aggregate initialization,
   11562              :          and can refer to the address of the object being initialized, so
   11563              :          we need to pass in the relevant VAR_DECL if we want to do the
   11564              :          evaluation in a single pass.  The evaluation will dynamically
   11565              :          update ctx.values for the VAR_DECL.  We use the same strategy
   11566              :          for C++11 constexpr constructors that refer to the object being
   11567              :          initialized.  */
   11568     49606912 :       if (constexpr_dtor)
   11569              :         {
   11570          200 :           gcc_assert (object && VAR_P (object));
   11571          200 :           gcc_assert (DECL_DECLARED_CONSTEXPR_P (object));
   11572          200 :           gcc_assert (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object));
   11573          200 :           if (error_operand_p (DECL_INITIAL (object)))
   11574              :             return t;
   11575          183 :           ctx.ctor = unshare_expr (DECL_INITIAL (object));
   11576          183 :           TREE_READONLY (ctx.ctor) = false;
   11577              :           /* Temporarily force decl_really_constant_value to return false
   11578              :              for it, we want to use ctx.ctor for the current value instead.  */
   11579          183 :           DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = false;
   11580              :         }
   11581              :       else
   11582              :         {
   11583     49606712 :           ctx.ctor = build_constructor (type, NULL);
   11584     49606712 :           CONSTRUCTOR_NO_CLEARING (ctx.ctor) = true;
   11585              :         }
   11586     49606895 :       if (!object)
   11587              :         {
   11588     21998700 :           if (TREE_CODE (t) == CALL_EXPR)
   11589              :             {
   11590              :               /* If T is calling a constructor to initialize an object, reframe
   11591              :                  it as an AGGR_INIT_EXPR to avoid trying to modify an object
   11592              :                  from outside the constant evaluation, which will fail even if
   11593              :                  the value is actually constant (is_constant_evaluated3.C).  */
   11594      9971237 :               tree fn = cp_get_callee_fndecl_nofold (t);
   11595     19942266 :               if (fn && DECL_CONSTRUCTOR_P (fn))
   11596              :                 {
   11597      4096262 :                   object = CALL_EXPR_ARG (t, 0);
   11598      4096262 :                   object = build_fold_indirect_ref (object);
   11599      4096262 :                   r = build_aggr_init_expr (type, r);
   11600              :                 }
   11601              :             }
   11602     12027463 :           else if (TREE_CODE (t) == TARGET_EXPR)
   11603      5359003 :             object = TARGET_EXPR_SLOT (t);
   11604      6668460 :           else if (TREE_CODE (t) == AGGR_INIT_EXPR)
   11605       707588 :             object = AGGR_INIT_EXPR_SLOT (t);
   11606              :         }
   11607     49606895 :       ctx.object = object;
   11608     49606895 :       if (object)
   11609     37771048 :         gcc_assert (same_type_ignoring_top_level_qualifiers_p
   11610              :                     (type, TREE_TYPE (object)));
   11611     37771048 :       if (object && DECL_P (object))
   11612     31626790 :         global_ctx.put_value (object, ctx.ctor);
   11613     49606895 :       if (TREE_CODE (r) == TARGET_EXPR)
   11614              :         /* Avoid creating another CONSTRUCTOR when we expand the
   11615              :            TARGET_EXPR.  */
   11616      5500480 :         r = TARGET_EXPR_INITIAL (r);
   11617              :     }
   11618              : 
   11619              :   /* uid_sensitive_constexpr_evaluation_value restricts warning-dependent
   11620              :      constexpr evaluation to avoid unnecessary template instantiation, and is
   11621              :      always done with mce_unknown.  But due to gaps in the restriction logic
   11622              :      we may still end up taking an evaluation path that in turn requires
   11623              :      manifestly constant evaluation, and such evaluation must not be
   11624              :      restricted since it likely has semantic consequences.
   11625              :      TODO: Remove/replace the mechanism in GCC 17.  */
   11626    568524538 :   auto uids = make_temp_override (uid_sensitive_constexpr_evaluation_value);
   11627    568524538 :   if (ctx.manifestly_const_eval == mce_true)
   11628    290129718 :     uid_sensitive_constexpr_evaluation_value = false;
   11629              : 
   11630    568524538 :   auto_vec<tree, 16> cleanups;
   11631    568524538 :   global_ctx.cleanups = &cleanups;
   11632              : 
   11633    568524538 :   if (manifestly_const_eval == mce_true)
   11634    290129718 :     instantiate_constexpr_fns (r);
   11635    568524538 :   tree jmp_target = NULL_TREE;
   11636    568524538 :   r = cxx_eval_constant_expression (&ctx, r, vc_prvalue,
   11637              :                                     &non_constant_p, &overflow_p,
   11638              :                                     &jmp_target);
   11639    568523175 :   if (throws (&jmp_target) && !non_constant_p)
   11640              :     {
   11641         1336 :       if (!ctx.quiet)
   11642          374 :         diagnose_uncaught_exception (input_location, &ctx, jmp_target);
   11643         1336 :       non_constant_p = true;
   11644         1336 :       jmp_target = NULL_TREE;
   11645         1336 :       r = t;
   11646              :     }
   11647    568520503 :   else if (!non_constant_p && jmp_target)
   11648              :     {
   11649           24 :       non_constant_p = true;
   11650           24 :       if (!ctx.quiet)
   11651              :         {
   11652            3 :           if (breaks (&jmp_target))
   11653            3 :             error ("%<break%> outside of a loop or %<switch%>");
   11654            0 :           else if (continues (&jmp_target))
   11655            0 :             error ("%<continue%> outside of a loop");
   11656            0 :           else if (returns (&jmp_target))
   11657            0 :             error ("%<return%> in a statement expression");
   11658              :           else
   11659            0 :             gcc_unreachable ();
   11660              :         }
   11661           24 :       r = t;
   11662              :     }
   11663              : 
   11664              :   /* If we got a non-simple TARGET_EXPR, the initializer was a sequence
   11665              :      of statements, and the result ought to be stored in ctx.ctor.  */
   11666    568521839 :   if (r == void_node && !constexpr_dtor && ctx.ctor)
   11667            0 :     r = ctx.ctor;
   11668              : 
   11669    568521839 :   unsigned int i;
   11670    568521839 :   tree cleanup;
   11671    568521839 :   jmp_target = NULL_TREE;
   11672              :   /* Evaluate the cleanups.  */
   11673   1137146170 :   FOR_EACH_VEC_ELT_REVERSE (cleanups, i, cleanup)
   11674       102492 :     if (cleanup == NULL_TREE)
   11675              :       /* NULL_TREE cleanup is a marker that before it is
   11676              :          CLEANUP_EH_ONLY cleanup.  Skip the cleanup before it.  */
   11677           23 :       --i;
   11678              :     else
   11679       102469 :       cxx_eval_constant_expression (&ctx, cleanup, vc_discard,
   11680              :                                     &non_constant_p, &overflow_p,
   11681              :                                     &jmp_target);
   11682    568521839 :   if (throws (&jmp_target) && !non_constant_p)
   11683              :     {
   11684            0 :       if (!ctx.quiet)
   11685            0 :         diagnose_uncaught_exception (input_location, &ctx, jmp_target);
   11686            0 :       non_constant_p = true;
   11687            0 :       r = t;
   11688              :     }
   11689              : 
   11690              :   /* Mutable logic is a bit tricky: we want to allow initialization of
   11691              :      constexpr variables with mutable members, but we can't copy those
   11692              :      members to another constexpr variable.  */
   11693    568521839 :   if (!non_constant_p
   11694    417057482 :       && TREE_CODE (r) == CONSTRUCTOR
   11695    585449045 :       && CONSTRUCTOR_MUTABLE_POISON (r))
   11696              :     {
   11697           93 :       if (!allow_non_constant)
   11698            6 :         error ("%qE is not a constant expression because it refers to "
   11699              :                "mutable subobjects of %qT", t, type);
   11700           93 :       non_constant_p = true;
   11701              :     }
   11702              : 
   11703    417057389 :   if (!non_constant_p && cxx_dialect >= cxx20
   11704    985579228 :       && !global_ctx.heap_vars.is_empty ())
   11705              :     {
   11706       124515 :       tree heap_var = cp_walk_tree_without_duplicates (&r, find_heap_var_refs,
   11707              :                                                        NULL);
   11708       124515 :       unsigned int i;
   11709       124515 :       if (heap_var)
   11710              :         {
   11711       113813 :           if (!allow_non_constant && !non_constant_p)
   11712              :             {
   11713           17 :               auto_diagnostic_group d;
   11714           17 :               if (DECL_LANG_SPECIFIC (heap_var))
   11715            4 :                 error ("%qE is not a constant expression because it refers to "
   11716              :                        "exception object allocated with "
   11717              :                        "%<__cxa_allocate_exception%>", t);
   11718              :               else
   11719           13 :                 error ("%qE is not a constant expression because it refers to "
   11720              :                        "a result of %<operator new%>", t);
   11721           17 :               inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
   11722           17 :             }
   11723       113813 :           r = t;
   11724       113813 :           non_constant_p = true;
   11725              :         }
   11726       322944 :       FOR_EACH_VEC_ELT (global_ctx.heap_vars, i, heap_var)
   11727              :         {
   11728       198429 :           if (DECL_NAME (heap_var) != heap_deleted_identifier)
   11729              :             {
   11730       114385 :               if (!allow_non_constant && !non_constant_p)
   11731              :                 {
   11732           16 :                   auto_diagnostic_group d;
   11733           16 :                   error ("%qE is not a constant expression because allocated "
   11734              :                          "storage has not been deallocated", t);
   11735           16 :                   inform (DECL_SOURCE_LOCATION (heap_var), "allocated here");
   11736           16 :                 }
   11737       114385 :               r = t;
   11738       114385 :               non_constant_p = true;
   11739              :             }
   11740              :         }
   11741              :     }
   11742              : 
   11743              :   /* Check that immediate invocation does not return an expression referencing
   11744              :      any immediate function decls.  */
   11745    568521839 :   if (!non_constant_p && cxx_dialect >= cxx20)
   11746    822459638 :     if (tree immediate_fndecl
   11747    411229819 :         = cp_walk_tree_without_duplicates (&r, find_immediate_fndecl,
   11748              :                                            NULL))
   11749              :     {
   11750         7563 :       if (!allow_non_constant && !non_constant_p)
   11751              :         {
   11752           74 :           if (is_consteval)
   11753           36 :             error_at (cp_expr_loc_or_input_loc (t),
   11754              :                       "immediate evaluation returns address of immediate "
   11755              :                       "function %qD", immediate_fndecl);
   11756              :           else
   11757           58 :             error_at (cp_expr_loc_or_input_loc (t),
   11758              :                       "constant evaluation returns address of immediate "
   11759              :                       "function %qD", immediate_fndecl);
   11760              :         }
   11761         7563 :       r = t;
   11762         7563 :       non_constant_p = true;
   11763              :     }
   11764              : 
   11765              :   /* Detect consteval-only smuggling: turning a consteval-only object
   11766              :      into one that is not.  For instance, in
   11767              :        struct B { };
   11768              :        struct D : B { info r; };
   11769              :        constexpr D d{^^::};
   11770              :        constexpr const B &b = d; // #1
   11771              :      #1 is wrong because D is a consteval-only type but B is not.  */
   11772    568521839 :   if (flag_reflection
   11773     11600417 :       && !non_constant_p
   11774      9336990 :       && object
   11775      1024462 :       && POINTER_TYPE_P (TREE_TYPE (object))
   11776         4256 :       && !consteval_only_p (object)
   11777    568525981 :       && check_out_of_consteval_use (r, /*complain=*/false))
   11778              :     {
   11779           30 :       if (!allow_non_constant)
   11780              :         {
   11781           10 :           if (TYPE_REF_P (TREE_TYPE (object)))
   11782           12 :             error_at (cp_expr_loc_or_input_loc (t),
   11783              :                       "reference into an object of consteval-only type is "
   11784              :                       "not a constant expression unless it also has "
   11785              :                       "consteval-only type");
   11786              :           else
   11787            4 :             error_at (cp_expr_loc_or_input_loc (t),
   11788              :                       "pointer into an object of consteval-only type is "
   11789              :                       "not a constant expression unless it also has "
   11790              :                       "consteval-only type");
   11791              :         }
   11792           30 :       r = t;
   11793           30 :       non_constant_p = true;
   11794              :     }
   11795              : 
   11796    568521839 :   if (!non_constant_p && !constexpr_dtor)
   11797    416935738 :     verify_constant (r, allow_non_constant, &non_constant_p, &overflow_p);
   11798              : 
   11799              :   /* After verify_constant because reduced_constant_expression_p can unset
   11800              :      CONSTRUCTOR_NO_CLEARING.  */
   11801    568521839 :   if (TREE_CODE (r) == CONSTRUCTOR && CONSTRUCTOR_NO_CLEARING (r))
   11802              :     {
   11803        69850 :       if (!allow_non_constant)
   11804           45 :         error ("%qE is not a constant expression because it refers to "
   11805              :                "an incompletely initialized variable", t);
   11806        69850 :       TREE_CONSTANT (r) = false;
   11807        69850 :       non_constant_p = true;
   11808              :     }
   11809              : 
   11810    568521839 :   if (non_constant_p)
   11811              :     /* If we saw something bad, go back to our argument.  The wrapping below is
   11812              :        only for the cases of TREE_CONSTANT argument or overflow.  */
   11813    154022990 :     r = t;
   11814              : 
   11815    568521839 :   if (!non_constant_p && overflow_p)
   11816          215 :     non_constant_p = true;
   11817              : 
   11818              :   /* Unshare the result.  */
   11819    568521839 :   bool should_unshare = true;
   11820    568521839 :   if (r == t || (TREE_CODE (t) == TARGET_EXPR
   11821      1507213 :                  && TARGET_EXPR_INITIAL (t) == r))
   11822              :     should_unshare = false;
   11823              : 
   11824    568521839 :   if (non_constant_p && !allow_non_constant)
   11825         4134 :     return error_mark_node;
   11826    568517705 :   else if (check_for_failed_contracts (&ctx))
   11827              :     {
   11828           24 :       if (manifestly_const_eval == mce_true)
   11829              :         /* If MCE, we gave a hard error and return error_mark_node.  */
   11830           21 :         return error_mark_node;
   11831              :       else
   11832              :         {
   11833              :           /* Otherwise treat it as non-constant so the violation is still
   11834              :              detectable at run-time.  */
   11835            3 :           gcc_checking_assert (allow_non_constant);
   11836              :           return t;
   11837              :         }
   11838              :     }
   11839    568517681 :   else if (non_constant_p && TREE_CONSTANT (r))
   11840       143965 :     r = mark_non_constant (r);
   11841    568373716 :   else if (non_constant_p)
   11842              :     return t;
   11843              : 
   11844    414642575 :   if (constexpr_dtor)
   11845              :     {
   11846          165 :       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (object) = true;
   11847          165 :       return r;
   11848              :     }
   11849              : 
   11850              :   /* Check we are not trying to return the wrong type.  */
   11851    414642410 :   if (!same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (r)))
   11852              :     {
   11853              :       /* If so, this is not a constant expression.  */
   11854          156 :       if (!allow_non_constant)
   11855            4 :         error ("%qE is not a constant expression because it initializes "
   11856            4 :                "a %qT rather than %qT", t, TREE_TYPE (t), type);
   11857              :       return t;
   11858              :     }
   11859              : 
   11860    414642254 :   if (should_unshare)
   11861    232675246 :     r = unshare_expr (r);
   11862              : 
   11863    414642254 :   if (TREE_CODE (r) == CONSTRUCTOR && CLASS_TYPE_P (TREE_TYPE (r)))
   11864              :     {
   11865     15974732 :       r = adjust_temp_type (type, r);
   11866     15974732 :       if (TREE_CODE (t) == TARGET_EXPR
   11867     15974732 :           && TARGET_EXPR_INITIAL (t) == r)
   11868              :         return t;
   11869     15020630 :       else if (TREE_CODE (t) == CONSTRUCTOR || TREE_CODE (t) == CALL_EXPR
   11870      2521762 :                || TREE_CODE (t) == AGGR_INIT_EXPR)
   11871              :         /* Don't add a TARGET_EXPR if our argument didn't have one.  */;
   11872       837275 :       else if (TREE_CODE (t) == TARGET_EXPR && TARGET_EXPR_CLEANUP (t))
   11873          767 :         r = get_target_expr (r);
   11874       836508 :       else if (processing_template_decl)
   11875              :         /* Don't insert TARGET_EXPR in template trees.  */
   11876              :         return r;
   11877              :       else
   11878              :         {
   11879       836505 :           r = get_target_expr (r, tf_warning_or_error | tf_no_cleanup);
   11880       836505 :           TREE_CONSTANT (r) = true;
   11881              :         }
   11882              :     }
   11883              : 
   11884    413688149 :   if (TREE_CODE (t) == TARGET_EXPR
   11885       553111 :       && TREE_CODE (r) == TARGET_EXPR)
   11886              :     {
   11887              :       /* Preserve this flag for potential_constant_expression, and the others
   11888              :          for good measure.  */
   11889       552999 :       TARGET_EXPR_ELIDING_P (r) = TARGET_EXPR_ELIDING_P (t);
   11890       552999 :       TARGET_EXPR_IMPLICIT_P (r) = TARGET_EXPR_IMPLICIT_P (t);
   11891       552999 :       TARGET_EXPR_LIST_INIT_P (r) = TARGET_EXPR_LIST_INIT_P (t);
   11892       552999 :       TARGET_EXPR_DIRECT_INIT_P (r) = TARGET_EXPR_DIRECT_INIT_P (t);
   11893              :     }
   11894              : 
   11895              :   /* Remember the original location if that wouldn't need a wrapper.  */
   11896    413688149 :   if (location_t loc = EXPR_LOCATION (t))
   11897    189597845 :     protected_set_expr_location (r, loc);
   11898              : 
   11899    413688149 :   return r;
   11900    578605995 : }
   11901              : 
   11902              : /* If T represents a constant expression returns its reduced value.
   11903              :    Otherwise return error_mark_node.  */
   11904              : 
   11905              : tree
   11906    159089996 : cxx_constant_value (tree t, tree decl /* = NULL_TREE */,
   11907              :                     tsubst_flags_t complain /* = tf_error */)
   11908              : {
   11909    159089996 :   bool sfinae = !(complain & tf_error);
   11910    159089996 :   tree r = cxx_eval_outermost_constant_expr (t, sfinae, true, mce_true, false, decl);
   11911    159089996 :   if (sfinae && !TREE_CONSTANT (r))
   11912         2685 :     r = error_mark_node;
   11913    159089996 :   return r;
   11914              : }
   11915              : 
   11916              : /* Like cxx_constant_value, but used for evaluation of constexpr destructors
   11917              :    of constexpr variables.  The actual initializer of DECL is not modified.  */
   11918              : 
   11919              : void
   11920          200 : cxx_constant_dtor (tree t, tree decl)
   11921              : {
   11922          200 :   cxx_eval_outermost_constant_expr (t, false, true, mce_true, true, decl);
   11923          200 : }
   11924              : 
   11925              : /* Helper routine for fold_simple function.  Either return simplified
   11926              :    expression T, otherwise NULL_TREE.
   11927              :    In contrast to cp_fully_fold, and to maybe_constant_value, we try to fold
   11928              :    even if we are within template-declaration.  So be careful on call, as in
   11929              :    such case types can be undefined.  */
   11930              : 
   11931              : static tree
   11932    170688289 : fold_simple_1 (tree t)
   11933              : {
   11934    170688289 :   tree op1;
   11935    170688289 :   enum tree_code code = TREE_CODE (t);
   11936              : 
   11937    170688289 :   switch (code)
   11938              :     {
   11939              :     case INTEGER_CST:
   11940              :     case REAL_CST:
   11941              :     case VECTOR_CST:
   11942              :     case FIXED_CST:
   11943              :     case COMPLEX_CST:
   11944              :       return t;
   11945              : 
   11946      1462028 :     case SIZEOF_EXPR:
   11947      1462028 :       return fold_sizeof_expr (t);
   11948              : 
   11949     40435257 :     case ABS_EXPR:
   11950     40435257 :     case ABSU_EXPR:
   11951     40435257 :     case CONJ_EXPR:
   11952     40435257 :     case REALPART_EXPR:
   11953     40435257 :     case IMAGPART_EXPR:
   11954     40435257 :     case NEGATE_EXPR:
   11955     40435257 :     case BIT_NOT_EXPR:
   11956     40435257 :     case TRUTH_NOT_EXPR:
   11957     40435257 :     case VIEW_CONVERT_EXPR:
   11958     40435257 :     CASE_CONVERT:
   11959     40435257 :     case FLOAT_EXPR:
   11960     40435257 :     case FIX_TRUNC_EXPR:
   11961     40435257 :     case FIXED_CONVERT_EXPR:
   11962     40435257 :     case ADDR_SPACE_CONVERT_EXPR:
   11963              : 
   11964     40435257 :       op1 = TREE_OPERAND (t, 0);
   11965              : 
   11966     40435257 :       t = const_unop (code, TREE_TYPE (t), op1);
   11967     40435257 :       if (!t)
   11968              :         return NULL_TREE;
   11969              : 
   11970      6121672 :       if (CONVERT_EXPR_CODE_P (code)
   11971      6121672 :           && TREE_OVERFLOW_P (t) && !TREE_OVERFLOW_P (op1))
   11972            0 :         TREE_OVERFLOW (t) = false;
   11973              :       return t;
   11974              : 
   11975              :     default:
   11976              :       return NULL_TREE;
   11977              :     }
   11978              : }
   11979              : 
   11980              : /* If T is a simple constant expression, returns its simplified value.
   11981              :    Otherwise returns T.  In contrast to maybe_constant_value we
   11982              :    simplify only few operations on constant-expressions, and we don't
   11983              :    try to simplify constexpressions.  */
   11984              : 
   11985              : tree
   11986    171458882 : fold_simple (tree t)
   11987              : {
   11988    171458882 :   if (processing_template_decl)
   11989              :     return t;
   11990              : 
   11991    170688289 :   tree r = fold_simple_1 (t);
   11992    170688289 :   if (r)
   11993    119871937 :     return r;
   11994              : 
   11995              :   return t;
   11996              : }
   11997              : 
   11998              : /* Try folding the expression T to a simple constant.
   11999              :    Returns that constant, otherwise returns T.  */
   12000              : 
   12001              : tree
   12002      1681603 : fold_to_constant (tree t)
   12003              : {
   12004      1681603 :   if (processing_template_decl)
   12005              :     return t;
   12006              : 
   12007      1584204 :   tree r = fold (t);
   12008      1584204 :   if (CONSTANT_CLASS_P (r) && !TREE_OVERFLOW (r))
   12009              :     return r;
   12010              :   else
   12011       140970 :     return t;
   12012              : }
   12013              : 
   12014              : /* If T is a constant expression, returns its reduced value.
   12015              :    Otherwise, if T does not have TREE_CONSTANT set, returns T.
   12016              :    Otherwise, returns a version of T without TREE_CONSTANT.
   12017              :    MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated
   12018              :    as per P0595.  */
   12019              : 
   12020              : static GTY((deletable)) hash_map<tree, tree> *cv_cache;
   12021              : 
   12022              : tree
   12023    869736575 : maybe_constant_value (tree t, tree decl /* = NULL_TREE */,
   12024              :                       mce_value manifestly_const_eval /* = mce_unknown */)
   12025              : {
   12026    869736575 :   tree orig_t = t;
   12027    869736575 :   tree r;
   12028              : 
   12029    869736575 :   if (EXPR_P (t) && manifestly_const_eval == mce_unknown)
   12030              :     {
   12031              :       /* Look up each operand in the cv_cache first to see if we've already
   12032              :          reduced it, and reuse that result to avoid quadratic behavior if
   12033              :          we're called when building up a large expression.  */
   12034    252199376 :       int n = cp_tree_operand_length (t);
   12035    252199376 :       tree *ops = XALLOCAVEC (tree, n);
   12036    252199376 :       bool rebuild = false;
   12037    705950935 :       for (int i = 0; i < n; ++i)
   12038              :         {
   12039    453751559 :           ops[i] = TREE_OPERAND (t, i);
   12040    938257840 :           if (tree *cached = hash_map_safe_get (cv_cache, ops[i]))
   12041     31382345 :             if (*cached != ops[i])
   12042              :               {
   12043      9807538 :                 ops[i] = *cached;
   12044      9807538 :                 rebuild = true;
   12045              :               }
   12046              :         }
   12047    252199376 :       if (rebuild)
   12048              :         {
   12049      8234324 :           t = copy_node (t);
   12050     26822074 :           for (int i = 0; i < n; ++i)
   12051     18587750 :             TREE_OPERAND (t, i) = ops[i];
   12052              :         }
   12053              :     }
   12054              : 
   12055    869736575 :   if (!is_nondependent_constant_expression (t))
   12056              :     {
   12057            0 :       if (TREE_OVERFLOW_P (t)
   12058    128883151 :           || (!processing_template_decl && TREE_CONSTANT (t)))
   12059         4498 :         t = mark_non_constant (t);
   12060    128883151 :       return t;
   12061              :     }
   12062    740853424 :   else if (CONSTANT_CLASS_P (t))
   12063              :     /* No caching or evaluation needed.  */
   12064              :     return t;
   12065              : 
   12066              :   /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
   12067              :      but at least try folding it to a simple constant.  */
   12068    339049981 :   if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
   12069       511180 :     return fold_to_constant (t);
   12070              : 
   12071    321949973 :   if (manifestly_const_eval != mce_unknown)
   12072              :     /* TODO: Extend the cache to be mce_value aware.  And if we have a
   12073              :        previously cached mce_unknown result that's TREE_CONSTANT, it means
   12074              :        the reduced value is independent of mce_value and so we should
   12075              :        be able to reuse it in the mce_true/false case.  */
   12076    173546981 :     return cxx_eval_outermost_constant_expr (t, true, true,
   12077    173544282 :                                              manifestly_const_eval, false, decl);
   12078              : 
   12079    164991820 :   if (cv_cache == NULL)
   12080       151184 :     cv_cache = hash_map<tree, tree>::create_ggc (101);
   12081    164991820 :   if (tree *cached = cv_cache->get (t))
   12082              :     {
   12083     13439962 :       r = *cached;
   12084     13439962 :       if (r != t)
   12085              :         {
   12086              :           /* Clear processing_template_decl for sake of break_out_target_exprs;
   12087              :              entries in the cv_cache are non-templated.  */
   12088      4526747 :           processing_template_decl_sentinel ptds;
   12089              : 
   12090      4526747 :           r = break_out_target_exprs (r, /*clear_loc*/true);
   12091      4526747 :           protected_set_expr_location (r, EXPR_LOCATION (t));
   12092      4526747 :         }
   12093     13439962 :       return r;
   12094              :     }
   12095              : 
   12096    151551858 :   uid_sensitive_constexpr_evaluation_checker c;
   12097    151551858 :   r = cxx_eval_outermost_constant_expr (t, true, true,
   12098              :                                         manifestly_const_eval, false, decl);
   12099    151551858 :   gcc_checking_assert (r == t
   12100              :                        || CONVERT_EXPR_P (t)
   12101              :                        || TREE_CODE (t) == VIEW_CONVERT_EXPR
   12102              :                        || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
   12103              :                        || !cp_tree_equal (r, t));
   12104    151551858 :   if (!c.evaluation_restricted_p ())
   12105    151308016 :     cv_cache->put (orig_t, r);
   12106              :   return r;
   12107              : }
   12108              : 
   12109              : /* Dispose of the whole CV_CACHE.  */
   12110              : 
   12111              : static void
   12112     41314662 : clear_cv_cache (void)
   12113              : {
   12114     41314662 :   if (cv_cache != NULL)
   12115     41000245 :     cv_cache->empty ();
   12116     41314662 : }
   12117              : 
   12118              : /* Dispose of the whole CV_CACHE and FOLD_CACHE.  */
   12119              : 
   12120              : void
   12121     41314662 : clear_cv_and_fold_caches ()
   12122              : {
   12123     41314662 :   clear_cv_cache ();
   12124     41314662 :   clear_fold_cache ();
   12125     41314662 : }
   12126              : 
   12127              : /* Internal function handling expressions in templates for
   12128              :    fold_non_dependent_expr and fold_non_dependent_init.
   12129              : 
   12130              :    If we're in a template, but T isn't value dependent, simplify
   12131              :    it.  We're supposed to treat:
   12132              : 
   12133              :      template <typename T> void f(T[1 + 1]);
   12134              :      template <typename T> void f(T[2]);
   12135              : 
   12136              :    as two declarations of the same function, for example.  */
   12137              : 
   12138              : static tree
   12139     31734084 : fold_non_dependent_expr_template (tree t, tsubst_flags_t complain,
   12140              :                                   bool manifestly_const_eval,
   12141              :                                   tree object)
   12142              : {
   12143     31734084 :   gcc_assert (processing_template_decl);
   12144              : 
   12145     31734084 :   if (is_nondependent_constant_expression (t))
   12146              :     {
   12147     17661923 :       processing_template_decl_sentinel s;
   12148     17661923 :       t = instantiate_non_dependent_expr_internal (t, complain);
   12149              : 
   12150     17661923 :       if (type_unknown_p (t) || BRACE_ENCLOSED_INITIALIZER_P (t))
   12151              :         {
   12152            0 :           if (TREE_OVERFLOW_P (t))
   12153              :             {
   12154            0 :               t = build_nop (TREE_TYPE (t), t);
   12155            0 :               TREE_CONSTANT (t) = false;
   12156              :             }
   12157              :           return t;
   12158              :         }
   12159     17661923 :       else if (CONSTANT_CLASS_P (t))
   12160              :         /* No evaluation needed.  */
   12161              :         return t;
   12162              : 
   12163              :       /* Don't constant evaluate an unevaluated non-manifestly-constant operand,
   12164              :          but at least try folding it to a simple constant.  */
   12165      4687905 :       if (cp_unevaluated_operand && !manifestly_const_eval)
   12166           89 :         return fold_to_constant (t);
   12167              : 
   12168      4687816 :       tree r = cxx_eval_outermost_constant_expr (t, true, true,
   12169              :                                                  mce_value (manifestly_const_eval),
   12170              :                                                  false, object);
   12171              :       /* cp_tree_equal looks through NOPs, so allow them.  */
   12172      4687816 :       gcc_checking_assert (r == t
   12173              :                            || CONVERT_EXPR_P (t)
   12174              :                            || TREE_CODE (t) == VIEW_CONVERT_EXPR
   12175              :                            || (TREE_CONSTANT (t) && !TREE_CONSTANT (r))
   12176              :                            || !cp_tree_equal (r, t));
   12177              :       return r;
   12178     17661923 :     }
   12179     14072161 :   else if (TREE_OVERFLOW_P (t))
   12180              :     {
   12181            0 :       t = build_nop (TREE_TYPE (t), t);
   12182            0 :       TREE_CONSTANT (t) = false;
   12183              :     }
   12184              : 
   12185              :   return t;
   12186              : }
   12187              : 
   12188              : /* Like maybe_constant_value but first fully instantiate the argument.
   12189              : 
   12190              :    Note: this is equivalent to instantiate_non_dependent_expr (t, complain)
   12191              :    followed by maybe_constant_value but is more efficient,
   12192              :    because it calls instantiation_dependent_expression_p and
   12193              :    potential_constant_expression at most once.
   12194              :    The manifestly_const_eval argument is passed to maybe_constant_value.
   12195              : 
   12196              :    Callers should generally pass their active complain, or if they are in a
   12197              :    non-template, diagnosing context, they can use the default of
   12198              :    tf_warning_or_error.  Callers that might be within a template context, don't
   12199              :    have a complain parameter, and aren't going to remember the result for long
   12200              :    (e.g. null_ptr_cst_p), can pass tf_none and deal with error_mark_node
   12201              :    appropriately.  */
   12202              : 
   12203              : tree
   12204    266005778 : fold_non_dependent_expr (tree t,
   12205              :                          tsubst_flags_t complain /* = tf_warning_or_error */,
   12206              :                          bool manifestly_const_eval /* = false */,
   12207              :                          tree object /* = NULL_TREE */)
   12208              : {
   12209    266005778 :   if (t == NULL_TREE)
   12210              :     return NULL_TREE;
   12211              : 
   12212    264877669 :   if (processing_template_decl)
   12213     30600205 :     return fold_non_dependent_expr_template (t, complain,
   12214     30600205 :                                              manifestly_const_eval, object);
   12215              : 
   12216    234277464 :   return maybe_constant_value (t, object, mce_value (manifestly_const_eval));
   12217              : }
   12218              : 
   12219              : /* Like fold_non_dependent_expr, but if EXPR couldn't be folded to a constant,
   12220              :    return the original expression.  */
   12221              : 
   12222              : tree
   12223      2403796 : maybe_fold_non_dependent_expr (tree expr,
   12224              :                                tsubst_flags_t complain/*=tf_warning_or_error*/)
   12225              : {
   12226      2403796 :   tree t = fold_non_dependent_expr (expr, complain);
   12227      2403796 :   if (t && TREE_CONSTANT (t))
   12228      1155136 :     return t;
   12229              : 
   12230              :   return expr;
   12231              : }
   12232              : 
   12233              : /* Like maybe_constant_init but first fully instantiate the argument.  */
   12234              : 
   12235              : tree
   12236     62944934 : fold_non_dependent_init (tree t,
   12237              :                          tsubst_flags_t complain /*=tf_warning_or_error*/,
   12238              :                          bool manifestly_const_eval /*=false*/,
   12239              :                          tree object /* = NULL_TREE */)
   12240              : {
   12241     62944934 :   if (t == NULL_TREE)
   12242              :     return NULL_TREE;
   12243              : 
   12244     62944934 :   if (processing_template_decl)
   12245              :     {
   12246      1133879 :       t = fold_non_dependent_expr_template (t, complain,
   12247              :                                             manifestly_const_eval, object);
   12248              :       /* maybe_constant_init does this stripping, so do it here too.  */
   12249      1133879 :       if (TREE_CODE (t) == TARGET_EXPR)
   12250              :         {
   12251         2107 :           tree init = TARGET_EXPR_INITIAL (t);
   12252         2107 :           if (TREE_CODE (init) == CONSTRUCTOR)
   12253     62944934 :             t = init;
   12254              :         }
   12255              :       return t;
   12256              :     }
   12257              : 
   12258     61811055 :   return maybe_constant_init (t, object, manifestly_const_eval);
   12259              : }
   12260              : 
   12261              : /* Like maybe_constant_value, but returns a CONSTRUCTOR directly, rather
   12262              :    than wrapped in a TARGET_EXPR.
   12263              :    ALLOW_NON_CONSTANT is false if T is required to be a constant expression.
   12264              :    MANIFESTLY_CONST_EVAL is true if T is manifestly const-evaluated as
   12265              :    per P0595 even when ALLOW_NON_CONSTANT is true.  */
   12266              : 
   12267              : static tree
   12268    175811675 : maybe_constant_init_1 (tree t, tree decl, bool allow_non_constant,
   12269              :                        mce_value manifestly_const_eval)
   12270              : {
   12271    175811675 :   if (!t)
   12272              :     return t;
   12273    175811675 :   if (TREE_CODE (t) == EXPR_STMT)
   12274          264 :     t = TREE_OPERAND (t, 0);
   12275    175811675 :   if (TREE_CODE (t) == CONVERT_EXPR
   12276    175811675 :       && VOID_TYPE_P (TREE_TYPE (t)))
   12277         2833 :     t = TREE_OPERAND (t, 0);
   12278              :   /* If the types don't match, the INIT_EXPR is initializing a subobject of
   12279              :      DECL and losing that information would cause mischief later.  */
   12280    175811675 :   if (TREE_CODE (t) == INIT_EXPR
   12281    175811675 :       && (!decl
   12282         2587 :           || same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (decl),
   12283         2587 :                                                         TREE_TYPE (t))))
   12284         1688 :     t = TREE_OPERAND (t, 1);
   12285    175811675 :   if (TREE_CODE (t) == TARGET_EXPR)
   12286      7880716 :     t = TARGET_EXPR_INITIAL (t);
   12287    175811675 :   if (!is_nondependent_static_init_expression (t))
   12288              :     /* Don't try to evaluate it.  */;
   12289    142077863 :   else if (CONSTANT_CLASS_P (t) && TREE_CODE (t) != PTRMEM_CST)
   12290              :     /* No evaluation needed.  PTRMEM_CST needs the immediate fn check.  */;
   12291              :   else
   12292              :     {
   12293              :       /* [basic.start.static] allows constant-initialization of variables with
   12294              :          static or thread storage duration even if it isn't required, but we
   12295              :          shouldn't bend the rules the same way for automatic variables.
   12296              : 
   12297              :          But still enforce the requirements of constexpr/constinit.
   12298              :          [dcl.constinit] "If a variable declared with the constinit specifier
   12299              :          has dynamic initialization, the program is ill-formed, even if the
   12300              :          implementation would perform that initialization as a static
   12301              :          initialization."  */
   12302     43353784 :       bool is_static = (decl && DECL_P (decl)
   12303    103437761 :                         && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)));
   12304              :       bool strict = (!is_static
   12305              :                      || (decl && DECL_P (decl)
   12306      3447268 :                          && (DECL_DECLARED_CONSTEXPR_P (decl)
   12307       992815 :                              || DECL_DECLARED_CONSTINIT_P (decl))));
   12308              :       if (is_static)
   12309              :         manifestly_const_eval = mce_true;
   12310              : 
   12311     65854657 :       if (cp_unevaluated_operand && manifestly_const_eval != mce_true)
   12312        89181 :         return fold_to_constant (t);
   12313              : 
   12314     65765476 :       t = cxx_eval_outermost_constant_expr (t, allow_non_constant, strict,
   12315              :                                             manifestly_const_eval,
   12316              :                                             false, decl);
   12317              :     }
   12318    175722494 :   if (TREE_CODE (t) == TARGET_EXPR)
   12319              :     {
   12320       283715 :       tree init = TARGET_EXPR_INITIAL (t);
   12321       283715 :       if (TREE_CODE (init) == CONSTRUCTOR)
   12322    175811675 :         t = init;
   12323              :     }
   12324              :   return t;
   12325              : }
   12326              : 
   12327              : /* Wrapper for maybe_constant_init_1 which permits non constants.  */
   12328              : 
   12329              : tree
   12330     96279646 : maybe_constant_init (tree t, tree decl, bool manifestly_const_eval)
   12331              : {
   12332     96279646 :   return maybe_constant_init_1 (t, decl, true, mce_value (manifestly_const_eval));
   12333              : }
   12334              : 
   12335              : tree
   12336     79529802 : maybe_constant_init (tree t, tree decl, mce_value manifestly_const_eval)
   12337              : {
   12338     79529802 :   return maybe_constant_init_1 (t, decl, true, manifestly_const_eval);
   12339              : }
   12340              : 
   12341              : /* Wrapper for maybe_constant_init_1 which does not permit non constants.  */
   12342              : 
   12343              : tree
   12344         2227 : cxx_constant_init (tree t, tree decl)
   12345              : {
   12346         2227 :   return maybe_constant_init_1 (t, decl, false, mce_true);
   12347              : }
   12348              : 
   12349              : /* Return true if CALL_EXPR T might throw during constant evaluation.  */
   12350              : 
   12351              : static bool
   12352    232137147 : callee_might_throw (tree t)
   12353              : {
   12354    232137147 :   if (cxx_dialect < cxx26 || !flag_exceptions)
   12355              :     return false;
   12356     36692915 :   tree callee = cp_get_callee (t);
   12357     36692915 :   if (callee == NULL_TREE)
   12358              :     return false;
   12359     36636167 :   tree callee_fn = cp_get_fndecl_from_callee (callee, false);
   12360     36636167 :   return (!flag_enforce_eh_specs
   12361     36636167 :           || type_dependent_expression_p (callee)
   12362     33607750 :           || !POINTER_TYPE_P (TREE_TYPE (callee))
   12363     68050805 :           || (!type_noexcept_p (TREE_TYPE (TREE_TYPE (callee)))
   12364     14779740 :               && (callee_fn == NULL_TREE || !TREE_NOTHROW (callee_fn))));
   12365              : }
   12366              : 
   12367              : #if 0
   12368              : /* FIXME see ADDR_EXPR section in potential_constant_expression_1.  */
   12369              : /* Return true if the object referred to by REF has automatic or thread
   12370              :    local storage.  */
   12371              : 
   12372              : enum { ck_ok, ck_bad, ck_unknown };
   12373              : static int
   12374              : check_automatic_or_tls (tree ref)
   12375              : {
   12376              :   machine_mode mode;
   12377              :   poly_int64 bitsize, bitpos;
   12378              :   tree offset;
   12379              :   int volatilep = 0, unsignedp = 0;
   12380              :   tree decl = get_inner_reference (ref, &bitsize, &bitpos, &offset,
   12381              :                                    &mode, &unsignedp, &volatilep, false);
   12382              :   duration_kind dk;
   12383              : 
   12384              :   /* If there isn't a decl in the middle, we don't know the linkage here,
   12385              :      and this isn't a constant expression anyway.  */
   12386              :   if (!DECL_P (decl))
   12387              :     return ck_unknown;
   12388              :   dk = decl_storage_duration (decl);
   12389              :   return (dk == dk_auto || dk == dk_thread) ? ck_bad : ck_ok;
   12390              : }
   12391              : #endif
   12392              : 
   12393              : /* Data structure for passing data from potential_constant_expression_1
   12394              :    to check_for_return_continue via cp_walk_tree.  */
   12395              : struct check_for_return_continue_data {
   12396              :   hash_set<tree> *pset;
   12397              :   tree continue_stmt;
   12398              :   tree break_stmt;
   12399              :   bool could_throw;
   12400              : };
   12401              : 
   12402              : /* Helper function for potential_constant_expression_1 SWITCH_STMT handling,
   12403              :    called through cp_walk_tree.  Return the first RETURN_EXPR found, or note
   12404              :    the first CONTINUE_STMT and/or BREAK_STMT if RETURN_EXPR is not found.
   12405              :    For C++26 also note presence of possibly throwing calls.  */
   12406              : static tree
   12407     51622841 : check_for_return_continue (tree *tp, int *walk_subtrees, void *data)
   12408              : {
   12409     51622841 :   tree t = *tp, s, b;
   12410     51622841 :   check_for_return_continue_data *d = (check_for_return_continue_data *) data;
   12411     51622841 :   switch (TREE_CODE (t))
   12412              :     {
   12413              :     case RETURN_EXPR:
   12414              :       return t;
   12415              : 
   12416           28 :     case CONTINUE_STMT:
   12417           28 :       if (d->continue_stmt == NULL_TREE)
   12418           28 :         d->continue_stmt = t;
   12419              :       break;
   12420              : 
   12421         3268 :     case BREAK_STMT:
   12422         3268 :       if (d->break_stmt == NULL_TREE)
   12423         1345 :         d->break_stmt = t;
   12424              :       break;
   12425              : 
   12426              : #define RECUR(x) \
   12427              :       if (tree r = cp_walk_tree (&x, check_for_return_continue, data,       \
   12428              :                                  d->pset))                           \
   12429              :         return r
   12430              : 
   12431              :       /* For loops, walk subtrees manually, so that continue stmts found
   12432              :          inside of the bodies of the loops are ignored.  */
   12433        42311 :     case DO_STMT:
   12434        42311 :       *walk_subtrees = 0;
   12435        42311 :       RECUR (DO_COND (t));
   12436        42311 :       s = d->continue_stmt;
   12437        42311 :       b = d->break_stmt;
   12438        42311 :       RECUR (DO_BODY (t));
   12439        42311 :       d->continue_stmt = s;
   12440        42311 :       d->break_stmt = b;
   12441        42311 :       break;
   12442              : 
   12443          123 :     case WHILE_STMT:
   12444          123 :       *walk_subtrees = 0;
   12445          123 :       RECUR (WHILE_COND_PREP (t));
   12446          123 :       RECUR (WHILE_COND (t));
   12447          123 :       s = d->continue_stmt;
   12448          123 :       b = d->break_stmt;
   12449          123 :       RECUR (WHILE_BODY (t));
   12450          109 :       d->continue_stmt = s;
   12451          109 :       d->break_stmt = b;
   12452          109 :       break;
   12453              : 
   12454          402 :     case FOR_STMT:
   12455          402 :       *walk_subtrees = 0;
   12456          402 :       RECUR (FOR_INIT_STMT (t));
   12457          402 :       RECUR (FOR_COND_PREP (t));
   12458          402 :       RECUR (FOR_COND (t));
   12459          402 :       RECUR (FOR_EXPR (t));
   12460          402 :       s = d->continue_stmt;
   12461          402 :       b = d->break_stmt;
   12462          402 :       RECUR (FOR_BODY (t));
   12463          348 :       d->continue_stmt = s;
   12464          348 :       d->break_stmt = b;
   12465          348 :       break;
   12466              : 
   12467            0 :     case RANGE_FOR_STMT:
   12468            0 :       *walk_subtrees = 0;
   12469            0 :       RECUR (RANGE_FOR_EXPR (t));
   12470            0 :       s = d->continue_stmt;
   12471            0 :       b = d->break_stmt;
   12472            0 :       RECUR (RANGE_FOR_BODY (t));
   12473            0 :       d->continue_stmt = s;
   12474            0 :       d->break_stmt = b;
   12475            0 :       break;
   12476              : 
   12477          209 :     case SWITCH_STMT:
   12478          209 :       *walk_subtrees = 0;
   12479          209 :       RECUR (SWITCH_STMT_COND (t));
   12480          209 :       b = d->break_stmt;
   12481          209 :       RECUR (SWITCH_STMT_BODY (t));
   12482          189 :       d->break_stmt = b;
   12483          189 :       break;
   12484              : #undef RECUR
   12485              : 
   12486              :     case STATEMENT_LIST:
   12487              :     case CONSTRUCTOR:
   12488              :       break;
   12489              : 
   12490      2658569 :     case AGGR_INIT_EXPR:
   12491      2658569 :     case CALL_EXPR:
   12492              :       /* In C++26 a function could throw.  */
   12493      2658569 :       if (callee_might_throw (t))
   12494       126437 :         d->could_throw = true;
   12495              :       break;
   12496              : 
   12497     47502851 :     default:
   12498     47502851 :       if (!EXPR_P (t))
   12499     14734956 :         *walk_subtrees = 0;
   12500              :       break;
   12501              :     }
   12502              : 
   12503              :   return NULL_TREE;
   12504              : }
   12505              : 
   12506              : /* Return true if T denotes a potentially constant expression.  Issue
   12507              :    diagnostic as appropriate under control of FLAGS.  If WANT_RVAL is true,
   12508              :    an lvalue-rvalue conversion is implied.  If NOW is true, we want to
   12509              :    consider the expression in the current context, independent of constexpr
   12510              :    substitution.  If FUNDEF_P is true, we're checking a constexpr function body
   12511              :    and hard errors should not be reported by constexpr_error.
   12512              : 
   12513              :    C++0x [expr.const] used to say
   12514              : 
   12515              :    6 An expression is a potential constant expression if it is
   12516              :      a constant expression where all occurrences of function
   12517              :      parameters are replaced by arbitrary constant expressions
   12518              :      of the appropriate type.
   12519              : 
   12520              :    2  A conditional expression is a constant expression unless it
   12521              :       involves one of the following as a potentially evaluated
   12522              :       subexpression (3.2), but subexpressions of logical AND (5.14),
   12523              :       logical OR (5.15), and conditional (5.16) operations that are
   12524              :       not evaluated are not considered.   */
   12525              : 
   12526              : static bool
   12527   4971433753 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
   12528              :                                  bool fundef_p, tsubst_flags_t flags,
   12529              :                                  tree *jump_target)
   12530              : {
   12531              : #define RECUR(T,RV) \
   12532              :   potential_constant_expression_1 ((T), (RV), strict, now, fundef_p, flags, \
   12533              :                                    jump_target)
   12534              : 
   12535   4971433753 :   enum { any = false, rval = true };
   12536   4971433753 :   int i;
   12537   4971433753 :   tree tmp;
   12538              : 
   12539   4971433753 :   if (t == error_mark_node)
   12540              :     return false;
   12541   4971421298 :   if (t == NULL_TREE)
   12542              :     return true;
   12543   4963232489 :   location_t loc = cp_expr_loc_or_input_loc (t);
   12544   4963232489 :   iloc_sentinel ils = loc;
   12545              : 
   12546   4963232489 :   if (*jump_target)
   12547              :     /* If we are jumping, ignore everything.  This is simpler than the
   12548              :        cxx_eval_constant_expression handling because we only need to be
   12549              :        conservatively correct, and we don't necessarily have a constant value
   12550              :        available, so we don't bother with switch tracking.  */
   12551              :     return true;
   12552              : 
   12553      2242578 :   if (TREE_THIS_VOLATILE (t) && want_rval
   12554      1267414 :       && !FUNC_OR_METHOD_TYPE_P (TREE_TYPE (t))
   12555   4953730719 :       && !NULLPTR_TYPE_P (TREE_TYPE (t)))
   12556              :     {
   12557        78758 :       if (TREE_CLOBBER_P (t))
   12558              :         {
   12559              :           /* We should have caught any clobbers in INIT/MODIFY_EXPR.  */
   12560            0 :           gcc_checking_assert (false);
   12561              :           return true;
   12562              :         }
   12563              : 
   12564        78758 :       if (flags & tf_error)
   12565           25 :         constexpr_error (loc, fundef_p, "lvalue-to-rvalue conversion of "
   12566              :                          "a volatile lvalue %qE with type %qT", t,
   12567           25 :                          TREE_TYPE (t));
   12568              :       return false;
   12569              :     }
   12570   4953573176 :   if (CONSTANT_CLASS_P (t))
   12571              :     return true;
   12572   3609799427 :   if (CODE_CONTAINS_STRUCT (TREE_CODE (t), TS_TYPED)
   12573   3609799427 :       && TREE_TYPE (t) == error_mark_node)
   12574              :     return false;
   12575              : 
   12576   3609799384 :   switch (TREE_CODE (t))
   12577              :     {
   12578              :     case FUNCTION_DECL:
   12579              :     case BASELINK:
   12580              :     case TEMPLATE_DECL:
   12581              :     case OVERLOAD:
   12582              :     case TEMPLATE_ID_EXPR:
   12583              :     case LABEL_DECL:
   12584              :     case CASE_LABEL_EXPR:
   12585              :     case PREDICT_EXPR:
   12586              :     case CONST_DECL:
   12587              :     case SIZEOF_EXPR:
   12588              :     case ALIGNOF_EXPR:
   12589              :     case OFFSETOF_EXPR:
   12590              :     case NOEXCEPT_EXPR:
   12591              :     case TEMPLATE_PARM_INDEX:
   12592              :     case TRAIT_EXPR:
   12593              :     case IDENTIFIER_NODE:
   12594              :     case USERDEF_LITERAL:
   12595              :       /* We can see a FIELD_DECL in a pointer-to-member expression.  */
   12596              :     case FIELD_DECL:
   12597              :     case RESULT_DECL:
   12598              :     case USING_DECL:
   12599              :     case USING_STMT:
   12600              :     case PLACEHOLDER_EXPR:
   12601              :     case REQUIRES_EXPR:
   12602              :     case STATIC_ASSERT:
   12603              :     case DEBUG_BEGIN_STMT:
   12604              :     case REFLECT_EXPR:
   12605              :       return true;
   12606              : 
   12607     24993874 :     case RETURN_EXPR:
   12608     24993874 :       if (!RECUR (TREE_OPERAND (t, 0), any))
   12609              :         return false;
   12610              :       /* FALLTHROUGH */
   12611              : 
   12612     24825783 :     case BREAK_STMT:
   12613     24825783 :     case CONTINUE_STMT:
   12614     24825783 :       *jump_target = t;
   12615     24825783 :       return true;
   12616              : 
   12617    395375434 :     case PARM_DECL:
   12618    395375434 :       if (now && want_rval)
   12619              :         {
   12620    101578608 :           tree type = TREE_TYPE (t);
   12621    101578608 :           if (dependent_type_p (type)
   12622     72583936 :               || !COMPLETE_TYPE_P (processing_template_decl
   12623              :                                    ? type : complete_type (type))
   12624    174162544 :               || is_really_empty_class (type, /*ignore_vptr*/false))
   12625              :             /* An empty class has no data to read.  */
   12626              :             return true;
   12627     72583230 :           if (flags & tf_error)
   12628           19 :             constexpr_error (input_location, fundef_p,
   12629              :                              "%qE is not a constant expression", t);
   12630              :           return false;
   12631              :         }
   12632              :       return true;
   12633              : 
   12634    286486040 :     case AGGR_INIT_EXPR:
   12635    286486040 :     case CALL_EXPR:
   12636              :       /* -- an invocation of a function other than a constexpr function
   12637              :             or a constexpr constructor.  */
   12638    286486040 :       {
   12639    286486040 :         tree fun = get_function_named_in_call (t);
   12640    286486040 :         const int nargs = call_expr_nargs (t);
   12641    286486040 :         i = 0;
   12642              : 
   12643    286486040 :         if (fun == NULL_TREE)
   12644              :           {
   12645              :             /* Reset to allow the function to continue past the end
   12646              :                of the block below.  Otherwise return early.  */
   12647       427271 :             bool bail = true;
   12648              : 
   12649       427271 :             if (TREE_CODE (t) == CALL_EXPR
   12650       427271 :                 && CALL_EXPR_FN (t) == NULL_TREE)
   12651       427271 :               switch (CALL_EXPR_IFN (t))
   12652              :                 {
   12653              :                 /* These should be ignored, they are optimized away from
   12654              :                    constexpr functions.  */
   12655              :                 case IFN_UBSAN_NULL:
   12656              :                 case IFN_UBSAN_BOUNDS:
   12657              :                 case IFN_UBSAN_VPTR:
   12658              :                 case IFN_FALLTHROUGH:
   12659              :                 case IFN_ASSUME:
   12660              :                   return true;
   12661              : 
   12662              :                 case IFN_ADD_OVERFLOW:
   12663              :                 case IFN_SUB_OVERFLOW:
   12664              :                 case IFN_MUL_OVERFLOW:
   12665              :                 case IFN_LAUNDER:
   12666              :                 case IFN_VEC_CONVERT:
   12667              :                 case IFN_BSWAP:
   12668              :                 case IFN_BITREVERSE:
   12669              :                   bail = false;
   12670              :                   break;
   12671              : 
   12672              :                 default:
   12673              :                   break;
   12674              :                 }
   12675              : 
   12676              :             if (bail)
   12677              :               {
   12678              :                 /* fold_call_expr can't do anything with IFN calls.  */
   12679          172 :                 if (flags & tf_error)
   12680            0 :                   constexpr_error (loc, fundef_p,
   12681              :                                    "call to internal function %qE", t);
   12682              :                 return false;
   12683              :               }
   12684              :           }
   12685              : 
   12686    286058769 :         if (fun && is_overloaded_fn (fun))
   12687              :           {
   12688    267175130 :             if (!RECUR (fun, true))
   12689              :               return false;
   12690    266749229 :             fun = get_fns (fun);
   12691              : 
   12692    266749229 :             if (TREE_CODE (fun) == FUNCTION_DECL)
   12693              :               {
   12694    248787105 :                 if (builtin_valid_in_constant_expr_p (fun))
   12695              :                   return true;
   12696    246962861 :                 if (!maybe_constexpr_fn (fun)
   12697              :                     /* Allow any built-in function; if the expansion
   12698              :                        isn't constant, we'll deal with that then.  */
   12699     55452823 :                     && !fndecl_built_in_p (fun)
   12700              :                     /* In C++20, replaceable global allocation functions
   12701              :                        are constant expressions.  */
   12702     37823282 :                     && (!cxx_replaceable_global_alloc_fn (fun)
   12703       993086 :                         || TREE_CODE (t) != CALL_EXPR
   12704       993086 :                         || (!CALL_FROM_NEW_OR_DELETE_P (t)
   12705       362790 :                             && (current_function_decl == NULL_TREE
   12706       362790 :                                 || !is_std_allocator_allocate_deallocate
   12707       362790 :                                                 (current_function_decl))))
   12708              :                     /* Allow placement new in std::construct_at.  */
   12709     36837262 :                     && (!cxx_placement_new_fn (fun)
   12710       403009 :                         || TREE_CODE (t) != CALL_EXPR
   12711       403009 :                         || current_function_decl == NULL_TREE
   12712       402997 :                         || !is_std_construct_at (current_function_decl))
   12713     36564824 :                     && !cxx_dynamic_cast_fn_p (fun)
   12714    283524074 :                     && !cxx_cxa_builtin_fn_p (fun))
   12715              :                   {
   12716              :                     /* In C++26 evaluation of the function arguments might
   12717              :                        throw and in that case it is irrelevant whether
   12718              :                        fun is constexpr or not.  */
   12719     36508381 :                     if (cxx_dialect >= cxx26)
   12720      8061981 :                       for (; i < nargs; ++i)
   12721              :                         {
   12722      4838123 :                           tree x = get_nth_callarg (t, i);
   12723      4838123 :                           bool rv = processing_template_decl ? any : rval;
   12724      4838123 :                           bool sub_now = false;
   12725      4838123 :                           if (!potential_constant_expression_1 (x, rv, strict,
   12726              :                                                                 sub_now,
   12727              :                                                                 fundef_p,
   12728              :                                                                 flags,
   12729              :                                                                 jump_target))
   12730              :                             return false;
   12731      4550312 :                           if (throws (jump_target))
   12732              :                             return true;
   12733              :                         }
   12734     36191310 :                     if ((flags & tf_error)
   12735     36191310 :                         && constexpr_error (loc, fundef_p,
   12736              :                                             "call to non-%<constexpr%> "
   12737              :                                             "function %qD", fun))
   12738          272 :                       explain_invalid_constexpr_fn (fun);
   12739              :                     return false;
   12740              :                   }
   12741              :               }
   12742              : 
   12743    228416604 :             fun = OVL_FIRST (fun);
   12744              :             /* Skip initial arguments to base constructors.  */
   12745    228416604 :             if (DECL_BASE_CONSTRUCTOR_P (fun))
   12746      4182562 :               i = num_artificial_parms_for (fun);
   12747              :           }
   12748     18883639 :         else if (fun)
   12749              :           {
   12750     18883639 :             if (TREE_TYPE (fun)
   12751     18883639 :                 && FUNCTION_POINTER_TYPE_P (TREE_TYPE (fun)))
   12752              :               want_rval = rval;
   12753              :             else
   12754              :               want_rval = any;
   12755     18883639 :             if (RECUR (fun, want_rval))
   12756              :               /* Might end up being a constant function pointer.  But it
   12757              :                  could also be a function object with constexpr op(), so
   12758              :                  we pass 'any' so that the underlying VAR_DECL is deemed
   12759              :                  as potentially-constant even though it wasn't declared
   12760              :                  constexpr.  */;
   12761              :             else
   12762              :               return false;
   12763              :           }
   12764    548954504 :         for (; i < nargs; ++i)
   12765              :           {
   12766    319420904 :             tree x = get_nth_callarg (t, i);
   12767              :             /* In a template, reference arguments haven't been converted to
   12768              :                REFERENCE_TYPE and we might not even know if the parameter
   12769              :                is a reference, so accept lvalue constants too.  */
   12770    319420904 :             bool rv = processing_template_decl ? any : rval;
   12771              :             /* Don't require an immediately constant value, as constexpr
   12772              :                substitution might not use the value of the argument.  */
   12773    319420904 :             bool sub_now = false;
   12774    319420904 :             if (!potential_constant_expression_1 (x, rv, strict,
   12775              :                                                   sub_now, fundef_p, flags,
   12776              :                                                   jump_target))
   12777              :               return false;
   12778   3234435181 :             if (throws (jump_target))
   12779              :               return true;
   12780              :           }
   12781              :         /* In C++26 a function could throw.  */
   12782    229533600 :         if (*jump_target == NULL_TREE && callee_might_throw (t))
   12783     11624615 :           *jump_target = void_node;
   12784              :         return true;
   12785              :       }
   12786              : 
   12787    203569263 :     case NON_LVALUE_EXPR:
   12788              :       /* -- an lvalue-to-rvalue conversion (4.1) unless it is applied to
   12789              :             -- an lvalue of integral type that refers to a non-volatile
   12790              :                const variable or static data member initialized with
   12791              :                constant expressions, or
   12792              : 
   12793              :             -- an lvalue of literal type that refers to non-volatile
   12794              :                object defined with constexpr, or that refers to a
   12795              :                sub-object of such an object;  */
   12796    203569263 :       return RECUR (TREE_OPERAND (t, 0), rval);
   12797              : 
   12798        71291 :     case EXCESS_PRECISION_EXPR:
   12799        71291 :       return RECUR (TREE_OPERAND (t, 0), rval);
   12800              : 
   12801    315819031 :     case VAR_DECL:
   12802    315819031 :       if (DECL_HAS_VALUE_EXPR_P (t))
   12803              :         {
   12804      5240931 :           if (now && is_normal_capture_proxy (t))
   12805              :             {
   12806              :               /* -- in a lambda-expression, a reference to this or to a
   12807              :                  variable with automatic storage duration defined outside that
   12808              :                  lambda-expression, where the reference would be an
   12809              :                  odr-use.  */
   12810              : 
   12811       471187 :               if (want_rval)
   12812              :                 /* Since we're doing an lvalue-rvalue conversion, this might
   12813              :                    not be an odr-use, so evaluate the variable directly. */
   12814       464220 :                 return RECUR (DECL_CAPTURED_VARIABLE (t), rval);
   12815              : 
   12816         6967 :               if (flags & tf_error)
   12817              :                 {
   12818            3 :                   tree cap = DECL_CAPTURED_VARIABLE (t);
   12819            3 :                   auto_diagnostic_group d;
   12820            3 :                   if (constexpr_error (input_location, fundef_p,
   12821              :                                        "lambda capture of %qE is not a "
   12822              :                                        "constant expression", cap)
   12823            3 :                       && decl_constant_var_p (cap))
   12824            3 :                     inform (input_location, "because it is used as a glvalue");
   12825            3 :                 }
   12826              :               return false;
   12827              :             }
   12828      4769744 :           tree ve = DECL_VALUE_EXPR (t);
   12829              :           /* Treat __PRETTY_FUNCTION__ inside a template function as
   12830              :              potentially-constant.  */
   12831      4769744 :           if (DECL_PRETTY_FUNCTION_P (t) && ve == error_mark_node)
   12832              :             return true;
   12833      4769739 :           if (DECL_DECOMPOSITION_P (t) && TREE_CODE (ve) == TREE_VEC)
   12834         2736 :             return RECUR (TREE_VEC_ELT (ve, 0), rval);
   12835      4767003 :           return RECUR (ve, rval);
   12836              :         }
   12837    310578100 :       if (want_rval
   12838    219446310 :           && (now || !var_in_maybe_constexpr_fn (t))
   12839    200023293 :           && !type_dependent_expression_p (t)
   12840    168104817 :           && !decl_maybe_constant_var_p (t)
   12841     55128858 :           && !is_local_temp (t)
   12842     54553424 :           && (strict
   12843      4115744 :               || !CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (t))
   12844      1635792 :               || (DECL_INITIAL (t)
   12845      1166364 :                   && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (t)))
   12846     54044881 :           && COMPLETE_TYPE_P (TREE_TYPE (t))
   12847    364622829 :           && !is_really_empty_class (TREE_TYPE (t), /*ignore_vptr*/false))
   12848              :         {
   12849     54039898 :           if (flags & tf_error)
   12850          171 :             non_const_var_error (loc, t, fundef_p);
   12851              :           return false;
   12852              :         }
   12853              :       return true;
   12854              : 
   12855    449714767 :     case NOP_EXPR:
   12856    449714767 :       if (REINTERPRET_CAST_P (t))
   12857              :         {
   12858       163487 :           if (flags & tf_error)
   12859           49 :             constexpr_error (loc, fundef_p, "%<reinterpret_cast%> is not a "
   12860              :                              "constant expression");
   12861              :           return false;
   12862              :         }
   12863              :       /* FALLTHRU */
   12864    905246588 :     case CONVERT_EXPR:
   12865    905246588 :     case VIEW_CONVERT_EXPR:
   12866              :       /* -- a reinterpret_cast.  FIXME not implemented, and this rule
   12867              :          may change to something more specific to type-punning (DR 1312).  */
   12868    905246588 :       {
   12869    905246588 :         tree from = TREE_OPERAND (t, 0);
   12870    905246588 :         if (location_wrapper_p (t))
   12871    371526362 :           return (RECUR (from, want_rval));
   12872    533720226 :         if (INDIRECT_TYPE_P (TREE_TYPE (t)))
   12873              :           {
   12874    304369200 :             STRIP_ANY_LOCATION_WRAPPER (from);
   12875    304369200 :             if (TREE_CODE (from) == INTEGER_CST
   12876    304369200 :                 && !integer_zerop (from))
   12877              :               {
   12878         1629 :                 if (flags & tf_error)
   12879           28 :                   constexpr_error (loc, fundef_p,
   12880              :                                    "%<reinterpret_cast%> from integer to "
   12881              :                                    "pointer");
   12882              :                 return false;
   12883              :               }
   12884              :           }
   12885    533718597 :         return (RECUR (from, TREE_CODE (t) != VIEW_CONVERT_EXPR));
   12886              :       }
   12887              : 
   12888        12973 :     case ADDRESSOF_EXPR:
   12889              :       /* This is like ADDR_EXPR, except it won't form pointer-to-member.  */
   12890        12973 :       t = TREE_OPERAND (t, 0);
   12891        12973 :       goto handle_addr_expr;
   12892              : 
   12893    100727132 :     case ADDR_EXPR:
   12894              :       /* -- a unary operator & that is applied to an lvalue that
   12895              :             designates an object with thread or automatic storage
   12896              :             duration;  */
   12897    100727132 :       t = TREE_OPERAND (t, 0);
   12898              : 
   12899    100727132 :       if (TREE_CODE (t) == OFFSET_REF && PTRMEM_OK_P (t))
   12900              :         /* A pointer-to-member constant.  */
   12901              :         return true;
   12902              : 
   12903    100739839 :     handle_addr_expr:
   12904              : #if 0
   12905              :       /* FIXME adjust when issue 1197 is fully resolved.  For now don't do
   12906              :          any checking here, as we might dereference the pointer later.  If
   12907              :          we remove this code, also remove check_automatic_or_tls.  */
   12908              :       i = check_automatic_or_tls (t);
   12909              :       if (i == ck_ok)
   12910              :         return true;
   12911              :       if (i == ck_bad)
   12912              :         {
   12913              :           if (flags & tf_error)
   12914              :             error ("address-of an object %qE with thread local or "
   12915              :                    "automatic storage is not a constant expression", t);
   12916              :           return false;
   12917              :         }
   12918              : #endif
   12919    100739839 :       return RECUR (t, any);
   12920              : 
   12921    107557270 :     case COMPONENT_REF:
   12922    107557270 :     case ARROW_EXPR:
   12923    107557270 :     case OFFSET_REF:
   12924              :       /* -- a class member access unless its postfix-expression is
   12925              :             of literal type or of pointer to literal type.  */
   12926              :       /* This test would be redundant, as it follows from the
   12927              :          postfix-expression being a potential constant expression.  */
   12928    107557270 :       if (type_unknown_p (t))
   12929              :         return true;
   12930     99567194 :       if (is_overloaded_fn (t))
   12931              :         /* In a template, a COMPONENT_REF of a function expresses ob.fn(),
   12932              :            which uses ob as an lvalue.  */
   12933    102084510 :         want_rval = false;
   12934    102084510 :       gcc_fallthrough ();
   12935              : 
   12936    102084510 :     case REALPART_EXPR:
   12937    102084510 :     case IMAGPART_EXPR:
   12938    102084510 :     case BIT_FIELD_REF:
   12939    102084510 :       return RECUR (TREE_OPERAND (t, 0), want_rval);
   12940              : 
   12941       295649 :     case EXPR_PACK_EXPANSION:
   12942       295649 :       return RECUR (PACK_EXPANSION_PATTERN (t), want_rval);
   12943              : 
   12944              :     case PACK_INDEX_EXPR:
   12945              :       return true;
   12946              : 
   12947    113225020 :     case INDIRECT_REF:
   12948    113225020 :       return RECUR (TREE_OPERAND (t, 0), rval);
   12949              : 
   12950     25648171 :     case STATEMENT_LIST:
   12951   5064207081 :       for (tree stmt : tsi_range (t))
   12952     75853893 :         if (!RECUR (stmt, any))
   12953   4963232489 :           return false;
   12954              :       return true;
   12955              : 
   12956      5178015 :     case MODIFY_EXPR:
   12957      5178015 :       if (cxx_dialect < cxx14)
   12958         3892 :         goto fail;
   12959      5174123 :       if (!RECUR (TREE_OPERAND (t, 0), any))
   12960              :         return false;
   12961              :       /* Just ignore clobbers.  */
   12962      4315799 :       if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
   12963              :         return true;
   12964      3833495 :       if (!RECUR (TREE_OPERAND (t, 1), rval))
   12965              :         return false;
   12966              :       return true;
   12967              : 
   12968       908574 :     case MODOP_EXPR:
   12969       908574 :       if (cxx_dialect < cxx14)
   12970           98 :         goto fail;
   12971       908476 :       if (!RECUR (TREE_OPERAND (t, 0), rval))
   12972              :         return false;
   12973       897883 :       if (!RECUR (TREE_OPERAND (t, 2), rval))
   12974              :         return false;
   12975              :       return true;
   12976              : 
   12977       552152 :     case DO_STMT:
   12978       552152 :       if (!RECUR (DO_COND (t), rval))
   12979              :         return false;
   12980       552152 :       if (!RECUR (DO_BODY (t), any))
   12981              :         return false;
   12982       551537 :       if (breaks (jump_target) || continues (jump_target))
   12983            5 :         *jump_target = NULL_TREE;
   12984              :       return true;
   12985              : 
   12986       454790 :     case FOR_STMT:
   12987       454790 :       if (!RECUR (FOR_INIT_STMT (t), any))
   12988              :         return false;
   12989       454790 :       if (!RECUR (FOR_COND_PREP (t), any))
   12990              :         return false;
   12991       454790 :       tmp = FOR_COND (t);
   12992       454790 :       if (!RECUR (tmp, rval))
   12993              :         return false;
   12994       454716 :       if (tmp)
   12995              :         {
   12996       406141 :           if (!processing_template_decl)
   12997       401596 :             tmp = cxx_eval_outermost_constant_expr (tmp, true);
   12998              :           /* If we couldn't evaluate the condition, it might not ever be
   12999              :              true.  */
   13000       406141 :           if (!integer_onep (tmp))
   13001              :             {
   13002              :               /* Before returning true, check if the for body can contain
   13003              :                  a return.  */
   13004       406141 :               hash_set<tree> pset;
   13005       406141 :               check_for_return_continue_data data = { &pset, NULL_TREE,
   13006       406141 :                                                       NULL_TREE, false };
   13007       406141 :               if (tree ret_expr
   13008       406141 :                   = cp_walk_tree (&FOR_BODY (t), check_for_return_continue,
   13009              :                                   &data, &pset))
   13010       141251 :                 *jump_target = ret_expr;
   13011       406141 :               if (data.could_throw)
   13012        17863 :                 *jump_target = void_node;
   13013       406141 :               return true;
   13014       406141 :             }
   13015              :         }
   13016        48575 :       if (!RECUR (FOR_EXPR (t), any))
   13017              :         return false;
   13018        48575 :       if (!RECUR (FOR_BODY (t), any))
   13019              :         return false;
   13020        48575 :       if (!RECUR (FOR_COND_CLEANUP (t), any))
   13021              :         return false;
   13022        48575 :       if (breaks (jump_target) || continues (jump_target))
   13023           12 :         *jump_target = NULL_TREE;
   13024              :       return true;
   13025              : 
   13026          480 :     case RANGE_FOR_STMT:
   13027          480 :       if (!RECUR (RANGE_FOR_INIT_STMT (t), any))
   13028              :         return false;
   13029          480 :       if (!RECUR (RANGE_FOR_EXPR (t), any))
   13030              :         return false;
   13031          480 :       if (!RECUR (RANGE_FOR_BODY (t), any))
   13032              :         return false;
   13033          478 :       if (breaks (jump_target) || continues (jump_target))
   13034            0 :         *jump_target = NULL_TREE;
   13035              :       return true;
   13036              : 
   13037       169017 :     case WHILE_STMT:
   13038       169017 :       if (!RECUR (WHILE_COND_PREP (t), any))
   13039              :         return false;
   13040       169017 :       tmp = WHILE_COND (t);
   13041       169017 :       if (!RECUR (tmp, rval))
   13042              :         return false;
   13043       168953 :       if (!processing_template_decl)
   13044       168916 :         tmp = cxx_eval_outermost_constant_expr (tmp, true);
   13045              :       /* If we couldn't evaluate the condition, it might not ever be true.  */
   13046       168953 :       if (!integer_onep (tmp))
   13047              :         {
   13048              :           /* Before returning true, check if the while body can contain
   13049              :              a return.  */
   13050       158761 :           hash_set<tree> pset;
   13051       158761 :           check_for_return_continue_data data = { &pset, NULL_TREE,
   13052       158761 :                                                   NULL_TREE, false };
   13053       158761 :           if (tree ret_expr
   13054       158761 :               = cp_walk_tree (&WHILE_BODY (t), check_for_return_continue,
   13055              :                               &data, &pset))
   13056          476 :             *jump_target = ret_expr;
   13057       158761 :           if (data.could_throw)
   13058         4617 :             *jump_target = void_node;
   13059       158761 :           return true;
   13060       158761 :         }
   13061        10192 :       if (!RECUR (WHILE_BODY (t), any))
   13062              :         return false;
   13063        10181 :       if (!RECUR (WHILE_COND_CLEANUP (t), any))
   13064              :         return false;
   13065        10181 :       if (breaks (jump_target) || continues (jump_target))
   13066           24 :         *jump_target = NULL_TREE;
   13067              :       return true;
   13068              : 
   13069        43086 :     case SWITCH_STMT:
   13070        43086 :       if (!RECUR (SWITCH_STMT_COND (t), rval))
   13071              :         return false;
   13072              :       /* FIXME we don't check SWITCH_STMT_BODY currently, because even
   13073              :          unreachable labels would be checked and it is enough if there is
   13074              :          a single switch cond value for which it is a valid constant
   13075              :          expression.  We need to check if there are any RETURN_EXPRs
   13076              :          or CONTINUE_STMTs inside of the body though, as in that case
   13077              :          we need to set *jump_target.  */
   13078              :       else
   13079              :         {
   13080        43080 :           hash_set<tree> pset;
   13081        43080 :           check_for_return_continue_data data = { &pset, NULL_TREE,
   13082        43080 :                                                   NULL_TREE, false };
   13083        43080 :           if (tree ret_expr
   13084        43080 :               = cp_walk_tree (&SWITCH_STMT_BODY (t), check_for_return_continue,
   13085              :                               &data, &pset))
   13086              :             /* The switch might return.  */
   13087        42687 :             *jump_target = ret_expr;
   13088          393 :           else if (data.continue_stmt)
   13089              :             /* The switch can't return, but might continue.  */
   13090            3 :             *jump_target = data.continue_stmt;
   13091        43080 :           if (data.could_throw)
   13092         1859 :             *jump_target = void_node;
   13093        43080 :         }
   13094        43080 :       return true;
   13095              : 
   13096           50 :     case STMT_EXPR:
   13097           50 :       return RECUR (STMT_EXPR_STMT (t), rval);
   13098              : 
   13099       626489 :     case LAMBDA_EXPR:
   13100       626489 :       if (cxx_dialect >= cxx17)
   13101              :         /* In C++17 lambdas can be constexpr, don't give up yet.  */
   13102              :         return true;
   13103          476 :       else if (flags & tf_error)
   13104            0 :         constexpr_error (loc, fundef_p, "lambda-expression is not a "
   13105              :                          "constant expression before C++17");
   13106              :       return false;
   13107              : 
   13108       114145 :     case NEW_EXPR:
   13109       114145 :     case VEC_NEW_EXPR:
   13110       114145 :     case DELETE_EXPR:
   13111       114145 :     case VEC_DELETE_EXPR:
   13112       114145 :       if (cxx_dialect >= cxx20)
   13113              :         /* In C++20, new-expressions are potentially constant.  */
   13114              :         return true;
   13115         1077 :       else if (flags & tf_error)
   13116            0 :         constexpr_error (loc, fundef_p, "new-expression is not a "
   13117              :                          "constant expression before C++20");
   13118              :       return false;
   13119              : 
   13120        85331 :     case DYNAMIC_CAST_EXPR:
   13121        85331 :     case PSEUDO_DTOR_EXPR:
   13122        85331 :     case OMP_PARALLEL:
   13123        85331 :     case OMP_TASK:
   13124        85331 :     case OMP_FOR:
   13125        85331 :     case OMP_SIMD:
   13126        85331 :     case OMP_DISTRIBUTE:
   13127        85331 :     case OMP_TASKLOOP:
   13128        85331 :     case OMP_LOOP:
   13129        85331 :     case OMP_TEAMS:
   13130        85331 :     case OMP_TARGET_DATA:
   13131        85331 :     case OMP_TARGET:
   13132        85331 :     case OMP_SECTIONS:
   13133        85331 :     case OMP_ORDERED:
   13134        85331 :     case OMP_CRITICAL:
   13135        85331 :     case OMP_SINGLE:
   13136        85331 :     case OMP_SCAN:
   13137        85331 :     case OMP_SCOPE:
   13138        85331 :     case OMP_SECTION:
   13139        85331 :     case OMP_MASTER:
   13140        85331 :     case OMP_MASKED:
   13141        85331 :     case OMP_TASKGROUP:
   13142        85331 :     case OMP_TARGET_UPDATE:
   13143        85331 :     case OMP_TARGET_ENTER_DATA:
   13144        85331 :     case OMP_TARGET_EXIT_DATA:
   13145        85331 :     case OMP_ATOMIC:
   13146        85331 :     case OMP_ATOMIC_READ:
   13147        85331 :     case OMP_ATOMIC_CAPTURE_OLD:
   13148        85331 :     case OMP_ATOMIC_CAPTURE_NEW:
   13149        85331 :     case OMP_DEPOBJ:
   13150        85331 :     case OACC_PARALLEL:
   13151        85331 :     case OACC_KERNELS:
   13152        85331 :     case OACC_SERIAL:
   13153        85331 :     case OACC_DATA:
   13154        85331 :     case OACC_HOST_DATA:
   13155        85331 :     case OACC_LOOP:
   13156        85331 :     case OACC_CACHE:
   13157        85331 :     case OACC_DECLARE:
   13158        85331 :     case OACC_ENTER_DATA:
   13159        85331 :     case OACC_EXIT_DATA:
   13160        85331 :     case OACC_UPDATE:
   13161        85331 :     case OMP_ARRAY_SECTION:
   13162              :       /* GCC internal stuff.  */
   13163        85331 :     case VA_ARG_EXPR:
   13164        85331 :     case TRANSACTION_EXPR:
   13165        85331 :     case AT_ENCODE_EXPR:
   13166        85331 :     fail:
   13167        85331 :       if (flags & tf_error)
   13168           23 :          constexpr_error (loc, fundef_p, "expression %qE is not a constant "
   13169              :                           "expression", t);
   13170              :       return false;
   13171              : 
   13172              :     case OMP_DECLARE_MAPPER:
   13173              :       /* This can be used to initialize VAR_DECLs: it's treated as a magic
   13174              :          constant.  */
   13175              :       return true;
   13176              : 
   13177        26692 :     case THROW_EXPR:
   13178        26692 :       if (cxx_dialect < cxx26)
   13179          291 :         goto fail;
   13180        26401 :       return RECUR (TREE_OPERAND (t, 0), rval);
   13181              : 
   13182          531 :     case ASM_EXPR:
   13183          531 :       if (flags & tf_error)
   13184            6 :         inline_asm_in_constexpr_error (loc, fundef_p);
   13185              :       return false;
   13186              : 
   13187       543485 :     case OBJ_TYPE_REF:
   13188       543485 :       if (cxx_dialect >= cxx20)
   13189              :         /* In C++20 virtual calls can be constexpr, don't give up yet.  */
   13190              :         return true;
   13191         9122 :       else if (flags & tf_error)
   13192            0 :         constexpr_error (loc, fundef_p, "virtual functions cannot be "
   13193              :                          "%<constexpr%> before C++20");
   13194              :       return false;
   13195              : 
   13196         6599 :     case TYPEID_EXPR:
   13197              :       /* In C++20, a typeid expression whose operand is of polymorphic
   13198              :          class type can be constexpr.  */
   13199         6599 :       {
   13200         6599 :         tree e = TREE_OPERAND (t, 0);
   13201         6599 :         if (cxx_dialect < cxx20
   13202           26 :             && strict
   13203           26 :             && !TYPE_P (e)
   13204           19 :             && !type_dependent_expression_p (e)
   13205            7 :             && CLASS_TYPE_P (TREE_TYPE (e))
   13206         6604 :             && TYPE_POLYMORPHIC_P (TREE_TYPE (e)))
   13207              :           {
   13208            4 :             if (flags & tf_error)
   13209            1 :               constexpr_error (loc, fundef_p, "%<typeid%> is not a "
   13210              :                                "constant expression because %qE is "
   13211              :                                "of polymorphic type", e);
   13212              :             return false;
   13213              :           }
   13214              :         return true;
   13215              :       }
   13216              : 
   13217     31475300 :     case POINTER_DIFF_EXPR:
   13218     31475300 :     case MINUS_EXPR:
   13219     31475300 :       want_rval = true;
   13220     31475300 :       goto binary;
   13221              : 
   13222     84611545 :     case LT_EXPR:
   13223     84611545 :     case LE_EXPR:
   13224     84611545 :     case GT_EXPR:
   13225     84611545 :     case GE_EXPR:
   13226     84611545 :     case EQ_EXPR:
   13227     84611545 :     case NE_EXPR:
   13228     84611545 :     case SPACESHIP_EXPR:
   13229     84611545 :       want_rval = true;
   13230     84611545 :       goto binary;
   13231              : 
   13232      2006159 :     case PREINCREMENT_EXPR:
   13233      2006159 :     case POSTINCREMENT_EXPR:
   13234      2006159 :     case PREDECREMENT_EXPR:
   13235      2006159 :     case POSTDECREMENT_EXPR:
   13236      2006159 :       if (cxx_dialect < cxx14)
   13237         9471 :         goto fail;
   13238      1996688 :       goto unary;
   13239              : 
   13240      1284894 :     case BIT_NOT_EXPR:
   13241              :       /* A destructor.  */
   13242      1284894 :       if (TYPE_P (TREE_OPERAND (t, 0)))
   13243              :         return true;
   13244              :       /* fall through.  */
   13245              : 
   13246     48650126 :     case CONJ_EXPR:
   13247     48650126 :     case SAVE_EXPR:
   13248     48650126 :     case FIX_TRUNC_EXPR:
   13249     48650126 :     case FLOAT_EXPR:
   13250     48650126 :     case NEGATE_EXPR:
   13251     48650126 :     case ABS_EXPR:
   13252     48650126 :     case ABSU_EXPR:
   13253     48650126 :     case TRUTH_NOT_EXPR:
   13254     48650126 :     case FIXED_CONVERT_EXPR:
   13255     48650126 :     case UNARY_PLUS_EXPR:
   13256     48650126 :     case UNARY_LEFT_FOLD_EXPR:
   13257     48650126 :     case UNARY_RIGHT_FOLD_EXPR:
   13258     48650126 :     case VEC_DUPLICATE_EXPR:
   13259      1284894 :     unary:
   13260     48650126 :       return RECUR (TREE_OPERAND (t, 0), rval);
   13261              : 
   13262     31749141 :     case CAST_EXPR:
   13263     31749141 :     case CONST_CAST_EXPR:
   13264     31749141 :     case STATIC_CAST_EXPR:
   13265     31749141 :     case REINTERPRET_CAST_EXPR:
   13266     31749141 :     case IMPLICIT_CONV_EXPR:
   13267     31749141 :       if (!cast_valid_in_integral_constant_expression_p (TREE_TYPE (t)))
   13268              :         /* In C++98, a conversion to non-integral type can't be part of a
   13269              :            constant expression.  */
   13270              :         {
   13271          346 :           if (flags & tf_error)
   13272            0 :             constexpr_error (loc, fundef_p,
   13273              :                              "cast to non-integral type %qT in a constant "
   13274            0 :                              "expression", TREE_TYPE (t));
   13275              :           return false;
   13276              :         }
   13277              :       /* This might be a conversion from a class to a (potentially) literal
   13278              :          type.  Let's consider it potentially constant since the conversion
   13279              :          might be a constexpr user-defined conversion.  */
   13280     31748795 :       else if (cxx_dialect >= cxx11
   13281     31726246 :                && (dependent_type_p (TREE_TYPE (t))
   13282     11172788 :                    || !COMPLETE_TYPE_P (TREE_TYPE (t))
   13283     11158064 :                    || literal_type_p (TREE_TYPE (t)))
   13284     31688011 :                && TREE_OPERAND (t, 0)
   13285     63190417 :                && (TREE_CODE (t) != CAST_EXPR
   13286     23832985 :                    || !TREE_CHAIN (TREE_OPERAND (t, 0))))
   13287              :         {
   13288     31398376 :           tree from = TREE_OPERAND (t, 0);
   13289     31398376 :           if (TREE_CODE (t) == CAST_EXPR)
   13290     23789739 :             from = TREE_VALUE (from);
   13291     31398376 :           tree type = TREE_TYPE (from);
   13292              :           /* If this is a dependent type, it could end up being a class
   13293              :              with conversions.  */
   13294     31398376 :           if (type == NULL_TREE || WILDCARD_TYPE_P (type))
   13295              :             return true;
   13296              :           /* Or a non-dependent class which has conversions.  */
   13297       595762 :           else if (CLASS_TYPE_P (type)
   13298       595762 :                    && (TYPE_HAS_CONVERSION (type) || dependent_scope_p (type)))
   13299              :             return true;
   13300              :         }
   13301              : 
   13302     25222333 :       return (RECUR (TREE_OPERAND (t, 0),
   13303     25222333 :                      !TYPE_REF_P (TREE_TYPE (t))));
   13304              : 
   13305     14577736 :     case BIND_EXPR:
   13306     14577736 :       return RECUR (BIND_EXPR_BODY (t), want_rval);
   13307              : 
   13308     71503537 :     case CLEANUP_POINT_EXPR:
   13309     71503537 :     case MUST_NOT_THROW_EXPR:
   13310     71503537 :     case TRY_CATCH_EXPR:
   13311              :       /* Even for C++26 handle TRY_BLOCK conservatively, if we detect the
   13312              :          body could throw, even with catch (...) among handlers we'd need
   13313              :          to analyze them in detail if they couldn't rethrow it.  More
   13314              :          importantly though, throws (jump_target) is just conservative,
   13315              :          and there could be e.g.
   13316              :            try
   13317              :              {
   13318              :                possibly_throwing_fn (args);
   13319              :                break;
   13320              :              }
   13321              :            catch (...)
   13322              :              {
   13323              :              }
   13324              :          or continue or return instead of break.  So, clearing *jump_target
   13325              :          because we see catch (...) handler might mean we missed break
   13326              :          etc.  */
   13327     71503537 :     case TRY_BLOCK:
   13328     71503537 :     case EH_SPEC_BLOCK:
   13329     71503537 :     case EXPR_STMT:
   13330     71503537 :     case PAREN_EXPR:
   13331              :       /* For convenience.  */
   13332     71503537 :     case LOOP_EXPR:
   13333     71503537 :     case EXIT_EXPR:
   13334     71503537 :       return RECUR (TREE_OPERAND (t, 0), want_rval);
   13335              : 
   13336     13006049 :     case DECL_EXPR:
   13337     13006049 :       tmp = DECL_EXPR_DECL (t);
   13338      8632031 :       if (VAR_P (tmp) && !DECL_ARTIFICIAL (tmp)
   13339     19078589 :           && (processing_template_decl
   13340      5587245 :               ? !decl_maybe_constant_var_p (tmp)
   13341      5101950 :               : !decl_constant_var_p (tmp)))
   13342              :         {
   13343      5022449 :           if (CP_DECL_THREAD_LOCAL_P (tmp) && !DECL_REALLY_EXTERN (tmp))
   13344              :             {
   13345            8 :               if (flags & tf_error)
   13346            3 :                 constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
   13347              :                                  "%qD defined %<thread_local%> in "
   13348              :                                  "%<constexpr%> context", tmp);
   13349              :               return false;
   13350              :             }
   13351      5022441 :           else if (TREE_STATIC (tmp))
   13352              :             {
   13353          142 :               if (flags & tf_error)
   13354           34 :                 constexpr_error (DECL_SOURCE_LOCATION (tmp), fundef_p,
   13355              :                                  "%qD defined %<static%> in %<constexpr%> "
   13356              :                                  "context", tmp);
   13357              :               return false;
   13358              :             }
   13359      5022299 :           else if (!check_for_uninitialized_const_var
   13360      5022299 :                    (tmp, /*constexpr_context_p=*/true, flags))
   13361              :             return false;
   13362              :         }
   13363     13000954 :       if (VAR_P (tmp))
   13364      8626936 :         return RECUR (DECL_INITIAL (tmp), want_rval);
   13365              :       return true;
   13366              : 
   13367        43667 :     case TRY_FINALLY_EXPR:
   13368        43667 :       return (RECUR (TREE_OPERAND (t, 0), want_rval)
   13369        43667 :               && RECUR (TREE_OPERAND (t, 1), any));
   13370              : 
   13371            0 :     case EH_ELSE_EXPR:
   13372              :       /* maybe_apply_function_contracts uses this to check postconditions only
   13373              :          on normal return.  */
   13374            0 :       return (RECUR (TREE_OPERAND (t, 1), any)
   13375            0 :               || RECUR (TREE_OPERAND (t, 0), any));
   13376              : 
   13377     24772272 :     case SCOPE_REF:
   13378     24772272 :       return RECUR (TREE_OPERAND (t, 1), want_rval);
   13379              : 
   13380     49808466 :     case TARGET_EXPR:
   13381     49808466 :       if (!TARGET_EXPR_DIRECT_INIT_P (t)
   13382     49599064 :           && !TARGET_EXPR_ELIDING_P (t)
   13383     89685414 :           && !literal_type_p (TREE_TYPE (t)))
   13384              :         {
   13385       905276 :           if (flags & tf_error)
   13386              :             {
   13387           25 :               auto_diagnostic_group d;
   13388           25 :               if (constexpr_error (loc, fundef_p,
   13389              :                                    "temporary of non-literal type %qT in a "
   13390           25 :                                    "constant expression", TREE_TYPE (t)))
   13391           25 :                 explain_non_literal_class (TREE_TYPE (t));
   13392           25 :             }
   13393              :           return false;
   13394              :         }
   13395              :       /* FALLTHRU */
   13396     77728278 :     case INIT_EXPR:
   13397     77728278 :       if (TREE_CLOBBER_P (TREE_OPERAND (t, 1)))
   13398              :         return true;
   13399     77607320 :       return RECUR (TREE_OPERAND (t, 1), rval);
   13400              : 
   13401     40101976 :     case CONSTRUCTOR:
   13402     40101976 :       {
   13403     40101976 :         vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (t);
   13404     40101976 :         constructor_elt *ce;
   13405   5236396379 :         for (i = 0; vec_safe_iterate (v, i, &ce); ++i)
   13406    234354936 :           if (!RECUR (ce->value, want_rval))
   13407              :             return false;
   13408              :         return true;
   13409              :       }
   13410              : 
   13411     21348607 :     case TREE_LIST:
   13412     21348607 :       {
   13413     21348607 :         gcc_assert (TREE_PURPOSE (t) == NULL_TREE
   13414              :                     || DECL_P (TREE_PURPOSE (t)));
   13415     21348607 :         if (!RECUR (TREE_VALUE (t), want_rval))
   13416              :           return false;
   13417     19131945 :         if (TREE_CHAIN (t) == NULL_TREE)
   13418              :           return true;
   13419        55384 :         return RECUR (TREE_CHAIN (t), want_rval);
   13420              :       }
   13421              : 
   13422     15519952 :     case TRUNC_DIV_EXPR:
   13423     15519952 :     case CEIL_DIV_EXPR:
   13424     15519952 :     case FLOOR_DIV_EXPR:
   13425     15519952 :     case ROUND_DIV_EXPR:
   13426     15519952 :     case TRUNC_MOD_EXPR:
   13427     15519952 :     case CEIL_MOD_EXPR:
   13428     15519952 :     case ROUND_MOD_EXPR:
   13429     15519952 :       {
   13430     15519952 :         tree denom = TREE_OPERAND (t, 1);
   13431     15519952 :         if (!RECUR (denom, rval))
   13432              :           return false;
   13433              :         /* We can't call cxx_eval_outermost_constant_expr on an expression
   13434              :            that hasn't been through instantiate_non_dependent_expr yet.  */
   13435     14996255 :         if (!processing_template_decl)
   13436      7959145 :           denom = cxx_eval_outermost_constant_expr (denom, true);
   13437     14996255 :         if (integer_zerop (denom))
   13438              :           {
   13439          377 :             if (flags & tf_error)
   13440           38 :               constexpr_error (input_location, fundef_p,
   13441              :                                "division by zero is not a constant expression");
   13442              :             return false;
   13443              :           }
   13444              :         else
   13445              :           {
   13446     14995878 :             want_rval = true;
   13447     14995878 :             return RECUR (TREE_OPERAND (t, 0), want_rval);
   13448              :           }
   13449              :       }
   13450              : 
   13451      9758891 :     case COMPOUND_EXPR:
   13452      9758891 :       {
   13453              :         /* check_return_expr sometimes wraps a TARGET_EXPR in a
   13454              :            COMPOUND_EXPR; don't get confused.  */
   13455      9758891 :         tree op0 = TREE_OPERAND (t, 0);
   13456      9758891 :         tree op1 = TREE_OPERAND (t, 1);
   13457      9758891 :         STRIP_NOPS (op1);
   13458      9758891 :         if (TREE_CODE (op0) == TARGET_EXPR && op1 == TARGET_EXPR_SLOT (op0))
   13459      2737184 :           return RECUR (op0, want_rval);
   13460              :         else
   13461      7021707 :           goto binary;
   13462              :       }
   13463              : 
   13464              :       /* If the first operand is the non-short-circuit constant, look at
   13465              :          the second operand; otherwise we only care about the first one for
   13466              :          potentiality.  */
   13467     18910479 :     case TRUTH_AND_EXPR:
   13468     18910479 :     case TRUTH_ANDIF_EXPR:
   13469     18910479 :       tmp = boolean_true_node;
   13470     18910479 :       goto truth;
   13471      7676753 :     case TRUTH_OR_EXPR:
   13472      7676753 :     case TRUTH_ORIF_EXPR:
   13473      7676753 :       tmp = boolean_false_node;
   13474     26587232 :     truth:
   13475     26587232 :       {
   13476     26587232 :         tree op0 = TREE_OPERAND (t, 0);
   13477     26587232 :         tree op1 = TREE_OPERAND (t, 1);
   13478     26587232 :         if (!RECUR (op0, rval))
   13479              :           return false;
   13480     18335680 :         if (!(flags & tf_error) && RECUR (op1, rval))
   13481              :           /* When quiet, try to avoid expensive trial evaluation by first
   13482              :              checking potentiality of the second operand.  */
   13483              :           return true;
   13484      1849584 :         if (!processing_template_decl)
   13485      1445817 :           op0 = cxx_eval_outermost_constant_expr (op0, true);
   13486      1849584 :         if (tree_int_cst_equal (op0, tmp))
   13487         5203 :           return (flags & tf_error) ? RECUR (op1, rval) : false;
   13488              :         else
   13489              :           return true;
   13490              :       }
   13491              : 
   13492              :     case PLUS_EXPR:
   13493              :     case MULT_EXPR:
   13494              :     case POINTER_PLUS_EXPR:
   13495              :     case RDIV_EXPR:
   13496              :     case EXACT_DIV_EXPR:
   13497              :     case MIN_EXPR:
   13498              :     case MAX_EXPR:
   13499              :     case LSHIFT_EXPR:
   13500              :     case RSHIFT_EXPR:
   13501              :     case LROTATE_EXPR:
   13502              :     case RROTATE_EXPR:
   13503              :     case BIT_IOR_EXPR:
   13504              :     case BIT_XOR_EXPR:
   13505              :     case BIT_AND_EXPR:
   13506              :     case TRUTH_XOR_EXPR:
   13507              :     case UNORDERED_EXPR:
   13508              :     case ORDERED_EXPR:
   13509              :     case UNLT_EXPR:
   13510              :     case UNLE_EXPR:
   13511              :     case UNGT_EXPR:
   13512              :     case UNGE_EXPR:
   13513              :     case UNEQ_EXPR:
   13514              :     case LTGT_EXPR:
   13515              :     case RANGE_EXPR:
   13516              :     case COMPLEX_EXPR:
   13517    237201602 :       want_rval = true;
   13518              :       /* Fall through.  */
   13519    249536765 :     case ARRAY_REF:
   13520    249536765 :     case ARRAY_RANGE_REF:
   13521    249536765 :     case MEMBER_REF:
   13522    249536765 :     case DOTSTAR_EXPR:
   13523    249536765 :     case MEM_REF:
   13524    249536765 :     case BINARY_LEFT_FOLD_EXPR:
   13525    249536765 :     case BINARY_RIGHT_FOLD_EXPR:
   13526    249536765 :     binary:
   13527    548119364 :       for (i = 0; i < 2; ++i)
   13528    406090799 :         if (!RECUR (TREE_OPERAND (t, i), want_rval))
   13529              :           return false;
   13530              :       return true;
   13531              : 
   13532              :     case VEC_PERM_EXPR:
   13533       121529 :      for (i = 0; i < 3; ++i)
   13534       120583 :       if (!RECUR (TREE_OPERAND (t, i), true))
   13535              :         return false;
   13536              :      return true;
   13537              : 
   13538      7567255 :     case COND_EXPR:
   13539      7567255 :       if (COND_EXPR_IS_VEC_DELETE (t) && cxx_dialect < cxx20)
   13540              :         {
   13541            8 :           if (flags & tf_error)
   13542            2 :             constexpr_error (loc, fundef_p, "%<delete[]%> is not a "
   13543              :                              "constant expression");
   13544              :           return false;
   13545              :         }
   13546              :       /* Fall through.  */
   13547     18317624 :     case IF_STMT:
   13548     18317624 :     case VEC_COND_EXPR:
   13549              :       /* If the condition is a known constant, we know which of the legs we
   13550              :          care about; otherwise we only require that the condition and
   13551              :          either of the legs be potentially constant.  */
   13552     18317624 :       tmp = TREE_OPERAND (t, 0);
   13553     18317624 :       if (!RECUR (tmp, rval))
   13554              :         return false;
   13555     15998455 :       if (!processing_template_decl)
   13556     13990893 :         tmp = cxx_eval_outermost_constant_expr (tmp, true);
   13557              :       /* potential_constant_expression* isn't told if it is called for
   13558              :          manifestly_const_eval or not, so for consteval if always
   13559              :          process both branches as if the condition is not a known
   13560              :          constant.  */
   13561     15998455 :       if (TREE_CODE (t) != IF_STMT || !IF_STMT_CONSTEVAL_P (t))
   13562              :         {
   13563     15921813 :           if (integer_zerop (tmp))
   13564      3451120 :             return RECUR (TREE_OPERAND (t, 2), want_rval);
   13565     12470693 :           else if (TREE_CODE (tmp) == INTEGER_CST)
   13566      3817646 :             return RECUR (TREE_OPERAND (t, 1), want_rval);
   13567              :         }
   13568      8729689 :       tmp = *jump_target;
   13569     10090189 :       for (i = 1; i < 3; ++i)
   13570              :         {
   13571      9940139 :           tree this_jump_target = tmp;
   13572      9940139 :           if (potential_constant_expression_1 (TREE_OPERAND (t, i),
   13573              :                                                want_rval, strict, now, fundef_p,
   13574              :                                                tf_none, &this_jump_target))
   13575              :             {
   13576      8877740 :               if (returns (&this_jump_target) || throws (&this_jump_target))
   13577      2477253 :                 *jump_target = this_jump_target;
   13578      6102386 :               else if (!returns (jump_target) && !throws (jump_target))
   13579              :                 {
   13580      6102386 :                   if (breaks (&this_jump_target)
   13581      6102386 :                       || continues (&this_jump_target))
   13582           45 :                     *jump_target = this_jump_target;
   13583      6102386 :                   if (i == 1)
   13584              :                     {
   13585              :                       /* If the then branch is potentially constant, but
   13586              :                          does not return, check if the else branch
   13587              :                          couldn't return, break or continue.  */
   13588      5042659 :                       hash_set<tree> pset;
   13589      5042659 :                       check_for_return_continue_data data = { &pset, NULL_TREE,
   13590              :                                                               NULL_TREE,
   13591      5042659 :                                                               false };
   13592     10085318 :                       if (tree ret_expr
   13593      5042659 :                         = cp_walk_tree (&TREE_OPERAND (t, 2),
   13594              :                                         check_for_return_continue, &data,
   13595              :                                         &pset))
   13596        80715 :                         *jump_target = ret_expr;
   13597      4961944 :                       else if (*jump_target == NULL_TREE)
   13598              :                         {
   13599      4961902 :                           if (data.continue_stmt)
   13600            0 :                             *jump_target = data.continue_stmt;
   13601      4961902 :                           else if (data.break_stmt)
   13602           13 :                             *jump_target = data.break_stmt;
   13603              :                         }
   13604      5042659 :                       if (data.could_throw)
   13605        54507 :                         *jump_target = void_node;
   13606      5042659 :                     }
   13607              :                 }
   13608      8579639 :               return true;
   13609              :             }
   13610              :         }
   13611       150050 :       if (flags & tf_error)
   13612              :         {
   13613            3 :           if (TREE_CODE (t) == IF_STMT)
   13614            3 :             constexpr_error (loc, fundef_p, "neither branch of %<if%> is a "
   13615              :                              "constant expression");
   13616              :           else
   13617            0 :             constexpr_error (loc, fundef_p, "expression %qE is not a "
   13618              :                              "constant expression", t);
   13619              :         }
   13620              :       return false;
   13621              : 
   13622         1742 :     case VEC_INIT_EXPR:
   13623         1742 :       if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
   13624              :         return true;
   13625          868 :       if (flags & tf_error)
   13626              :         {
   13627            3 :           if (constexpr_error (loc, fundef_p, "non-constant array "
   13628              :                                "initialization"))
   13629            2 :             diagnose_non_constexpr_vec_init (t);
   13630              :         }
   13631              :       return false;
   13632              : 
   13633              :     case TYPE_DECL:
   13634              :     case TAG_DEFN:
   13635              :       /* We can see these in statement-expressions.  */
   13636              :       return true;
   13637              : 
   13638      1498318 :     case CLEANUP_STMT:
   13639      1498318 :       if (!RECUR (CLEANUP_BODY (t), any))
   13640              :         return false;
   13641      2502700 :       if (!CLEANUP_EH_ONLY (t) && !RECUR (CLEANUP_EXPR (t), any))
   13642              :         return false;
   13643              :       return true;
   13644              : 
   13645              :     case EMPTY_CLASS_EXPR:
   13646              :       return true;
   13647              : 
   13648          128 :     case GOTO_EXPR:
   13649          128 :       {
   13650          128 :         tree *target = &TREE_OPERAND (t, 0);
   13651              :         /* Gotos representing break, continue and cdtor return are OK.  */
   13652          128 :         if (breaks (target) || continues (target) || returns (target))
   13653              :           {
   13654          108 :             *jump_target = *target;
   13655          108 :             return true;
   13656              :           }
   13657           20 :         if (TREE_CODE (*target) == LABEL_DECL && DECL_ARTIFICIAL (*target))
   13658              :           /* The user didn't write this goto, this isn't the problem.  */
   13659              :           return true;
   13660           16 :         if (flags & tf_error)
   13661            3 :           constexpr_error (loc, fundef_p, "%<goto%> is not a constant "
   13662              :                            "expression");
   13663              :         return false;
   13664              :       }
   13665              : 
   13666              :     case ASSERTION_STMT:
   13667              :     case PRECONDITION_STMT:
   13668              :     case POSTCONDITION_STMT:
   13669              :       /* Contracts are not supposed to alter this; we have to check that this
   13670              :          is not violated at a later time.  */
   13671              :       return true;
   13672              : 
   13673          228 :     case LABEL_EXPR:
   13674          228 :       t = LABEL_EXPR_LABEL (t);
   13675          228 :       if (DECL_ARTIFICIAL (t) || cxx_dialect >= cxx23)
   13676              :         return true;
   13677           25 :       else if (flags & tf_error)
   13678            5 :         constexpr_error (loc, fundef_p, "label definition in %<constexpr%> "
   13679              :                          "function only available with %<-std=c++23%> or "
   13680              :                          "%<-std=gnu++23%>");
   13681              :       return false;
   13682              : 
   13683        10318 :     case ANNOTATE_EXPR:
   13684        10318 :       return RECUR (TREE_OPERAND (t, 0), rval);
   13685              : 
   13686       188709 :     case BIT_CAST_EXPR:
   13687       188709 :       return RECUR (TREE_OPERAND (t, 0), rval);
   13688              : 
   13689              :     /* Coroutine await, yield and return expressions are not.  */
   13690          768 :     case CO_AWAIT_EXPR:
   13691          768 :     case CO_YIELD_EXPR:
   13692          768 :     case CO_RETURN_EXPR:
   13693          768 :     case TEMPLATE_FOR_STMT:
   13694          768 :       if (flags & tf_error)
   13695            3 :         constexpr_error (cp_expr_loc_or_loc (t, input_location), fundef_p,
   13696              :                          "%qE is not a constant expression", t);
   13697              :       return false;
   13698              : 
   13699              :     /* Assume a TU-local entity is not constant, we'll error later when
   13700              :        instantiating.  */
   13701              :     case TU_LOCAL_ENTITY:
   13702              :       return false;
   13703              : 
   13704              :     /* A splice expression is dependent, but will be constant after
   13705              :        substitution.  */
   13706              :     case SPLICE_EXPR:
   13707              :       return true;
   13708              : 
   13709           30 :     case NONTYPE_ARGUMENT_PACK:
   13710           30 :       {
   13711           30 :         tree args = ARGUMENT_PACK_ARGS (t);
   13712           30 :         int len = TREE_VEC_LENGTH (args);
   13713           90 :         for (int i = 0; i < len; ++i)
   13714           60 :           if (!RECUR (TREE_VEC_ELT (args, i), any))
   13715              :             return false;
   13716              :         return true;
   13717              :       }
   13718              : 
   13719            0 :     default:
   13720            0 :       if (objc_non_constant_expr_p (t))
   13721              :         return false;
   13722              : 
   13723            0 :       sorry ("unexpected AST of kind %s", get_tree_code_name (TREE_CODE (t)));
   13724            0 :       gcc_unreachable ();
   13725              :       return false;
   13726              :     }
   13727              : #undef RECUR
   13728   4963232489 : }
   13729              : 
   13730              : bool
   13731   1777656030 : potential_constant_expression_1 (tree t, bool want_rval, bool strict, bool now,
   13732              :                                  bool fundef_p, tsubst_flags_t flags)
   13733              : {
   13734   1777656030 :   if (flags & tf_error)
   13735              :     {
   13736              :       /* Check potentiality quietly first, as that could be performed more
   13737              :          efficiently in some cases (currently only for TRUTH_*_EXPR).  If
   13738              :          that fails, replay the check noisily to give errors.  */
   13739     11132843 :       flags &= ~tf_error;
   13740     11132843 :       if (potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
   13741              :                                            flags))
   13742              :         return true;
   13743         1073 :       flags |= tf_error;
   13744              :     }
   13745              : 
   13746   1766524260 :   tree target = NULL_TREE;
   13747   1766524260 :   return potential_constant_expression_1 (t, want_rval, strict, now, fundef_p,
   13748   1766524260 :                                           flags, &target);
   13749              : }
   13750              : 
   13751              : /* The main entry point to the above.  */
   13752              : 
   13753              : bool
   13754    452748750 : potential_constant_expression (tree t)
   13755              : {
   13756    452748750 :   return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
   13757              :                                           /*now*/false, /*fundef_p*/false,
   13758    452748750 :                                           tf_none);
   13759              : }
   13760              : 
   13761              : /* As above, but require a constant rvalue.  */
   13762              : 
   13763              : bool
   13764     35758414 : potential_rvalue_constant_expression (tree t)
   13765              : {
   13766     35758414 :   return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
   13767              :                                           /*now*/false, /*fundef_p*/false,
   13768     35758414 :                                           tf_none);
   13769              : }
   13770              : 
   13771              : /* Like above, but complain about non-constant expressions.  */
   13772              : 
   13773              : bool
   13774           88 : require_potential_constant_expression (tree t)
   13775              : {
   13776           88 :   return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
   13777              :                                           /*now*/false, /*fundef_p*/false,
   13778           88 :                                           tf_warning_or_error);
   13779              : }
   13780              : 
   13781              : /* Cross product of the above.  */
   13782              : 
   13783              : bool
   13784       133116 : require_potential_rvalue_constant_expression (tree t)
   13785              : {
   13786       133116 :   return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
   13787              :                                           /*now*/false, /*fundef_p*/false,
   13788       133116 :                                           tf_warning_or_error);
   13789              : }
   13790              : 
   13791              : /* Like require_potential_rvalue_constant_expression, but fundef_p is true.  */
   13792              : 
   13793              : bool
   13794          290 : require_potential_rvalue_constant_expression_fncheck (tree t)
   13795              : {
   13796          290 :   return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
   13797              :                                           /*now*/false, /*fundef_p*/true,
   13798          290 :                                           tf_warning_or_error);
   13799              : }
   13800              : 
   13801              : /* Like above, but don't consider PARM_DECL a potential_constant_expression.  */
   13802              : 
   13803              : bool
   13804         1143 : require_rvalue_constant_expression (tree t)
   13805              : {
   13806         1143 :   return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
   13807              :                                           /*now*/true, /*fundef_p*/false,
   13808         1143 :                                           tf_warning_or_error);
   13809              : }
   13810              : 
   13811              : /* Like potential_constant_expression, but don't consider possible constexpr
   13812              :    substitution of the current function.  That is, PARM_DECL qualifies under
   13813              :    potential_constant_expression, but not here.
   13814              : 
   13815              :    This is basically what you can check when any actual constant values might
   13816              :    be value-dependent.  */
   13817              : 
   13818              : bool
   13819    933888316 : is_constant_expression (tree t)
   13820              : {
   13821    933888316 :   return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
   13822              :                                           /*now*/true, /*fundef_p*/false,
   13823    933888316 :                                           tf_none);
   13824              : }
   13825              : 
   13826              : /* As above, but expect an rvalue.  */
   13827              : 
   13828              : bool
   13829    157183189 : is_rvalue_constant_expression (tree t)
   13830              : {
   13831    157183189 :   return potential_constant_expression_1 (t, /*want_rval*/true, /*strict*/true,
   13832              :                                           /*now*/true, /*fundef_p*/false,
   13833    157183189 :                                           tf_none);
   13834              : }
   13835              : 
   13836              : /* Like above, but complain about non-constant expressions.  */
   13837              : 
   13838              : bool
   13839     10998206 : require_constant_expression (tree t)
   13840              : {
   13841     10998206 :   return potential_constant_expression_1 (t, /*want_rval*/false, /*strict*/true,
   13842              :                                           /*now*/true, /*fundef_p*/false,
   13843     10998206 :                                           tf_warning_or_error);
   13844              : }
   13845              : 
   13846              : /* Like is_constant_expression, but allow const variables that are not allowed
   13847              :    under constexpr rules.  */
   13848              : 
   13849              : bool
   13850    175811675 : is_static_init_expression (tree t)
   13851              : {
   13852    175811675 :   return potential_constant_expression_1 (t, /*want_rval*/false,
   13853              :                                           /*strict*/false, /*now*/true,
   13854    175811675 :                                           /*fundef_p*/false, tf_none);
   13855              : }
   13856              : 
   13857              : /* Returns true if T is a potential constant expression that is not
   13858              :    instantiation-dependent, and therefore a candidate for constant folding even
   13859              :    in a template.  */
   13860              : 
   13861              : bool
   13862    901855448 : is_nondependent_constant_expression (tree t)
   13863              : {
   13864    901855448 :   return (!type_unknown_p (t)
   13865    901855398 :           && is_constant_expression (t)
   13866   1692238923 :           && !instantiation_dependent_expression_p (t));
   13867              : }
   13868              : 
   13869              : /* Returns true if T is a potential static initializer expression that is not
   13870              :    instantiation-dependent.  */
   13871              : 
   13872              : bool
   13873    175811675 : is_nondependent_static_init_expression (tree t)
   13874              : {
   13875    175811675 :   return (!type_unknown_p (t)
   13876    175811675 :           && is_static_init_expression (t)
   13877    317889546 :           && !instantiation_dependent_expression_p (t));
   13878              : }
   13879              : 
   13880              : /* True iff FN is an implicitly constexpr function.  */
   13881              : 
   13882              : bool
   13883       465994 : decl_implicit_constexpr_p (tree fn)
   13884              : {
   13885       465994 :   if (!(flag_implicit_constexpr
   13886            3 :         && TREE_CODE (fn) == FUNCTION_DECL
   13887            3 :         && DECL_DECLARED_CONSTEXPR_P (fn)))
   13888              :     return false;
   13889              : 
   13890            3 :   if (DECL_CLONED_FUNCTION_P (fn))
   13891            0 :     fn = DECL_CLONED_FUNCTION (fn);
   13892              : 
   13893            3 :   return (DECL_LANG_SPECIFIC (fn)
   13894            3 :           && DECL_LANG_SPECIFIC (fn)->u.fn.implicit_constexpr);
   13895              : }
   13896              : 
   13897              : /* Finalize constexpr processing after parsing.  */
   13898              : 
   13899              : void
   13900        99724 : fini_constexpr (void)
   13901              : {
   13902              :   /* The contexpr call and fundef copies tables are no longer needed.  */
   13903        99724 :   constexpr_call_table = NULL;
   13904        99724 :   fundef_copies_table = NULL;
   13905        99724 : }
   13906              : 
   13907              : #include "gt-cp-constexpr.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.