LCOV - code coverage report
Current view: top level - gcc/cp - typeck2.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.0 % 1237 1151
Test Date: 2025-03-22 13:13:03 Functions: 100.0 % 40 40
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-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.