LCOV - code coverage report
Current view: top level - gcc/cp - typeck2.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.4 % 1283 1198
Test Date: 2026-02-28 14:20:25 Functions: 100.0 % 40 40
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Report error messages, build initializers, and perform
       2              :    some front-end optimizations for C++ compiler.
       3              :    Copyright (C) 1987-2026 Free Software Foundation, Inc.
       4              :    Hacked by Michael Tiemann (tiemann@cygnus.com)
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful,
      14              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16              : GNU General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : 
      23              : /* This file is part of the C++ front end.
      24              :    It contains routines to build C++ expressions given their operands,
      25              :    including computing the types of the result, C and C++ specific error
      26              :    checks, and some optimization.  */
      27              : 
      28              : #include "config.h"
      29              : #include "system.h"
      30              : #include "coretypes.h"
      31              : #include "cp-tree.h"
      32              : #include "stor-layout.h"
      33              : #include "varasm.h"
      34              : #include "intl.h"
      35              : #include "gcc-rich-location.h"
      36              : #include "target.h"
      37              : 
      38              : static tree
      39              : process_init_constructor (tree type, tree init, int nested, int flags,
      40              :                           tsubst_flags_t complain);
      41              : 
      42              : 
      43              : /* Print an error message stemming from an attempt to use
      44              :    BASETYPE as a base class for TYPE.  */
      45              : 
      46              : tree
      47           27 : error_not_base_type (tree basetype, tree type)
      48              : {
      49           27 :   if (TREE_CODE (basetype) == FUNCTION_DECL)
      50            0 :     basetype = DECL_CONTEXT (basetype);
      51           27 :   error ("type %qT is not a base type for type %qT", basetype, type);
      52           27 :   return error_mark_node;
      53              : }
      54              : 
      55              : tree
      56         1109 : binfo_or_else (tree base, tree type)
      57              : {
      58         1109 :   tree binfo = lookup_base (type, base, ba_unique,
      59              :                             NULL, tf_warning_or_error);
      60              : 
      61         1109 :   if (binfo == error_mark_node)
      62              :     return NULL_TREE;
      63         1109 :   else if (!binfo)
      64            0 :     error_not_base_type (base, type);
      65              :   return binfo;
      66              : }
      67              : 
      68              : /* According to ARM $7.1.6, "A `const' object may be initialized, but its
      69              :    value may not be changed thereafter.  */
      70              : 
      71              : void
      72          210 : cxx_readonly_error (location_t loc, tree arg, enum lvalue_use errstring)
      73              : {
      74              : 
      75              : /* This macro is used to emit diagnostics to ensure that all format
      76              :    strings are complete sentences, visible to gettext and checked at
      77              :    compile time.  */
      78              : 
      79              : #define ERROR_FOR_ASSIGNMENT(LOC, AS, ASM, IN, DE, ARG)                 \
      80              :   do {                                                                  \
      81              :     switch (errstring)                                                  \
      82              :       {                                                                 \
      83              :       case lv_assign:                                                   \
      84              :         error_at (LOC, AS, ARG);                                        \
      85              :         break;                                                          \
      86              :       case lv_asm:                                                      \
      87              :         error_at (LOC, ASM, ARG);                                       \
      88              :         break;                                                          \
      89              :       case lv_increment:                                                \
      90              :         error_at (LOC, IN, ARG);                                        \
      91              :         break;                                                          \
      92              :       case lv_decrement:                                                \
      93              :         error_at (LOC, DE, ARG);                                        \
      94              :         break;                                                          \
      95              :       default:                                                          \
      96              :         gcc_unreachable ();                                             \
      97              :       }                                                                 \
      98              :   } while (0)
      99              : 
     100              :   /* Handle C++-specific things first.  */
     101              : 
     102          210 :   if (VAR_P (arg)
     103           15 :       && DECL_LANG_SPECIFIC (arg)
     104            0 :       && DECL_IN_AGGR_P (arg)
     105          210 :       && !TREE_STATIC (arg))
     106            0 :     ERROR_FOR_ASSIGNMENT (loc,
     107              :                           G_("assignment of constant field %qD"),
     108              :                           G_("constant field %qD used as %<asm%> output"),
     109              :                           G_("increment of constant field %qD"),
     110              :                           G_("decrement of constant field %qD"),
     111              :                           arg);
     112          210 :   else if (INDIRECT_REF_P (arg)
     113           35 :            && TYPE_REF_P (TREE_TYPE (TREE_OPERAND (arg, 0)))
     114          239 :            && (VAR_P (TREE_OPERAND (arg, 0))
     115           16 :                || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL))
     116           15 :     ERROR_FOR_ASSIGNMENT (loc,
     117              :                           G_("assignment of read-only reference %qD"),
     118              :                           G_("read-only reference %qD used as %<asm%> output"),
     119              :                           G_("increment of read-only reference %qD"),
     120              :                           G_("decrement of read-only reference %qD"),
     121              :                           TREE_OPERAND (arg, 0));
     122          195 :   else if (is_stub_object (arg))
     123              :     {
     124            7 :       gcc_assert (errstring == lv_assign);
     125            7 :       error_at (loc, "assignment to read-only type %qT", TREE_TYPE (arg));
     126              :     }
     127              :   else
     128          188 :     readonly_error (loc, arg, errstring);
     129          210 : }
     130              : 
     131              : /* If TYPE has abstract virtual functions, issue an error about trying
     132              :    to create an object of that type.  DECL is the object declared, or
     133              :    NULL_TREE if the declaration is unavailable, in which case USE specifies
     134              :    the kind of invalid use.  Returns 1 if an error occurred; zero if
     135              :    all was well.  */
     136              : 
     137              : static int
     138    442168285 : abstract_virtuals_error (tree decl, tree type, abstract_class_use use,
     139              :                          tsubst_flags_t complain)
     140              : {
     141    442168285 :   vec<tree, va_gc> *pure;
     142              : 
     143    442168285 :   if (TREE_CODE (type) == ARRAY_TYPE)
     144              :     {
     145      1243231 :       decl = NULL_TREE;
     146      1243231 :       use = ACU_ARRAY;
     147      1243231 :       type = strip_array_types (type);
     148              :     }
     149              : 
     150              :   /* This function applies only to classes. Any other entity can never
     151              :      be abstract.  */
     152    442168285 :   if (!CLASS_TYPE_P (type))
     153              :     return 0;
     154     95667257 :   type = TYPE_MAIN_VARIANT (type);
     155              : 
     156              : #if 0
     157              :   /* Instantiation here seems to be required by the standard,
     158              :      but breaks e.g. boost::bind.  FIXME!  */
     159              :   /* In SFINAE, non-N3276 context, force instantiation.  */
     160              :   if (!(complain & (tf_error|tf_decltype)))
     161              :     complete_type (type);
     162              : #endif
     163              : 
     164     95667257 :   if (!TYPE_SIZE (type))
     165              :     /* TYPE is being defined, and during that time
     166              :        CLASSTYPE_PURE_VIRTUALS holds the inline friends.  */
     167              :     return 0;
     168              : 
     169     95667179 :   pure = CLASSTYPE_PURE_VIRTUALS (type);
     170     95667179 :   if (!pure)
     171              :     return 0;
     172              : 
     173          208 :   if (!(complain & tf_error))
     174              :     return 1;
     175              : 
     176          111 :   auto_diagnostic_group d;
     177          111 :   if (decl)
     178              :     {
     179           54 :       if (VAR_P (decl))
     180            9 :         error ("cannot declare variable %q+D to be of abstract "
     181              :                "type %qT", decl, type);
     182           45 :       else if (TREE_CODE (decl) == PARM_DECL)
     183              :         {
     184           27 :           if (DECL_NAME (decl))
     185           24 :             error ("cannot declare parameter %q+D to be of abstract type %qT",
     186              :                    decl, type);
     187              :           else
     188            3 :             error ("cannot declare parameter to be of abstract type %qT",
     189              :                    type);
     190              :         }
     191           18 :       else if (TREE_CODE (decl) == FIELD_DECL)
     192           15 :         error ("cannot declare field %q+D to be of abstract type %qT",
     193              :                decl, type);
     194            3 :       else if (TREE_CODE (decl) == FUNCTION_DECL
     195            3 :                && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE)
     196            0 :         error ("invalid abstract return type for member function %q+#D", decl);
     197            3 :       else if (TREE_CODE (decl) == FUNCTION_DECL)
     198            3 :         error ("invalid abstract return type for function %q+#D", decl);
     199            0 :       else if (identifier_p (decl))
     200              :         /* Here we do not have location information.  */
     201            0 :         error ("invalid abstract type %qT for %qE", type, decl);
     202              :       else
     203            0 :         error ("invalid abstract type for %q+D", decl);
     204              :     }
     205           57 :   else switch (use)
     206              :     {
     207            9 :     case ACU_ARRAY:
     208            9 :       error ("creating array of %qT, which is an abstract class type", type);
     209            9 :       break;
     210            9 :     case ACU_CAST:
     211            9 :       error ("invalid cast to abstract class type %qT", type);
     212            9 :       break;
     213            0 :     case ACU_NEW:
     214            0 :       error ("invalid new-expression of abstract class type %qT", type);
     215            0 :       break;
     216            0 :     case ACU_RETURN:
     217            0 :       error ("invalid abstract return type %qT", type);
     218            0 :       break;
     219            0 :     case ACU_PARM:
     220            0 :       error ("invalid abstract parameter type %qT", type);
     221            0 :       break;
     222            6 :     case ACU_THROW:
     223            6 :       error ("expression of abstract class type %qT cannot "
     224              :              "be used in throw-expression", type);
     225            6 :       break;
     226            3 :     case ACU_CATCH:
     227            3 :       error ("cannot declare %<catch%> parameter to be of abstract "
     228              :              "class type %qT", type);
     229            3 :       break;
     230           30 :     default:
     231           30 :       error ("cannot construct an object of abstract type %qT", type);
     232              :     }
     233              : 
     234              :   /* Only go through this once.  */
     235          111 :   if (pure->length ())
     236              :     {
     237           48 :       unsigned ix;
     238           48 :       tree fn;
     239              : 
     240           48 :       inform (DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type)),
     241              :               "because the following virtual functions are pure within %qT:",
     242              :               type);
     243              : 
     244           48 :       auto_diagnostic_nesting_level adnl;
     245          144 :       FOR_EACH_VEC_ELT (*pure, ix, fn)
     246           96 :         if (! DECL_CLONED_FUNCTION_P (fn)
     247           48 :             || DECL_COMPLETE_DESTRUCTOR_P (fn))
     248           48 :           inform (DECL_SOURCE_LOCATION (fn), "%#qD", fn);
     249              : 
     250              :       /* Now truncate the vector.  This leaves it non-null, so we know
     251              :          there are pure virtuals, but empty so we don't list them out
     252              :          again.  */
     253           48 :       pure->truncate (0);
     254           48 :     }
     255              : 
     256          111 :   return 1;
     257          111 : }
     258              : 
     259              : int
     260    389008764 : abstract_virtuals_error (tree decl, tree type,
     261              :                          tsubst_flags_t complain /* = tf_warning_or_error */)
     262              : {
     263    389008764 :   return abstract_virtuals_error (decl, type, ACU_UNKNOWN, complain);
     264              : }
     265              : 
     266              : int
     267     53159521 : abstract_virtuals_error (abstract_class_use use, tree type,
     268              :                          tsubst_flags_t complain /* = tf_warning_or_error */)
     269              : {
     270     53159521 :   return abstract_virtuals_error (NULL_TREE, type, use, complain);
     271              : }
     272              : 
     273              : 
     274              : /* Print an inform about the declaration of the incomplete type TYPE.  */
     275              : 
     276              : void
     277          922 : cxx_incomplete_type_inform (const_tree type)
     278              : {
     279          922 :   if (!TYPE_MAIN_DECL (type))
     280              :     return;
     281              : 
     282          832 :   location_t loc = DECL_SOURCE_LOCATION (TYPE_MAIN_DECL (type));
     283          832 :   tree ptype = strip_top_quals (const_cast<tree> (type));
     284              : 
     285              :   /* When defining a template, current_class_type will be the pattern on
     286              :      the template definition, while non-self-reference usages of this
     287              :      template will be an instantiation; we should pull out the pattern to
     288              :      compare against.  And for partial specs we should use the loc of the
     289              :      partial spec rather than the primary template.  */
     290          832 :   tree ttype = NULL_TREE;
     291          832 :   tree tinfo = TYPE_TEMPLATE_INFO (ptype);
     292          832 :   if (tinfo)
     293              :     {
     294          197 :       tree tmpl = TI_TEMPLATE (tinfo);
     295          197 :       if (PRIMARY_TEMPLATE_P (tmpl) && TI_PARTIAL_INFO (tinfo))
     296              :         {
     297           37 :           tree partial = TI_TEMPLATE (TI_PARTIAL_INFO (tinfo));
     298           37 :           loc = DECL_SOURCE_LOCATION (partial);
     299           37 :           ttype = TREE_TYPE (partial);
     300              :         }
     301              :       else
     302          160 :         ttype = TREE_TYPE (tmpl);
     303              :     }
     304              : 
     305          832 :   if (current_class_type
     306          274 :       && TYPE_BEING_DEFINED (current_class_type)
     307         1058 :       && (same_type_p (ptype, current_class_type)
     308          133 :           || (ttype && same_type_p (ttype, current_class_type))))
     309          103 :     inform (loc, "definition of %q#T is not complete until "
     310              :             "the closing brace", ptype);
     311              :   else
     312              :     {
     313          729 :       if (!tinfo)
     314          593 :         inform (loc, "forward declaration of %q#T", ptype);
     315              :       else
     316          136 :         inform (loc, "declaration of %q#T", ptype);
     317              : 
     318              :       /* If there's a similar-looking complete type attached
     319              :          to a different module, point at that as a suggestion.  */
     320          729 :       if (modules_p () && TYPE_NAMESPACE_SCOPE_P (ptype))
     321              :         {
     322           24 :           tree result = lookup_qualified_name (CP_TYPE_CONTEXT (ptype),
     323           24 :                                                TYPE_IDENTIFIER (ptype),
     324              :                                                LOOK_want::TYPE);
     325           24 :           if (TREE_CODE (result) == TREE_LIST)
     326           72 :             for (; result; result = TREE_CHAIN (result))
     327              :               {
     328           48 :                 tree cand = TREE_VALUE (result);
     329              : 
     330              :                 /* Typedefs are not likely intended to correspond.  */
     331           48 :                 if (is_typedef_decl (STRIP_TEMPLATE (cand))
     332           42 :                     || DECL_ALIAS_TEMPLATE_P (cand))
     333            6 :                   continue;
     334              : 
     335              :                 /* Only look at templates if type was a template.  */
     336           42 :                 if ((tinfo != nullptr) != (TREE_CODE (cand) == TEMPLATE_DECL))
     337            3 :                   continue;
     338              : 
     339              :                 /* If we're looking for a template specialisation,
     340              :                    only consider matching specialisations.  */
     341           39 :                 if (tinfo)
     342              :                   {
     343           27 :                     tree t = lookup_template_class (cand, TI_ARGS (tinfo),
     344              :                                                     NULL_TREE, NULL_TREE,
     345              :                                                     tf_none);
     346           27 :                     if (t == error_mark_node
     347           27 :                         || !CLASS_TYPE_P (t)
     348           54 :                         || TYPE_BEING_DEFINED (t))
     349            0 :                       continue;
     350              : 
     351           27 :                     if (CLASSTYPE_TEMPLATE_INSTANTIATION (t))
     352              :                       {
     353              :                         /* An uninstantiated template: check if there is a
     354              :                            pattern that could be used.  We don't want to
     355              :                            call instantiate_class_template as that could
     356              :                            cause further errors; this is just a hint.  */
     357           21 :                         tree part = most_specialized_partial_spec (t, tf_none);
     358           27 :                         cand = (part ? TI_TEMPLATE (part)
     359           15 :                                 : CLASSTYPE_TI_TEMPLATE (t));
     360              :                       }
     361              :                     else
     362            6 :                       cand = TYPE_NAME (t);
     363              :                   }
     364              :                 
     365           39 :                 if (!COMPLETE_TYPE_P (TREE_TYPE (cand)))
     366           24 :                   continue;
     367              : 
     368           15 :                 inform (DECL_SOURCE_LOCATION (cand),
     369              :                         "%q#T has a definition but does not correspond with "
     370              :                         "%q#T because it is attached to a different module",
     371           15 :                         TREE_TYPE (cand), ptype);
     372              :               }
     373              :         }
     374              :     }
     375              : }
     376              : 
     377              : /* Print an error message for invalid use of an incomplete type.
     378              :    VALUE is the expression that was used (or 0 if that isn't known)
     379              :    and TYPE is the type that was invalid.  DIAG_KIND indicates the
     380              :    type of diagnostic (see diagnostics/kinds.def).  */
     381              : 
     382              : bool
     383          929 : cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
     384              :                                 const_tree type,
     385              :                                 enum diagnostics::kind diag_kind)
     386              : {
     387          929 :   bool is_decl = false, complained = false;
     388              : 
     389              :   /* Avoid duplicate error message.  */
     390          929 :   if (TREE_CODE (type) == ERROR_MARK)
     391              :     return false;
     392              : 
     393          929 :   auto_diagnostic_group d;
     394          929 :   if (value)
     395              :     {
     396          411 :       STRIP_ANY_LOCATION_WRAPPER (value);
     397              : 
     398          411 :       if (VAR_P (value)
     399          366 :           || TREE_CODE (value) == PARM_DECL
     400          321 :           || TREE_CODE (value) == FIELD_DECL)
     401              :         {
     402          119 :           complained = emit_diagnostic (diag_kind, DECL_SOURCE_LOCATION (value), 0,
     403              :                                         "%qD has incomplete type", value);
     404          119 :           is_decl = true;
     405              :         }
     406              :     }
     407          929 :  retry:
     408              :   /* We must print an error message.  Be clever about what it says.  */
     409              : 
     410          935 :   switch (TREE_CODE (type))
     411              :     {
     412          669 :     case RECORD_TYPE:
     413          669 :     case UNION_TYPE:
     414          669 :     case ENUMERAL_TYPE:
     415          669 :       if (!is_decl)
     416          573 :         complained = emit_diagnostic (diag_kind, loc, 0,
     417              :                                       "invalid use of incomplete type %q#T",
     418              :                                       type);
     419          669 :       if (complained)
     420          666 :         cxx_incomplete_type_inform (type);
     421              :       break;
     422              : 
     423           12 :     case VOID_TYPE:
     424           12 :       complained = emit_diagnostic (diag_kind, loc, 0,
     425              :                        "invalid use of %qT", type);
     426           12 :       break;
     427              : 
     428           60 :     case ARRAY_TYPE:
     429           60 :       if (TYPE_DOMAIN (type))
     430              :         {
     431            6 :           type = TREE_TYPE (type);
     432            6 :           goto retry;
     433              :         }
     434           54 :       complained = emit_diagnostic (diag_kind, loc, 0,
     435              :                        "invalid use of array with unspecified bounds");
     436           54 :       break;
     437              : 
     438           72 :     case OFFSET_TYPE:
     439           72 :     bad_member:
     440           72 :       {
     441           72 :         tree member = TREE_OPERAND (value, 1);
     442           72 :         if (is_overloaded_fn (member) && !flag_ms_extensions)
     443              :           {
     444           69 :             gcc_rich_location richloc (loc);
     445              :             /* If "member" has no arguments (other than "this"), then
     446              :                add a fix-it hint.  */
     447           69 :             member = MAYBE_BASELINK_FUNCTIONS (member);
     448           69 :             if (TREE_CODE (member) == FUNCTION_DECL
     449           57 :                 && DECL_OBJECT_MEMBER_FUNCTION_P (member)
     450          126 :                 && type_num_arguments (TREE_TYPE (member)) == 1)
     451           54 :               richloc.add_fixit_insert_after ("()");
     452           69 :             complained = emit_diagnostic (diag_kind, &richloc, 0,
     453              :                              "invalid use of member function %qD "
     454              :                              "(did you forget the %<()%> ?)", member);
     455           69 :           }
     456              :         else
     457            3 :           complained = emit_diagnostic (diag_kind, loc, 0,
     458              :                            "invalid use of member %qD "
     459              :                            "(did you forget the %<&%> ?)", member);
     460              :       }
     461              :       break;
     462              : 
     463           28 :     case TEMPLATE_TYPE_PARM:
     464           28 :       if (is_auto (type))
     465              :         {
     466           16 :           if (CLASS_PLACEHOLDER_TEMPLATE (type))
     467            3 :             complained = emit_diagnostic (diag_kind, loc, 0,
     468              :                              "invalid use of placeholder %qT", type);
     469              :           else
     470           13 :             complained = emit_diagnostic (diag_kind, loc, 0,
     471              :                              "invalid use of %qT", type);
     472              :         }
     473              :       else
     474           12 :         complained = emit_diagnostic (diag_kind, loc, 0,
     475              :                          "invalid use of template type parameter %qT", type);
     476              :       break;
     477              : 
     478            3 :     case BOUND_TEMPLATE_TEMPLATE_PARM:
     479            3 :       complained = emit_diagnostic (diag_kind, loc, 0,
     480              :                        "invalid use of template template parameter %qT",
     481            3 :                        TYPE_NAME (type));
     482            3 :       break;
     483              : 
     484            0 :     case TYPE_PACK_EXPANSION:
     485            0 :       complained = emit_diagnostic (diag_kind, loc, 0,
     486              :                        "invalid use of pack expansion %qT", type);
     487            0 :       break;
     488              : 
     489           16 :     case TYPENAME_TYPE:
     490           16 :     case DECLTYPE_TYPE:
     491           16 :       complained = emit_diagnostic (diag_kind, loc, 0,
     492              :                        "invalid use of dependent type %qT", type);
     493           16 :       break;
     494              : 
     495          147 :     case LANG_TYPE:
     496          147 :       if (type == init_list_type_node)
     497              :         {
     498            3 :           complained = emit_diagnostic (diag_kind, loc, 0,
     499              :                            "invalid use of brace-enclosed initializer list");
     500            3 :           break;
     501              :         }
     502          144 :       gcc_assert (type == unknown_type_node);
     503          144 :       if (value && TREE_CODE (value) == COMPONENT_REF)
     504           72 :         goto bad_member;
     505           72 :       else if (value && TREE_CODE (value) == ADDR_EXPR)
     506           27 :         complained = emit_diagnostic (diag_kind, loc, 0,
     507              :                          "address of overloaded function with no contextual "
     508              :                          "type information");
     509           45 :       else if (value && TREE_CODE (value) == OVERLOAD)
     510           42 :         complained = emit_diagnostic (diag_kind, loc, 0,
     511              :                          "overloaded function with no contextual type information");
     512              :       else
     513            3 :         complained = emit_diagnostic (diag_kind, loc, 0,
     514              :                          "insufficient contextual information to determine type");
     515              :       break;
     516              : 
     517            0 :     default:
     518            0 :       gcc_unreachable ();
     519              :     }
     520              : 
     521          929 :   return complained;
     522          929 : }
     523              : 
     524              : /* Print an error message for invalid use of an incomplete type.
     525              :    VALUE is the expression that was used (or 0 if that isn't known)
     526              :    and TYPE is the type that was invalid.  */
     527              : 
     528              : void
     529           55 : cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type)
     530              : {
     531           55 :   cxx_incomplete_type_diagnostic (loc, value, type, diagnostics::kind::error);
     532           55 : }
     533              : 
     534              : 
     535              : /* We've just initialized subobject SUB; also insert a TARGET_EXPR with an
     536              :    EH-only cleanup for SUB.  Because of EH region nesting issues, we need to
     537              :    make the cleanup conditional on a flag that we will clear once the object is
     538              :    fully initialized, so push a new flag onto FLAGS.  */
     539              : 
     540              : static void
     541       998654 : maybe_push_temp_cleanup (tree sub, vec<tree,va_gc> **flags)
     542              : {
     543       998654 :   if (!flag_exceptions)
     544              :     return;
     545      1994336 :   if (tree cleanup
     546       997168 :       = cxx_maybe_build_cleanup (sub, tf_warning_or_error))
     547              :     {
     548          193 :       tree tx = get_internal_target_expr (boolean_true_node);
     549          193 :       tree flag = TARGET_EXPR_SLOT (tx);
     550          193 :       TARGET_EXPR_CLEANUP (tx) = build3 (COND_EXPR, void_type_node,
     551              :                                          flag, cleanup, void_node);
     552          193 :       add_stmt (tx);
     553          193 :       vec_safe_push (*flags, flag);
     554              :     }
     555              : }
     556              : 
     557              : /* F is something added to a cleanup flags vec by maybe_push_temp_cleanup or
     558              :    build_vec_init.  Return the code to disable the cleanup it controls.  */
     559              : 
     560              : tree
     561          750 : build_disable_temp_cleanup (tree f)
     562              : {
     563          750 :   tree d = f;
     564          750 :   tree i = boolean_false_node;
     565          750 :   if (TREE_CODE (f) == TREE_LIST)
     566              :     {
     567              :       /* To disable a build_vec_init cleanup, set
     568              :          iterator = maxindex.  */
     569          557 :       d = TREE_PURPOSE (f);
     570          557 :       i = TREE_VALUE (f);
     571          557 :       ggc_free (f);
     572              :     }
     573          750 :   return build2 (MODIFY_EXPR, TREE_TYPE (d), d, i);
     574              : }
     575              : 
     576              : /* The recursive part of split_nonconstant_init.  DEST is an lvalue
     577              :    expression to which INIT should be assigned.  INIT is a CONSTRUCTOR.
     578              :    Return true if the whole of the value was initialized by the
     579              :    generated statements.  */
     580              : 
     581              : static bool
     582       726849 : split_nonconstant_init_1 (tree dest, tree init, bool last,
     583              :                           vec<tree,va_gc> **flags)
     584              : {
     585       726849 :   unsigned HOST_WIDE_INT idx, tidx = HOST_WIDE_INT_M1U;
     586       726849 :   tree field_index, value;
     587       726849 :   tree type = TREE_TYPE (dest);
     588       726849 :   tree inner_type = NULL;
     589       726849 :   bool array_type_p = false;
     590       726849 :   bool complete_p = true;
     591       726849 :   HOST_WIDE_INT num_split_elts = 0;
     592       726849 :   tree last_split_elt = NULL_TREE;
     593              : 
     594       726849 :   switch (TREE_CODE (type))
     595              :     {
     596        20438 :     case ARRAY_TYPE:
     597        20438 :       inner_type = TREE_TYPE (type);
     598        20438 :       array_type_p = true;
     599        20438 :       if ((TREE_SIDE_EFFECTS (init)
     600          969 :            && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
     601        21143 :           || vla_type_p (type))
     602              :         {
     603          334 :           if (!TYPE_DOMAIN (type)
     604            3 :               && TREE_CODE (init) == CONSTRUCTOR
     605          337 :               && CONSTRUCTOR_NELTS (init))
     606              :             {
     607              :               /* Flexible array.  */
     608            3 :               cp_complete_array_type (&type, init, /*default*/true);
     609            3 :               dest = build1 (VIEW_CONVERT_EXPR, type, dest);
     610              :             }
     611              : 
     612              :           /* For an array, we only need/want a single cleanup region rather
     613              :              than one per element.  build_vec_init will handle it.  */
     614          334 :           tree code = build_vec_init (dest, NULL_TREE, init, false, 1,
     615              :                                       tf_warning_or_error, flags);
     616          334 :           add_stmt (code);
     617          334 :           return true;
     618              :         }
     619              :       /* FALLTHRU */
     620              : 
     621       725307 :     case RECORD_TYPE:
     622       725307 :     case UNION_TYPE:
     623       725307 :     case QUAL_UNION_TYPE:
     624      2420994 :       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx,
     625              :                                 field_index, value)
     626              :         {
     627              :           /* The current implementation of this algorithm assumes that
     628              :              the field was set for all the elements. This is usually done
     629              :              by process_init_constructor.  */
     630      1695687 :           gcc_assert (field_index);
     631              : 
     632      1695687 :           if (!array_type_p)
     633      1670621 :             inner_type = TREE_TYPE (field_index);
     634              : 
     635      1695687 :           tree sub;
     636      1695687 :           if (array_type_p)
     637        25066 :             sub = build4 (ARRAY_REF, inner_type, dest, field_index,
     638              :                           NULL_TREE, NULL_TREE);
     639              :           else
     640      1670621 :             sub = build3 (COMPONENT_REF, inner_type, dest, field_index,
     641              :                           NULL_TREE);
     642              : 
     643      5084255 :           bool elt_last = last && idx == CONSTRUCTOR_NELTS (init) - 1;
     644              : 
     645              :           /* We need to see sub-array TARGET_EXPR before cp_fold_r so we can
     646              :              handle cleanup flags properly.  */
     647      1695687 :           gcc_checking_assert (!target_expr_needs_replace (value));
     648              : 
     649      1695687 :           if (TREE_CODE (value) == CONSTRUCTOR)
     650              :             {
     651         1673 :               if (!split_nonconstant_init_1 (sub, value, elt_last, flags)
     652              :                       /* For flexible array member with initializer we
     653              :                          can't remove the initializer, because only the
     654              :                          initializer determines how many elements the
     655              :                          flexible array member has.  */
     656         1673 :                   || (!array_type_p
     657          653 :                       && TREE_CODE (inner_type) == ARRAY_TYPE
     658          547 :                       && TYPE_DOMAIN (inner_type) == NULL
     659           49 :                       && TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE
     660           49 :                       && COMPLETE_TYPE_P (TREE_TYPE (value))
     661           49 :                       && !integer_zerop (TYPE_SIZE (TREE_TYPE (value)))
     662           49 :                       && elt_last
     663           49 :                       && TYPE_HAS_TRIVIAL_DESTRUCTOR
     664              :                                 (strip_array_types (inner_type))))
     665              :                 complete_p = false;
     666              :               else
     667              :                 {
     668              :                   /* Mark element for removal.  */
     669          643 :                   last_split_elt = field_index;
     670          643 :                   CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
     671          643 :                   if (idx < tidx)
     672              :                     tidx = idx;
     673          643 :                   num_split_elts++;
     674              :                 }
     675              :             }
     676      1694014 :           else if (tree vi = get_vec_init_expr (value))
     677              :             {
     678           31 :               add_stmt (expand_vec_init_expr (sub, vi, tf_warning_or_error,
     679              :                                               flags));
     680              : 
     681              :               /* Mark element for removal.  */
     682           31 :               last_split_elt = field_index;
     683           31 :               CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
     684           31 :               if (idx < tidx)
     685              :                 tidx = idx;
     686           31 :               num_split_elts++;
     687              :             }
     688      1693983 :           else if (!initializer_constant_valid_p (value, inner_type))
     689              :             {
     690      1506738 :               tree code;
     691              : 
     692              :               /* Push cleanups for any preceding members with constant
     693              :                  initialization.  */
     694      1506738 :               if (CLASS_TYPE_P (type))
     695      1483787 :                 for (tree prev = (last_split_elt ?
     696       811736 :                                   DECL_CHAIN (last_split_elt)
     697      1483787 :                                   : TYPE_FIELDS (type));
     698         1706 :                      ; prev = DECL_CHAIN (prev))
     699              :                   {
     700      1485493 :                     prev = next_aggregate_field (prev);
     701      1485493 :                     if (prev == field_index)
     702              :                       break;
     703         1706 :                     tree ptype = TREE_TYPE (prev);
     704         1706 :                     if (TYPE_P (ptype) && type_build_dtor_call (ptype))
     705              :                       {
     706           42 :                         tree pcref = build3 (COMPONENT_REF, ptype, dest, prev,
     707              :                                              NULL_TREE);
     708           42 :                         maybe_push_temp_cleanup (pcref, flags);
     709              :                       }
     710         1706 :                   }
     711              : 
     712              :               /* Mark element for removal.  */
     713      1506738 :               CONSTRUCTOR_ELT (init, idx)->index = NULL_TREE;
     714      1506738 :               if (idx < tidx)
     715              :                 tidx = idx;
     716              : 
     717      1506738 :               if (TREE_CODE (field_index) == RANGE_EXPR)
     718              :                 {
     719              :                   /* Use build_vec_init to initialize a range.  */
     720            0 :                   tree low = TREE_OPERAND (field_index, 0);
     721            0 :                   tree hi = TREE_OPERAND (field_index, 1);
     722            0 :                   sub = build4 (ARRAY_REF, inner_type, dest, low,
     723              :                                 NULL_TREE, NULL_TREE);
     724            0 :                   sub = cp_build_addr_expr (sub, tf_warning_or_error);
     725            0 :                   tree max = size_binop (MINUS_EXPR, hi, low);
     726            0 :                   code = build_vec_init (sub, max, value, false, 0,
     727              :                                          tf_warning_or_error);
     728            0 :                   add_stmt (code);
     729            0 :                   if (tree_fits_shwi_p (max))
     730            0 :                     num_split_elts += tree_to_shwi (max);
     731              :                 }
     732              :               else
     733              :                 {
     734              :                   /* We may need to add a copy constructor call if
     735              :                      the field has [[no_unique_address]].  */
     736      1506738 :                   if (unsafe_return_slot_p (sub))
     737              :                     {
     738              :                       /* But not if the initializer is an implicit ctor call
     739              :                          we just built in digest_init.  */
     740          462 :                       if (TREE_CODE (value) == TARGET_EXPR
     741          462 :                           && TARGET_EXPR_LIST_INIT_P (value)
     742          485 :                           && make_safe_copy_elision (sub, value))
     743           23 :                         goto build_init;
     744              : 
     745          439 :                       if (TREE_CODE (value) == TARGET_EXPR)
     746              :                         /* We have to add this constructor, so we will not
     747              :                            elide.  */
     748          439 :                         TARGET_EXPR_ELIDING_P (value) = false;
     749              : 
     750          439 :                       tree name = (DECL_FIELD_IS_BASE (field_index)
     751          439 :                                    ? base_ctor_identifier
     752          439 :                                    : complete_ctor_identifier);
     753          439 :                       releasing_vec args = make_tree_vector_single (value);
     754          439 :                       code = build_special_member_call
     755          439 :                         (sub, name, &args, inner_type,
     756              :                          LOOKUP_NORMAL, tf_warning_or_error);
     757          439 :                     }
     758              :                   else
     759              :                     {
     760      1506276 :                     build_init:
     761      1506299 :                       code = cp_build_init_expr (sub, value);
     762              :                     }
     763      1506738 :                   code = build_stmt (input_location, EXPR_STMT, code);
     764      1506738 :                   add_stmt (code);
     765      1506738 :                   if (!elt_last)
     766       998612 :                     maybe_push_temp_cleanup (sub, flags);
     767              :                 }
     768              : 
     769      1506738 :               last_split_elt = field_index;
     770      1506738 :               num_split_elts++;
     771              :             }
     772              :         }
     773       725307 :       if (num_split_elts == 1)
     774       288969 :         CONSTRUCTOR_ELTS (init)->ordered_remove (tidx);
     775       436338 :       else if (num_split_elts > 1)
     776              :         {
     777              :           /* Perform the delayed ordered removal of non-constant elements
     778              :              we split out.  */
     779      1622116 :           for (idx = tidx; idx < CONSTRUCTOR_NELTS (init); ++idx)
     780      1218757 :             if (CONSTRUCTOR_ELT (init, idx)->index == NULL_TREE)
     781              :               ;
     782              :             else
     783              :               {
     784          314 :                 *CONSTRUCTOR_ELT (init, tidx) = *CONSTRUCTOR_ELT (init, idx);
     785          314 :                 ++tidx;
     786              :               }
     787       403359 :           vec_safe_truncate (CONSTRUCTOR_ELTS (init), tidx);
     788              :         }
     789              :       break;
     790              : 
     791         1208 :     case VECTOR_TYPE:
     792         1208 :       if (!initializer_constant_valid_p (init, type))
     793              :         {
     794         1203 :           tree code;
     795         1203 :           tree cons = copy_node (init);
     796         1203 :           CONSTRUCTOR_ELTS (init) = NULL;
     797         1203 :           code = build2 (MODIFY_EXPR, type, dest, cons);
     798         1203 :           code = build_stmt (input_location, EXPR_STMT, code);
     799         1203 :           add_stmt (code);
     800         1203 :           num_split_elts += CONSTRUCTOR_NELTS (init);
     801              :         }
     802              :       break;
     803              : 
     804            0 :     default:
     805            0 :       gcc_unreachable ();
     806              :     }
     807              : 
     808              :   /* The rest of the initializer is now a constant. */
     809       726515 :   TREE_CONSTANT (init) = 1;
     810       726515 :   TREE_SIDE_EFFECTS (init) = 0;
     811              : 
     812              :   /* We didn't split out anything.  */
     813       726515 :   if (num_split_elts == 0)
     814              :     return false;
     815              : 
     816       692328 :   return complete_p && complete_ctor_at_level_p (TREE_TYPE (init),
     817              :                                                  num_split_elts, inner_type);
     818              : }
     819              : 
     820              : /* A subroutine of store_init_value.  Splits non-constant static
     821              :    initializer INIT into a constant part and generates code to
     822              :    perform the non-constant part of the initialization to DEST.
     823              :    Returns the code for the runtime init.  */
     824              : 
     825              : tree
     826     18444040 : split_nonconstant_init (tree dest, tree init)
     827              : {
     828     18444040 :   tree code;
     829              : 
     830     18444040 :   if (TREE_CODE (init) == TARGET_EXPR)
     831       965110 :     init = TARGET_EXPR_INITIAL (init);
     832     18444040 :   if (TREE_CODE (init) == CONSTRUCTOR)
     833              :     {
     834              :       /* Subobject initializers are not full-expressions.  */
     835       725176 :       auto fe = (make_temp_override
     836       725176 :                  (current_stmt_tree ()->stmts_are_full_exprs_p, 0));
     837              : 
     838       725176 :       init = cp_fully_fold_init (init);
     839       725176 :       code = push_stmt_list ();
     840              : 
     841              :       /* If the complete object is an array, build_vec_init's cleanup is
     842              :          enough.  Otherwise, collect flags for disabling subobject
     843              :          cleanups once the complete object is fully constructed.  */
     844       725176 :       vec<tree, va_gc> *flags = nullptr;
     845       725176 :       if (TREE_CODE (TREE_TYPE (dest)) != ARRAY_TYPE)
     846       705791 :         flags = make_tree_vector ();
     847              : 
     848       725176 :       if (split_nonconstant_init_1 (dest, init, true, &flags))
     849       507674 :         init = NULL_TREE;
     850              : 
     851      2137712 :       for (tree f : flags)
     852          476 :         finish_expr_stmt (build_disable_temp_cleanup (f));
     853       725176 :       release_tree_vector (flags);
     854              : 
     855       725176 :       code = pop_stmt_list (code);
     856       725176 :       if (VAR_P (dest) && !is_local_temp (dest))
     857              :         {
     858       723626 :           DECL_INITIAL (dest) = init;
     859       723626 :           TREE_READONLY (dest) = 0;
     860              :         }
     861         1550 :       else if (init)
     862              :         {
     863          332 :           tree ie = cp_build_init_expr (dest, init);
     864          332 :           code = add_stmt_to_compound (ie, code);
     865              :         }
     866       725176 :     }
     867     17718864 :   else if (TREE_CODE (init) == STRING_CST
     868     17718864 :            && array_of_runtime_bound_p (TREE_TYPE (dest)))
     869           25 :     code = build_vec_init (dest, NULL_TREE, init, /*value-init*/false,
     870              :                            /*from array*/1, tf_warning_or_error);
     871              :   else
     872     17718839 :     code = cp_build_init_expr (dest, init);
     873              : 
     874     18444040 :   return code;
     875              : }
     876              : 
     877              : /* T is the initializer of a constexpr variable.  Set CONSTRUCTOR_MUTABLE_POISON
     878              :    for any CONSTRUCTOR within T that contains (directly or indirectly) a mutable
     879              :    member, thereby poisoning it so it can't be copied to another a constexpr
     880              :    variable or read during constexpr evaluation.  */
     881              : 
     882              : static void
     883     39957753 : poison_mutable_constructors (tree t)
     884              : {
     885     39957753 :   if (TREE_CODE (t) != CONSTRUCTOR)
     886              :     return;
     887              : 
     888      2659949 :   if (cp_has_mutable_p (TREE_TYPE (t)))
     889              :     {
     890          157 :       CONSTRUCTOR_MUTABLE_POISON (t) = true;
     891              : 
     892          157 :       if (vec<constructor_elt, va_gc> *elts = CONSTRUCTOR_ELTS (t))
     893          339 :         for (const constructor_elt &ce : *elts)
     894          188 :           poison_mutable_constructors (ce.value);
     895              :     }
     896              : }
     897              : 
     898              : /* Perform appropriate conversions on the initial value of a variable,
     899              :    store it in the declaration DECL,
     900              :    and print any error messages that are appropriate.
     901              :    If the init is invalid, store an ERROR_MARK.
     902              : 
     903              :    C++: Note that INIT might be a TREE_LIST, which would mean that it is
     904              :    a base class initializer for some aggregate type, hopefully compatible
     905              :    with DECL.  If INIT is a single element, and DECL is an aggregate
     906              :    type, we silently convert INIT into a TREE_LIST, allowing a constructor
     907              :    to be called.
     908              : 
     909              :    If INIT is a TREE_LIST and there is no constructor, turn INIT
     910              :    into a CONSTRUCTOR and use standard initialization techniques.
     911              :    Perhaps a warning should be generated?
     912              : 
     913              :    Returns code to be executed if initialization could not be performed
     914              :    for static variable.  In that case, caller must emit the code.  */
     915              : 
     916              : tree
     917     61198350 : store_init_value (tree decl, tree init, vec<tree, va_gc>** cleanups, int flags)
     918              : {
     919     61198350 :   tree value, type;
     920              : 
     921              :   /* If variable's type was invalidly declared, just ignore it.  */
     922              : 
     923     61198350 :   type = TREE_TYPE (decl);
     924     61198350 :   if (TREE_CODE (type) == ERROR_MARK)
     925              :     return NULL_TREE;
     926              : 
     927      5971291 :   if (MAYBE_CLASS_TYPE_P (type))
     928              :     {
     929      5941917 :       if (TREE_CODE (init) == TREE_LIST)
     930              :         {
     931            0 :           error ("constructor syntax used, but no constructor declared "
     932              :                  "for type %qT", type);
     933            0 :           init = build_constructor_from_list (init_list_type_node, nreverse (init));
     934              :         }
     935              :     }
     936              : 
     937              :   /* End of special C++ code.  */
     938              : 
     939     61198350 :   if (flags & LOOKUP_ALREADY_DIGESTED)
     940              :     value = init;
     941              :   else
     942              :     {
     943     57221199 :       if (TREE_STATIC (decl))
     944     34357342 :         flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
     945              :       /* Digest the specified initializer into an expression.  */
     946     57221199 :       value = digest_init_flags (type, init, flags, tf_warning_or_error);
     947              :     }
     948              : 
     949              :   /* Look for braced array initializers for character arrays and
     950              :      recursively convert them into STRING_CSTs.  */
     951     61198350 :   value = braced_lists_to_strings (type, value);
     952              : 
     953     61198350 :   current_ref_temp_count = 0;
     954     61198350 :   value = extend_ref_init_temps (decl, value, cleanups);
     955              : 
     956              :   /* In C++11 constant expression is a semantic, not syntactic, property.
     957              :      In C++98, make sure that what we thought was a constant expression at
     958              :      template definition time is still constant and otherwise perform this
     959              :      as optimization, e.g. to fold SIZEOF_EXPRs in the initializer.  */
     960     61198350 :   if (decl_maybe_constant_var_p (decl) || TREE_STATIC (decl))
     961              :     {
     962     39960262 :       bool const_init;
     963     39960262 :       tree oldval = value;
     964     39960262 :       if (DECL_DECLARED_CONSTEXPR_P (decl)
     965      7096702 :           || DECL_DECLARED_CONSTINIT_P (decl)
     966     47056572 :           || (DECL_IN_AGGR_P (decl)
     967      1226408 :               && DECL_INITIALIZED_IN_CLASS_P (decl)))
     968              :         {
     969     34090240 :           value = fold_non_dependent_expr (value, tf_warning_or_error,
     970              :                                            /*manifestly_const_eval=*/true,
     971              :                                            decl);
     972     34087543 :           if (value == error_mark_node)
     973              :             ;
     974              :           /* Diagnose a non-constant initializer for constexpr variable or
     975              :              non-inline in-class-initialized static data member.  */
     976     34087324 :           else if (!is_constant_expression (value))
     977              :             {
     978              :               /* Maybe we want to give this message for constexpr variables as
     979              :                  well, but that will mean a lot of testsuite adjustment.  */
     980          262 :               if (DECL_DECLARED_CONSTINIT_P (decl))
     981           88 :               error_at (location_of (decl),
     982              :                         "%<constinit%> variable %qD does not have a "
     983              :                         "constant initializer", decl);
     984          262 :               require_constant_expression (value);
     985          262 :               value = error_mark_node;
     986              :             }
     987              :           else
     988              :             {
     989     34087062 :               value = maybe_constant_init (value, decl, true);
     990              : 
     991              :               /* In a template we might not have done the necessary
     992              :                  transformations to make value actually constant,
     993              :                  e.g. extend_ref_init_temps.  */
     994     34087062 :               if (!processing_template_decl
     995     34087062 :                   && !TREE_CONSTANT (value))
     996              :                 {
     997         1510 :                   if (DECL_DECLARED_CONSTINIT_P (decl))
     998           41 :                   error_at (location_of (decl),
     999              :                             "%<constinit%> variable %qD does not have a "
    1000              :                             "constant initializer", decl);
    1001         1510 :                   value = cxx_constant_init (value, decl);
    1002              :                 }
    1003              :             }
    1004              :         }
    1005              :       else
    1006      5870022 :         value = fold_non_dependent_init (value, tf_warning_or_error,
    1007              :                                          /*manifestly_const_eval=*/true, decl);
    1008     39957565 :       poison_mutable_constructors (value);
    1009     39957565 :       const_init = (reduced_constant_expression_p (value)
    1010     39957565 :                     || error_operand_p (value));
    1011     39957565 :       DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = const_init;
    1012              :       /* FIXME setting TREE_CONSTANT on refs breaks the back end.  */
    1013     39957565 :       if (!TYPE_REF_P (type))
    1014     43309037 :         TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl);
    1015     39957565 :       if (!const_init)
    1016     24519340 :         value = oldval;
    1017              :     }
    1018              :   /* Don't fold initializers of automatic variables in constexpr functions,
    1019              :      that might fold away something that needs to be diagnosed at constexpr
    1020              :      evaluation time.  */
    1021     61195653 :   if (!current_function_decl
    1022     26520219 :       || !DECL_DECLARED_CONSTEXPR_P (current_function_decl)
    1023     69118451 :       || TREE_STATIC (decl))
    1024     53273460 :     value = cp_fully_fold_init (value);
    1025              : 
    1026              :   /* Handle aggregate NSDMI in non-constant initializers, too.  */
    1027     61195653 :   value = replace_placeholders (value, decl);
    1028              : 
    1029              :   /* A COMPOUND_LITERAL_P CONSTRUCTOR is the syntactic form; by the time we get
    1030              :      here it should have been digested into an actual value for the type.  */
    1031     61195653 :   gcc_checking_assert (TREE_CODE (value) != CONSTRUCTOR
    1032              :                        || processing_template_decl
    1033              :                        || VECTOR_TYPE_P (type)
    1034              :                        || !TREE_HAS_CONSTRUCTOR (value));
    1035              : 
    1036              :   /* If the initializer is not a constant, fill in DECL_INITIAL with
    1037              :      the bits that are constant, and then return an expression that
    1038              :      will perform the dynamic initialization.  */
    1039     61195653 :   if (value != error_mark_node
    1040     61190854 :       && !processing_template_decl
    1041    120139865 :       && (TREE_SIDE_EFFECTS (value)
    1042     49873492 :           || vla_type_p (type)
    1043     49873397 :           || ! reduced_constant_expression_p (value)))
    1044     18419657 :     return split_nonconstant_init (decl, value);
    1045              : 
    1046              :   /* DECL may change value; purge caches.  */
    1047     42775996 :   clear_cv_and_fold_caches ();
    1048              : 
    1049              :   /* If the value is a constant, just put it in DECL_INITIAL.  If DECL
    1050              :      is an automatic variable, the middle end will turn this into a
    1051              :      dynamic initialization later.  */
    1052     42775996 :   DECL_INITIAL (decl) = value;
    1053     42775996 :   return NULL_TREE;
    1054              : }
    1055              : 
    1056              : 
    1057              : /* Give diagnostic about narrowing conversions within { }, or as part of
    1058              :    a converted constant expression.  If CONST_ONLY, only check
    1059              :    constants.  */
    1060              : 
    1061              : bool
    1062     55804159 : check_narrowing (tree type, tree init, tsubst_flags_t complain,
    1063              :                  bool const_only/*= false*/)
    1064              : {
    1065     55804159 :   tree ftype = unlowered_expr_type (init);
    1066     55804159 :   bool ok = true;
    1067     55804159 :   REAL_VALUE_TYPE d;
    1068              : 
    1069     55753753 :   if (((!warn_narrowing || !(complain & tf_warning))
    1070      5100574 :        && cxx_dialect == cxx98)
    1071     55754658 :       || !ARITHMETIC_TYPE_P (type)
    1072              :       /* Don't emit bogus warnings with e.g. value-dependent trees.  */
    1073    111320649 :       || instantiation_dependent_expression_p (init))
    1074       433123 :     return ok;
    1075              : 
    1076           14 :   if (BRACE_ENCLOSED_INITIALIZER_P (init)
    1077     55371036 :       && TREE_CODE (type) == COMPLEX_TYPE)
    1078              :     {
    1079            0 :       tree elttype = TREE_TYPE (type);
    1080            0 :       if (CONSTRUCTOR_NELTS (init) > 0)
    1081            0 :         ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 0)->value,
    1082              :                                complain);
    1083            0 :       if (CONSTRUCTOR_NELTS (init) > 1)
    1084            0 :         ok &= check_narrowing (elttype, CONSTRUCTOR_ELT (init, 1)->value,
    1085              :                                complain);
    1086            0 :       return ok;
    1087              :     }
    1088              : 
    1089              :   /* Even non-dependent expressions can still have template
    1090              :      codes like CAST_EXPR, so use *_non_dependent_expr to cope.  */
    1091     55371036 :   init = fold_non_dependent_expr (init, complain, /*manifest*/true);
    1092     55371036 :   if (init == error_mark_node)
    1093              :     return ok;
    1094              : 
    1095              :   /* If we were asked to only check constants, return early.  */
    1096     55371033 :   if (const_only && !TREE_CONSTANT (init))
    1097              :     return ok;
    1098              : 
    1099     55369535 :   if (CP_INTEGRAL_TYPE_P (type)
    1100     55356077 :       && SCALAR_FLOAT_TYPE_P (ftype))
    1101              :     ok = false;
    1102     55369315 :   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
    1103     55155344 :            && CP_INTEGRAL_TYPE_P (type))
    1104              :     {
    1105     55149503 :       if (TREE_CODE (ftype) == ENUMERAL_TYPE)
    1106              :         /* Check for narrowing based on the values of the enumeration. */
    1107       299469 :         ftype = ENUM_UNDERLYING_TYPE (ftype);
    1108              :       /* Undo convert_bitfield_to_declared_type (STRIP_NOPS isn't enough).  */
    1109     55149503 :       tree op = init;
    1110     55151118 :       while (CONVERT_EXPR_P (op))
    1111         1615 :         op = TREE_OPERAND (op, 0);
    1112              :       /* Core 2627 says that we shouldn't warn when "the source is a bit-field
    1113              :          whose width w is less than that of its type (or, for an enumeration
    1114              :          type, its underlying type) and the target type can represent all the
    1115              :          values of a hypothetical extended integer type with width w and with
    1116              :          the same signedness as the original type".  */
    1117     55149503 :       if (is_bitfield_expr_with_lowered_type (op)
    1118     55149503 :           && TYPE_PRECISION (TREE_TYPE (op)) < TYPE_PRECISION (ftype))
    1119           70 :         ftype = TREE_TYPE (op);
    1120     55149503 :       if ((tree_int_cst_lt (TYPE_MAX_VALUE (type),
    1121     55149503 :                             TYPE_MAX_VALUE (ftype))
    1122     54885421 :            || tree_int_cst_lt (TYPE_MIN_VALUE (ftype),
    1123     54885421 :                                TYPE_MIN_VALUE (type)))
    1124    107344688 :           && (TREE_CODE (init) != INTEGER_CST
    1125     52459151 :               || !int_fits_type_p (init, type)))
    1126              :         ok = false;
    1127              :     }
    1128              :   /* [dcl.init.list]#7.2: "from long double to double or float, or from
    1129              :       double to float".  */
    1130       219812 :   else if (SCALAR_FLOAT_TYPE_P (ftype)
    1131         7617 :            && SCALAR_FLOAT_TYPE_P (type))
    1132              :     {
    1133        15258 :       if ((extended_float_type_p (ftype) || extended_float_type_p (type))
    1134         7608 :           ? /* "from a floating-point type T to another floating-point type
    1135              :                whose floating-point conversion rank is neither greater than
    1136              :                nor equal to that of T".
    1137              :                So, it is ok if
    1138              :                cp_compare_floating_point_conversion_ranks (ftype, type)
    1139              :                returns -2 (type has greater conversion rank than ftype)
    1140              :                or [-1..1] (type has equal conversion rank as ftype, possibly
    1141              :                different subrank.  Only do this if at least one of the
    1142              :                types is extended floating-point type, otherwise keep doing
    1143              :                what we did before (for the sake of non-standard
    1144              :                backend types).  */
    1145          209 :             cp_compare_floating_point_conversion_ranks (ftype, type) >= 2
    1146         7399 :           : ((same_type_p (ftype, long_double_type_node)
    1147           76 :               && (same_type_p (type, double_type_node)
    1148           65 :                   || same_type_p (type, float_type_node)))
    1149         7386 :              || (same_type_p (ftype, double_type_node)
    1150         6918 :                  && same_type_p (type, float_type_node))
    1151         9112 :              || (TYPE_PRECISION (type) < TYPE_PRECISION (ftype))))
    1152              :         {
    1153         5742 :           if (TREE_CODE (init) == REAL_CST)
    1154              :             {
    1155              :               /* Issue 703: Loss of precision is OK as long as the value is
    1156              :                  within the representable range of the new type.  */
    1157         5666 :               REAL_VALUE_TYPE r;
    1158         5666 :               d = TREE_REAL_CST (init);
    1159         5666 :               real_convert (&r, TYPE_MODE (type), &d);
    1160         5666 :               if (real_isinf (&r))
    1161            0 :                 ok = false;
    1162              :             }
    1163              :           else
    1164              :             ok = false;
    1165              :         }
    1166              :     }
    1167       212204 :   else if (INTEGRAL_OR_ENUMERATION_TYPE_P (ftype)
    1168         5841 :            && SCALAR_FLOAT_TYPE_P (type))
    1169              :     {
    1170         5806 :       ok = false;
    1171         5806 :       if (TREE_CODE (init) == INTEGER_CST)
    1172              :         {
    1173         5768 :           d = real_value_from_int_cst (0, init);
    1174         5768 :           if (exact_real_truncate (TYPE_MODE (type), &d))
    1175              :             ok = true;
    1176              :         }
    1177              :     }
    1178       206398 :   else if (TREE_CODE (type) == BOOLEAN_TYPE
    1179       206398 :            && (TYPE_PTR_P (ftype) || TYPE_PTRMEM_P (ftype)))
    1180              :     /* C++20 P1957R2: converting from a pointer type or a pointer-to-member
    1181              :        type to bool should be considered narrowing.  This is a DR so is not
    1182              :        limited to C++20 only.  */
    1183              :     ok = false;
    1184              : 
    1185         6559 :   bool almost_ok = ok;
    1186         6559 :   if (!ok && !CONSTANT_CLASS_P (init) && (complain & tf_warning_or_error))
    1187              :     {
    1188          161 :       tree folded = cp_fully_fold (init);
    1189          161 :       if (TREE_CONSTANT (folded) && check_narrowing (type, folded, tf_none))
    1190              :         almost_ok = true;
    1191              :     }
    1192              : 
    1193          893 :   if (!ok)
    1194              :     {
    1195          893 :       location_t loc = cp_expr_loc_or_input_loc (init);
    1196          893 :       if (cxx_dialect == cxx98)
    1197              :         {
    1198            1 :           if (complain & tf_warning)
    1199            1 :             warning_at (loc, OPT_Wnarrowing, "narrowing conversion of %qE "
    1200              :                         "from %qH to %qI is ill-formed in C++11",
    1201              :                         init, ftype, type);
    1202              :           ok = true;
    1203              :         }
    1204          892 :       else if (!CONSTANT_CLASS_P (init))
    1205              :         {
    1206          286 :           if (complain & tf_warning_or_error)
    1207              :             {
    1208          161 :               auto_diagnostic_group d;
    1209            4 :               if ((!almost_ok || pedantic)
    1210          304 :                   && pedwarn (loc, OPT_Wnarrowing,
    1211              :                               "narrowing conversion of %qE from %qH to %qI",
    1212              :                               init, ftype, type)
    1213          306 :                   && almost_ok)
    1214            2 :                 inform (loc, " the expression has a constant value but is not "
    1215              :                         "a C++ constant-expression");
    1216          161 :               ok = true;
    1217          161 :             }
    1218              :         }
    1219          606 :       else if (complain & tf_error)
    1220              :         {
    1221          592 :           int savederrorcount = errorcount;
    1222          592 :           permerror_opt (loc, OPT_Wnarrowing,
    1223              :                          "narrowing conversion of %qE from %qH to %qI",
    1224              :                          init, ftype, type);
    1225          592 :           if (errorcount == savederrorcount)
    1226     55803543 :             ok = true;
    1227              :         }
    1228              :     }
    1229              : 
    1230              :   return ok;
    1231              : }
    1232              : 
    1233              : /* True iff TYPE is a C++20 "ordinary" character type.  */
    1234              : 
    1235              : bool
    1236        39375 : ordinary_char_type_p (tree type)
    1237              : {
    1238        39375 :   type = TYPE_MAIN_VARIANT (type);
    1239        39375 :   return (type == char_type_node
    1240        19746 :           || type == signed_char_type_node
    1241        59099 :           || type == unsigned_char_type_node);
    1242              : }
    1243              : 
    1244              : /* True iff the string literal INIT has a type suitable for initializing array
    1245              :    TYPE.  */
    1246              : 
    1247              : bool
    1248       693305 : array_string_literal_compatible_p (tree type, tree init)
    1249              : {
    1250       693305 :   tree to_char_type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
    1251       693305 :   tree from_char_type = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init)));
    1252              : 
    1253       693305 :   if (to_char_type == from_char_type)
    1254              :     return true;
    1255              :   /* The array element type does not match the initializing string
    1256              :      literal element type; this is only allowed when both types are
    1257              :      ordinary character type.  There are no string literals of
    1258              :      signed or unsigned char type in the language, but we can get
    1259              :      them internally from converting braced-init-lists to
    1260              :      STRING_CST.  */
    1261        19732 :   if (ordinary_char_type_p (to_char_type)
    1262        19732 :       && ordinary_char_type_p (from_char_type))
    1263              :     return true;
    1264              : 
    1265              :   /* P2513 (C++20/C++23): "an array of char or unsigned char may
    1266              :      be initialized by a UTF-8 string literal, or by such a string
    1267              :      literal enclosed in braces."  */
    1268          190 :   if (from_char_type == char8_type_node
    1269           98 :       && (to_char_type == char_type_node
    1270           32 :           || to_char_type == unsigned_char_type_node))
    1271              :     return true;
    1272              : 
    1273              :   return false;
    1274              : }
    1275              : 
    1276              : /* Process the initializer INIT for a variable of type TYPE, emitting
    1277              :    diagnostics for invalid initializers and converting the initializer as
    1278              :    appropriate.
    1279              : 
    1280              :    For aggregate types, it assumes that reshape_init has already run, thus the
    1281              :    initializer will have the right shape (brace elision has been undone).
    1282              : 
    1283              :    NESTED is non-zero iff we are being called for an element of a CONSTRUCTOR,
    1284              :    2 iff the element of a CONSTRUCTOR is inside another CONSTRUCTOR.  */
    1285              : 
    1286              : static tree
    1287    120351578 : digest_init_r (tree type, tree init, int nested, int flags,
    1288              :                tsubst_flags_t complain)
    1289              : {
    1290    120351578 :   enum tree_code code = TREE_CODE (type);
    1291              : 
    1292    120351578 :   if (error_operand_p (init))
    1293         2017 :     return error_mark_node;
    1294              : 
    1295    120349561 :   gcc_assert (init);
    1296              : 
    1297              :   /* We must strip the outermost array type when completing the type,
    1298              :      because the its bounds might be incomplete at the moment.  */
    1299    121444439 :   if (!complete_type_or_maybe_complain (code == ARRAY_TYPE
    1300      1094878 :                                         ? TREE_TYPE (type) : type, NULL_TREE,
    1301              :                                         complain))
    1302           28 :     return error_mark_node;
    1303              : 
    1304    120349533 :   location_t loc = cp_expr_loc_or_input_loc (init);
    1305              : 
    1306    120349533 :   tree stripped_init = init;
    1307              : 
    1308     11684282 :   if (BRACE_ENCLOSED_INITIALIZER_P (init)
    1309    132030248 :       && CONSTRUCTOR_IS_PAREN_INIT (init))
    1310         1335 :     flags |= LOOKUP_AGGREGATE_PAREN_INIT;
    1311              : 
    1312              :   /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue
    1313              :      (g++.old-deja/g++.law/casts2.C).  */
    1314    120349533 :   if (TREE_CODE (init) == NON_LVALUE_EXPR)
    1315     34564002 :     stripped_init = TREE_OPERAND (init, 0);
    1316              : 
    1317    120349533 :   stripped_init = tree_strip_any_location_wrapper (stripped_init);
    1318              : 
    1319              :   /* Initialization of an array of chars from a string constant. The initializer
    1320              :      can be optionally enclosed in braces, but reshape_init has already removed
    1321              :      them if they were present.  */
    1322    120349533 :   if (code == ARRAY_TYPE)
    1323              :     {
    1324      1218909 :       if (nested && !TYPE_DOMAIN (type))
    1325              :         /* C++ flexible array members have a null domain.  */
    1326              :         {
    1327          461 :           if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
    1328          410 :             pedwarn (loc, OPT_Wpedantic,
    1329              :                      "initialization of a flexible array member");
    1330              :           else
    1331              :             {
    1332           51 :               if (complain & tf_error)
    1333           51 :                 error_at (loc, "non-static initialization of"
    1334              :                                " a flexible array member");
    1335           51 :               return error_mark_node;
    1336              :             }
    1337              :         }
    1338              : 
    1339      1094827 :       tree typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type));
    1340      1094827 :       if (char_type_p (typ1)
    1341      1094827 :           && TREE_CODE (stripped_init) == STRING_CST)
    1342              :         {
    1343       693260 :           if (!array_string_literal_compatible_p (type, init))
    1344              :             {
    1345          111 :               if (complain & tf_error)
    1346          111 :                 error_at (loc, "cannot initialize array of %qT from "
    1347              :                           "a string literal with type array of %qT",
    1348              :                           typ1,
    1349          111 :                           TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (init))));
    1350          111 :               return error_mark_node;
    1351              :             }
    1352              : 
    1353       693531 :           if (nested == 2 && !TYPE_DOMAIN (type))
    1354              :             {
    1355           24 :               if (complain & tf_error)
    1356           24 :                 error_at (loc, "initialization of flexible array member "
    1357              :                                "in a nested context");
    1358           24 :               return error_mark_node;
    1359              :             }
    1360              : 
    1361       693125 :           if (type != TREE_TYPE (init)
    1362       693125 :               && !variably_modified_type_p (type, NULL_TREE))
    1363              :             {
    1364        21806 :               init = copy_node (init);
    1365        21806 :               TREE_TYPE (init) = type;
    1366              :               /* If we have a location wrapper, then also copy the wrapped
    1367              :                  node, and update the copy's type.  */
    1368        21806 :               if (location_wrapper_p (init))
    1369              :                 {
    1370        20877 :                   stripped_init = copy_node (stripped_init);
    1371        20877 :                   TREE_OPERAND (init, 0) = stripped_init;
    1372        20877 :                   TREE_TYPE (stripped_init) = type;
    1373              :                 }
    1374              :             }
    1375       693125 :           if (TYPE_DOMAIN (type) && TREE_CONSTANT (TYPE_SIZE (type)))
    1376              :             {
    1377              :               /* Not a flexible array member.  */
    1378       693055 :               int size = TREE_INT_CST_LOW (TYPE_SIZE (type));
    1379       693055 :               size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
    1380              :               /* In C it is ok to subtract 1 from the length of the string
    1381              :                  because it's ok to ignore the terminating null char that is
    1382              :                  counted in the length of the constant, but in C++ this would
    1383              :                  be invalid.  */
    1384       693055 :               if (size < TREE_STRING_LENGTH (stripped_init))
    1385              :                 {
    1386          159 :                   permerror (loc, "initializer-string for %qT is too long",
    1387              :                              type);
    1388              : 
    1389          159 :                   init = build_string (size,
    1390          159 :                                        TREE_STRING_POINTER (stripped_init));
    1391          159 :                   TREE_TYPE (init) = type;
    1392              :                 }
    1393              :             }
    1394       693125 :           return init;
    1395              :         }
    1396              :     }
    1397              : 
    1398              :   /* Handle scalar types (including conversions) and references.  */
    1399         1209 :   if ((code != COMPLEX_TYPE || BRACE_ENCLOSED_INITIALIZER_P (stripped_init))
    1400    119656267 :       && (SCALAR_TYPE_P (type) || code == REFERENCE_TYPE))
    1401              :     {
    1402              :       /* Narrowing is OK when initializing an aggregate from
    1403              :          a parenthesized list.  */
    1404    108260197 :       if (nested && !(flags & LOOKUP_AGGREGATE_PAREN_INIT))
    1405     53126594 :         flags |= LOOKUP_NO_NARROWING;
    1406    108260197 :       if (TREE_CODE (init) == RAW_DATA_CST && !TYPE_UNSIGNED (type))
    1407              :         {
    1408           48 :           tree ret = init;
    1409           48 :           if ((flags & LOOKUP_NO_NARROWING) || warn_conversion)
    1410        11022 :             for (unsigned int i = 0;
    1411        11070 :                  i < (unsigned) RAW_DATA_LENGTH (init); ++i)
    1412        11022 :               if (RAW_DATA_SCHAR_ELT (init, i) < 0)
    1413              :                 {
    1414           60 :                   if ((flags & LOOKUP_NO_NARROWING))
    1415              :                     {
    1416           60 :                       tree elt
    1417           60 :                         = build_int_cst (integer_type_node,
    1418           60 :                                          RAW_DATA_UCHAR_ELT (init, i));
    1419           60 :                       if (!check_narrowing (type, elt, complain, false))
    1420              :                         {
    1421           30 :                           if (!(complain & tf_warning_or_error))
    1422            0 :                             ret = error_mark_node;
    1423           30 :                           continue;
    1424              :                         }
    1425              :                     }
    1426           30 :                   if (warn_conversion)
    1427           60 :                     warning (OPT_Wconversion,
    1428              :                              "conversion from %qT to %qT changes value from "
    1429              :                              "%qd to %qd",
    1430              :                              integer_type_node, type,
    1431           30 :                              RAW_DATA_UCHAR_ELT (init, i),
    1432           30 :                              RAW_DATA_SCHAR_ELT (init, i));
    1433              :                 }
    1434           48 :           return ret;
    1435              :         }
    1436    108260149 :       init = convert_for_initialization (0, type, init, flags,
    1437              :                                          ICR_INIT, NULL_TREE, 0,
    1438              :                                          complain);
    1439              : 
    1440    108260149 :       return init;
    1441              :     }
    1442              : 
    1443              :   /* Come here only for aggregates: records, arrays, unions, complex numbers
    1444              :      and vectors.  */
    1445     11396025 :   gcc_assert (code == ARRAY_TYPE
    1446              :               || VECTOR_TYPE_P (type)
    1447              :               || code == RECORD_TYPE
    1448              :               || code == UNION_TYPE
    1449              :               || code == OPAQUE_TYPE
    1450              :               || code == COMPLEX_TYPE);
    1451              : 
    1452              :   /* "If T is a class type and the initializer list has a single
    1453              :      element of type cv U, where U is T or a class derived from T,
    1454              :      the object is initialized from that element."  */
    1455     11396025 :   if (cxx_dialect >= cxx11
    1456     11356843 :       && BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
    1457     10988217 :       && !CONSTRUCTOR_IS_DESIGNATED_INIT (stripped_init)
    1458     10370935 :       && CONSTRUCTOR_NELTS (stripped_init) == 1
    1459     11949399 :       && ((CLASS_TYPE_P (type) && !CLASSTYPE_NON_AGGREGATE (type))
    1460        93640 :           || VECTOR_TYPE_P (type)))
    1461              :     {
    1462       460021 :       tree elt = CONSTRUCTOR_ELT (stripped_init, 0)->value;
    1463       460021 :       if (reference_related_p (type, TREE_TYPE (elt)))
    1464              :         {
    1465              :           /* In C++17, aggregates can have bases, thus participate in
    1466              :              aggregate initialization.  In the following case:
    1467              : 
    1468              :                struct B { int c; };
    1469              :                struct D : B { };
    1470              :                D d{{D{{42}}}};
    1471              : 
    1472              :             there's an extra set of braces, so the D temporary initializes
    1473              :             the first element of d, which is the B base subobject.  The base
    1474              :             of type B is copy-initialized from the D temporary, causing
    1475              :             object slicing.  */
    1476           30 :           tree field = next_aggregate_field (TYPE_FIELDS (type));
    1477           60 :           if (field && DECL_FIELD_IS_BASE (field))
    1478              :             {
    1479           30 :               if (warning_at (loc, 0, "initializing a base class of type %qT "
    1480           30 :                               "results in object slicing", TREE_TYPE (field)))
    1481           30 :                 inform (loc, "remove %<{ }%> around initializer");
    1482              :             }
    1483            0 :           else if (flag_checking)
    1484              :             /* We should have fixed this in reshape_init.  */
    1485            0 :             gcc_unreachable ();
    1486              :         }
    1487              :     }
    1488              : 
    1489     11396025 :   if (SIMPLE_TARGET_EXPR_P (stripped_init))
    1490         6717 :     stripped_init = TARGET_EXPR_INITIAL (stripped_init);
    1491              : 
    1492     11009936 :   if (BRACE_ENCLOSED_INITIALIZER_P (stripped_init)
    1493     22401322 :       && !TYPE_NON_AGGREGATE_CLASS (type))
    1494     10668912 :     return process_init_constructor (type, stripped_init, nested, flags,
    1495     10668912 :                                      complain);
    1496              :   else
    1497              :     {
    1498       727113 :       if (COMPOUND_LITERAL_P (stripped_init) && code == ARRAY_TYPE)
    1499              :         {
    1500            0 :           if (complain & tf_error)
    1501            0 :             error_at (loc, "cannot initialize aggregate of type %qT with "
    1502              :                       "a compound literal", type);
    1503              : 
    1504            0 :           return error_mark_node;
    1505              :         }
    1506              : 
    1507       727113 :       if (code == ARRAY_TYPE
    1508       727113 :           && !BRACE_ENCLOSED_INITIALIZER_P (stripped_init))
    1509              :         {
    1510              :           /* Allow the result of build_array_copy and of
    1511              :              build_value_init_noctor.  */
    1512          130 :           if ((TREE_CODE (stripped_init) == VEC_INIT_EXPR
    1513          111 :                || TREE_CODE (stripped_init) == CONSTRUCTOR)
    1514          216 :               && (same_type_ignoring_top_level_qualifiers_p
    1515           86 :                   (type, TREE_TYPE (init))))
    1516              :             return init;
    1517              : 
    1518           53 :           if (complain & tf_error)
    1519           53 :             error_at (loc, "array must be initialized with a brace-enclosed"
    1520              :                       " initializer");
    1521           53 :           return error_mark_node;
    1522              :         }
    1523              : 
    1524       726983 :       return convert_for_initialization (NULL_TREE, type, init,
    1525              :                                          flags,
    1526              :                                          ICR_INIT, NULL_TREE, 0,
    1527       726983 :                                          complain);
    1528              :     }
    1529              : }
    1530              : 
    1531              : tree
    1532      1390185 : digest_init (tree type, tree init, tsubst_flags_t complain)
    1533              : {
    1534      1390185 :   return digest_init_r (type, init, 0, LOOKUP_IMPLICIT, complain);
    1535              : }
    1536              : 
    1537              : tree
    1538     63900225 : digest_init_flags (tree type, tree init, int flags, tsubst_flags_t complain)
    1539              : {
    1540     63900225 :   return digest_init_r (type, init, 0, flags, complain);
    1541              : }
    1542              : 
    1543              : /* Callback to replace PLACEHOLDER_EXPRs in a TARGET_EXPR (which isn't used
    1544              :    in the context of guaranteed copy elision).  */
    1545              : 
    1546              : static tree
    1547      3843614 : replace_placeholders_for_class_temp_r (tree *tp, int *, void *)
    1548              : {
    1549      3843614 :   tree t = *tp;
    1550              : 
    1551              :   /* We're looking for a TARGET_EXPR nested in the whole expression.  */
    1552      3843614 :   if (TREE_CODE (t) == TARGET_EXPR
    1553              :       /* That serves as temporary materialization, not an initializer.  */
    1554      3843614 :       && !TARGET_EXPR_ELIDING_P (t))
    1555              :     {
    1556          762 :       tree init = TARGET_EXPR_INITIAL (t);
    1557          765 :       while (TREE_CODE (init) == COMPOUND_EXPR)
    1558            3 :         init = TREE_OPERAND (init, 1);
    1559          762 :       if (TREE_CODE (init) == CONSTRUCTOR
    1560          762 :           && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init))
    1561              :         {
    1562          129 :           tree obj = TARGET_EXPR_SLOT (t);
    1563          129 :           replace_placeholders (init, obj);
    1564              :           /* We should have dealt with all PLACEHOLDER_EXPRs.  */
    1565          129 :           CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = false;
    1566          129 :           gcc_checking_assert (!find_placeholders (init));
    1567              :         }
    1568              :     }
    1569              : 
    1570      3843614 :   return NULL_TREE;
    1571              : }
    1572              : 
    1573              : /* Process the initializer INIT for an NSDMI DECL (a FIELD_DECL).  */
    1574              : tree
    1575       931695 : digest_nsdmi_init (tree decl, tree init, tsubst_flags_t complain)
    1576              : {
    1577       931695 :   gcc_assert (TREE_CODE (decl) == FIELD_DECL);
    1578              : 
    1579       931695 :   tree type = TREE_TYPE (decl);
    1580       931695 :   if (DECL_BIT_FIELD_TYPE (decl))
    1581        11991 :     type = DECL_BIT_FIELD_TYPE (decl);
    1582       931695 :   int flags = LOOKUP_IMPLICIT;
    1583       931695 :   if (DIRECT_LIST_INIT_P (init))
    1584              :     {
    1585       153739 :       flags = LOOKUP_NORMAL;
    1586       153739 :       complain |= tf_no_cleanup;
    1587              :     }
    1588       293339 :   if (BRACE_ENCLOSED_INITIALIZER_P (init)
    1589      1225034 :       && CP_AGGREGATE_TYPE_P (type))
    1590       189798 :     init = reshape_init (type, init, complain);
    1591       931695 :   init = digest_init_flags (type, init, flags, complain);
    1592              : 
    1593              :   /* Fold away any non-ODR used constants so that we don't need to
    1594              :      stream them in modules.  */
    1595       931695 :   init = cp_fold_non_odr_use (init, /*rval=*/!TYPE_REF_P (type));
    1596              : 
    1597       931695 :   set_target_expr_eliding (init);
    1598              : 
    1599              :   /* We may have temporary materialization in a NSDMI, if the initializer
    1600              :      has something like A{} in it.  Digesting the {} could have introduced
    1601              :      a PLACEHOLDER_EXPR referring to A.  Now that we've got a TARGET_EXPR,
    1602              :      we have an object we can refer to.  The reason we bother doing this
    1603              :      here is for code like
    1604              : 
    1605              :        struct A {
    1606              :          int x;
    1607              :          int y = x;
    1608              :        };
    1609              : 
    1610              :        struct B {
    1611              :          int x = 0;
    1612              :          int y = A{x}.y; // #1
    1613              :        };
    1614              : 
    1615              :      where in #1 we don't want to end up with two PLACEHOLDER_EXPRs for
    1616              :      different types on the same level in a {} when lookup_placeholder
    1617              :      wouldn't find a named object for the PLACEHOLDER_EXPR for A.  Note,
    1618              :      temporary materialization does not occur when initializing an object
    1619              :      from a prvalue of the same type, therefore we must not replace the
    1620              :      placeholder with a temporary object so that it can be elided.  */
    1621       931695 :   cp_walk_tree_without_duplicates (&init, replace_placeholders_for_class_temp_r,
    1622              :                                    nullptr);
    1623              : 
    1624       931695 :   return init;
    1625              : }
    1626              : 
    1627              : /* Set of flags used within process_init_constructor to describe the
    1628              :    initializers.  */
    1629              : #define PICFLAG_ERRONEOUS 1
    1630              : #define PICFLAG_NOT_ALL_CONSTANT 2
    1631              : #define PICFLAG_NOT_ALL_SIMPLE 4
    1632              : #define PICFLAG_SIDE_EFFECTS 8
    1633              : #define PICFLAG_VEC_INIT 16
    1634              : 
    1635              : /* Given an initializer INIT, return the flag (PICFLAG_*) which better
    1636              :    describe it.  */
    1637              : 
    1638              : static int
    1639     57139924 : picflag_from_initializer (tree init)
    1640              : {
    1641     57139924 :   if (init == error_mark_node)
    1642              :     return PICFLAG_ERRONEOUS;
    1643     57139493 :   else if (!TREE_CONSTANT (init))
    1644              :     {
    1645      2454542 :       if (TREE_SIDE_EFFECTS (init))
    1646              :         return PICFLAG_SIDE_EFFECTS;
    1647              :       else
    1648      2222478 :         return PICFLAG_NOT_ALL_CONSTANT;
    1649              :     }
    1650     54684951 :   else if (!initializer_constant_valid_p (init, TREE_TYPE (init)))
    1651        58203 :     return PICFLAG_NOT_ALL_SIMPLE;
    1652              :   return 0;
    1653              : }
    1654              : 
    1655              : /* Adjust INIT for going into a CONSTRUCTOR.  */
    1656              : 
    1657              : static tree
    1658     55061168 : massage_init_elt (tree type, tree init, int nested, int flags,
    1659              :                   tsubst_flags_t complain)
    1660              : {
    1661     55061168 :   int new_flags = LOOKUP_IMPLICIT;
    1662     55061168 :   if (flags & LOOKUP_ALLOW_FLEXARRAY_INIT)
    1663     49871188 :     new_flags |= LOOKUP_ALLOW_FLEXARRAY_INIT;
    1664     55061168 :   if (flags & LOOKUP_AGGREGATE_PAREN_INIT)
    1665         2077 :     new_flags |= LOOKUP_AGGREGATE_PAREN_INIT;
    1666    106521716 :   init = digest_init_r (type, init, nested ? 2 : 1, new_flags, complain);
    1667              :   /* When we defer constant folding within a statement, we may want to
    1668              :      defer this folding as well.  Don't call this on CONSTRUCTORs in
    1669              :      a template because their elements have already been folded, and
    1670              :      we must avoid folding the result of get_nsdmi.  */
    1671     55061168 :   if (!(processing_template_decl && TREE_CODE (init) == CONSTRUCTOR))
    1672              :     {
    1673     55061002 :       tree t = fold_non_dependent_init (init, complain);
    1674     55061002 :       if (TREE_CONSTANT (t))
    1675     52588138 :         init = t;
    1676     55061002 :       set_target_expr_eliding (init);
    1677              :     }
    1678     55061168 :   return init;
    1679              : }
    1680              : 
    1681              : /* Subroutine of process_init_constructor, which will process an initializer
    1682              :    INIT for an array or vector of type TYPE. Returns the flags (PICFLAG_*)
    1683              :    which describe the initializers.  */
    1684              : 
    1685              : static int
    1686       447771 : process_init_constructor_array (tree type, tree init, int nested, int flags,
    1687              :                                 tsubst_flags_t complain)
    1688              : {
    1689       447771 :   unsigned HOST_WIDE_INT i, j, len = 0;
    1690       447771 :   int picflags = 0;
    1691       447771 :   bool unbounded = false;
    1692       447771 :   constructor_elt *ce;
    1693       447771 :   vec<constructor_elt, va_gc> *v = CONSTRUCTOR_ELTS (init);
    1694              : 
    1695       447771 :   gcc_assert (TREE_CODE (type) == ARRAY_TYPE
    1696              :               || VECTOR_TYPE_P (type));
    1697              : 
    1698       447771 :   if (TREE_CODE (type) == ARRAY_TYPE)
    1699              :     {
    1700              :       /* C++ flexible array members have a null domain.  */
    1701       401437 :       tree domain = TYPE_DOMAIN (type);
    1702       401437 :       if (domain && TREE_CONSTANT (TYPE_MAX_VALUE (domain)))
    1703       801962 :         len = wi::ext (wi::to_offset (TYPE_MAX_VALUE (domain))
    1704       801962 :                        - wi::to_offset (TYPE_MIN_VALUE (domain)) + 1,
    1705       400981 :                        TYPE_PRECISION (TREE_TYPE (domain)),
    1706       801962 :                        TYPE_SIGN (TREE_TYPE (domain))).to_uhwi ();
    1707              :       else
    1708              :         unbounded = true;  /* Take as many as there are.  */
    1709              : 
    1710       401437 :       if (nested == 2 && !domain && !vec_safe_is_empty (v))
    1711              :         {
    1712           69 :           if (complain & tf_error)
    1713          138 :             error_at (cp_expr_loc_or_input_loc (init),
    1714              :                       "initialization of flexible array member "
    1715              :                       "in a nested context");
    1716           69 :           return PICFLAG_ERRONEOUS;
    1717              :         }
    1718              :     }
    1719              :   else
    1720              :     /* Vectors are like simple fixed-size arrays.  */
    1721        46334 :     unbounded = !TYPE_VECTOR_SUBPARTS (type).is_constant (&len);
    1722              : 
    1723              :   /* There must not be more initializers than needed.  */
    1724       447702 :   if (!unbounded && vec_safe_length (v) > len)
    1725              :     {
    1726           14 :       if (complain & tf_error)
    1727           14 :         error ("too many initializers for %qT", type);
    1728              :       else
    1729              :         return PICFLAG_ERRONEOUS;
    1730              :     }
    1731              : 
    1732       447702 :   j = 0;
    1733     48336848 :   FOR_EACH_VEC_SAFE_ELT (v, i, ce)
    1734              :     {
    1735     47889146 :       if (!ce->index)
    1736          600 :         ce->index = size_int (j);
    1737     47888546 :       else if (!check_array_designated_initializer (ce, j))
    1738            0 :         ce->index = error_mark_node;
    1739     47889146 :       gcc_assert (ce->value);
    1740     47889146 :       ce->value
    1741     47889146 :         = massage_init_elt (TREE_TYPE (type), ce->value, nested, flags,
    1742              :                             complain);
    1743              : 
    1744     47889146 :       gcc_checking_assert
    1745              :         (ce->value == error_mark_node
    1746              :          || (same_type_ignoring_top_level_qualifiers_p
    1747              :              (strip_array_types (TREE_TYPE (type)),
    1748              :               strip_array_types (TREE_TYPE (ce->value)))));
    1749              : 
    1750     47889146 :       picflags |= picflag_from_initializer (ce->value);
    1751              :       /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer
    1752              :          CONSTRUCTOR.  */
    1753     47889146 :       if (TREE_CODE (ce->value) == CONSTRUCTOR
    1754     47889146 :           && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value))
    1755              :         {
    1756           17 :           CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
    1757           17 :           CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0;
    1758              :         }
    1759     47889146 :       if (TREE_CODE (ce->value) == RAW_DATA_CST)
    1760          284 :         j += RAW_DATA_LENGTH (ce->value);
    1761              :       else
    1762     47888862 :         ++j;
    1763              :     }
    1764              : 
    1765              :   /* No more initializers. If the array is unbounded, we are done. Otherwise,
    1766              :      we must add initializers ourselves.  */
    1767       447702 :   if (!unbounded)
    1768       447399 :     for (; i < len; ++i)
    1769              :       {
    1770        35055 :         tree next;
    1771              : 
    1772        35055 :         if (type_build_ctor_call (TREE_TYPE (type)))
    1773              :           {
    1774              :             /* If this type needs constructors run for default-initialization,
    1775              :                we can't rely on the back end to do it for us, so make the
    1776              :                initialization explicit by list-initializing from T{}.  */
    1777          404 :             next = build_constructor (init_list_type_node, NULL);
    1778          404 :             next = massage_init_elt (TREE_TYPE (type), next, nested, flags,
    1779              :                                      complain);
    1780          404 :             if (initializer_zerop (next))
    1781              :               /* The default zero-initialization is fine for us; don't
    1782              :                  add anything to the CONSTRUCTOR.  */
    1783              :               next = NULL_TREE;
    1784              :           }
    1785        34651 :         else if (!zero_init_p (TREE_TYPE (type)))
    1786          147 :           next = build_zero_init (TREE_TYPE (type),
    1787              :                                   /*nelts=*/NULL_TREE,
    1788              :                                   /*static_storage_p=*/false);
    1789              :         else
    1790              :           /* The default zero-initialization is fine for us; don't
    1791              :              add anything to the CONSTRUCTOR.  */
    1792              :           next = NULL_TREE;
    1793              : 
    1794          300 :         if (next)
    1795              :           {
    1796          300 :             if (next != error_mark_node
    1797          300 :                 && (initializer_constant_valid_p (next, TREE_TYPE (next))
    1798          285 :                     != null_pointer_node))
    1799              :               {
    1800              :                 /* Use VEC_INIT_EXPR for non-constant initialization of
    1801              :                    trailing elements with no explicit initializers.  */
    1802          119 :                 picflags |= PICFLAG_VEC_INIT;
    1803          119 :                 break;
    1804              :               }
    1805              : 
    1806          181 :             picflags |= picflag_from_initializer (next);
    1807              :             /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer
    1808              :                CONSTRUCTOR.  */
    1809          181 :             if (TREE_CODE (next) == CONSTRUCTOR
    1810          181 :                 && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next))
    1811              :               {
    1812            0 :                 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
    1813            0 :                 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0;
    1814              :               }
    1815          181 :             if (len > i+1)
    1816              :               {
    1817           97 :                 tree range = build2 (RANGE_EXPR, size_type_node,
    1818           97 :                                      build_int_cst (size_type_node, i),
    1819           97 :                                      build_int_cst (size_type_node, len - 1));
    1820           97 :                 CONSTRUCTOR_APPEND_ELT (v, range, next);
    1821           97 :                 break;
    1822              :               }
    1823              :             else
    1824           84 :               CONSTRUCTOR_APPEND_ELT (v, size_int (i), next);
    1825              :           }
    1826              :         else
    1827              :           /* Don't bother checking all the other elements.  */
    1828              :           break;
    1829              :       }
    1830              : 
    1831       447702 :   CONSTRUCTOR_ELTS (init) = v;
    1832       447702 :   return picflags;
    1833              : }
    1834              : 
    1835              : /* Subroutine of process_init_constructor, which will process an initializer
    1836              :    INIT for a class of type TYPE. Returns the flags (PICFLAG_*) which describe
    1837              :    the initializers.  */
    1838              : 
    1839              : static int
    1840     10108914 : process_init_constructor_record (tree type, tree init, int nested, int flags,
    1841              :                                  tsubst_flags_t complain)
    1842              : {
    1843     10108914 :   vec<constructor_elt, va_gc> *v = NULL;
    1844     10108914 :   tree field;
    1845     10108914 :   int skipped = 0;
    1846              : 
    1847     10108914 :   gcc_assert (TREE_CODE (type) == RECORD_TYPE);
    1848     10108914 :   gcc_assert (!CLASSTYPE_VBASECLASSES (type));
    1849     10108914 :   gcc_assert (!TYPE_BINFO (type)
    1850              :               || cxx_dialect >= cxx17
    1851              :               || !BINFO_N_BASE_BINFOS (TYPE_BINFO (type)));
    1852     10108914 :   gcc_assert (!TYPE_POLYMORPHIC_P (type));
    1853              : 
    1854     10108914 :  restart:
    1855     10256760 :   int picflags = 0;
    1856     10256760 :   unsigned HOST_WIDE_INT idx = 0;
    1857     10256760 :   int designator_skip = -1;
    1858              :   /* Generally, we will always have an index for each initializer (which is
    1859              :      a FIELD_DECL, put by reshape_init), but compound literals don't go trough
    1860              :      reshape_init. So we need to handle both cases.  */
    1861    101198456 :   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
    1862              :     {
    1863     91090108 :       tree next;
    1864              : 
    1865    171166857 :       if (TREE_CODE (field) != FIELD_DECL
    1866     91090108 :           || (DECL_ARTIFICIAL (field)
    1867       892683 :               && !(cxx_dialect >= cxx17 && DECL_FIELD_IS_BASE (field))))
    1868     80076749 :         continue;
    1869              : 
    1870     11013359 :       if (DECL_UNNAMED_BIT_FIELD (field))
    1871          146 :         continue;
    1872              : 
    1873              :       /* If this is a bitfield, first convert to the declared type.  */
    1874     11013213 :       tree fldtype = TREE_TYPE (field);
    1875     11013213 :       if (DECL_BIT_FIELD_TYPE (field))
    1876      1480145 :         fldtype = DECL_BIT_FIELD_TYPE (field);
    1877     11013213 :       if (fldtype == error_mark_node)
    1878              :         return PICFLAG_ERRONEOUS;
    1879              : 
    1880     11013198 :       next = NULL_TREE;
    1881     11013198 :       if (idx < CONSTRUCTOR_NELTS (init))
    1882              :         {
    1883      7056804 :           constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
    1884      7056804 :           if (ce->index)
    1885              :             {
    1886              :               /* We can have either a FIELD_DECL or an IDENTIFIER_NODE. The
    1887              :                  latter case can happen in templates where lookup has to be
    1888              :                  deferred.  */
    1889      7055356 :               gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
    1890              :                           || identifier_p (ce->index));
    1891      7055356 :               if (ce->index == field || ce->index == DECL_NAME (field))
    1892      7055137 :                 next = ce->value;
    1893              :               else
    1894              :                 {
    1895          219 :                   ce = NULL;
    1896          219 :                   if (designator_skip == -1)
    1897              :                     designator_skip = 1;
    1898              :                 }
    1899              :             }
    1900              :           else
    1901              :             {
    1902         1448 :               designator_skip = 0;
    1903         1448 :               next = ce->value;
    1904              :             }
    1905              : 
    1906      7056585 :           if (ce)
    1907              :             {
    1908      7056585 :               gcc_assert (ce->value);
    1909      7056585 :               next = massage_init_elt (fldtype, next, nested, flags, complain);
    1910      7056585 :               ++idx;
    1911              :             }
    1912              :         }
    1913     11013198 :       if (next == error_mark_node)
    1914              :         /* We skip initializers for empty bases/fields, so skipping an invalid
    1915              :            one could make us accept invalid code.  */
    1916              :         return PICFLAG_ERRONEOUS;
    1917     11012647 :       else if (next)
    1918              :         /* Already handled above.  */;
    1919      3956613 :       else if (DECL_INITIAL (field))
    1920              :         {
    1921       455754 :           if (skipped > 0)
    1922              :             {
    1923              :               /* We're using an NSDMI past a field with implicit
    1924              :                  zero-init.  Go back and make it explicit.  */
    1925       147846 :               skipped = -1;
    1926       147846 :               vec_safe_truncate (v, 0);
    1927       147846 :               goto restart;
    1928              :             }
    1929              :           /* C++14 aggregate NSDMI.  */
    1930       307908 :           next = get_nsdmi (field, /*ctor*/false, complain);
    1931       307908 :           if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)
    1932       307908 :               && find_placeholders (next))
    1933          958 :             CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
    1934              :         }
    1935      3500859 :       else if (type_build_ctor_call (fldtype))
    1936              :         {
    1937              :           /* If this type needs constructors run for
    1938              :              default-initialization, we can't rely on the back end to do it
    1939              :              for us, so build up TARGET_EXPRs.  If the type in question is
    1940              :              a class, just build one up; if it's an array, recurse.  */
    1941        12001 :           next = build_constructor (init_list_type_node, NULL);
    1942        12001 :           next = massage_init_elt (fldtype, next, nested, flags, complain);
    1943        12001 :           if (TREE_CODE (next) == TARGET_EXPR
    1944        12001 :               && unsafe_copy_elision_p (field, next))
    1945            0 :             TARGET_EXPR_ELIDING_P (next) = false;
    1946              : 
    1947              :           /* Warn when some struct elements are implicitly initialized.  */
    1948        12001 :           if ((complain & tf_warning)
    1949        11730 :               && !cp_unevaluated_operand
    1950        23709 :               && !EMPTY_CONSTRUCTOR_P (init))
    1951          579 :             warning (OPT_Wmissing_field_initializers,
    1952              :                      "missing initializer for member %qD", field);
    1953              :         }
    1954              :       else
    1955              :         {
    1956      3488858 :           if (TYPE_REF_P (fldtype))
    1957              :             {
    1958           22 :               if (complain & tf_error)
    1959           22 :                 error ("member %qD is uninitialized reference", field);
    1960              :               else
    1961              :                 return PICFLAG_ERRONEOUS;
    1962              :             }
    1963      3488836 :           else if (CLASSTYPE_REF_FIELDS_NEED_INIT (fldtype))
    1964              :             {
    1965            1 :               if (complain & tf_error)
    1966            1 :                 error ("member %qD with uninitialized reference fields", field);
    1967              :               else
    1968              :                 return PICFLAG_ERRONEOUS;
    1969              :             }
    1970              :           /* Do nothing for flexible array members since they need not have any
    1971              :              elements.  Don't worry about 'skipped' because a flexarray has to
    1972              :              be the last field.  */
    1973      3488835 :           else if (TREE_CODE (fldtype) == ARRAY_TYPE && !TYPE_DOMAIN (fldtype))
    1974          103 :             continue;
    1975              : 
    1976              :           /* Warn when some struct elements are implicitly initialized
    1977              :              to zero.  */
    1978      3488755 :           if ((complain & tf_warning)
    1979      3467141 :               && !cp_unevaluated_operand
    1980      3466623 :               && !EMPTY_CONSTRUCTOR_P (init)
    1981      3489896 :               && !is_really_empty_class (fldtype, /*ignore_vptr*/false))
    1982         1059 :             warning (OPT_Wmissing_field_initializers,
    1983              :                      "missing initializer for member %qD", field);
    1984              : 
    1985      3488755 :           if (!zero_init_p (fldtype) || skipped < 0)
    1986              :             {
    1987      1921023 :               if (TYPE_REF_P (fldtype))
    1988            3 :                 next = build_zero_cst (fldtype);
    1989              :               else
    1990      1921020 :                 next = build_zero_init (fldtype, /*nelts=*/NULL_TREE,
    1991              :                                         /*static_storage_p=*/false);
    1992              :             }
    1993              :           else
    1994              :             {
    1995              :               /* The default zero-initialization is fine for us; don't
    1996              :                  add anything to the CONSTRUCTOR.  */
    1997      1567732 :               skipped = 1;
    1998      1567732 :               continue;
    1999              :             }
    2000              :         }
    2001              : 
    2002              :       /* We can't actually elide the temporary when initializing a
    2003              :          potentially-overlapping field from a function that returns by
    2004              :          value.  */
    2005      9296966 :       if (TREE_CODE (next) == TARGET_EXPR
    2006      9296966 :           && unsafe_copy_elision_p (field, next))
    2007           25 :         TARGET_EXPR_ELIDING_P (next) = false;
    2008              : 
    2009      9296966 :       if (is_empty_field (field)
    2010      9296966 :           && !TREE_SIDE_EFFECTS (next))
    2011              :         /* Don't add trivial initialization of an empty base/field to the
    2012              :            constructor, as they might not be ordered the way the back-end
    2013              :            expects.  */
    2014       149403 :         continue;
    2015              : 
    2016              :       /* If this is a bitfield, now convert to the lowered type.  */
    2017      9147563 :       if (fldtype != TREE_TYPE (field))
    2018      1478471 :         next = cp_convert_and_check (TREE_TYPE (field), next, complain);
    2019      9147563 :       picflags |= picflag_from_initializer (next);
    2020              :       /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR.  */
    2021      9147563 :       if (TREE_CODE (next) == CONSTRUCTOR
    2022      9147563 :           && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next))
    2023              :         {
    2024           66 :           CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
    2025           66 :           CONSTRUCTOR_PLACEHOLDER_BOUNDARY (next) = 0;
    2026              :         }
    2027    100089259 :       CONSTRUCTOR_APPEND_ELT (v, field, next);
    2028              :     }
    2029              : 
    2030     10108348 :   if (idx < CONSTRUCTOR_NELTS (init))
    2031              :     {
    2032          169 :       if (complain & tf_error)
    2033              :         {
    2034           26 :           constructor_elt *ce = &(*CONSTRUCTOR_ELTS (init))[idx];
    2035              :           /* For better diagnostics, try to find out if it is really
    2036              :              the case of too many initializers or if designators are
    2037              :              in incorrect order.  */
    2038           26 :           if (designator_skip == 1 && ce->index)
    2039              :             {
    2040           15 :               gcc_assert (TREE_CODE (ce->index) == FIELD_DECL
    2041              :                           || identifier_p (ce->index));
    2042           15 :               for (field = TYPE_FIELDS (type);
    2043           54 :                    field; field = DECL_CHAIN (field))
    2044              :                 {
    2045           90 :                   if (TREE_CODE (field) != FIELD_DECL
    2046           54 :                       || (DECL_ARTIFICIAL (field)
    2047            0 :                           && !(cxx_dialect >= cxx17
    2048            0 :                                && DECL_FIELD_IS_BASE (field))))
    2049           36 :                     continue;
    2050              : 
    2051           18 :                   if (DECL_UNNAMED_BIT_FIELD (field))
    2052            0 :                     continue;
    2053              : 
    2054           18 :                   if (ce->index == field || ce->index == DECL_NAME (field))
    2055              :                     break;
    2056              :                 }
    2057              :             }
    2058           26 :           if (field)
    2059           15 :             error ("designator order for field %qD does not match declaration "
    2060              :                    "order in %qT", field, type);
    2061              :           else
    2062           11 :             error ("too many initializers for %qT", type);
    2063              :         }
    2064              :       else
    2065              :         return PICFLAG_ERRONEOUS;
    2066              :     }
    2067              : 
    2068     10108205 :   CONSTRUCTOR_ELTS (init) = v;
    2069     10108205 :   return picflags;
    2070              : }
    2071              : 
    2072              : /* Subroutine of process_init_constructor, which will process a single
    2073              :    initializer INIT for a union of type TYPE. Returns the flags (PICFLAG_*)
    2074              :    which describe the initializer.  */
    2075              : 
    2076              : static int
    2077       112227 : process_init_constructor_union (tree type, tree init, int nested, int flags,
    2078              :                                 tsubst_flags_t complain)
    2079              : {
    2080       112227 :   constructor_elt *ce;
    2081       112227 :   int len;
    2082              : 
    2083              :   /* If the initializer was empty, use the union's NSDMI if it has one.
    2084              :      Otherwise use default zero initialization.  */
    2085       112227 :   if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
    2086              :     {
    2087       101223 :       for (tree field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
    2088              :         {
    2089        92034 :           if (TREE_CODE (field) == FIELD_DECL
    2090        92034 :               && DECL_INITIAL (field) != NULL_TREE)
    2091              :             {
    2092           25 :               tree val = get_nsdmi (field, /*in_ctor=*/false, complain);
    2093           25 :               if (!CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init)
    2094           25 :                   && find_placeholders (val))
    2095           19 :                 CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
    2096           25 :               CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (init), field, val);
    2097           25 :               break;
    2098              :             }
    2099              :         }
    2100              : 
    2101         9214 :       if (vec_safe_is_empty (CONSTRUCTOR_ELTS (init)))
    2102              :         return 0;
    2103              :     }
    2104              : 
    2105       103038 :   len = CONSTRUCTOR_ELTS (init)->length ();
    2106       103038 :   if (len > 1)
    2107              :     {
    2108            7 :       if (!(complain & tf_error))
    2109              :         return PICFLAG_ERRONEOUS;
    2110            3 :       error ("too many initializers for %qT", type);
    2111            3 :       CONSTRUCTOR_ELTS (init)->block_remove (1, len-1);
    2112              :     }
    2113              : 
    2114       103034 :   ce = &(*CONSTRUCTOR_ELTS (init))[0];
    2115              : 
    2116              :   /* If this element specifies a field, initialize via that field.  */
    2117       103034 :   if (ce->index)
    2118              :     {
    2119       103018 :       if (TREE_CODE (ce->index) == FIELD_DECL)
    2120              :         ;
    2121            0 :       else if (identifier_p (ce->index))
    2122              :         {
    2123              :           /* This can happen within a cast, see g++.dg/opt/cse2.C.  */
    2124            0 :           tree name = ce->index;
    2125            0 :           tree field;
    2126            0 :           for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
    2127            0 :             if (DECL_NAME (field) == name)
    2128              :               break;
    2129            0 :           if (!field)
    2130              :             {
    2131            0 :               if (complain & tf_error)
    2132            0 :                 error ("no field %qD found in union being initialized",
    2133              :                        field);
    2134            0 :               ce->value = error_mark_node;
    2135              :             }
    2136            0 :           ce->index = field;
    2137              :         }
    2138              :       else
    2139              :         {
    2140            0 :           gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
    2141              :                       || TREE_CODE (ce->index) == RANGE_EXPR);
    2142            0 :           if (complain & tf_error)
    2143            0 :             error ("index value instead of field name in union initializer");
    2144            0 :           ce->value = error_mark_node;
    2145              :         }
    2146              :     }
    2147              :   else
    2148              :     {
    2149              :       /* Find the first named field.  ANSI decided in September 1990
    2150              :          that only named fields count here.  */
    2151           16 :       tree field = TYPE_FIELDS (type);
    2152          189 :       while (field && (!DECL_NAME (field) || TREE_CODE (field) != FIELD_DECL))
    2153          173 :         field = TREE_CHAIN (field);
    2154           16 :       if (field == NULL_TREE)
    2155              :         {
    2156            2 :           if (complain & tf_error)
    2157            2 :             error ("too many initializers for %qT", type);
    2158            2 :           ce->value = error_mark_node;
    2159              :         }
    2160           16 :       ce->index = field;
    2161              :     }
    2162              : 
    2163       103034 :   if (ce->value && ce->value != error_mark_node)
    2164       103032 :     ce->value = massage_init_elt (TREE_TYPE (ce->index), ce->value, nested,
    2165              :                                   flags, complain);
    2166              : 
    2167              :   /* Propagate CONSTRUCTOR_PLACEHOLDER_BOUNDARY to outer CONSTRUCTOR.  */
    2168       103034 :   if (ce->value
    2169       103034 :       && TREE_CODE (ce->value) == CONSTRUCTOR
    2170       167696 :       && CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value))
    2171              :     {
    2172            0 :       CONSTRUCTOR_PLACEHOLDER_BOUNDARY (init) = 1;
    2173            0 :       CONSTRUCTOR_PLACEHOLDER_BOUNDARY (ce->value) = 0;
    2174              :     }
    2175       103034 :   return picflag_from_initializer (ce->value);
    2176              : }
    2177              : 
    2178              : /* Process INIT, a constructor for a variable of aggregate type TYPE. The
    2179              :    constructor is a brace-enclosed initializer, and will be modified in-place.
    2180              : 
    2181              :    Each element is converted to the right type through digest_init, and
    2182              :    missing initializers are added following the language rules (zero-padding,
    2183              :    etc.).
    2184              : 
    2185              :    After the execution, the initializer will have TREE_CONSTANT if all elts are
    2186              :    constant, and TREE_STATIC set if, in addition, all elts are simple enough
    2187              :    constants that the assembler and linker can compute them.
    2188              : 
    2189              :    The function returns the initializer itself, or error_mark_node in case
    2190              :    of error.  */
    2191              : 
    2192              : static tree
    2193     10668912 : process_init_constructor (tree type, tree init, int nested, int flags,
    2194              :                           tsubst_flags_t complain)
    2195              : {
    2196     10668912 :   int picflags;
    2197              : 
    2198     10668912 :   gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
    2199              : 
    2200     10668912 :   if (TREE_CODE (type) == ARRAY_TYPE || VECTOR_TYPE_P (type))
    2201       447771 :     picflags = process_init_constructor_array (type, init, nested, flags,
    2202              :                                                complain);
    2203     10221141 :   else if (TREE_CODE (type) == RECORD_TYPE)
    2204     10108914 :     picflags = process_init_constructor_record (type, init, nested, flags,
    2205              :                                                 complain);
    2206       112227 :   else if (TREE_CODE (type) == UNION_TYPE)
    2207       112227 :     picflags = process_init_constructor_union (type, init, nested, flags,
    2208              :                                                complain);
    2209              :   else
    2210            0 :     gcc_unreachable ();
    2211              : 
    2212     10668912 :   if (picflags & PICFLAG_ERRONEOUS)
    2213         1152 :     return error_mark_node;
    2214              : 
    2215     10667760 :   TREE_TYPE (init) = type;
    2216     10667760 :   if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type) == NULL_TREE)
    2217          323 :     cp_complete_array_type (&TREE_TYPE (init), init, /*do_default=*/0);
    2218     10667760 :   if (picflags & PICFLAG_SIDE_EFFECTS)
    2219              :     {
    2220       186476 :       TREE_CONSTANT (init) = false;
    2221       186476 :       TREE_SIDE_EFFECTS (init) = true;
    2222              :     }
    2223     10481284 :   else if (picflags & PICFLAG_NOT_ALL_CONSTANT)
    2224              :     {
    2225              :       /* Make sure TREE_CONSTANT isn't set from build_constructor.  */
    2226      1177970 :       TREE_CONSTANT (init) = false;
    2227      1177970 :       TREE_SIDE_EFFECTS (init) = false;
    2228              :     }
    2229              :   else
    2230              :     {
    2231      9303314 :       TREE_CONSTANT (init) = 1;
    2232      9303314 :       TREE_SIDE_EFFECTS (init) = false;
    2233      9303314 :       if (!(picflags & PICFLAG_NOT_ALL_SIMPLE))
    2234      9279379 :         TREE_STATIC (init) = 1;
    2235              :     }
    2236     10667760 :   if (picflags & PICFLAG_VEC_INIT)
    2237              :     {
    2238              :       /* Defer default-initialization of array elements with no corresponding
    2239              :          initializer-clause until later so we can use a loop.  */
    2240          119 :       TREE_TYPE (init) = init_list_type_node;
    2241          119 :       init = build_vec_init_expr (type, init, complain);
    2242          119 :       init = get_target_expr (init);
    2243              :     }
    2244              :   return init;
    2245              : }
    2246              : 
    2247              : /* Given a structure or union value DATUM, construct and return
    2248              :    the structure or union component which results from narrowing
    2249              :    that value to the base specified in BASETYPE.  For example, given the
    2250              :    hierarchy
    2251              : 
    2252              :    class L { int ii; };
    2253              :    class A : L { ... };
    2254              :    class B : L { ... };
    2255              :    class C : A, B { ... };
    2256              : 
    2257              :    and the declaration
    2258              : 
    2259              :    C x;
    2260              : 
    2261              :    then the expression
    2262              : 
    2263              :    x.A::ii refers to the ii member of the L part of
    2264              :    the A part of the C object named by X.  In this case,
    2265              :    DATUM would be x, and BASETYPE would be A.
    2266              : 
    2267              :    I used to think that this was nonconformant, that the standard specified
    2268              :    that first we look up ii in A, then convert x to an L& and pull out the
    2269              :    ii part.  But in fact, it does say that we convert x to an A&; A here
    2270              :    is known as the "naming class".  (jason 2000-12-19)
    2271              : 
    2272              :    BINFO_P points to a variable initialized either to NULL_TREE or to the
    2273              :    binfo for the specific base subobject we want to convert to.  */
    2274              : 
    2275              : tree
    2276         1867 : build_scoped_ref (tree datum, tree basetype, tree* binfo_p)
    2277              : {
    2278         1867 :   tree binfo;
    2279              : 
    2280         1867 :   if (datum == error_mark_node)
    2281              :     return error_mark_node;
    2282         1867 :   if (*binfo_p)
    2283              :     binfo = *binfo_p;
    2284              :   else
    2285         1867 :     binfo = lookup_base (TREE_TYPE (datum), basetype, ba_check,
    2286              :                          NULL, tf_warning_or_error);
    2287              : 
    2288         1867 :   if (!binfo || binfo == error_mark_node)
    2289              :     {
    2290            6 :       *binfo_p = NULL_TREE;
    2291            6 :       if (!binfo)
    2292            0 :         error_not_base_type (basetype, TREE_TYPE (datum));
    2293            6 :       return error_mark_node;
    2294              :     }
    2295              : 
    2296         1861 :   *binfo_p = binfo;
    2297         1861 :   return build_base_path (PLUS_EXPR, datum, binfo, 1,
    2298         1861 :                           tf_warning_or_error);
    2299              : }
    2300              : 
    2301              : /* Build a reference to an object specified by the C++ `->' operator.
    2302              :    Usually this just involves dereferencing the object, but if the
    2303              :    `->' operator is overloaded, then such overloads must be
    2304              :    performed until an object which does not have the `->' operator
    2305              :    overloaded is found.  An error is reported when circular pointer
    2306              :    delegation is detected.  */
    2307              : 
    2308              : tree
    2309     40002730 : build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
    2310              : {
    2311     40002730 :   tree orig_expr = expr;
    2312     40002730 :   tree type = TREE_TYPE (expr);
    2313     40002730 :   tree last_rval = NULL_TREE;
    2314     40002730 :   vec<tree, va_gc> *types_memoized = NULL;
    2315              : 
    2316     40002730 :   if (type == error_mark_node)
    2317              :     return error_mark_node;
    2318              : 
    2319     40002678 :   if (processing_template_decl)
    2320              :     {
    2321     32674371 :       tree ttype = NULL_TREE;
    2322     32674371 :       if (type && TYPE_PTR_P (type))
    2323     26842165 :         ttype = TREE_TYPE (type);
    2324     26842165 :       if (ttype && !dependent_scope_p (ttype))
    2325              :         /* Pointer to current instantiation, don't treat as dependent.  */;
    2326      9740422 :       else if (type_dependent_expression_p (expr))
    2327              :         {
    2328      9649326 :           expr = build_min_nt_loc (loc, ARROW_EXPR, expr);
    2329      9649326 :           TREE_TYPE (expr) = ttype;
    2330      9649326 :           return expr;
    2331              :         }
    2332              :     }
    2333              : 
    2334     30353352 :   if (MAYBE_CLASS_TYPE_P (type))
    2335              :     {
    2336       268958 :       struct tinst_level *actual_inst = current_instantiation ();
    2337       268958 :       tree fn = NULL;
    2338              : 
    2339       540743 :       while ((expr = build_new_op (loc, COMPONENT_REF,
    2340              :                                    LOOKUP_NORMAL, expr, NULL_TREE, NULL_TREE,
    2341              :                                    NULL_TREE, &fn, complain)))
    2342              :         {
    2343       271801 :           if (expr == error_mark_node)
    2344           23 :             return error_mark_node;
    2345              : 
    2346              :           /* This provides a better instantiation backtrace in case of
    2347              :              error.  */
    2348       271785 :           if (fn && DECL_USE_TEMPLATE (fn))
    2349       157747 :             push_tinst_level_loc (fn,
    2350       154899 :                                   (current_instantiation () != actual_inst)
    2351         2848 :                                   ? DECL_SOURCE_LOCATION (fn)
    2352              :                                   : input_location);
    2353       271785 :           fn = NULL;
    2354              : 
    2355       271785 :           if (vec_member (TREE_TYPE (expr), types_memoized))
    2356              :             {
    2357            0 :               if (complain & tf_error)
    2358            0 :                 error ("circular pointer delegation detected");
    2359            0 :               return error_mark_node;
    2360              :             }
    2361              : 
    2362       271785 :           vec_safe_push (types_memoized, TREE_TYPE (expr));
    2363       271785 :           last_rval = expr;
    2364              :         }
    2365              : 
    2366       421138 :       while (current_instantiation () != actual_inst)
    2367       152199 :         pop_tinst_level ();
    2368              : 
    2369       268939 :       if (last_rval == NULL_TREE)
    2370              :         {
    2371            7 :           if (complain & tf_error)
    2372            7 :             error ("base operand of %<->%> has non-pointer type %qT", type);
    2373            7 :           return error_mark_node;
    2374              :         }
    2375              : 
    2376       268932 :       if (TYPE_REF_P (TREE_TYPE (last_rval)))
    2377            0 :         last_rval = convert_from_reference (last_rval);
    2378              :     }
    2379              :   else
    2380              :     {
    2381     30084394 :       last_rval = decay_conversion (expr, complain);
    2382     30084394 :       if (last_rval == error_mark_node)
    2383              :         return error_mark_node;
    2384              :     }
    2385              : 
    2386     30353323 :   if (TYPE_PTR_P (TREE_TYPE (last_rval)))
    2387              :     {
    2388     30353320 :       if (processing_template_decl)
    2389              :         {
    2390     23025042 :           expr = build_min (ARROW_EXPR, TREE_TYPE (TREE_TYPE (last_rval)),
    2391              :                             orig_expr);
    2392     23025042 :           TREE_SIDE_EFFECTS (expr) = TREE_SIDE_EFFECTS (last_rval);
    2393     23025042 :           return expr;
    2394              :         }
    2395              : 
    2396      7328278 :       return cp_build_indirect_ref (loc, last_rval, RO_ARROW, complain);
    2397              :     }
    2398              : 
    2399            3 :   if (complain & tf_error)
    2400              :     {
    2401            3 :       if (types_memoized)
    2402            0 :         error ("result of %<operator->()%> yields non-pointer result");
    2403              :       else
    2404            3 :         error ("base operand of %<->%> is not a pointer");
    2405              :     }
    2406            3 :   return error_mark_node;
    2407              : }
    2408              : 
    2409              : /* Return an expression for "DATUM .* COMPONENT".  DATUM has not
    2410              :    already been checked out to be of aggregate type.  */
    2411              : 
    2412              : tree
    2413       102965 : build_m_component_ref (tree datum, tree component, tsubst_flags_t complain)
    2414              : {
    2415       102965 :   tree ptrmem_type;
    2416       102965 :   tree objtype;
    2417       102965 :   tree type;
    2418       102965 :   tree binfo;
    2419       102965 :   tree ctype;
    2420              : 
    2421       102965 :   datum = mark_lvalue_use (datum);
    2422       102965 :   component = mark_rvalue_use (component);
    2423              : 
    2424       102965 :   if (error_operand_p (datum) || error_operand_p (component))
    2425           56 :     return error_mark_node;
    2426              : 
    2427       102909 :   ptrmem_type = TREE_TYPE (component);
    2428       102909 :   if (!TYPE_PTRMEM_P (ptrmem_type))
    2429              :     {
    2430            6 :       if (complain & tf_error)
    2431            3 :         error ("%qE cannot be used as a member pointer, since it is of "
    2432              :                "type %qT", component, ptrmem_type);
    2433            6 :       return error_mark_node;
    2434              :     }
    2435              : 
    2436       102903 :   objtype = TYPE_MAIN_VARIANT (TREE_TYPE (datum));
    2437       102903 :   if (! MAYBE_CLASS_TYPE_P (objtype))
    2438              :     {
    2439           20 :       if (complain & tf_error)
    2440            0 :         error ("cannot apply member pointer %qE to %qE, which is of "
    2441              :                "non-class type %qT", component, datum, objtype);
    2442           20 :       return error_mark_node;
    2443              :     }
    2444              : 
    2445       102883 :   type = TYPE_PTRMEM_POINTED_TO_TYPE (ptrmem_type);
    2446       102883 :   ctype = complete_type (TYPE_PTRMEM_CLASS_TYPE (ptrmem_type));
    2447              : 
    2448       102883 :   if (!COMPLETE_TYPE_P (ctype))
    2449              :     {
    2450           83 :       if (!same_type_p (ctype, objtype))
    2451            0 :         goto mismatch;
    2452              :       binfo = NULL;
    2453              :     }
    2454              :   else
    2455              :     {
    2456       102800 :       binfo = lookup_base (objtype, ctype, ba_check, NULL, complain);
    2457              : 
    2458       102800 :       if (!binfo)
    2459              :         {
    2460           36 :         mismatch:
    2461           36 :           if (complain & tf_error)
    2462              :             {
    2463            6 :               if (COMPLETE_TYPE_P (objtype))
    2464            3 :                 error ("pointer to member type %qT incompatible "
    2465              :                        "with object type %qT because %qT is not "
    2466              :                        "derived from %qT", ptrmem_type, objtype,
    2467              :                        objtype, ctype);
    2468              :               else
    2469            3 :                 error ("pointer to member type %qT incompatible with "
    2470              :                        "incomplete object type %qT", ptrmem_type, objtype);
    2471              :             }
    2472           36 :           return error_mark_node;
    2473              :         }
    2474       102764 :       else if (binfo == error_mark_node)
    2475              :         return error_mark_node;
    2476              :     }
    2477              : 
    2478       102838 :   if (TYPE_PTRDATAMEM_P (ptrmem_type))
    2479              :     {
    2480         1198 :       bool is_lval = real_lvalue_p (datum);
    2481         1198 :       tree ptype;
    2482              : 
    2483              :       /* Compute the type of the field, as described in [expr.ref].
    2484              :          There's no such thing as a mutable pointer-to-member, so
    2485              :          things are not as complex as they are for references to
    2486              :          non-static data members.  */
    2487         1198 :       type = cp_build_qualified_type (type,
    2488         1198 :                                       (cp_type_quals (type)
    2489         1198 :                                        | cp_type_quals (TREE_TYPE (datum))));
    2490              : 
    2491         1198 :       datum = cp_build_addr_expr (datum, complain);
    2492              : 
    2493              :       /* Convert object to the correct base.  */
    2494         1198 :       if (binfo)
    2495              :         {
    2496         1171 :           datum = build_base_path (PLUS_EXPR, datum, binfo, 1, complain);
    2497         1171 :           if (datum == error_mark_node)
    2498              :             return error_mark_node;
    2499              :         }
    2500              : 
    2501              :       /* Build an expression for "object + offset" where offset is the
    2502              :          value stored in the pointer-to-data-member.  */
    2503         1198 :       ptype = build_pointer_type (type);
    2504         1198 :       datum = convert (ptype, datum);
    2505         1198 :       if (!processing_template_decl)
    2506         1177 :         datum = build2 (POINTER_PLUS_EXPR, ptype,
    2507              :                         datum, convert_to_ptrofftype (component));
    2508         1198 :       datum = cp_fully_fold (datum);
    2509         1198 :       datum = cp_build_fold_indirect_ref (datum);
    2510         1198 :       if (datum == error_mark_node)
    2511              :         return error_mark_node;
    2512              : 
    2513              :       /* If the object expression was an rvalue, return an rvalue.  */
    2514         1198 :       if (!is_lval)
    2515          126 :         datum = move (datum);
    2516         1198 :       return datum;
    2517              :     }
    2518              :   else
    2519              :     {
    2520              :       /* 5.5/6: In a .* expression whose object expression is an rvalue, the
    2521              :          program is ill-formed if the second operand is a pointer to member
    2522              :          function with ref-qualifier & (for C++20: unless its cv-qualifier-seq
    2523              :          is const). In a .* expression whose object expression is an lvalue,
    2524              :          the program is ill-formed if the second operand is a pointer to member
    2525              :          function with ref-qualifier &&.  */
    2526       101640 :       if (FUNCTION_REF_QUALIFIED (type))
    2527              :         {
    2528          126 :           bool lval = lvalue_p (datum);
    2529          126 :           if (lval && FUNCTION_RVALUE_QUALIFIED (type))
    2530              :             {
    2531           15 :               if (complain & tf_error)
    2532            6 :                 error ("pointer-to-member-function type %qT requires an rvalue",
    2533              :                        ptrmem_type);
    2534           15 :               return error_mark_node;
    2535              :             }
    2536          111 :           else if (!lval && !FUNCTION_RVALUE_QUALIFIED (type))
    2537              :             {
    2538           33 :               if ((type_memfn_quals (type)
    2539           33 :                    & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE))
    2540              :                   != TYPE_QUAL_CONST)
    2541              :                 {
    2542           27 :                   if (complain & tf_error)
    2543           24 :                     error ("pointer-to-member-function type %qT requires "
    2544              :                            "an lvalue", ptrmem_type);
    2545           27 :                   return error_mark_node;
    2546              :                 }
    2547            6 :               else if (cxx_dialect < cxx20)
    2548              :                 {
    2549            3 :                   if (complain & tf_warning_or_error)
    2550            3 :                     pedwarn (input_location, OPT_Wpedantic,
    2551              :                              "pointer-to-member-function type %qT requires "
    2552              :                              "an lvalue before C++20", ptrmem_type);
    2553              :                   else
    2554            0 :                     return error_mark_node;
    2555              :                 }
    2556              :             }
    2557              :         }
    2558       101598 :       return build2 (OFFSET_REF, type, datum, component);
    2559              :     }
    2560              : }
    2561              : 
    2562              : /* Return a tree node for the expression TYPENAME '(' PARMS ')'.  */
    2563              : 
    2564              : static tree
    2565     74793235 : build_functional_cast_1 (location_t loc, tree exp, tree parms,
    2566              :                          tsubst_flags_t complain)
    2567              : {
    2568              :   /* This is either a call to a constructor,
    2569              :      or a C cast in C++'s `functional' notation.  */
    2570              : 
    2571              :   /* The type to which we are casting.  */
    2572     74793235 :   tree type;
    2573              : 
    2574     74793235 :   if (error_operand_p (exp) || parms == error_mark_node)
    2575        24400 :     return error_mark_node;
    2576              : 
    2577     74768835 :   if (TREE_CODE (exp) == TYPE_DECL)
    2578              :     {
    2579     41899324 :       type = TREE_TYPE (exp);
    2580              : 
    2581     41899324 :       if (DECL_ARTIFICIAL (exp))
    2582     26921823 :         cp_handle_deprecated_or_unavailable (type);
    2583              :     }
    2584              :   else
    2585              :     type = exp;
    2586              : 
    2587              :   /* We need to check this explicitly, since value-initialization of
    2588              :      arrays is allowed in other situations.  */
    2589     74768835 :   if (TREE_CODE (type) == ARRAY_TYPE)
    2590              :     {
    2591           12 :       if (complain & tf_error)
    2592            6 :         error_at (loc, "functional cast to array type %qT", type);
    2593           12 :       return error_mark_node;
    2594              :     }
    2595              : 
    2596     74768823 :   if (tree anode = type_uses_auto (type))
    2597              :     {
    2598       626202 :       tree init;
    2599       626202 :       if (CLASS_PLACEHOLDER_TEMPLATE (anode))
    2600              :         init = parms;
    2601              :       /* C++23 auto(x).  */
    2602       121426 :       else if (!AUTO_IS_DECLTYPE (anode)
    2603       121426 :                && list_length (parms) == 1)
    2604              :         {
    2605       121415 :           init = TREE_VALUE (parms);
    2606       121415 :           if (is_constrained_auto (anode))
    2607              :             {
    2608            2 :               if (complain & tf_error)
    2609            2 :                 error_at (loc, "%<auto(x)%> cannot be constrained");
    2610            2 :               return error_mark_node;
    2611              :             }
    2612       121413 :           else if (cxx_dialect < cxx23)
    2613              :             {
    2614           25 :               if ((complain & tf_warning_or_error) == 0)
    2615            2 :                 return error_mark_node;
    2616           23 :               pedwarn (loc, OPT_Wc__23_extensions,
    2617              :                        "%<auto(x)%> only available with "
    2618              :                        "%<-std=c++23%> or %<-std=gnu++23%>");
    2619              :             }
    2620              :         }
    2621              :       else
    2622              :         {
    2623           11 :           if (complain & tf_error)
    2624           11 :             error_at (loc, "invalid use of %qT", anode);
    2625           11 :           return error_mark_node;
    2626              :         }
    2627       626187 :       type = do_auto_deduction (type, init, anode, complain,
    2628              :                                 adc_variable_type);
    2629       626187 :       if (type == error_mark_node)
    2630              :         return error_mark_node;
    2631              :     }
    2632              : 
    2633     74768696 :   if (processing_template_decl)
    2634              :     {
    2635     39990356 :       tree t;
    2636              : 
    2637              :       /* Diagnose this even in a template.  We could also try harder
    2638              :          to give all the usual errors when the type and args are
    2639              :          non-dependent...  */
    2640     39990356 :       if (TYPE_REF_P (type) && !parms)
    2641              :         {
    2642            3 :           if (complain & tf_error)
    2643            3 :             error_at (loc, "invalid value-initialization of reference type");
    2644            3 :           return error_mark_node;
    2645              :         }
    2646              : 
    2647     39990353 :       t = build_min (CAST_EXPR, type, parms);
    2648              :       /* We don't know if it will or will not have side effects.  */
    2649     39990353 :       TREE_SIDE_EFFECTS (t) = 1;
    2650     39990353 :       return convert_from_reference (t);
    2651              :     }
    2652              : 
    2653     34778340 :   if (! MAYBE_CLASS_TYPE_P (type))
    2654              :     {
    2655     30000747 :       if (parms == NULL_TREE)
    2656              :         {
    2657       796407 :           if (VOID_TYPE_P (type))
    2658         4173 :             return void_node;
    2659       792234 :           return build_value_init (cv_unqualified (type), complain);
    2660              :         }
    2661              : 
    2662              :       /* This must build a C cast.  */
    2663     29204340 :       parms = build_x_compound_expr_from_list (parms, ELK_FUNC_CAST, complain);
    2664     29204340 :       return cp_build_c_cast (loc, type, parms, complain);
    2665              :     }
    2666              : 
    2667              :   /* Prepare to evaluate as a call to a constructor.  If this expression
    2668              :      is actually used, for example,
    2669              : 
    2670              :      return X (arg1, arg2, ...);
    2671              : 
    2672              :      then the slot being initialized will be filled in.  */
    2673              : 
    2674      4777593 :   if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
    2675           18 :     return error_mark_node;
    2676      4777572 :   if (abstract_virtuals_error (ACU_CAST, type, complain))
    2677           15 :     return error_mark_node;
    2678              : 
    2679              :   /* [expr.type.conv]
    2680              : 
    2681              :      If the expression list is a single-expression, the type
    2682              :      conversion is equivalent (in definedness, and if defined in
    2683              :      meaning) to the corresponding cast expression.  */
    2684      4777557 :   if (parms && TREE_CHAIN (parms) == NULL_TREE)
    2685      2931335 :     return cp_build_c_cast (loc, type, TREE_VALUE (parms), complain);
    2686              : 
    2687              :   /* [expr.type.conv]
    2688              : 
    2689              :      The expression T(), where T is a simple-type-specifier for a
    2690              :      non-array complete object type or the (possibly cv-qualified)
    2691              :      void type, creates an rvalue of the specified type, which is
    2692              :      value-initialized.  */
    2693              : 
    2694      1846222 :   if (parms == NULL_TREE)
    2695              :     {
    2696      1105532 :       exp = build_value_init (type, complain);
    2697      1105532 :       exp = get_target_expr (exp, complain);
    2698      1105532 :       return exp;
    2699              :     }
    2700              : 
    2701              :   /* Call the constructor.  */
    2702       740690 :   releasing_vec parmvec;
    2703      2362100 :   for (; parms != NULL_TREE; parms = TREE_CHAIN (parms))
    2704      1621410 :     vec_safe_push (parmvec, TREE_VALUE (parms));
    2705       740690 :   exp = build_special_member_call (NULL_TREE, complete_ctor_identifier,
    2706              :                                    &parmvec, type, LOOKUP_NORMAL, complain);
    2707              : 
    2708       740690 :   if (exp == error_mark_node)
    2709              :     return error_mark_node;
    2710              : 
    2711       740660 :   return build_cplus_new (type, exp, complain);
    2712       740690 : }
    2713              : 
    2714              : tree
    2715     74793235 : build_functional_cast (location_t loc, tree exp, tree parms,
    2716              :                        tsubst_flags_t complain)
    2717              : {
    2718     74793235 :   tree result = build_functional_cast_1 (loc, exp, parms, complain);
    2719     74793232 :   protected_set_expr_location (result, loc);
    2720     74793232 :   return result;
    2721              : }
    2722              : 
    2723              : 
    2724              : /* Add new exception specifier SPEC, to the LIST we currently have.
    2725              :    If it's already in LIST then do nothing.
    2726              :    Moan if it's bad and we're allowed to. COMPLAIN < 0 means we
    2727              :    know what we're doing.  */
    2728              : 
    2729              : tree
    2730        15530 : add_exception_specifier (tree list, tree spec, tsubst_flags_t complain)
    2731              : {
    2732        15530 :   bool ok;
    2733        15530 :   tree core = spec;
    2734        15530 :   bool is_ptr;
    2735        15530 :   enum diagnostics::kind diag_type = diagnostics::kind::unspecified; /* none */
    2736              : 
    2737        15530 :   if (spec == error_mark_node)
    2738              :     return list;
    2739              : 
    2740        15555 :   gcc_assert (spec && (!list || TREE_VALUE (list)));
    2741              : 
    2742              :   /* [except.spec] 1, type in an exception specifier shall not be
    2743              :      incomplete, or pointer or ref to incomplete other than pointer
    2744              :      to cv void.  */
    2745        15516 :   is_ptr = TYPE_PTR_P (core);
    2746        15516 :   if (is_ptr || TYPE_REF_P (core))
    2747           19 :     core = TREE_TYPE (core);
    2748        15516 :   if (complain < 0)
    2749              :     ok = true;
    2750         1350 :   else if (VOID_TYPE_P (core))
    2751              :     ok = is_ptr;
    2752         1342 :   else if (TREE_CODE (core) == TEMPLATE_TYPE_PARM)
    2753              :     ok = true;
    2754         1332 :   else if (processing_template_decl)
    2755              :     ok = true;
    2756         1295 :   else if (!verify_type_context (input_location, TCTX_EXCEPTIONS, core,
    2757              :                                  !(complain & tf_error)))
    2758            0 :     return error_mark_node;
    2759              :   else
    2760              :     {
    2761         1295 :       ok = true;
    2762              :       /* 15.4/1 says that types in an exception specifier must be complete,
    2763              :          but it seems more reasonable to only require this on definitions
    2764              :          and calls.  So just give a pedwarn at this point; we will give an
    2765              :          error later if we hit one of those two cases.  */
    2766         1295 :       if (!COMPLETE_TYPE_P (complete_type (core)))
    2767        15516 :         diag_type = diagnostics::kind::pedwarn; /* pedwarn */
    2768              :     }
    2769              : 
    2770        15516 :   if (ok)
    2771              :     {
    2772              :       tree probe;
    2773              : 
    2774        15555 :       for (probe = list; probe; probe = TREE_CHAIN (probe))
    2775           47 :         if (same_type_p (TREE_VALUE (probe), spec))
    2776              :           break;
    2777        15510 :       if (!probe)
    2778        15508 :         list = tree_cons (NULL_TREE, spec, list);
    2779              :     }
    2780              :   else
    2781              :     diag_type = diagnostics::kind::error; /* error */
    2782              : 
    2783        15510 :   if (diag_type != diagnostics::kind::unspecified
    2784           12 :       && (complain & tf_warning_or_error))
    2785           10 :     cxx_incomplete_type_diagnostic (NULL_TREE, core, diag_type);
    2786              : 
    2787              :   return list;
    2788              : }
    2789              : 
    2790              : /* Like nothrow_spec_p, but don't abort on deferred noexcept.  */
    2791              : 
    2792              : static bool
    2793      5106294 : nothrow_spec_p_uninst (const_tree spec)
    2794              : {
    2795     10212588 :   if (DEFERRED_NOEXCEPT_SPEC_P (spec))
    2796              :     return false;
    2797      5106292 :   return nothrow_spec_p (spec);
    2798              : }
    2799              : 
    2800              : /* Combine the two exceptions specifier lists LIST and ADD, and return
    2801              :    their union.  */
    2802              : 
    2803              : tree
    2804     12541017 : merge_exception_specifiers (tree list, tree add)
    2805              : {
    2806     12541017 :   tree noex, orig_list;
    2807              : 
    2808     12541017 :   if (list == error_mark_node || add == error_mark_node)
    2809              :     return error_mark_node;
    2810              : 
    2811              :   /* No exception-specifier or noexcept(false) are less strict than
    2812              :      anything else.  Prefer the newer variant (LIST).  */
    2813     12541017 :   if (!list || list == noexcept_false_spec)
    2814              :     return list;
    2815      5187415 :   else if (!add || add == noexcept_false_spec)
    2816              :     return add;
    2817              : 
    2818              :   /* noexcept(true) and throw() are stricter than anything else.
    2819              :      As above, prefer the more recent one (LIST).  */
    2820      5069422 :   if (nothrow_spec_p_uninst (add))
    2821              :     return list;
    2822              : 
    2823              :   /* Two implicit noexcept specs (e.g. on a destructor) are equivalent.  */
    2824        36874 :   if (UNEVALUATED_NOEXCEPT_SPEC_P (add)
    2825            2 :       && UNEVALUATED_NOEXCEPT_SPEC_P (list))
    2826              :     return list;
    2827              :   /* We should have instantiated other deferred noexcept specs by now.  */
    2828        36872 :   gcc_assert (!DEFERRED_NOEXCEPT_SPEC_P (add));
    2829              : 
    2830        36872 :   if (nothrow_spec_p_uninst (list))
    2831              :     return add;
    2832        36869 :   noex = TREE_PURPOSE (list);
    2833        36869 :   gcc_checking_assert (!TREE_PURPOSE (add)
    2834              :                        || errorcount || !flag_exceptions
    2835              :                        || cp_tree_equal (noex, TREE_PURPOSE (add)));
    2836              : 
    2837              :   /* Combine the dynamic-exception-specifiers, if any.  */
    2838              :   orig_list = list;
    2839        73773 :   for (; add && TREE_VALUE (add); add = TREE_CHAIN (add))
    2840              :     {
    2841           40 :       tree spec = TREE_VALUE (add);
    2842              :       tree probe;
    2843              : 
    2844           74 :       for (probe = orig_list; probe && TREE_VALUE (probe);
    2845           12 :            probe = TREE_CHAIN (probe))
    2846           34 :         if (same_type_p (TREE_VALUE (probe), spec))
    2847              :           break;
    2848           28 :       if (!probe)
    2849              :         {
    2850            6 :           spec = build_tree_list (NULL_TREE, spec);
    2851            6 :           TREE_CHAIN (spec) = list;
    2852            6 :           list = spec;
    2853              :         }
    2854              :     }
    2855              : 
    2856              :   /* Keep the noexcept-specifier at the beginning of the list.  */
    2857        36869 :   if (noex != TREE_PURPOSE (list))
    2858            0 :     list = tree_cons (noex, TREE_VALUE (list), TREE_CHAIN (list));
    2859              : 
    2860              :   return list;
    2861              : }
    2862              : 
    2863              : /* Subroutine of build_call.  Ensure that each of the types in the
    2864              :    exception specification is complete.  Technically, 15.4/1 says that
    2865              :    they need to be complete when we see a declaration of the function,
    2866              :    but we should be able to get away with only requiring this when the
    2867              :    function is defined or called.  See also add_exception_specifier.  */
    2868              : 
    2869              : void
    2870    226019904 : require_complete_eh_spec_types (tree fntype, tree decl)
    2871              : {
    2872    226019904 :   tree raises;
    2873              :   /* Don't complain about calls to op new.  */
    2874    226019904 :   if (decl && DECL_ARTIFICIAL (decl))
    2875              :     return;
    2876    330608035 :   for (raises = TYPE_RAISES_EXCEPTIONS (fntype); raises;
    2877    117935311 :        raises = TREE_CHAIN (raises))
    2878              :     {
    2879    117935311 :       tree type = TREE_VALUE (raises);
    2880    117935311 :       if (type && !COMPLETE_TYPE_P (type))
    2881              :         {
    2882            1 :           if (decl)
    2883            1 :             error
    2884            1 :               ("call to function %qD which throws incomplete type %q#T",
    2885              :                decl, type);
    2886              :           else
    2887            0 :             error ("call to function which throws incomplete type %q#T",
    2888              :                    decl);
    2889              :         }
    2890              :     }
    2891              : }
    2892              : 
    2893              : /* Record that any TARGET_EXPR in T are going to be elided in
    2894              :    cp_gimplify_init_expr (or sooner).  */
    2895              : 
    2896              : void
    2897    200265061 : set_target_expr_eliding (tree t)
    2898              : {
    2899    203305189 :   if (!t)
    2900              :     return;
    2901    202241267 :   switch (TREE_CODE (t))
    2902              :     {
    2903     19718453 :     case TARGET_EXPR:
    2904     19718453 :       TARGET_EXPR_ELIDING_P (t) = true;
    2905     19718453 :       break;
    2906      1867503 :     case COMPOUND_EXPR:
    2907      1867503 :       set_target_expr_eliding (TREE_OPERAND (t, 1));
    2908      1867503 :       break;
    2909      1172625 :     case COND_EXPR:
    2910      1172625 :       set_target_expr_eliding (TREE_OPERAND (t, 1));
    2911      1172625 :       set_target_expr_eliding (TREE_OPERAND (t, 2));
    2912      1172625 :       break;
    2913              : 
    2914              :     default:
    2915              :       break;
    2916              :     }
    2917              : }
    2918              : 
    2919              : /* Call the above in the process of building an INIT_EXPR.  */
    2920              : 
    2921              : tree
    2922     76033059 : cp_build_init_expr (location_t loc, tree target, tree init)
    2923              : {
    2924     76033059 :   set_target_expr_eliding (init);
    2925     76033059 :   tree ie = build2_loc (loc, INIT_EXPR, TREE_TYPE (target),
    2926              :                         target, init);
    2927     76033059 :   TREE_SIDE_EFFECTS (ie) = true;
    2928     76033059 :   return ie;
    2929              : }
        

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.