xref: /dflybsd-src/contrib/gcc-8.0/gcc/cp/init.c (revision 95059079af47f9a66a175f374f2da1a5020e3255)
138fd1498Szrj /* Handle initialization things in C++.
238fd1498Szrj    Copyright (C) 1987-2018 Free Software Foundation, Inc.
338fd1498Szrj    Contributed by Michael Tiemann (tiemann@cygnus.com)
438fd1498Szrj 
538fd1498Szrj This file is part of GCC.
638fd1498Szrj 
738fd1498Szrj GCC is free software; you can redistribute it and/or modify
838fd1498Szrj it under the terms of the GNU General Public License as published by
938fd1498Szrj the Free Software Foundation; either version 3, or (at your option)
1038fd1498Szrj any later version.
1138fd1498Szrj 
1238fd1498Szrj GCC is distributed in the hope that it will be useful,
1338fd1498Szrj but WITHOUT ANY WARRANTY; without even the implied warranty of
1438fd1498Szrj MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1538fd1498Szrj GNU General Public License for more details.
1638fd1498Szrj 
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3.  If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>.  */
2038fd1498Szrj 
2138fd1498Szrj /* High-level class interface.  */
2238fd1498Szrj 
2338fd1498Szrj #include "config.h"
2438fd1498Szrj #include "system.h"
2538fd1498Szrj #include "coretypes.h"
2638fd1498Szrj #include "target.h"
2738fd1498Szrj #include "cp-tree.h"
2838fd1498Szrj #include "stringpool.h"
2938fd1498Szrj #include "varasm.h"
3038fd1498Szrj #include "gimplify.h"
3138fd1498Szrj #include "c-family/c-ubsan.h"
3238fd1498Szrj #include "intl.h"
3338fd1498Szrj #include "stringpool.h"
3438fd1498Szrj #include "attribs.h"
3538fd1498Szrj #include "asan.h"
3638fd1498Szrj 
3738fd1498Szrj static bool begin_init_stmts (tree *, tree *);
3838fd1498Szrj static tree finish_init_stmts (bool, tree, tree);
3938fd1498Szrj static void construct_virtual_base (tree, tree);
4038fd1498Szrj static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
4138fd1498Szrj static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
4238fd1498Szrj static void perform_member_init (tree, tree);
4338fd1498Szrj static int member_init_ok_or_else (tree, tree, tree);
4438fd1498Szrj static void expand_virtual_init (tree, tree);
4538fd1498Szrj static tree sort_mem_initializers (tree, tree);
4638fd1498Szrj static tree initializing_context (tree);
4738fd1498Szrj static void expand_cleanup_for_base (tree, tree);
4838fd1498Szrj static tree dfs_initialize_vtbl_ptrs (tree, void *);
4938fd1498Szrj static tree build_field_list (tree, tree, int *);
5038fd1498Szrj static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool);
5138fd1498Szrj 
5238fd1498Szrj static GTY(()) tree fn;
5338fd1498Szrj 
5438fd1498Szrj /* We are about to generate some complex initialization code.
5538fd1498Szrj    Conceptually, it is all a single expression.  However, we may want
5638fd1498Szrj    to include conditionals, loops, and other such statement-level
5738fd1498Szrj    constructs.  Therefore, we build the initialization code inside a
5838fd1498Szrj    statement-expression.  This function starts such an expression.
5938fd1498Szrj    STMT_EXPR_P and COMPOUND_STMT_P are filled in by this function;
6038fd1498Szrj    pass them back to finish_init_stmts when the expression is
6138fd1498Szrj    complete.  */
6238fd1498Szrj 
6338fd1498Szrj static bool
begin_init_stmts(tree * stmt_expr_p,tree * compound_stmt_p)6438fd1498Szrj begin_init_stmts (tree *stmt_expr_p, tree *compound_stmt_p)
6538fd1498Szrj {
6638fd1498Szrj   bool is_global = !building_stmt_list_p ();
6738fd1498Szrj 
6838fd1498Szrj   *stmt_expr_p = begin_stmt_expr ();
6938fd1498Szrj   *compound_stmt_p = begin_compound_stmt (BCS_NO_SCOPE);
7038fd1498Szrj 
7138fd1498Szrj   return is_global;
7238fd1498Szrj }
7338fd1498Szrj 
7438fd1498Szrj /* Finish out the statement-expression begun by the previous call to
7538fd1498Szrj    begin_init_stmts.  Returns the statement-expression itself.  */
7638fd1498Szrj 
7738fd1498Szrj static tree
finish_init_stmts(bool is_global,tree stmt_expr,tree compound_stmt)7838fd1498Szrj finish_init_stmts (bool is_global, tree stmt_expr, tree compound_stmt)
7938fd1498Szrj {
8038fd1498Szrj   finish_compound_stmt (compound_stmt);
8138fd1498Szrj 
8238fd1498Szrj   stmt_expr = finish_stmt_expr (stmt_expr, true);
8338fd1498Szrj 
8438fd1498Szrj   gcc_assert (!building_stmt_list_p () == is_global);
8538fd1498Szrj 
8638fd1498Szrj   return stmt_expr;
8738fd1498Szrj }
8838fd1498Szrj 
8938fd1498Szrj /* Constructors */
9038fd1498Szrj 
9138fd1498Szrj /* Called from initialize_vtbl_ptrs via dfs_walk.  BINFO is the base
9238fd1498Szrj    which we want to initialize the vtable pointer for, DATA is
9338fd1498Szrj    TREE_LIST whose TREE_VALUE is the this ptr expression.  */
9438fd1498Szrj 
9538fd1498Szrj static tree
dfs_initialize_vtbl_ptrs(tree binfo,void * data)9638fd1498Szrj dfs_initialize_vtbl_ptrs (tree binfo, void *data)
9738fd1498Szrj {
9838fd1498Szrj   if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
9938fd1498Szrj     return dfs_skip_bases;
10038fd1498Szrj 
10138fd1498Szrj   if (!BINFO_PRIMARY_P (binfo) || BINFO_VIRTUAL_P (binfo))
10238fd1498Szrj     {
10338fd1498Szrj       tree base_ptr = TREE_VALUE ((tree) data);
10438fd1498Szrj 
10538fd1498Szrj       base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1,
10638fd1498Szrj 				  tf_warning_or_error);
10738fd1498Szrj 
10838fd1498Szrj       expand_virtual_init (binfo, base_ptr);
10938fd1498Szrj     }
11038fd1498Szrj 
11138fd1498Szrj   return NULL_TREE;
11238fd1498Szrj }
11338fd1498Szrj 
11438fd1498Szrj /* Initialize all the vtable pointers in the object pointed to by
11538fd1498Szrj    ADDR.  */
11638fd1498Szrj 
11738fd1498Szrj void
initialize_vtbl_ptrs(tree addr)11838fd1498Szrj initialize_vtbl_ptrs (tree addr)
11938fd1498Szrj {
12038fd1498Szrj   tree list;
12138fd1498Szrj   tree type;
12238fd1498Szrj 
12338fd1498Szrj   type = TREE_TYPE (TREE_TYPE (addr));
12438fd1498Szrj   list = build_tree_list (type, addr);
12538fd1498Szrj 
12638fd1498Szrj   /* Walk through the hierarchy, initializing the vptr in each base
12738fd1498Szrj      class.  We do these in pre-order because we can't find the virtual
12838fd1498Szrj      bases for a class until we've initialized the vtbl for that
12938fd1498Szrj      class.  */
13038fd1498Szrj   dfs_walk_once (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, NULL, list);
13138fd1498Szrj }
13238fd1498Szrj 
13338fd1498Szrj /* Return an expression for the zero-initialization of an object with
13438fd1498Szrj    type T.  This expression will either be a constant (in the case
13538fd1498Szrj    that T is a scalar), or a CONSTRUCTOR (in the case that T is an
13638fd1498Szrj    aggregate), or NULL (in the case that T does not require
13738fd1498Szrj    initialization).  In either case, the value can be used as
13838fd1498Szrj    DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
13938fd1498Szrj    initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
14038fd1498Szrj    is the number of elements in the array.  If STATIC_STORAGE_P is
14138fd1498Szrj    TRUE, initializers are only generated for entities for which
14238fd1498Szrj    zero-initialization does not simply mean filling the storage with
14338fd1498Szrj    zero bytes.  FIELD_SIZE, if non-NULL, is the bit size of the field,
14438fd1498Szrj    subfields with bit positions at or above that bit size shouldn't
14538fd1498Szrj    be added.  Note that this only works when the result is assigned
14638fd1498Szrj    to a base COMPONENT_REF; if we only have a pointer to the base subobject,
14738fd1498Szrj    expand_assignment will end up clearing the full size of TYPE.  */
14838fd1498Szrj 
14938fd1498Szrj static tree
build_zero_init_1(tree type,tree nelts,bool static_storage_p,tree field_size)15038fd1498Szrj build_zero_init_1 (tree type, tree nelts, bool static_storage_p,
15138fd1498Szrj 		   tree field_size)
15238fd1498Szrj {
15338fd1498Szrj   tree init = NULL_TREE;
15438fd1498Szrj 
15538fd1498Szrj   /* [dcl.init]
15638fd1498Szrj 
15738fd1498Szrj      To zero-initialize an object of type T means:
15838fd1498Szrj 
15938fd1498Szrj      -- if T is a scalar type, the storage is set to the value of zero
16038fd1498Szrj 	converted to T.
16138fd1498Szrj 
16238fd1498Szrj      -- if T is a non-union class type, the storage for each nonstatic
16338fd1498Szrj 	data member and each base-class subobject is zero-initialized.
16438fd1498Szrj 
16538fd1498Szrj      -- if T is a union type, the storage for its first data member is
16638fd1498Szrj 	zero-initialized.
16738fd1498Szrj 
16838fd1498Szrj      -- if T is an array type, the storage for each element is
16938fd1498Szrj 	zero-initialized.
17038fd1498Szrj 
17138fd1498Szrj      -- if T is a reference type, no initialization is performed.  */
17238fd1498Szrj 
17338fd1498Szrj   gcc_assert (nelts == NULL_TREE || TREE_CODE (nelts) == INTEGER_CST);
17438fd1498Szrj 
17538fd1498Szrj   if (type == error_mark_node)
17638fd1498Szrj     ;
17738fd1498Szrj   else if (static_storage_p && zero_init_p (type))
17838fd1498Szrj     /* In order to save space, we do not explicitly build initializers
17938fd1498Szrj        for items that do not need them.  GCC's semantics are that
18038fd1498Szrj        items with static storage duration that are not otherwise
18138fd1498Szrj        initialized are initialized to zero.  */
18238fd1498Szrj     ;
18338fd1498Szrj   else if (TYPE_PTR_OR_PTRMEM_P (type))
18438fd1498Szrj     init = fold (convert (type, nullptr_node));
18538fd1498Szrj   else if (NULLPTR_TYPE_P (type))
18638fd1498Szrj     init = build_int_cst (type, 0);
18738fd1498Szrj   else if (SCALAR_TYPE_P (type))
18838fd1498Szrj     init = fold (convert (type, integer_zero_node));
18938fd1498Szrj   else if (RECORD_OR_UNION_CODE_P (TREE_CODE (type)))
19038fd1498Szrj     {
19138fd1498Szrj       tree field;
19238fd1498Szrj       vec<constructor_elt, va_gc> *v = NULL;
19338fd1498Szrj 
19438fd1498Szrj       /* Iterate over the fields, building initializations.  */
19538fd1498Szrj       for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
19638fd1498Szrj 	{
19738fd1498Szrj 	  if (TREE_CODE (field) != FIELD_DECL)
19838fd1498Szrj 	    continue;
19938fd1498Szrj 
20038fd1498Szrj 	  if (TREE_TYPE (field) == error_mark_node)
20138fd1498Szrj 	    continue;
20238fd1498Szrj 
20338fd1498Szrj 	  /* Don't add virtual bases for base classes if they are beyond
20438fd1498Szrj 	     the size of the current field, that means it is present
20538fd1498Szrj 	     somewhere else in the object.  */
20638fd1498Szrj 	  if (field_size)
20738fd1498Szrj 	    {
20838fd1498Szrj 	      tree bitpos = bit_position (field);
20938fd1498Szrj 	      if (TREE_CODE (bitpos) == INTEGER_CST
21038fd1498Szrj 		  && !tree_int_cst_lt (bitpos, field_size))
21138fd1498Szrj 		continue;
21238fd1498Szrj 	    }
21338fd1498Szrj 
21438fd1498Szrj 	  /* Note that for class types there will be FIELD_DECLs
21538fd1498Szrj 	     corresponding to base classes as well.  Thus, iterating
21638fd1498Szrj 	     over TYPE_FIELDs will result in correct initialization of
21738fd1498Szrj 	     all of the subobjects.  */
21838fd1498Szrj 	  if (!static_storage_p || !zero_init_p (TREE_TYPE (field)))
21938fd1498Szrj 	    {
22038fd1498Szrj 	      tree new_field_size
22138fd1498Szrj 		= (DECL_FIELD_IS_BASE (field)
22238fd1498Szrj 		   && DECL_SIZE (field)
22338fd1498Szrj 		   && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
22438fd1498Szrj 		  ? DECL_SIZE (field) : NULL_TREE;
22538fd1498Szrj 	      tree value = build_zero_init_1 (TREE_TYPE (field),
22638fd1498Szrj 					      /*nelts=*/NULL_TREE,
22738fd1498Szrj 					      static_storage_p,
22838fd1498Szrj 					      new_field_size);
22938fd1498Szrj 	      if (value)
23038fd1498Szrj 		CONSTRUCTOR_APPEND_ELT(v, field, value);
23138fd1498Szrj 	    }
23238fd1498Szrj 
23338fd1498Szrj 	  /* For unions, only the first field is initialized.  */
23438fd1498Szrj 	  if (TREE_CODE (type) == UNION_TYPE)
23538fd1498Szrj 	    break;
23638fd1498Szrj 	}
23738fd1498Szrj 
23838fd1498Szrj       /* Build a constructor to contain the initializations.  */
23938fd1498Szrj       init = build_constructor (type, v);
24038fd1498Szrj     }
24138fd1498Szrj   else if (TREE_CODE (type) == ARRAY_TYPE)
24238fd1498Szrj     {
24338fd1498Szrj       tree max_index;
24438fd1498Szrj       vec<constructor_elt, va_gc> *v = NULL;
24538fd1498Szrj 
24638fd1498Szrj       /* Iterate over the array elements, building initializations.  */
24738fd1498Szrj       if (nelts)
24838fd1498Szrj 	max_index = fold_build2_loc (input_location,
24938fd1498Szrj 				 MINUS_EXPR, TREE_TYPE (nelts),
25038fd1498Szrj 				 nelts, integer_one_node);
25138fd1498Szrj       else
25238fd1498Szrj 	max_index = array_type_nelts (type);
25338fd1498Szrj 
25438fd1498Szrj       /* If we have an error_mark here, we should just return error mark
25538fd1498Szrj 	 as we don't know the size of the array yet.  */
25638fd1498Szrj       if (max_index == error_mark_node)
25738fd1498Szrj 	return error_mark_node;
25838fd1498Szrj       gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
25938fd1498Szrj 
26038fd1498Szrj       /* A zero-sized array, which is accepted as an extension, will
26138fd1498Szrj 	 have an upper bound of -1.  */
26238fd1498Szrj       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
26338fd1498Szrj 	{
26438fd1498Szrj 	  constructor_elt ce;
26538fd1498Szrj 
26638fd1498Szrj 	  /* If this is a one element array, we just use a regular init.  */
26738fd1498Szrj 	  if (tree_int_cst_equal (size_zero_node, max_index))
26838fd1498Szrj 	    ce.index = size_zero_node;
26938fd1498Szrj 	  else
27038fd1498Szrj 	    ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
27138fd1498Szrj 				max_index);
27238fd1498Szrj 
27338fd1498Szrj 	  ce.value = build_zero_init_1 (TREE_TYPE (type),
27438fd1498Szrj 					 /*nelts=*/NULL_TREE,
27538fd1498Szrj 					 static_storage_p, NULL_TREE);
27638fd1498Szrj 	  if (ce.value)
27738fd1498Szrj 	    {
27838fd1498Szrj 	      vec_alloc (v, 1);
27938fd1498Szrj 	      v->quick_push (ce);
28038fd1498Szrj 	    }
28138fd1498Szrj 	}
28238fd1498Szrj 
28338fd1498Szrj       /* Build a constructor to contain the initializations.  */
28438fd1498Szrj       init = build_constructor (type, v);
28538fd1498Szrj     }
28638fd1498Szrj   else if (VECTOR_TYPE_P (type))
28738fd1498Szrj     init = build_zero_cst (type);
28838fd1498Szrj   else
28938fd1498Szrj     {
29038fd1498Szrj       gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
29138fd1498Szrj       init = build_zero_cst (type);
29238fd1498Szrj     }
29338fd1498Szrj 
29438fd1498Szrj   /* In all cases, the initializer is a constant.  */
29538fd1498Szrj   if (init)
29638fd1498Szrj     TREE_CONSTANT (init) = 1;
29738fd1498Szrj 
29838fd1498Szrj   return init;
29938fd1498Szrj }
30038fd1498Szrj 
30138fd1498Szrj /* Return an expression for the zero-initialization of an object with
30238fd1498Szrj    type T.  This expression will either be a constant (in the case
30338fd1498Szrj    that T is a scalar), or a CONSTRUCTOR (in the case that T is an
30438fd1498Szrj    aggregate), or NULL (in the case that T does not require
30538fd1498Szrj    initialization).  In either case, the value can be used as
30638fd1498Szrj    DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
30738fd1498Szrj    initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
30838fd1498Szrj    is the number of elements in the array.  If STATIC_STORAGE_P is
30938fd1498Szrj    TRUE, initializers are only generated for entities for which
31038fd1498Szrj    zero-initialization does not simply mean filling the storage with
31138fd1498Szrj    zero bytes.  */
31238fd1498Szrj 
31338fd1498Szrj tree
build_zero_init(tree type,tree nelts,bool static_storage_p)31438fd1498Szrj build_zero_init (tree type, tree nelts, bool static_storage_p)
31538fd1498Szrj {
31638fd1498Szrj   return build_zero_init_1 (type, nelts, static_storage_p, NULL_TREE);
31738fd1498Szrj }
31838fd1498Szrj 
31938fd1498Szrj /* Return a suitable initializer for value-initializing an object of type
32038fd1498Szrj    TYPE, as described in [dcl.init].  */
32138fd1498Szrj 
32238fd1498Szrj tree
build_value_init(tree type,tsubst_flags_t complain)32338fd1498Szrj build_value_init (tree type, tsubst_flags_t complain)
32438fd1498Szrj {
32538fd1498Szrj   /* [dcl.init]
32638fd1498Szrj 
32738fd1498Szrj      To value-initialize an object of type T means:
32838fd1498Szrj 
32938fd1498Szrj      - if T is a class type (clause 9) with either no default constructor
33038fd1498Szrj        (12.1) or a default constructor that is user-provided or deleted,
33138fd1498Szrj        then the object is default-initialized;
33238fd1498Szrj 
33338fd1498Szrj      - if T is a (possibly cv-qualified) class type without a user-provided
33438fd1498Szrj        or deleted default constructor, then the object is zero-initialized
33538fd1498Szrj        and the semantic constraints for default-initialization are checked,
33638fd1498Szrj        and if T has a non-trivial default constructor, the object is
33738fd1498Szrj        default-initialized;
33838fd1498Szrj 
33938fd1498Szrj      - if T is an array type, then each element is value-initialized;
34038fd1498Szrj 
34138fd1498Szrj      - otherwise, the object is zero-initialized.
34238fd1498Szrj 
34338fd1498Szrj      A program that calls for default-initialization or
34438fd1498Szrj      value-initialization of an entity of reference type is ill-formed.  */
34538fd1498Szrj 
34638fd1498Szrj   /* The AGGR_INIT_EXPR tweaking below breaks in templates.  */
34738fd1498Szrj   gcc_assert (!processing_template_decl
34838fd1498Szrj 	      || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
34938fd1498Szrj 
35038fd1498Szrj   if (CLASS_TYPE_P (type)
35138fd1498Szrj       && type_build_ctor_call (type))
35238fd1498Szrj     {
35338fd1498Szrj       tree ctor =
35438fd1498Szrj 	 build_special_member_call (NULL_TREE, complete_ctor_identifier,
35538fd1498Szrj 				    NULL, type, LOOKUP_NORMAL,
35638fd1498Szrj 				    complain);
35738fd1498Szrj       if (ctor == error_mark_node)
35838fd1498Szrj 	return ctor;
35938fd1498Szrj       tree fn = NULL_TREE;
36038fd1498Szrj       if (TREE_CODE (ctor) == CALL_EXPR)
36138fd1498Szrj 	fn = get_callee_fndecl (ctor);
36238fd1498Szrj       ctor = build_aggr_init_expr (type, ctor);
36338fd1498Szrj       if (fn && user_provided_p (fn))
36438fd1498Szrj 	return ctor;
36538fd1498Szrj       else if (TYPE_HAS_COMPLEX_DFLT (type))
36638fd1498Szrj 	{
36738fd1498Szrj 	  /* This is a class that needs constructing, but doesn't have
36838fd1498Szrj 	     a user-provided constructor.  So we need to zero-initialize
36938fd1498Szrj 	     the object and then call the implicitly defined ctor.
37038fd1498Szrj 	     This will be handled in simplify_aggr_init_expr.  */
37138fd1498Szrj 	  AGGR_INIT_ZERO_FIRST (ctor) = 1;
37238fd1498Szrj 	  return ctor;
37338fd1498Szrj 	}
37438fd1498Szrj     }
37538fd1498Szrj 
37638fd1498Szrj   /* Discard any access checking during subobject initialization;
37738fd1498Szrj      the checks are implied by the call to the ctor which we have
37838fd1498Szrj      verified is OK (cpp0x/defaulted46.C).  */
37938fd1498Szrj   push_deferring_access_checks (dk_deferred);
38038fd1498Szrj   tree r = build_value_init_noctor (type, complain);
38138fd1498Szrj   pop_deferring_access_checks ();
38238fd1498Szrj   return r;
38338fd1498Szrj }
38438fd1498Szrj 
38538fd1498Szrj /* Like build_value_init, but don't call the constructor for TYPE.  Used
38638fd1498Szrj    for base initializers.  */
38738fd1498Szrj 
38838fd1498Szrj tree
build_value_init_noctor(tree type,tsubst_flags_t complain)38938fd1498Szrj build_value_init_noctor (tree type, tsubst_flags_t complain)
39038fd1498Szrj {
39138fd1498Szrj   if (!COMPLETE_TYPE_P (type))
39238fd1498Szrj     {
39338fd1498Szrj       if (complain & tf_error)
39438fd1498Szrj 	error ("value-initialization of incomplete type %qT", type);
39538fd1498Szrj       return error_mark_node;
39638fd1498Szrj     }
39738fd1498Szrj   /* FIXME the class and array cases should just use digest_init once it is
39838fd1498Szrj      SFINAE-enabled.  */
39938fd1498Szrj   if (CLASS_TYPE_P (type))
40038fd1498Szrj     {
40138fd1498Szrj       gcc_assert (!TYPE_HAS_COMPLEX_DFLT (type)
40238fd1498Szrj 		  || errorcount != 0);
40338fd1498Szrj 
40438fd1498Szrj       if (TREE_CODE (type) != UNION_TYPE)
40538fd1498Szrj 	{
40638fd1498Szrj 	  tree field;
40738fd1498Szrj 	  vec<constructor_elt, va_gc> *v = NULL;
40838fd1498Szrj 
40938fd1498Szrj 	  /* Iterate over the fields, building initializations.  */
41038fd1498Szrj 	  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
41138fd1498Szrj 	    {
41238fd1498Szrj 	      tree ftype, value;
41338fd1498Szrj 
41438fd1498Szrj 	      if (TREE_CODE (field) != FIELD_DECL)
41538fd1498Szrj 		continue;
41638fd1498Szrj 
41738fd1498Szrj 	      ftype = TREE_TYPE (field);
41838fd1498Szrj 
41938fd1498Szrj 	      if (ftype == error_mark_node)
42038fd1498Szrj 		continue;
42138fd1498Szrj 
42238fd1498Szrj 	      /* We could skip vfields and fields of types with
42338fd1498Szrj 		 user-defined constructors, but I think that won't improve
42438fd1498Szrj 		 performance at all; it should be simpler in general just
42538fd1498Szrj 		 to zero out the entire object than try to only zero the
42638fd1498Szrj 		 bits that actually need it.  */
42738fd1498Szrj 
42838fd1498Szrj 	      /* Note that for class types there will be FIELD_DECLs
42938fd1498Szrj 		 corresponding to base classes as well.  Thus, iterating
43038fd1498Szrj 		 over TYPE_FIELDs will result in correct initialization of
43138fd1498Szrj 		 all of the subobjects.  */
43238fd1498Szrj 	      value = build_value_init (ftype, complain);
43338fd1498Szrj 	      value = maybe_constant_init (value);
43438fd1498Szrj 
43538fd1498Szrj 	      if (value == error_mark_node)
43638fd1498Szrj 		return error_mark_node;
43738fd1498Szrj 
43838fd1498Szrj 	      CONSTRUCTOR_APPEND_ELT(v, field, value);
43938fd1498Szrj 
44038fd1498Szrj 	      /* We shouldn't have gotten here for anything that would need
44138fd1498Szrj 		 non-trivial initialization, and gimplify_init_ctor_preeval
44238fd1498Szrj 		 would need to be fixed to allow it.  */
44338fd1498Szrj 	      gcc_assert (TREE_CODE (value) != TARGET_EXPR
44438fd1498Szrj 			  && TREE_CODE (value) != AGGR_INIT_EXPR);
44538fd1498Szrj 	    }
44638fd1498Szrj 
44738fd1498Szrj 	  /* Build a constructor to contain the zero- initializations.  */
44838fd1498Szrj 	  return build_constructor (type, v);
44938fd1498Szrj 	}
45038fd1498Szrj     }
45138fd1498Szrj   else if (TREE_CODE (type) == ARRAY_TYPE)
45238fd1498Szrj     {
45338fd1498Szrj       vec<constructor_elt, va_gc> *v = NULL;
45438fd1498Szrj 
45538fd1498Szrj       /* Iterate over the array elements, building initializations.  */
45638fd1498Szrj       tree max_index = array_type_nelts (type);
45738fd1498Szrj 
45838fd1498Szrj       /* If we have an error_mark here, we should just return error mark
45938fd1498Szrj 	 as we don't know the size of the array yet.  */
46038fd1498Szrj       if (max_index == error_mark_node)
46138fd1498Szrj 	{
46238fd1498Szrj 	  if (complain & tf_error)
46338fd1498Szrj 	    error ("cannot value-initialize array of unknown bound %qT",
46438fd1498Szrj 		   type);
46538fd1498Szrj 	  return error_mark_node;
46638fd1498Szrj 	}
46738fd1498Szrj       gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
46838fd1498Szrj 
46938fd1498Szrj       /* A zero-sized array, which is accepted as an extension, will
47038fd1498Szrj 	 have an upper bound of -1.  */
47138fd1498Szrj       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
47238fd1498Szrj 	{
47338fd1498Szrj 	  constructor_elt ce;
47438fd1498Szrj 
47538fd1498Szrj 	  /* If this is a one element array, we just use a regular init.  */
47638fd1498Szrj 	  if (tree_int_cst_equal (size_zero_node, max_index))
47738fd1498Szrj 	    ce.index = size_zero_node;
47838fd1498Szrj 	  else
47938fd1498Szrj 	    ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node, max_index);
48038fd1498Szrj 
48138fd1498Szrj 	  ce.value = build_value_init (TREE_TYPE (type), complain);
48238fd1498Szrj 	  ce.value = maybe_constant_init (ce.value);
48338fd1498Szrj 	  if (ce.value == error_mark_node)
48438fd1498Szrj 	    return error_mark_node;
48538fd1498Szrj 
48638fd1498Szrj 	  vec_alloc (v, 1);
48738fd1498Szrj 	  v->quick_push (ce);
48838fd1498Szrj 
48938fd1498Szrj 	  /* We shouldn't have gotten here for anything that would need
49038fd1498Szrj 	     non-trivial initialization, and gimplify_init_ctor_preeval
49138fd1498Szrj 	     would need to be fixed to allow it.  */
49238fd1498Szrj 	  gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
49338fd1498Szrj 		      && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
49438fd1498Szrj 	}
49538fd1498Szrj 
49638fd1498Szrj       /* Build a constructor to contain the initializations.  */
49738fd1498Szrj       return build_constructor (type, v);
49838fd1498Szrj     }
49938fd1498Szrj   else if (TREE_CODE (type) == FUNCTION_TYPE)
50038fd1498Szrj     {
50138fd1498Szrj       if (complain & tf_error)
50238fd1498Szrj 	error ("value-initialization of function type %qT", type);
50338fd1498Szrj       return error_mark_node;
50438fd1498Szrj     }
50538fd1498Szrj   else if (TREE_CODE (type) == REFERENCE_TYPE)
50638fd1498Szrj     {
50738fd1498Szrj       if (complain & tf_error)
50838fd1498Szrj 	error ("value-initialization of reference type %qT", type);
50938fd1498Szrj       return error_mark_node;
51038fd1498Szrj     }
51138fd1498Szrj 
51238fd1498Szrj   return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
51338fd1498Szrj }
51438fd1498Szrj 
51538fd1498Szrj /* Initialize current class with INIT, a TREE_LIST of
51638fd1498Szrj    arguments for a target constructor. If TREE_LIST is void_type_node,
51738fd1498Szrj    an empty initializer list was given.  */
51838fd1498Szrj 
51938fd1498Szrj static void
perform_target_ctor(tree init)52038fd1498Szrj perform_target_ctor (tree init)
52138fd1498Szrj {
52238fd1498Szrj   tree decl = current_class_ref;
52338fd1498Szrj   tree type = current_class_type;
52438fd1498Szrj 
52538fd1498Szrj   finish_expr_stmt (build_aggr_init (decl, init,
52638fd1498Szrj 				     LOOKUP_NORMAL|LOOKUP_DELEGATING_CONS,
52738fd1498Szrj 				     tf_warning_or_error));
52838fd1498Szrj   if (type_build_dtor_call (type))
52938fd1498Szrj     {
53038fd1498Szrj       tree expr = build_delete (type, decl, sfk_complete_destructor,
53138fd1498Szrj 				LOOKUP_NORMAL
53238fd1498Szrj 				|LOOKUP_NONVIRTUAL
53338fd1498Szrj 				|LOOKUP_DESTRUCTOR,
53438fd1498Szrj 				0, tf_warning_or_error);
53538fd1498Szrj       if (expr != error_mark_node
53638fd1498Szrj 	  && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
53738fd1498Szrj 	finish_eh_cleanup (expr);
53838fd1498Szrj     }
53938fd1498Szrj }
54038fd1498Szrj 
54138fd1498Szrj /* Return the non-static data initializer for FIELD_DECL MEMBER.  */
54238fd1498Szrj 
54338fd1498Szrj static GTY((cache)) tree_cache_map *nsdmi_inst;
54438fd1498Szrj 
54538fd1498Szrj tree
get_nsdmi(tree member,bool in_ctor,tsubst_flags_t complain)54638fd1498Szrj get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
54738fd1498Szrj {
54838fd1498Szrj   tree init;
54938fd1498Szrj   tree save_ccp = current_class_ptr;
55038fd1498Szrj   tree save_ccr = current_class_ref;
55138fd1498Szrj 
55238fd1498Szrj   if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
55338fd1498Szrj     {
55438fd1498Szrj       init = DECL_INITIAL (DECL_TI_TEMPLATE (member));
55538fd1498Szrj       location_t expr_loc
55638fd1498Szrj 	= EXPR_LOC_OR_LOC (init, DECL_SOURCE_LOCATION (member));
55738fd1498Szrj       tree *slot;
55838fd1498Szrj       if (TREE_CODE (init) == DEFAULT_ARG)
55938fd1498Szrj 	/* Unparsed.  */;
56038fd1498Szrj       else if (nsdmi_inst && (slot = nsdmi_inst->get (member)))
56138fd1498Szrj 	init = *slot;
56238fd1498Szrj       /* Check recursive instantiation.  */
56338fd1498Szrj       else if (DECL_INSTANTIATING_NSDMI_P (member))
56438fd1498Szrj 	{
56538fd1498Szrj 	  if (complain & tf_error)
56638fd1498Szrj 	    error_at (expr_loc, "recursive instantiation of default member "
56738fd1498Szrj 		      "initializer for %qD", member);
56838fd1498Szrj 	  init = error_mark_node;
56938fd1498Szrj 	}
57038fd1498Szrj       else
57138fd1498Szrj 	{
57238fd1498Szrj 	  int un = cp_unevaluated_operand;
57338fd1498Szrj 	  cp_unevaluated_operand = 0;
57438fd1498Szrj 
57538fd1498Szrj 	  location_t sloc = input_location;
57638fd1498Szrj 	  input_location = expr_loc;
57738fd1498Szrj 
57838fd1498Szrj 	  DECL_INSTANTIATING_NSDMI_P (member) = 1;
57938fd1498Szrj 
580*58e805e6Szrj 	  bool pushed = false;
581*58e805e6Szrj 	  if (!currently_open_class (DECL_CONTEXT (member)))
582*58e805e6Szrj 	    {
583*58e805e6Szrj 	      push_to_top_level ();
584*58e805e6Szrj 	      push_nested_class (DECL_CONTEXT (member));
585*58e805e6Szrj 	      pushed = true;
586*58e805e6Szrj 	    }
587*58e805e6Szrj 
588*58e805e6Szrj 	  gcc_checking_assert (!processing_template_decl);
589*58e805e6Szrj 
59038fd1498Szrj 	  inject_this_parameter (DECL_CONTEXT (member), TYPE_UNQUALIFIED);
59138fd1498Szrj 
59238fd1498Szrj 	  start_lambda_scope (member);
59338fd1498Szrj 
59438fd1498Szrj 	  /* Do deferred instantiation of the NSDMI.  */
59538fd1498Szrj 	  init = (tsubst_copy_and_build
59638fd1498Szrj 		  (init, DECL_TI_ARGS (member),
59738fd1498Szrj 		   complain, member, /*function_p=*/false,
59838fd1498Szrj 		   /*integral_constant_expression_p=*/false));
59938fd1498Szrj 	  init = digest_nsdmi_init (member, init, complain);
60038fd1498Szrj 
60138fd1498Szrj 	  finish_lambda_scope ();
60238fd1498Szrj 
60338fd1498Szrj 	  DECL_INSTANTIATING_NSDMI_P (member) = 0;
60438fd1498Szrj 
60538fd1498Szrj 	  if (init != error_mark_node)
60638fd1498Szrj 	    {
60738fd1498Szrj 	      if (!nsdmi_inst)
60838fd1498Szrj 		nsdmi_inst = tree_cache_map::create_ggc (37);
60938fd1498Szrj 	      nsdmi_inst->put (member, init);
61038fd1498Szrj 	    }
61138fd1498Szrj 
612*58e805e6Szrj 	  if (pushed)
613*58e805e6Szrj 	    {
614*58e805e6Szrj 	      pop_nested_class ();
615*58e805e6Szrj 	      pop_from_top_level ();
616*58e805e6Szrj 	    }
617*58e805e6Szrj 
61838fd1498Szrj 	  input_location = sloc;
61938fd1498Szrj 	  cp_unevaluated_operand = un;
62038fd1498Szrj 	}
62138fd1498Szrj     }
62238fd1498Szrj   else
62338fd1498Szrj     init = DECL_INITIAL (member);
62438fd1498Szrj 
62538fd1498Szrj   if (init && TREE_CODE (init) == DEFAULT_ARG)
62638fd1498Szrj     {
62738fd1498Szrj       if (complain & tf_error)
62838fd1498Szrj 	{
62938fd1498Szrj 	  error ("default member initializer for %qD required before the end "
63038fd1498Szrj 		 "of its enclosing class", member);
63138fd1498Szrj 	  inform (location_of (init), "defined here");
63238fd1498Szrj 	  DECL_INITIAL (member) = error_mark_node;
63338fd1498Szrj 	}
63438fd1498Szrj       init = error_mark_node;
63538fd1498Szrj     }
63638fd1498Szrj 
63738fd1498Szrj   if (in_ctor)
63838fd1498Szrj     {
63938fd1498Szrj       current_class_ptr = save_ccp;
64038fd1498Szrj       current_class_ref = save_ccr;
64138fd1498Szrj     }
64238fd1498Szrj   else
64338fd1498Szrj     {
64438fd1498Szrj       /* Use a PLACEHOLDER_EXPR when we don't have a 'this' parameter to
64538fd1498Szrj 	 refer to; constexpr evaluation knows what to do with it.  */
64638fd1498Szrj       current_class_ref = build0 (PLACEHOLDER_EXPR, DECL_CONTEXT (member));
64738fd1498Szrj       current_class_ptr = build_address (current_class_ref);
64838fd1498Szrj     }
64938fd1498Szrj 
65038fd1498Szrj   /* Strip redundant TARGET_EXPR so we don't need to remap it, and
65138fd1498Szrj      so the aggregate init code below will see a CONSTRUCTOR.  */
65238fd1498Szrj   bool simple_target = (init && SIMPLE_TARGET_EXPR_P (init));
65338fd1498Szrj   if (simple_target)
65438fd1498Szrj     init = TARGET_EXPR_INITIAL (init);
65538fd1498Szrj   init = break_out_target_exprs (init, /*loc*/true);
65638fd1498Szrj   if (simple_target && TREE_CODE (init) != CONSTRUCTOR)
65738fd1498Szrj     /* Now put it back so C++17 copy elision works.  */
65838fd1498Szrj     init = get_target_expr (init);
65938fd1498Szrj 
66038fd1498Szrj   current_class_ptr = save_ccp;
66138fd1498Szrj   current_class_ref = save_ccr;
66238fd1498Szrj   return init;
66338fd1498Szrj }
66438fd1498Szrj 
66538fd1498Szrj /* Diagnose the flexible array MEMBER if its INITializer is non-null
66638fd1498Szrj    and return true if so.  Otherwise return false.  */
66738fd1498Szrj 
66838fd1498Szrj bool
maybe_reject_flexarray_init(tree member,tree init)66938fd1498Szrj maybe_reject_flexarray_init (tree member, tree init)
67038fd1498Szrj {
67138fd1498Szrj   tree type = TREE_TYPE (member);
67238fd1498Szrj 
67338fd1498Szrj   if (!init
67438fd1498Szrj       || TREE_CODE (type) != ARRAY_TYPE
67538fd1498Szrj       || TYPE_DOMAIN (type))
67638fd1498Szrj     return false;
67738fd1498Szrj 
67838fd1498Szrj   /* Point at the flexible array member declaration if it's initialized
67938fd1498Szrj      in-class, and at the ctor if it's initialized in a ctor member
68038fd1498Szrj      initializer list.  */
68138fd1498Szrj   location_t loc;
68238fd1498Szrj   if (DECL_INITIAL (member) == init
68338fd1498Szrj       || !current_function_decl
68438fd1498Szrj       || DECL_DEFAULTED_FN (current_function_decl))
68538fd1498Szrj     loc = DECL_SOURCE_LOCATION (member);
68638fd1498Szrj   else
68738fd1498Szrj     loc = DECL_SOURCE_LOCATION (current_function_decl);
68838fd1498Szrj 
68938fd1498Szrj   error_at (loc, "initializer for flexible array member %q#D", member);
69038fd1498Szrj   return true;
69138fd1498Szrj }
69238fd1498Szrj 
69338fd1498Szrj /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
69438fd1498Szrj    arguments.  If TREE_LIST is void_type_node, an empty initializer
69538fd1498Szrj    list was given; if NULL_TREE no initializer was given.  */
69638fd1498Szrj 
69738fd1498Szrj static void
perform_member_init(tree member,tree init)69838fd1498Szrj perform_member_init (tree member, tree init)
69938fd1498Szrj {
70038fd1498Szrj   tree decl;
70138fd1498Szrj   tree type = TREE_TYPE (member);
70238fd1498Szrj 
70338fd1498Szrj   /* Use the non-static data member initializer if there was no
70438fd1498Szrj      mem-initializer for this field.  */
70538fd1498Szrj   if (init == NULL_TREE)
70638fd1498Szrj     init = get_nsdmi (member, /*ctor*/true, tf_warning_or_error);
70738fd1498Szrj 
70838fd1498Szrj   if (init == error_mark_node)
70938fd1498Szrj     return;
71038fd1498Szrj 
71138fd1498Szrj   /* Effective C++ rule 12 requires that all data members be
71238fd1498Szrj      initialized.  */
71338fd1498Szrj   if (warn_ecpp && init == NULL_TREE && TREE_CODE (type) != ARRAY_TYPE)
71438fd1498Szrj     warning_at (DECL_SOURCE_LOCATION (current_function_decl), OPT_Weffc__,
71538fd1498Szrj 		"%qD should be initialized in the member initialization list",
71638fd1498Szrj 		member);
71738fd1498Szrj 
71838fd1498Szrj   /* Get an lvalue for the data member.  */
71938fd1498Szrj   decl = build_class_member_access_expr (current_class_ref, member,
72038fd1498Szrj 					 /*access_path=*/NULL_TREE,
72138fd1498Szrj 					 /*preserve_reference=*/true,
72238fd1498Szrj 					 tf_warning_or_error);
72338fd1498Szrj   if (decl == error_mark_node)
72438fd1498Szrj     return;
72538fd1498Szrj 
72638fd1498Szrj   if (warn_init_self && init && TREE_CODE (init) == TREE_LIST
72738fd1498Szrj       && TREE_CHAIN (init) == NULL_TREE)
72838fd1498Szrj     {
72938fd1498Szrj       tree val = TREE_VALUE (init);
73038fd1498Szrj       /* Handle references.  */
73138fd1498Szrj       if (REFERENCE_REF_P (val))
73238fd1498Szrj 	val = TREE_OPERAND (val, 0);
73338fd1498Szrj       if (TREE_CODE (val) == COMPONENT_REF && TREE_OPERAND (val, 1) == member
73438fd1498Szrj 	  && TREE_OPERAND (val, 0) == current_class_ref)
73538fd1498Szrj 	warning_at (DECL_SOURCE_LOCATION (current_function_decl),
73638fd1498Szrj 		    OPT_Winit_self, "%qD is initialized with itself",
73738fd1498Szrj 		    member);
73838fd1498Szrj     }
73938fd1498Szrj 
74038fd1498Szrj   if (init == void_type_node)
74138fd1498Szrj     {
74238fd1498Szrj       /* mem() means value-initialization.  */
74338fd1498Szrj       if (TREE_CODE (type) == ARRAY_TYPE)
74438fd1498Szrj 	{
74538fd1498Szrj 	  init = build_vec_init_expr (type, init, tf_warning_or_error);
74638fd1498Szrj 	  init = build2 (INIT_EXPR, type, decl, init);
74738fd1498Szrj 	  finish_expr_stmt (init);
74838fd1498Szrj 	}
74938fd1498Szrj       else
75038fd1498Szrj 	{
75138fd1498Szrj 	  tree value = build_value_init (type, tf_warning_or_error);
75238fd1498Szrj 	  if (value == error_mark_node)
75338fd1498Szrj 	    return;
75438fd1498Szrj 	  init = build2 (INIT_EXPR, type, decl, value);
75538fd1498Szrj 	  finish_expr_stmt (init);
75638fd1498Szrj 	}
75738fd1498Szrj     }
75838fd1498Szrj   /* Deal with this here, as we will get confused if we try to call the
75938fd1498Szrj      assignment op for an anonymous union.  This can happen in a
76038fd1498Szrj      synthesized copy constructor.  */
76138fd1498Szrj   else if (ANON_AGGR_TYPE_P (type))
76238fd1498Szrj     {
76338fd1498Szrj       if (init)
76438fd1498Szrj 	{
76538fd1498Szrj 	  init = build2 (INIT_EXPR, type, decl, TREE_VALUE (init));
76638fd1498Szrj 	  finish_expr_stmt (init);
76738fd1498Szrj 	}
76838fd1498Szrj     }
76938fd1498Szrj   else if (init
77038fd1498Szrj 	   && (TREE_CODE (type) == REFERENCE_TYPE
77138fd1498Szrj 	       /* Pre-digested NSDMI.  */
77238fd1498Szrj 	       || (((TREE_CODE (init) == CONSTRUCTOR
77338fd1498Szrj 		     && TREE_TYPE (init) == type)
77438fd1498Szrj 		    /* { } mem-initializer.  */
77538fd1498Szrj 		    || (TREE_CODE (init) == TREE_LIST
77638fd1498Szrj 			&& DIRECT_LIST_INIT_P (TREE_VALUE (init))))
77738fd1498Szrj 		   && (CP_AGGREGATE_TYPE_P (type)
77838fd1498Szrj 		       || is_std_init_list (type)))))
77938fd1498Szrj     {
78038fd1498Szrj       /* With references and list-initialization, we need to deal with
78138fd1498Szrj 	 extending temporary lifetimes.  12.2p5: "A temporary bound to a
78238fd1498Szrj 	 reference member in a constructor’s ctor-initializer (12.6.2)
78338fd1498Szrj 	 persists until the constructor exits."  */
78438fd1498Szrj       unsigned i; tree t;
78538fd1498Szrj       vec<tree, va_gc> *cleanups = make_tree_vector ();
78638fd1498Szrj       if (TREE_CODE (init) == TREE_LIST)
78738fd1498Szrj 	init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
78838fd1498Szrj 						tf_warning_or_error);
78938fd1498Szrj       if (TREE_TYPE (init) != type)
79038fd1498Szrj 	{
79138fd1498Szrj 	  if (BRACE_ENCLOSED_INITIALIZER_P (init)
79238fd1498Szrj 	      && CP_AGGREGATE_TYPE_P (type))
79338fd1498Szrj 	    init = reshape_init (type, init, tf_warning_or_error);
79438fd1498Szrj 	  init = digest_init (type, init, tf_warning_or_error);
79538fd1498Szrj 	}
79638fd1498Szrj       if (init == error_mark_node)
79738fd1498Szrj 	return;
79838fd1498Szrj       /* A FIELD_DECL doesn't really have a suitable lifetime, but
79938fd1498Szrj 	 make_temporary_var_for_ref_to_temp will treat it as automatic and
80038fd1498Szrj 	 set_up_extended_ref_temp wants to use the decl in a warning.  */
80138fd1498Szrj       init = extend_ref_init_temps (member, init, &cleanups);
80238fd1498Szrj       if (TREE_CODE (type) == ARRAY_TYPE
80338fd1498Szrj 	  && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type)))
80438fd1498Szrj 	init = build_vec_init_expr (type, init, tf_warning_or_error);
80538fd1498Szrj       init = build2 (INIT_EXPR, type, decl, init);
80638fd1498Szrj       finish_expr_stmt (init);
80738fd1498Szrj       FOR_EACH_VEC_ELT (*cleanups, i, t)
80838fd1498Szrj 	push_cleanup (decl, t, false);
80938fd1498Szrj       release_tree_vector (cleanups);
81038fd1498Szrj     }
81138fd1498Szrj   else if (type_build_ctor_call (type)
81238fd1498Szrj 	   || (init && CLASS_TYPE_P (strip_array_types (type))))
81338fd1498Szrj     {
81438fd1498Szrj       if (TREE_CODE (type) == ARRAY_TYPE)
81538fd1498Szrj 	{
81638fd1498Szrj 	  if (init)
81738fd1498Szrj 	    {
81838fd1498Szrj 	      /* Check to make sure the member initializer is valid and
81938fd1498Szrj 		 something like a CONSTRUCTOR in: T a[] = { 1, 2 } and
82038fd1498Szrj 		 if it isn't, return early to avoid triggering another
82138fd1498Szrj 		 error below.  */
82238fd1498Szrj 	      if (maybe_reject_flexarray_init (member, init))
82338fd1498Szrj 		return;
82438fd1498Szrj 
82538fd1498Szrj 	      if (TREE_CODE (init) != TREE_LIST || TREE_CHAIN (init))
82638fd1498Szrj 		init = error_mark_node;
82738fd1498Szrj 	      else
82838fd1498Szrj 		init = TREE_VALUE (init);
82938fd1498Szrj 
83038fd1498Szrj 	      if (BRACE_ENCLOSED_INITIALIZER_P (init))
83138fd1498Szrj 		init = digest_init (type, init, tf_warning_or_error);
83238fd1498Szrj 	    }
83338fd1498Szrj 	  if (init == NULL_TREE
83438fd1498Szrj 	      || same_type_ignoring_top_level_qualifiers_p (type,
83538fd1498Szrj 							    TREE_TYPE (init)))
83638fd1498Szrj 	    {
83738fd1498Szrj 	      if (TYPE_DOMAIN (type) && TYPE_MAX_VALUE (TYPE_DOMAIN (type)))
83838fd1498Szrj 		{
83938fd1498Szrj 		  /* Initialize the array only if it's not a flexible
84038fd1498Szrj 		     array member (i.e., if it has an upper bound).  */
84138fd1498Szrj 		  init = build_vec_init_expr (type, init, tf_warning_or_error);
84238fd1498Szrj 		  init = build2 (INIT_EXPR, type, decl, init);
84338fd1498Szrj 		  finish_expr_stmt (init);
84438fd1498Szrj 		}
84538fd1498Szrj 	    }
84638fd1498Szrj 	  else
84738fd1498Szrj 	    error ("invalid initializer for array member %q#D", member);
84838fd1498Szrj 	}
84938fd1498Szrj       else
85038fd1498Szrj 	{
85138fd1498Szrj 	  int flags = LOOKUP_NORMAL;
85238fd1498Szrj 	  if (DECL_DEFAULTED_FN (current_function_decl))
85338fd1498Szrj 	    flags |= LOOKUP_DEFAULTED;
85438fd1498Szrj 	  if (CP_TYPE_CONST_P (type)
85538fd1498Szrj 	      && init == NULL_TREE
85638fd1498Szrj 	      && default_init_uninitialized_part (type))
85738fd1498Szrj 	    {
85838fd1498Szrj 	      /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a
85938fd1498Szrj 		 vtable; still give this diagnostic.  */
86038fd1498Szrj 	      if (permerror (DECL_SOURCE_LOCATION (current_function_decl),
86138fd1498Szrj 			     "uninitialized const member in %q#T", type))
86238fd1498Szrj 		inform (DECL_SOURCE_LOCATION (member),
86338fd1498Szrj 			"%q#D should be initialized", member );
86438fd1498Szrj 	    }
86538fd1498Szrj 	  finish_expr_stmt (build_aggr_init (decl, init, flags,
86638fd1498Szrj 					     tf_warning_or_error));
86738fd1498Szrj 	}
86838fd1498Szrj     }
86938fd1498Szrj   else
87038fd1498Szrj     {
87138fd1498Szrj       if (init == NULL_TREE)
87238fd1498Szrj 	{
87338fd1498Szrj 	  tree core_type;
87438fd1498Szrj 	  /* member traversal: note it leaves init NULL */
87538fd1498Szrj 	  if (TREE_CODE (type) == REFERENCE_TYPE)
87638fd1498Szrj 	    {
87738fd1498Szrj 	      if (permerror (DECL_SOURCE_LOCATION (current_function_decl),
87838fd1498Szrj 			     "uninitialized reference member in %q#T", type))
87938fd1498Szrj 		inform (DECL_SOURCE_LOCATION (member),
88038fd1498Szrj 			"%q#D should be initialized", member);
88138fd1498Szrj 	    }
88238fd1498Szrj 	  else if (CP_TYPE_CONST_P (type))
88338fd1498Szrj 	    {
88438fd1498Szrj 	      if (permerror (DECL_SOURCE_LOCATION (current_function_decl),
88538fd1498Szrj 			     "uninitialized const member in %q#T", type))
88638fd1498Szrj 		  inform (DECL_SOURCE_LOCATION (member),
88738fd1498Szrj 			  "%q#D should be initialized", member );
88838fd1498Szrj 	    }
88938fd1498Szrj 
89038fd1498Szrj 	  core_type = strip_array_types (type);
89138fd1498Szrj 
89238fd1498Szrj 	  if (CLASS_TYPE_P (core_type)
89338fd1498Szrj 	      && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
89438fd1498Szrj 		  || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
89538fd1498Szrj 	    diagnose_uninitialized_cst_or_ref_member (core_type,
89638fd1498Szrj 						      /*using_new=*/false,
89738fd1498Szrj 						      /*complain=*/true);
89838fd1498Szrj 	}
89938fd1498Szrj       else if (TREE_CODE (init) == TREE_LIST)
90038fd1498Szrj 	/* There was an explicit member initialization.  Do some work
90138fd1498Szrj 	   in that case.  */
90238fd1498Szrj 	init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
90338fd1498Szrj 						tf_warning_or_error);
90438fd1498Szrj 
90538fd1498Szrj       /* Reject a member initializer for a flexible array member.  */
90638fd1498Szrj       if (init && !maybe_reject_flexarray_init (member, init))
90738fd1498Szrj 	finish_expr_stmt (cp_build_modify_expr (input_location, decl,
90838fd1498Szrj 						INIT_EXPR, init,
90938fd1498Szrj 						tf_warning_or_error));
91038fd1498Szrj     }
91138fd1498Szrj 
91238fd1498Szrj   if (type_build_dtor_call (type))
91338fd1498Szrj     {
91438fd1498Szrj       tree expr;
91538fd1498Szrj 
91638fd1498Szrj       expr = build_class_member_access_expr (current_class_ref, member,
91738fd1498Szrj 					     /*access_path=*/NULL_TREE,
91838fd1498Szrj 					     /*preserve_reference=*/false,
91938fd1498Szrj 					     tf_warning_or_error);
92038fd1498Szrj       expr = build_delete (type, expr, sfk_complete_destructor,
92138fd1498Szrj 			   LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0,
92238fd1498Szrj 			   tf_warning_or_error);
92338fd1498Szrj 
92438fd1498Szrj       if (expr != error_mark_node
92538fd1498Szrj 	  && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
92638fd1498Szrj 	finish_eh_cleanup (expr);
92738fd1498Szrj     }
92838fd1498Szrj }
92938fd1498Szrj 
93038fd1498Szrj /* Returns a TREE_LIST containing (as the TREE_PURPOSE of each node) all
93138fd1498Szrj    the FIELD_DECLs on the TYPE_FIELDS list for T, in reverse order.  */
93238fd1498Szrj 
93338fd1498Szrj static tree
build_field_list(tree t,tree list,int * uses_unions_or_anon_p)93438fd1498Szrj build_field_list (tree t, tree list, int *uses_unions_or_anon_p)
93538fd1498Szrj {
93638fd1498Szrj   tree fields;
93738fd1498Szrj 
93838fd1498Szrj   /* Note whether or not T is a union.  */
93938fd1498Szrj   if (TREE_CODE (t) == UNION_TYPE)
94038fd1498Szrj     *uses_unions_or_anon_p = 1;
94138fd1498Szrj 
94238fd1498Szrj   for (fields = TYPE_FIELDS (t); fields; fields = DECL_CHAIN (fields))
94338fd1498Szrj     {
94438fd1498Szrj       tree fieldtype;
94538fd1498Szrj 
94638fd1498Szrj       /* Skip CONST_DECLs for enumeration constants and so forth.  */
94738fd1498Szrj       if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
94838fd1498Szrj 	continue;
94938fd1498Szrj 
95038fd1498Szrj       fieldtype = TREE_TYPE (fields);
95138fd1498Szrj 
95238fd1498Szrj       /* For an anonymous struct or union, we must recursively
95338fd1498Szrj 	 consider the fields of the anonymous type.  They can be
95438fd1498Szrj 	 directly initialized from the constructor.  */
95538fd1498Szrj       if (ANON_AGGR_TYPE_P (fieldtype))
95638fd1498Szrj 	{
95738fd1498Szrj 	  /* Add this field itself.  Synthesized copy constructors
95838fd1498Szrj 	     initialize the entire aggregate.  */
95938fd1498Szrj 	  list = tree_cons (fields, NULL_TREE, list);
96038fd1498Szrj 	  /* And now add the fields in the anonymous aggregate.  */
96138fd1498Szrj 	  list = build_field_list (fieldtype, list, uses_unions_or_anon_p);
96238fd1498Szrj 	  *uses_unions_or_anon_p = 1;
96338fd1498Szrj 	}
96438fd1498Szrj       /* Add this field.  */
96538fd1498Szrj       else if (DECL_NAME (fields))
96638fd1498Szrj 	list = tree_cons (fields, NULL_TREE, list);
96738fd1498Szrj     }
96838fd1498Szrj 
96938fd1498Szrj   return list;
97038fd1498Szrj }
97138fd1498Szrj 
97238fd1498Szrj /* Return the innermost aggregate scope for FIELD, whether that is
97338fd1498Szrj    the enclosing class or an anonymous aggregate within it.  */
97438fd1498Szrj 
97538fd1498Szrj static tree
innermost_aggr_scope(tree field)97638fd1498Szrj innermost_aggr_scope (tree field)
97738fd1498Szrj {
97838fd1498Szrj   if (ANON_AGGR_TYPE_P (TREE_TYPE (field)))
97938fd1498Szrj     return TREE_TYPE (field);
98038fd1498Szrj   else
98138fd1498Szrj     return DECL_CONTEXT (field);
98238fd1498Szrj }
98338fd1498Szrj 
98438fd1498Szrj /* The MEM_INITS are a TREE_LIST.  The TREE_PURPOSE of each list gives
98538fd1498Szrj    a FIELD_DECL or BINFO in T that needs initialization.  The
98638fd1498Szrj    TREE_VALUE gives the initializer, or list of initializer arguments.
98738fd1498Szrj 
98838fd1498Szrj    Return a TREE_LIST containing all of the initializations required
98938fd1498Szrj    for T, in the order in which they should be performed.  The output
99038fd1498Szrj    list has the same format as the input.  */
99138fd1498Szrj 
99238fd1498Szrj static tree
sort_mem_initializers(tree t,tree mem_inits)99338fd1498Szrj sort_mem_initializers (tree t, tree mem_inits)
99438fd1498Szrj {
99538fd1498Szrj   tree init;
99638fd1498Szrj   tree base, binfo, base_binfo;
99738fd1498Szrj   tree sorted_inits;
99838fd1498Szrj   tree next_subobject;
99938fd1498Szrj   vec<tree, va_gc> *vbases;
100038fd1498Szrj   int i;
100138fd1498Szrj   int uses_unions_or_anon_p = 0;
100238fd1498Szrj 
100338fd1498Szrj   /* Build up a list of initializations.  The TREE_PURPOSE of entry
100438fd1498Szrj      will be the subobject (a FIELD_DECL or BINFO) to initialize.  The
100538fd1498Szrj      TREE_VALUE will be the constructor arguments, or NULL if no
100638fd1498Szrj      explicit initialization was provided.  */
100738fd1498Szrj   sorted_inits = NULL_TREE;
100838fd1498Szrj 
100938fd1498Szrj   /* Process the virtual bases.  */
101038fd1498Szrj   for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
101138fd1498Szrj        vec_safe_iterate (vbases, i, &base); i++)
101238fd1498Szrj     sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
101338fd1498Szrj 
101438fd1498Szrj   /* Process the direct bases.  */
101538fd1498Szrj   for (binfo = TYPE_BINFO (t), i = 0;
101638fd1498Szrj        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
101738fd1498Szrj     if (!BINFO_VIRTUAL_P (base_binfo))
101838fd1498Szrj       sorted_inits = tree_cons (base_binfo, NULL_TREE, sorted_inits);
101938fd1498Szrj 
102038fd1498Szrj   /* Process the non-static data members.  */
102138fd1498Szrj   sorted_inits = build_field_list (t, sorted_inits, &uses_unions_or_anon_p);
102238fd1498Szrj   /* Reverse the entire list of initializations, so that they are in
102338fd1498Szrj      the order that they will actually be performed.  */
102438fd1498Szrj   sorted_inits = nreverse (sorted_inits);
102538fd1498Szrj 
102638fd1498Szrj   /* If the user presented the initializers in an order different from
102738fd1498Szrj      that in which they will actually occur, we issue a warning.  Keep
102838fd1498Szrj      track of the next subobject which can be explicitly initialized
102938fd1498Szrj      without issuing a warning.  */
103038fd1498Szrj   next_subobject = sorted_inits;
103138fd1498Szrj 
103238fd1498Szrj   /* Go through the explicit initializers, filling in TREE_PURPOSE in
103338fd1498Szrj      the SORTED_INITS.  */
103438fd1498Szrj   for (init = mem_inits; init; init = TREE_CHAIN (init))
103538fd1498Szrj     {
103638fd1498Szrj       tree subobject;
103738fd1498Szrj       tree subobject_init;
103838fd1498Szrj 
103938fd1498Szrj       subobject = TREE_PURPOSE (init);
104038fd1498Szrj 
104138fd1498Szrj       /* If the explicit initializers are in sorted order, then
104238fd1498Szrj 	 SUBOBJECT will be NEXT_SUBOBJECT, or something following
104338fd1498Szrj 	 it.  */
104438fd1498Szrj       for (subobject_init = next_subobject;
104538fd1498Szrj 	   subobject_init;
104638fd1498Szrj 	   subobject_init = TREE_CHAIN (subobject_init))
104738fd1498Szrj 	if (TREE_PURPOSE (subobject_init) == subobject)
104838fd1498Szrj 	  break;
104938fd1498Szrj 
105038fd1498Szrj       /* Issue a warning if the explicit initializer order does not
105138fd1498Szrj 	 match that which will actually occur.
105238fd1498Szrj 	 ??? Are all these on the correct lines?  */
105338fd1498Szrj       if (warn_reorder && !subobject_init)
105438fd1498Szrj 	{
105538fd1498Szrj 	  if (TREE_CODE (TREE_PURPOSE (next_subobject)) == FIELD_DECL)
105638fd1498Szrj 	    warning_at (DECL_SOURCE_LOCATION (TREE_PURPOSE (next_subobject)),
105738fd1498Szrj 			OPT_Wreorder, "%qD will be initialized after",
105838fd1498Szrj 			TREE_PURPOSE (next_subobject));
105938fd1498Szrj 	  else
106038fd1498Szrj 	    warning (OPT_Wreorder, "base %qT will be initialized after",
106138fd1498Szrj 		     TREE_PURPOSE (next_subobject));
106238fd1498Szrj 	  if (TREE_CODE (subobject) == FIELD_DECL)
106338fd1498Szrj 	    warning_at (DECL_SOURCE_LOCATION (subobject),
106438fd1498Szrj 			OPT_Wreorder, "  %q#D", subobject);
106538fd1498Szrj 	  else
106638fd1498Szrj 	    warning (OPT_Wreorder, "  base %qT", subobject);
106738fd1498Szrj 	  warning_at (DECL_SOURCE_LOCATION (current_function_decl),
106838fd1498Szrj 		      OPT_Wreorder, "  when initialized here");
106938fd1498Szrj 	}
107038fd1498Szrj 
107138fd1498Szrj       /* Look again, from the beginning of the list.  */
107238fd1498Szrj       if (!subobject_init)
107338fd1498Szrj 	{
107438fd1498Szrj 	  subobject_init = sorted_inits;
107538fd1498Szrj 	  while (TREE_PURPOSE (subobject_init) != subobject)
107638fd1498Szrj 	    subobject_init = TREE_CHAIN (subobject_init);
107738fd1498Szrj 	}
107838fd1498Szrj 
107938fd1498Szrj       /* It is invalid to initialize the same subobject more than
108038fd1498Szrj 	 once.  */
108138fd1498Szrj       if (TREE_VALUE (subobject_init))
108238fd1498Szrj 	{
108338fd1498Szrj 	  if (TREE_CODE (subobject) == FIELD_DECL)
108438fd1498Szrj 	    error_at (DECL_SOURCE_LOCATION (current_function_decl),
108538fd1498Szrj 		      "multiple initializations given for %qD",
108638fd1498Szrj 		      subobject);
108738fd1498Szrj 	  else
108838fd1498Szrj 	    error_at (DECL_SOURCE_LOCATION (current_function_decl),
108938fd1498Szrj 		      "multiple initializations given for base %qT",
109038fd1498Szrj 		      subobject);
109138fd1498Szrj 	}
109238fd1498Szrj 
109338fd1498Szrj       /* Record the initialization.  */
109438fd1498Szrj       TREE_VALUE (subobject_init) = TREE_VALUE (init);
109538fd1498Szrj       next_subobject = subobject_init;
109638fd1498Szrj     }
109738fd1498Szrj 
109838fd1498Szrj   /* [class.base.init]
109938fd1498Szrj 
110038fd1498Szrj      If a ctor-initializer specifies more than one mem-initializer for
110138fd1498Szrj      multiple members of the same union (including members of
110238fd1498Szrj      anonymous unions), the ctor-initializer is ill-formed.
110338fd1498Szrj 
110438fd1498Szrj      Here we also splice out uninitialized union members.  */
110538fd1498Szrj   if (uses_unions_or_anon_p)
110638fd1498Szrj     {
110738fd1498Szrj       tree *last_p = NULL;
110838fd1498Szrj       tree *p;
110938fd1498Szrj       for (p = &sorted_inits; *p; )
111038fd1498Szrj 	{
111138fd1498Szrj 	  tree field;
111238fd1498Szrj 	  tree ctx;
111338fd1498Szrj 
111438fd1498Szrj 	  init = *p;
111538fd1498Szrj 
111638fd1498Szrj 	  field = TREE_PURPOSE (init);
111738fd1498Szrj 
111838fd1498Szrj 	  /* Skip base classes.  */
111938fd1498Szrj 	  if (TREE_CODE (field) != FIELD_DECL)
112038fd1498Szrj 	    goto next;
112138fd1498Szrj 
112238fd1498Szrj 	  /* If this is an anonymous aggregate with no explicit initializer,
112338fd1498Szrj 	     splice it out.  */
112438fd1498Szrj 	  if (!TREE_VALUE (init) && ANON_AGGR_TYPE_P (TREE_TYPE (field)))
112538fd1498Szrj 	    goto splice;
112638fd1498Szrj 
112738fd1498Szrj 	  /* See if this field is a member of a union, or a member of a
112838fd1498Szrj 	     structure contained in a union, etc.  */
112938fd1498Szrj 	  ctx = innermost_aggr_scope (field);
113038fd1498Szrj 
113138fd1498Szrj 	  /* If this field is not a member of a union, skip it.  */
113238fd1498Szrj 	  if (TREE_CODE (ctx) != UNION_TYPE
113338fd1498Szrj 	      && !ANON_AGGR_TYPE_P (ctx))
113438fd1498Szrj 	    goto next;
113538fd1498Szrj 
113638fd1498Szrj 	  /* If this union member has no explicit initializer and no NSDMI,
113738fd1498Szrj 	     splice it out.  */
113838fd1498Szrj 	  if (TREE_VALUE (init) || DECL_INITIAL (field))
113938fd1498Szrj 	    /* OK.  */;
114038fd1498Szrj 	  else
114138fd1498Szrj 	    goto splice;
114238fd1498Szrj 
114338fd1498Szrj 	  /* It's only an error if we have two initializers for the same
114438fd1498Szrj 	     union type.  */
114538fd1498Szrj 	  if (!last_p)
114638fd1498Szrj 	    {
114738fd1498Szrj 	      last_p = p;
114838fd1498Szrj 	      goto next;
114938fd1498Szrj 	    }
115038fd1498Szrj 
115138fd1498Szrj 	  /* See if LAST_FIELD and the field initialized by INIT are
115238fd1498Szrj 	     members of the same union (or the union itself). If so, there's
115338fd1498Szrj 	     a problem, unless they're actually members of the same structure
115438fd1498Szrj 	     which is itself a member of a union.  For example, given:
115538fd1498Szrj 
115638fd1498Szrj 	       union { struct { int i; int j; }; };
115738fd1498Szrj 
115838fd1498Szrj 	     initializing both `i' and `j' makes sense.  */
115938fd1498Szrj 	  ctx = common_enclosing_class
116038fd1498Szrj 	    (innermost_aggr_scope (field),
116138fd1498Szrj 	     innermost_aggr_scope (TREE_PURPOSE (*last_p)));
116238fd1498Szrj 
116338fd1498Szrj 	  if (ctx && (TREE_CODE (ctx) == UNION_TYPE
116438fd1498Szrj 		      || ctx == TREE_TYPE (TREE_PURPOSE (*last_p))))
116538fd1498Szrj 	    {
116638fd1498Szrj 	      /* A mem-initializer hides an NSDMI.  */
116738fd1498Szrj 	      if (TREE_VALUE (init) && !TREE_VALUE (*last_p))
116838fd1498Szrj 		*last_p = TREE_CHAIN (*last_p);
116938fd1498Szrj 	      else if (TREE_VALUE (*last_p) && !TREE_VALUE (init))
117038fd1498Szrj 		goto splice;
117138fd1498Szrj 	      else
117238fd1498Szrj 		{
117338fd1498Szrj 		  error_at (DECL_SOURCE_LOCATION (current_function_decl),
117438fd1498Szrj 			    "initializations for multiple members of %qT",
117538fd1498Szrj 			    ctx);
117638fd1498Szrj 		  goto splice;
117738fd1498Szrj 		}
117838fd1498Szrj 	    }
117938fd1498Szrj 
118038fd1498Szrj 	  last_p = p;
118138fd1498Szrj 
118238fd1498Szrj 	next:
118338fd1498Szrj 	  p = &TREE_CHAIN (*p);
118438fd1498Szrj 	  continue;
118538fd1498Szrj 	splice:
118638fd1498Szrj 	  *p = TREE_CHAIN (*p);
118738fd1498Szrj 	  continue;
118838fd1498Szrj 	}
118938fd1498Szrj     }
119038fd1498Szrj 
119138fd1498Szrj   return sorted_inits;
119238fd1498Szrj }
119338fd1498Szrj 
119438fd1498Szrj /* Callback for cp_walk_tree to mark all PARM_DECLs in a tree as read.  */
119538fd1498Szrj 
119638fd1498Szrj static tree
mark_exp_read_r(tree * tp,int *,void *)119738fd1498Szrj mark_exp_read_r (tree *tp, int *, void *)
119838fd1498Szrj {
119938fd1498Szrj   tree t = *tp;
120038fd1498Szrj   if (TREE_CODE (t) == PARM_DECL)
120138fd1498Szrj     mark_exp_read (t);
120238fd1498Szrj   return NULL_TREE;
120338fd1498Szrj }
120438fd1498Szrj 
120538fd1498Szrj /* Initialize all bases and members of CURRENT_CLASS_TYPE.  MEM_INITS
120638fd1498Szrj    is a TREE_LIST giving the explicit mem-initializer-list for the
120738fd1498Szrj    constructor.  The TREE_PURPOSE of each entry is a subobject (a
120838fd1498Szrj    FIELD_DECL or a BINFO) of the CURRENT_CLASS_TYPE.  The TREE_VALUE
120938fd1498Szrj    is a TREE_LIST giving the arguments to the constructor or
121038fd1498Szrj    void_type_node for an empty list of arguments.  */
121138fd1498Szrj 
121238fd1498Szrj void
emit_mem_initializers(tree mem_inits)121338fd1498Szrj emit_mem_initializers (tree mem_inits)
121438fd1498Szrj {
121538fd1498Szrj   int flags = LOOKUP_NORMAL;
121638fd1498Szrj 
121738fd1498Szrj   /* We will already have issued an error message about the fact that
121838fd1498Szrj      the type is incomplete.  */
121938fd1498Szrj   if (!COMPLETE_TYPE_P (current_class_type))
122038fd1498Szrj     return;
122138fd1498Szrj 
122238fd1498Szrj   if (mem_inits
122338fd1498Szrj       && TYPE_P (TREE_PURPOSE (mem_inits))
122438fd1498Szrj       && same_type_p (TREE_PURPOSE (mem_inits), current_class_type))
122538fd1498Szrj     {
122638fd1498Szrj       /* Delegating constructor. */
122738fd1498Szrj       gcc_assert (TREE_CHAIN (mem_inits) == NULL_TREE);
122838fd1498Szrj       perform_target_ctor (TREE_VALUE (mem_inits));
122938fd1498Szrj       return;
123038fd1498Szrj     }
123138fd1498Szrj 
123238fd1498Szrj   if (DECL_DEFAULTED_FN (current_function_decl)
123338fd1498Szrj       && ! DECL_INHERITED_CTOR (current_function_decl))
123438fd1498Szrj     flags |= LOOKUP_DEFAULTED;
123538fd1498Szrj 
123638fd1498Szrj   /* Sort the mem-initializers into the order in which the
123738fd1498Szrj      initializations should be performed.  */
123838fd1498Szrj   mem_inits = sort_mem_initializers (current_class_type, mem_inits);
123938fd1498Szrj 
124038fd1498Szrj   in_base_initializer = 1;
124138fd1498Szrj 
124238fd1498Szrj   /* Initialize base classes.  */
124338fd1498Szrj   for (; (mem_inits
124438fd1498Szrj 	  && TREE_CODE (TREE_PURPOSE (mem_inits)) != FIELD_DECL);
124538fd1498Szrj        mem_inits = TREE_CHAIN (mem_inits))
124638fd1498Szrj     {
124738fd1498Szrj       tree subobject = TREE_PURPOSE (mem_inits);
124838fd1498Szrj       tree arguments = TREE_VALUE (mem_inits);
124938fd1498Szrj 
125038fd1498Szrj       /* We already have issued an error message.  */
125138fd1498Szrj       if (arguments == error_mark_node)
125238fd1498Szrj 	continue;
125338fd1498Szrj 
125438fd1498Szrj       /* Suppress access control when calling the inherited ctor.  */
125538fd1498Szrj       bool inherited_base = (DECL_INHERITED_CTOR (current_function_decl)
125638fd1498Szrj 			     && flag_new_inheriting_ctors
125738fd1498Szrj 			     && arguments);
125838fd1498Szrj       if (inherited_base)
125938fd1498Szrj 	push_deferring_access_checks (dk_deferred);
126038fd1498Szrj 
126138fd1498Szrj       if (arguments == NULL_TREE)
126238fd1498Szrj 	{
126338fd1498Szrj 	  /* If these initializations are taking place in a copy constructor,
126438fd1498Szrj 	     the base class should probably be explicitly initialized if there
126538fd1498Szrj 	     is a user-defined constructor in the base class (other than the
126638fd1498Szrj 	     default constructor, which will be called anyway).  */
126738fd1498Szrj 	  if (extra_warnings
126838fd1498Szrj 	      && DECL_COPY_CONSTRUCTOR_P (current_function_decl)
126938fd1498Szrj 	      && type_has_user_nondefault_constructor (BINFO_TYPE (subobject)))
127038fd1498Szrj 	    warning_at (DECL_SOURCE_LOCATION (current_function_decl),
127138fd1498Szrj 			OPT_Wextra, "base class %q#T should be explicitly "
127238fd1498Szrj 			"initialized in the copy constructor",
127338fd1498Szrj 			BINFO_TYPE (subobject));
127438fd1498Szrj 	}
127538fd1498Szrj 
127638fd1498Szrj       /* Initialize the base.  */
127738fd1498Szrj       if (!BINFO_VIRTUAL_P (subobject))
127838fd1498Szrj 	{
127938fd1498Szrj 	  tree base_addr;
128038fd1498Szrj 
128138fd1498Szrj 	  base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
128238fd1498Szrj 				       subobject, 1, tf_warning_or_error);
128338fd1498Szrj 	  expand_aggr_init_1 (subobject, NULL_TREE,
128438fd1498Szrj 			      cp_build_fold_indirect_ref (base_addr),
128538fd1498Szrj 			      arguments,
128638fd1498Szrj 			      flags,
128738fd1498Szrj                               tf_warning_or_error);
128838fd1498Szrj 	  expand_cleanup_for_base (subobject, NULL_TREE);
128938fd1498Szrj 	}
129038fd1498Szrj       else if (!ABSTRACT_CLASS_TYPE_P (current_class_type))
129138fd1498Szrj 	/* C++14 DR1658 Means we do not have to construct vbases of
129238fd1498Szrj 	   abstract classes.  */
129338fd1498Szrj 	construct_virtual_base (subobject, arguments);
129438fd1498Szrj       else
129538fd1498Szrj 	/* When not constructing vbases of abstract classes, at least mark
129638fd1498Szrj 	   the arguments expressions as read to avoid
129738fd1498Szrj 	   -Wunused-but-set-parameter false positives.  */
129838fd1498Szrj 	cp_walk_tree (&arguments, mark_exp_read_r, NULL, NULL);
129938fd1498Szrj 
130038fd1498Szrj       if (inherited_base)
130138fd1498Szrj 	pop_deferring_access_checks ();
130238fd1498Szrj     }
130338fd1498Szrj   in_base_initializer = 0;
130438fd1498Szrj 
130538fd1498Szrj   /* Initialize the vptrs.  */
130638fd1498Szrj   initialize_vtbl_ptrs (current_class_ptr);
130738fd1498Szrj 
130838fd1498Szrj   /* Initialize the data members.  */
130938fd1498Szrj   while (mem_inits)
131038fd1498Szrj     {
131138fd1498Szrj       perform_member_init (TREE_PURPOSE (mem_inits),
131238fd1498Szrj 			   TREE_VALUE (mem_inits));
131338fd1498Szrj       mem_inits = TREE_CHAIN (mem_inits);
131438fd1498Szrj     }
131538fd1498Szrj }
131638fd1498Szrj 
131738fd1498Szrj /* Returns the address of the vtable (i.e., the value that should be
131838fd1498Szrj    assigned to the vptr) for BINFO.  */
131938fd1498Szrj 
132038fd1498Szrj tree
build_vtbl_address(tree binfo)132138fd1498Szrj build_vtbl_address (tree binfo)
132238fd1498Szrj {
132338fd1498Szrj   tree binfo_for = binfo;
132438fd1498Szrj   tree vtbl;
132538fd1498Szrj 
132638fd1498Szrj   if (BINFO_VPTR_INDEX (binfo) && BINFO_VIRTUAL_P (binfo))
132738fd1498Szrj     /* If this is a virtual primary base, then the vtable we want to store
132838fd1498Szrj        is that for the base this is being used as the primary base of.  We
132938fd1498Szrj        can't simply skip the initialization, because we may be expanding the
133038fd1498Szrj        inits of a subobject constructor where the virtual base layout
133138fd1498Szrj        can be different.  */
133238fd1498Szrj     while (BINFO_PRIMARY_P (binfo_for))
133338fd1498Szrj       binfo_for = BINFO_INHERITANCE_CHAIN (binfo_for);
133438fd1498Szrj 
133538fd1498Szrj   /* Figure out what vtable BINFO's vtable is based on, and mark it as
133638fd1498Szrj      used.  */
133738fd1498Szrj   vtbl = get_vtbl_decl_for_binfo (binfo_for);
133838fd1498Szrj   TREE_USED (vtbl) = true;
133938fd1498Szrj 
134038fd1498Szrj   /* Now compute the address to use when initializing the vptr.  */
134138fd1498Szrj   vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
134238fd1498Szrj   if (VAR_P (vtbl))
134338fd1498Szrj     vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
134438fd1498Szrj 
134538fd1498Szrj   return vtbl;
134638fd1498Szrj }
134738fd1498Szrj 
134838fd1498Szrj /* This code sets up the virtual function tables appropriate for
134938fd1498Szrj    the pointer DECL.  It is a one-ply initialization.
135038fd1498Szrj 
135138fd1498Szrj    BINFO is the exact type that DECL is supposed to be.  In
135238fd1498Szrj    multiple inheritance, this might mean "C's A" if C : A, B.  */
135338fd1498Szrj 
135438fd1498Szrj static void
expand_virtual_init(tree binfo,tree decl)135538fd1498Szrj expand_virtual_init (tree binfo, tree decl)
135638fd1498Szrj {
135738fd1498Szrj   tree vtbl, vtbl_ptr;
135838fd1498Szrj   tree vtt_index;
135938fd1498Szrj 
136038fd1498Szrj   /* Compute the initializer for vptr.  */
136138fd1498Szrj   vtbl = build_vtbl_address (binfo);
136238fd1498Szrj 
136338fd1498Szrj   /* We may get this vptr from a VTT, if this is a subobject
136438fd1498Szrj      constructor or subobject destructor.  */
136538fd1498Szrj   vtt_index = BINFO_VPTR_INDEX (binfo);
136638fd1498Szrj   if (vtt_index)
136738fd1498Szrj     {
136838fd1498Szrj       tree vtbl2;
136938fd1498Szrj       tree vtt_parm;
137038fd1498Szrj 
137138fd1498Szrj       /* Compute the value to use, when there's a VTT.  */
137238fd1498Szrj       vtt_parm = current_vtt_parm;
137338fd1498Szrj       vtbl2 = fold_build_pointer_plus (vtt_parm, vtt_index);
137438fd1498Szrj       vtbl2 = cp_build_fold_indirect_ref (vtbl2);
137538fd1498Szrj       vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
137638fd1498Szrj 
137738fd1498Szrj       /* The actual initializer is the VTT value only in the subobject
137838fd1498Szrj 	 constructor.  In maybe_clone_body we'll substitute NULL for
137938fd1498Szrj 	 the vtt_parm in the case of the non-subobject constructor.  */
138038fd1498Szrj       vtbl = build_if_in_charge (vtbl, vtbl2);
138138fd1498Szrj     }
138238fd1498Szrj 
138338fd1498Szrj   /* Compute the location of the vtpr.  */
138438fd1498Szrj   vtbl_ptr = build_vfield_ref (cp_build_fold_indirect_ref (decl),
138538fd1498Szrj 			       TREE_TYPE (binfo));
138638fd1498Szrj   gcc_assert (vtbl_ptr != error_mark_node);
138738fd1498Szrj 
138838fd1498Szrj   /* Assign the vtable to the vptr.  */
138938fd1498Szrj   vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
139038fd1498Szrj   finish_expr_stmt (cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
139138fd1498Szrj 					  vtbl, tf_warning_or_error));
139238fd1498Szrj }
139338fd1498Szrj 
139438fd1498Szrj /* If an exception is thrown in a constructor, those base classes already
139538fd1498Szrj    constructed must be destroyed.  This function creates the cleanup
139638fd1498Szrj    for BINFO, which has just been constructed.  If FLAG is non-NULL,
139738fd1498Szrj    it is a DECL which is nonzero when this base needs to be
139838fd1498Szrj    destroyed.  */
139938fd1498Szrj 
140038fd1498Szrj static void
expand_cleanup_for_base(tree binfo,tree flag)140138fd1498Szrj expand_cleanup_for_base (tree binfo, tree flag)
140238fd1498Szrj {
140338fd1498Szrj   tree expr;
140438fd1498Szrj 
140538fd1498Szrj   if (!type_build_dtor_call (BINFO_TYPE (binfo)))
140638fd1498Szrj     return;
140738fd1498Szrj 
140838fd1498Szrj   /* Call the destructor.  */
140938fd1498Szrj   expr = build_special_member_call (current_class_ref,
141038fd1498Szrj 				    base_dtor_identifier,
141138fd1498Szrj 				    NULL,
141238fd1498Szrj 				    binfo,
141338fd1498Szrj 				    LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
141438fd1498Szrj                                     tf_warning_or_error);
141538fd1498Szrj 
141638fd1498Szrj   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
141738fd1498Szrj     return;
141838fd1498Szrj 
141938fd1498Szrj   if (flag)
142038fd1498Szrj     expr = fold_build3_loc (input_location,
142138fd1498Szrj 			COND_EXPR, void_type_node,
142238fd1498Szrj 			c_common_truthvalue_conversion (input_location, flag),
142338fd1498Szrj 			expr, integer_zero_node);
142438fd1498Szrj 
142538fd1498Szrj   finish_eh_cleanup (expr);
142638fd1498Szrj }
142738fd1498Szrj 
142838fd1498Szrj /* Construct the virtual base-class VBASE passing the ARGUMENTS to its
142938fd1498Szrj    constructor.  */
143038fd1498Szrj 
143138fd1498Szrj static void
construct_virtual_base(tree vbase,tree arguments)143238fd1498Szrj construct_virtual_base (tree vbase, tree arguments)
143338fd1498Szrj {
143438fd1498Szrj   tree inner_if_stmt;
143538fd1498Szrj   tree exp;
143638fd1498Szrj   tree flag;
143738fd1498Szrj 
143838fd1498Szrj   /* If there are virtual base classes with destructors, we need to
143938fd1498Szrj      emit cleanups to destroy them if an exception is thrown during
144038fd1498Szrj      the construction process.  These exception regions (i.e., the
144138fd1498Szrj      period during which the cleanups must occur) begin from the time
144238fd1498Szrj      the construction is complete to the end of the function.  If we
144338fd1498Szrj      create a conditional block in which to initialize the
144438fd1498Szrj      base-classes, then the cleanup region for the virtual base begins
144538fd1498Szrj      inside a block, and ends outside of that block.  This situation
144638fd1498Szrj      confuses the sjlj exception-handling code.  Therefore, we do not
144738fd1498Szrj      create a single conditional block, but one for each
144838fd1498Szrj      initialization.  (That way the cleanup regions always begin
144938fd1498Szrj      in the outer block.)  We trust the back end to figure out
145038fd1498Szrj      that the FLAG will not change across initializations, and
145138fd1498Szrj      avoid doing multiple tests.  */
145238fd1498Szrj   flag = DECL_CHAIN (DECL_ARGUMENTS (current_function_decl));
145338fd1498Szrj   inner_if_stmt = begin_if_stmt ();
145438fd1498Szrj   finish_if_stmt_cond (flag, inner_if_stmt);
145538fd1498Szrj 
145638fd1498Szrj   /* Compute the location of the virtual base.  If we're
145738fd1498Szrj      constructing virtual bases, then we must be the most derived
145838fd1498Szrj      class.  Therefore, we don't have to look up the virtual base;
145938fd1498Szrj      we already know where it is.  */
146038fd1498Szrj   exp = convert_to_base_statically (current_class_ref, vbase);
146138fd1498Szrj 
146238fd1498Szrj   expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
146338fd1498Szrj 		      0, tf_warning_or_error);
146438fd1498Szrj   finish_then_clause (inner_if_stmt);
146538fd1498Szrj   finish_if_stmt (inner_if_stmt);
146638fd1498Szrj 
146738fd1498Szrj   expand_cleanup_for_base (vbase, flag);
146838fd1498Szrj }
146938fd1498Szrj 
147038fd1498Szrj /* Find the context in which this FIELD can be initialized.  */
147138fd1498Szrj 
147238fd1498Szrj static tree
initializing_context(tree field)147338fd1498Szrj initializing_context (tree field)
147438fd1498Szrj {
147538fd1498Szrj   tree t = DECL_CONTEXT (field);
147638fd1498Szrj 
147738fd1498Szrj   /* Anonymous union members can be initialized in the first enclosing
147838fd1498Szrj      non-anonymous union context.  */
147938fd1498Szrj   while (t && ANON_AGGR_TYPE_P (t))
148038fd1498Szrj     t = TYPE_CONTEXT (t);
148138fd1498Szrj   return t;
148238fd1498Szrj }
148338fd1498Szrj 
148438fd1498Szrj /* Function to give error message if member initialization specification
148538fd1498Szrj    is erroneous.  FIELD is the member we decided to initialize.
148638fd1498Szrj    TYPE is the type for which the initialization is being performed.
148738fd1498Szrj    FIELD must be a member of TYPE.
148838fd1498Szrj 
148938fd1498Szrj    MEMBER_NAME is the name of the member.  */
149038fd1498Szrj 
149138fd1498Szrj static int
member_init_ok_or_else(tree field,tree type,tree member_name)149238fd1498Szrj member_init_ok_or_else (tree field, tree type, tree member_name)
149338fd1498Szrj {
149438fd1498Szrj   if (field == error_mark_node)
149538fd1498Szrj     return 0;
149638fd1498Szrj   if (!field)
149738fd1498Szrj     {
149838fd1498Szrj       error ("class %qT does not have any field named %qD", type,
149938fd1498Szrj 	     member_name);
150038fd1498Szrj       return 0;
150138fd1498Szrj     }
150238fd1498Szrj   if (VAR_P (field))
150338fd1498Szrj     {
150438fd1498Szrj       error ("%q#D is a static data member; it can only be "
150538fd1498Szrj 	     "initialized at its definition",
150638fd1498Szrj 	     field);
150738fd1498Szrj       return 0;
150838fd1498Szrj     }
150938fd1498Szrj   if (TREE_CODE (field) != FIELD_DECL)
151038fd1498Szrj     {
151138fd1498Szrj       error ("%q#D is not a non-static data member of %qT",
151238fd1498Szrj 	     field, type);
151338fd1498Szrj       return 0;
151438fd1498Szrj     }
151538fd1498Szrj   if (initializing_context (field) != type)
151638fd1498Szrj     {
151738fd1498Szrj       error ("class %qT does not have any field named %qD", type,
151838fd1498Szrj 		member_name);
151938fd1498Szrj       return 0;
152038fd1498Szrj     }
152138fd1498Szrj 
152238fd1498Szrj   return 1;
152338fd1498Szrj }
152438fd1498Szrj 
152538fd1498Szrj /* NAME is a FIELD_DECL, an IDENTIFIER_NODE which names a field, or it
152638fd1498Szrj    is a _TYPE node or TYPE_DECL which names a base for that type.
152738fd1498Szrj    Check the validity of NAME, and return either the base _TYPE, base
152838fd1498Szrj    binfo, or the FIELD_DECL of the member.  If NAME is invalid, return
152938fd1498Szrj    NULL_TREE and issue a diagnostic.
153038fd1498Szrj 
153138fd1498Szrj    An old style unnamed direct single base construction is permitted,
153238fd1498Szrj    where NAME is NULL.  */
153338fd1498Szrj 
153438fd1498Szrj tree
expand_member_init(tree name)153538fd1498Szrj expand_member_init (tree name)
153638fd1498Szrj {
153738fd1498Szrj   tree basetype;
153838fd1498Szrj   tree field;
153938fd1498Szrj 
154038fd1498Szrj   if (!current_class_ref)
154138fd1498Szrj     return NULL_TREE;
154238fd1498Szrj 
154338fd1498Szrj   if (!name)
154438fd1498Szrj     {
154538fd1498Szrj       /* This is an obsolete unnamed base class initializer.  The
154638fd1498Szrj 	 parser will already have warned about its use.  */
154738fd1498Szrj       switch (BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type)))
154838fd1498Szrj 	{
154938fd1498Szrj 	case 0:
155038fd1498Szrj 	  error ("unnamed initializer for %qT, which has no base classes",
155138fd1498Szrj 		 current_class_type);
155238fd1498Szrj 	  return NULL_TREE;
155338fd1498Szrj 	case 1:
155438fd1498Szrj 	  basetype = BINFO_TYPE
155538fd1498Szrj 	    (BINFO_BASE_BINFO (TYPE_BINFO (current_class_type), 0));
155638fd1498Szrj 	  break;
155738fd1498Szrj 	default:
155838fd1498Szrj 	  error ("unnamed initializer for %qT, which uses multiple inheritance",
155938fd1498Szrj 		 current_class_type);
156038fd1498Szrj 	  return NULL_TREE;
156138fd1498Szrj       }
156238fd1498Szrj     }
156338fd1498Szrj   else if (TYPE_P (name))
156438fd1498Szrj     {
156538fd1498Szrj       basetype = TYPE_MAIN_VARIANT (name);
156638fd1498Szrj       name = TYPE_NAME (name);
156738fd1498Szrj     }
156838fd1498Szrj   else if (TREE_CODE (name) == TYPE_DECL)
156938fd1498Szrj     basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
157038fd1498Szrj   else
157138fd1498Szrj     basetype = NULL_TREE;
157238fd1498Szrj 
157338fd1498Szrj   if (basetype)
157438fd1498Szrj     {
157538fd1498Szrj       tree class_binfo;
157638fd1498Szrj       tree direct_binfo;
157738fd1498Szrj       tree virtual_binfo;
157838fd1498Szrj       int i;
157938fd1498Szrj 
158038fd1498Szrj       if (current_template_parms
158138fd1498Szrj 	  || same_type_p (basetype, current_class_type))
158238fd1498Szrj 	  return basetype;
158338fd1498Szrj 
158438fd1498Szrj       class_binfo = TYPE_BINFO (current_class_type);
158538fd1498Szrj       direct_binfo = NULL_TREE;
158638fd1498Szrj       virtual_binfo = NULL_TREE;
158738fd1498Szrj 
158838fd1498Szrj       /* Look for a direct base.  */
158938fd1498Szrj       for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
159038fd1498Szrj 	if (SAME_BINFO_TYPE_P (BINFO_TYPE (direct_binfo), basetype))
159138fd1498Szrj 	  break;
159238fd1498Szrj 
159338fd1498Szrj       /* Look for a virtual base -- unless the direct base is itself
159438fd1498Szrj 	 virtual.  */
159538fd1498Szrj       if (!direct_binfo || !BINFO_VIRTUAL_P (direct_binfo))
159638fd1498Szrj 	virtual_binfo = binfo_for_vbase (basetype, current_class_type);
159738fd1498Szrj 
159838fd1498Szrj       /* [class.base.init]
159938fd1498Szrj 
160038fd1498Szrj 	 If a mem-initializer-id is ambiguous because it designates
160138fd1498Szrj 	 both a direct non-virtual base class and an inherited virtual
160238fd1498Szrj 	 base class, the mem-initializer is ill-formed.  */
160338fd1498Szrj       if (direct_binfo && virtual_binfo)
160438fd1498Szrj 	{
160538fd1498Szrj 	  error ("%qD is both a direct base and an indirect virtual base",
160638fd1498Szrj 		 basetype);
160738fd1498Szrj 	  return NULL_TREE;
160838fd1498Szrj 	}
160938fd1498Szrj 
161038fd1498Szrj       if (!direct_binfo && !virtual_binfo)
161138fd1498Szrj 	{
161238fd1498Szrj 	  if (CLASSTYPE_VBASECLASSES (current_class_type))
161338fd1498Szrj 	    error ("type %qT is not a direct or virtual base of %qT",
161438fd1498Szrj 		   basetype, current_class_type);
161538fd1498Szrj 	  else
161638fd1498Szrj 	    error ("type %qT is not a direct base of %qT",
161738fd1498Szrj 		   basetype, current_class_type);
161838fd1498Szrj 	  return NULL_TREE;
161938fd1498Szrj 	}
162038fd1498Szrj 
162138fd1498Szrj       return direct_binfo ? direct_binfo : virtual_binfo;
162238fd1498Szrj     }
162338fd1498Szrj   else
162438fd1498Szrj     {
162538fd1498Szrj       if (identifier_p (name))
162638fd1498Szrj 	field = lookup_field (current_class_type, name, 1, false);
162738fd1498Szrj       else
162838fd1498Szrj 	field = name;
162938fd1498Szrj 
163038fd1498Szrj       if (member_init_ok_or_else (field, current_class_type, name))
163138fd1498Szrj 	return field;
163238fd1498Szrj     }
163338fd1498Szrj 
163438fd1498Szrj   return NULL_TREE;
163538fd1498Szrj }
163638fd1498Szrj 
163738fd1498Szrj /* This is like `expand_member_init', only it stores one aggregate
163838fd1498Szrj    value into another.
163938fd1498Szrj 
164038fd1498Szrj    INIT comes in two flavors: it is either a value which
164138fd1498Szrj    is to be stored in EXP, or it is a parameter list
164238fd1498Szrj    to go to a constructor, which will operate on EXP.
164338fd1498Szrj    If INIT is not a parameter list for a constructor, then set
164438fd1498Szrj    LOOKUP_ONLYCONVERTING.
164538fd1498Szrj    If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of
164638fd1498Szrj    the initializer, if FLAGS is 0, then it is the (init) form.
164738fd1498Szrj    If `init' is a CONSTRUCTOR, then we emit a warning message,
164838fd1498Szrj    explaining that such initializations are invalid.
164938fd1498Szrj 
165038fd1498Szrj    If INIT resolves to a CALL_EXPR which happens to return
165138fd1498Szrj    something of the type we are looking for, then we know
165238fd1498Szrj    that we can safely use that call to perform the
165338fd1498Szrj    initialization.
165438fd1498Szrj 
165538fd1498Szrj    The virtual function table pointer cannot be set up here, because
165638fd1498Szrj    we do not really know its type.
165738fd1498Szrj 
165838fd1498Szrj    This never calls operator=().
165938fd1498Szrj 
166038fd1498Szrj    When initializing, nothing is CONST.
166138fd1498Szrj 
166238fd1498Szrj    A default copy constructor may have to be used to perform the
166338fd1498Szrj    initialization.
166438fd1498Szrj 
166538fd1498Szrj    A constructor or a conversion operator may have to be used to
166638fd1498Szrj    perform the initialization, but not both, as it would be ambiguous.  */
166738fd1498Szrj 
166838fd1498Szrj tree
build_aggr_init(tree exp,tree init,int flags,tsubst_flags_t complain)166938fd1498Szrj build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
167038fd1498Szrj {
167138fd1498Szrj   tree stmt_expr;
167238fd1498Szrj   tree compound_stmt;
167338fd1498Szrj   int destroy_temps;
167438fd1498Szrj   tree type = TREE_TYPE (exp);
167538fd1498Szrj   int was_const = TREE_READONLY (exp);
167638fd1498Szrj   int was_volatile = TREE_THIS_VOLATILE (exp);
167738fd1498Szrj   int is_global;
167838fd1498Szrj 
167938fd1498Szrj   if (init == error_mark_node)
168038fd1498Szrj     return error_mark_node;
168138fd1498Szrj 
168238fd1498Szrj   location_t init_loc = (init
168338fd1498Szrj 			 ? EXPR_LOC_OR_LOC (init, input_location)
168438fd1498Szrj 			 : location_of (exp));
168538fd1498Szrj 
168638fd1498Szrj   TREE_READONLY (exp) = 0;
168738fd1498Szrj   TREE_THIS_VOLATILE (exp) = 0;
168838fd1498Szrj 
168938fd1498Szrj   if (TREE_CODE (type) == ARRAY_TYPE)
169038fd1498Szrj     {
169138fd1498Szrj       tree itype = init ? TREE_TYPE (init) : NULL_TREE;
169238fd1498Szrj       int from_array = 0;
169338fd1498Szrj 
169438fd1498Szrj       if (VAR_P (exp) && DECL_DECOMPOSITION_P (exp))
169538fd1498Szrj 	{
169638fd1498Szrj 	  from_array = 1;
1697*58e805e6Szrj 	  init = mark_rvalue_use (init);
169838fd1498Szrj 	  if (init && DECL_P (init)
169938fd1498Szrj 	      && !(flags & LOOKUP_ONLYCONVERTING))
170038fd1498Szrj 	    {
170138fd1498Szrj 	      /* Wrap the initializer in a CONSTRUCTOR so that build_vec_init
170238fd1498Szrj 		 recognizes it as direct-initialization.  */
170338fd1498Szrj 	      init = build_constructor_single (init_list_type_node,
170438fd1498Szrj 					       NULL_TREE, init);
170538fd1498Szrj 	      CONSTRUCTOR_IS_DIRECT_INIT (init) = true;
170638fd1498Szrj 	    }
170738fd1498Szrj 	}
170838fd1498Szrj       else
170938fd1498Szrj 	{
171038fd1498Szrj 	  /* Must arrange to initialize each element of EXP
171138fd1498Szrj 	     from elements of INIT.  */
171238fd1498Szrj 	  if (cv_qualified_p (type))
171338fd1498Szrj 	    TREE_TYPE (exp) = cv_unqualified (type);
171438fd1498Szrj 	  if (itype && cv_qualified_p (itype))
171538fd1498Szrj 	    TREE_TYPE (init) = cv_unqualified (itype);
171638fd1498Szrj 	  from_array = (itype && same_type_p (TREE_TYPE (init),
171738fd1498Szrj 					      TREE_TYPE (exp)));
171838fd1498Szrj 
171938fd1498Szrj 	  if (init && !BRACE_ENCLOSED_INITIALIZER_P (init)
172038fd1498Szrj 	      && (!from_array
172138fd1498Szrj 		  || (TREE_CODE (init) != CONSTRUCTOR
172238fd1498Szrj 		      /* Can happen, eg, handling the compound-literals
172338fd1498Szrj 			 extension (ext/complit12.C).  */
172438fd1498Szrj 		      && TREE_CODE (init) != TARGET_EXPR)))
172538fd1498Szrj 	    {
172638fd1498Szrj 	      if (complain & tf_error)
172738fd1498Szrj 		error_at (init_loc, "array must be initialized "
172838fd1498Szrj 			  "with a brace-enclosed initializer");
172938fd1498Szrj 	      return error_mark_node;
173038fd1498Szrj 	    }
173138fd1498Szrj 	}
173238fd1498Szrj 
173338fd1498Szrj       stmt_expr = build_vec_init (exp, NULL_TREE, init,
173438fd1498Szrj 				  /*explicit_value_init_p=*/false,
173538fd1498Szrj 				  from_array,
173638fd1498Szrj                                   complain);
173738fd1498Szrj       TREE_READONLY (exp) = was_const;
173838fd1498Szrj       TREE_THIS_VOLATILE (exp) = was_volatile;
173938fd1498Szrj       TREE_TYPE (exp) = type;
174038fd1498Szrj       /* Restore the type of init unless it was used directly.  */
174138fd1498Szrj       if (init && TREE_CODE (stmt_expr) != INIT_EXPR)
174238fd1498Szrj 	TREE_TYPE (init) = itype;
174338fd1498Szrj       return stmt_expr;
174438fd1498Szrj     }
174538fd1498Szrj 
174638fd1498Szrj   if (init && init != void_type_node
174738fd1498Szrj       && TREE_CODE (init) != TREE_LIST
174838fd1498Szrj       && !(TREE_CODE (init) == TARGET_EXPR
174938fd1498Szrj 	   && TARGET_EXPR_DIRECT_INIT_P (init))
175038fd1498Szrj       && !DIRECT_LIST_INIT_P (init))
175138fd1498Szrj     flags |= LOOKUP_ONLYCONVERTING;
175238fd1498Szrj 
175338fd1498Szrj   if ((VAR_P (exp) || TREE_CODE (exp) == PARM_DECL)
175438fd1498Szrj       && !lookup_attribute ("warn_unused", TYPE_ATTRIBUTES (type)))
175538fd1498Szrj     /* Just know that we've seen something for this node.  */
175638fd1498Szrj     TREE_USED (exp) = 1;
175738fd1498Szrj 
175838fd1498Szrj   is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
175938fd1498Szrj   destroy_temps = stmts_are_full_exprs_p ();
176038fd1498Szrj   current_stmt_tree ()->stmts_are_full_exprs_p = 0;
176138fd1498Szrj   expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
176238fd1498Szrj 		      init, LOOKUP_NORMAL|flags, complain);
176338fd1498Szrj   stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
176438fd1498Szrj   current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
176538fd1498Szrj   TREE_READONLY (exp) = was_const;
176638fd1498Szrj   TREE_THIS_VOLATILE (exp) = was_volatile;
176738fd1498Szrj 
176838fd1498Szrj   return stmt_expr;
176938fd1498Szrj }
177038fd1498Szrj 
177138fd1498Szrj static void
expand_default_init(tree binfo,tree true_exp,tree exp,tree init,int flags,tsubst_flags_t complain)177238fd1498Szrj expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
177338fd1498Szrj                      tsubst_flags_t complain)
177438fd1498Szrj {
177538fd1498Szrj   tree type = TREE_TYPE (exp);
177638fd1498Szrj 
177738fd1498Szrj   /* It fails because there may not be a constructor which takes
177838fd1498Szrj      its own type as the first (or only parameter), but which does
177938fd1498Szrj      take other types via a conversion.  So, if the thing initializing
178038fd1498Szrj      the expression is a unit element of type X, first try X(X&),
178138fd1498Szrj      followed by initialization by X.  If neither of these work
178238fd1498Szrj      out, then look hard.  */
178338fd1498Szrj   tree rval;
178438fd1498Szrj   vec<tree, va_gc> *parms;
178538fd1498Szrj 
178638fd1498Szrj   /* If we have direct-initialization from an initializer list, pull
178738fd1498Szrj      it out of the TREE_LIST so the code below can see it.  */
178838fd1498Szrj   if (init && TREE_CODE (init) == TREE_LIST
178938fd1498Szrj       && DIRECT_LIST_INIT_P (TREE_VALUE (init)))
179038fd1498Szrj     {
179138fd1498Szrj       gcc_checking_assert ((flags & LOOKUP_ONLYCONVERTING) == 0
179238fd1498Szrj 			   && TREE_CHAIN (init) == NULL_TREE);
179338fd1498Szrj       init = TREE_VALUE (init);
179438fd1498Szrj       /* Only call reshape_init if it has not been called earlier
179538fd1498Szrj 	 by the callers.  */
179638fd1498Szrj       if (BRACE_ENCLOSED_INITIALIZER_P (init) && CP_AGGREGATE_TYPE_P (type))
179738fd1498Szrj 	init = reshape_init (type, init, complain);
179838fd1498Szrj     }
179938fd1498Szrj 
180038fd1498Szrj   if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
180138fd1498Szrj       && CP_AGGREGATE_TYPE_P (type))
180238fd1498Szrj     /* A brace-enclosed initializer for an aggregate.  In C++0x this can
180338fd1498Szrj        happen for direct-initialization, too.  */
180438fd1498Szrj     init = digest_init (type, init, complain);
180538fd1498Szrj 
180638fd1498Szrj   /* A CONSTRUCTOR of the target's type is a previously digested
180738fd1498Szrj      initializer, whether that happened just above or in
180838fd1498Szrj      cp_parser_late_parsing_nsdmi.
180938fd1498Szrj 
181038fd1498Szrj      A TARGET_EXPR with TARGET_EXPR_DIRECT_INIT_P or TARGET_EXPR_LIST_INIT_P
181138fd1498Szrj      set represents the whole initialization, so we shouldn't build up
181238fd1498Szrj      another ctor call.  */
181338fd1498Szrj   if (init
181438fd1498Szrj       && (TREE_CODE (init) == CONSTRUCTOR
181538fd1498Szrj 	  || (TREE_CODE (init) == TARGET_EXPR
181638fd1498Szrj 	      && (TARGET_EXPR_DIRECT_INIT_P (init)
181738fd1498Szrj 		  || TARGET_EXPR_LIST_INIT_P (init))))
181838fd1498Szrj       && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init), type))
181938fd1498Szrj     {
182038fd1498Szrj       /* Early initialization via a TARGET_EXPR only works for
182138fd1498Szrj 	 complete objects.  */
182238fd1498Szrj       gcc_assert (TREE_CODE (init) == CONSTRUCTOR || true_exp == exp);
182338fd1498Szrj 
182438fd1498Szrj       init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
182538fd1498Szrj       TREE_SIDE_EFFECTS (init) = 1;
182638fd1498Szrj       finish_expr_stmt (init);
182738fd1498Szrj       return;
182838fd1498Szrj     }
182938fd1498Szrj 
183038fd1498Szrj   if (init && TREE_CODE (init) != TREE_LIST
183138fd1498Szrj       && (flags & LOOKUP_ONLYCONVERTING))
183238fd1498Szrj     {
183338fd1498Szrj       /* Base subobjects should only get direct-initialization.  */
183438fd1498Szrj       gcc_assert (true_exp == exp);
183538fd1498Szrj 
183638fd1498Szrj       if (flags & DIRECT_BIND)
183738fd1498Szrj 	/* Do nothing.  We hit this in two cases:  Reference initialization,
183838fd1498Szrj 	   where we aren't initializing a real variable, so we don't want
183938fd1498Szrj 	   to run a new constructor; and catching an exception, where we
184038fd1498Szrj 	   have already built up the constructor call so we could wrap it
184138fd1498Szrj 	   in an exception region.  */;
184238fd1498Szrj       else
184338fd1498Szrj 	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP,
184438fd1498Szrj 			    flags, complain);
184538fd1498Szrj 
184638fd1498Szrj       if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
184738fd1498Szrj 	/* We need to protect the initialization of a catch parm with a
184838fd1498Szrj 	   call to terminate(), which shows up as a MUST_NOT_THROW_EXPR
184938fd1498Szrj 	   around the TARGET_EXPR for the copy constructor.  See
185038fd1498Szrj 	   initialize_handler_parm.  */
185138fd1498Szrj 	{
185238fd1498Szrj 	  TREE_OPERAND (init, 0) = build2 (INIT_EXPR, TREE_TYPE (exp), exp,
185338fd1498Szrj 					   TREE_OPERAND (init, 0));
185438fd1498Szrj 	  TREE_TYPE (init) = void_type_node;
185538fd1498Szrj 	}
185638fd1498Szrj       else
185738fd1498Szrj 	init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
185838fd1498Szrj       TREE_SIDE_EFFECTS (init) = 1;
185938fd1498Szrj       finish_expr_stmt (init);
186038fd1498Szrj       return;
186138fd1498Szrj     }
186238fd1498Szrj 
186338fd1498Szrj   if (init == NULL_TREE)
186438fd1498Szrj     parms = NULL;
186538fd1498Szrj   else if (TREE_CODE (init) == TREE_LIST && !TREE_TYPE (init))
186638fd1498Szrj     {
186738fd1498Szrj       parms = make_tree_vector ();
186838fd1498Szrj       for (; init != NULL_TREE; init = TREE_CHAIN (init))
186938fd1498Szrj 	vec_safe_push (parms, TREE_VALUE (init));
187038fd1498Szrj     }
187138fd1498Szrj   else
187238fd1498Szrj     parms = make_tree_vector_single (init);
187338fd1498Szrj 
187438fd1498Szrj   if (exp == current_class_ref && current_function_decl
187538fd1498Szrj       && DECL_HAS_IN_CHARGE_PARM_P (current_function_decl))
187638fd1498Szrj     {
187738fd1498Szrj       /* Delegating constructor. */
187838fd1498Szrj       tree complete;
187938fd1498Szrj       tree base;
188038fd1498Szrj       tree elt; unsigned i;
188138fd1498Szrj 
188238fd1498Szrj       /* Unshare the arguments for the second call.  */
188338fd1498Szrj       vec<tree, va_gc> *parms2 = make_tree_vector ();
188438fd1498Szrj       FOR_EACH_VEC_SAFE_ELT (parms, i, elt)
188538fd1498Szrj 	{
188638fd1498Szrj 	  elt = break_out_target_exprs (elt);
188738fd1498Szrj 	  vec_safe_push (parms2, elt);
188838fd1498Szrj 	}
188938fd1498Szrj       complete = build_special_member_call (exp, complete_ctor_identifier,
189038fd1498Szrj 					    &parms2, binfo, flags,
189138fd1498Szrj 					    complain);
189238fd1498Szrj       complete = fold_build_cleanup_point_expr (void_type_node, complete);
189338fd1498Szrj       release_tree_vector (parms2);
189438fd1498Szrj 
189538fd1498Szrj       base = build_special_member_call (exp, base_ctor_identifier,
189638fd1498Szrj 					&parms, binfo, flags,
189738fd1498Szrj 					complain);
189838fd1498Szrj       base = fold_build_cleanup_point_expr (void_type_node, base);
189938fd1498Szrj       rval = build_if_in_charge (complete, base);
190038fd1498Szrj     }
190138fd1498Szrj    else
190238fd1498Szrj     {
190338fd1498Szrj       tree ctor_name = (true_exp == exp
190438fd1498Szrj 			? complete_ctor_identifier : base_ctor_identifier);
190538fd1498Szrj 
190638fd1498Szrj       rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
190738fd1498Szrj 					complain);
190838fd1498Szrj     }
190938fd1498Szrj 
191038fd1498Szrj   if (parms != NULL)
191138fd1498Szrj     release_tree_vector (parms);
191238fd1498Szrj 
191338fd1498Szrj   if (exp == true_exp && TREE_CODE (rval) == CALL_EXPR)
191438fd1498Szrj     {
191538fd1498Szrj       tree fn = get_callee_fndecl (rval);
191638fd1498Szrj       if (fn && DECL_DECLARED_CONSTEXPR_P (fn))
191738fd1498Szrj 	{
191838fd1498Szrj 	  tree e = maybe_constant_init (rval, exp);
191938fd1498Szrj 	  if (TREE_CONSTANT (e))
192038fd1498Szrj 	    rval = build2 (INIT_EXPR, type, exp, e);
192138fd1498Szrj 	}
192238fd1498Szrj     }
192338fd1498Szrj 
192438fd1498Szrj   /* FIXME put back convert_to_void?  */
192538fd1498Szrj   if (TREE_SIDE_EFFECTS (rval))
192638fd1498Szrj     finish_expr_stmt (rval);
192738fd1498Szrj }
192838fd1498Szrj 
192938fd1498Szrj /* This function is responsible for initializing EXP with INIT
193038fd1498Szrj    (if any).
193138fd1498Szrj 
193238fd1498Szrj    BINFO is the binfo of the type for who we are performing the
193338fd1498Szrj    initialization.  For example, if W is a virtual base class of A and B,
193438fd1498Szrj    and C : A, B.
193538fd1498Szrj    If we are initializing B, then W must contain B's W vtable, whereas
193638fd1498Szrj    were we initializing C, W must contain C's W vtable.
193738fd1498Szrj 
193838fd1498Szrj    TRUE_EXP is nonzero if it is the true expression being initialized.
193938fd1498Szrj    In this case, it may be EXP, or may just contain EXP.  The reason we
194038fd1498Szrj    need this is because if EXP is a base element of TRUE_EXP, we
194138fd1498Szrj    don't necessarily know by looking at EXP where its virtual
194238fd1498Szrj    baseclass fields should really be pointing.  But we do know
194338fd1498Szrj    from TRUE_EXP.  In constructors, we don't know anything about
194438fd1498Szrj    the value being initialized.
194538fd1498Szrj 
194638fd1498Szrj    FLAGS is just passed to `build_new_method_call'.  See that function
194738fd1498Szrj    for its description.  */
194838fd1498Szrj 
194938fd1498Szrj static void
expand_aggr_init_1(tree binfo,tree true_exp,tree exp,tree init,int flags,tsubst_flags_t complain)195038fd1498Szrj expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
195138fd1498Szrj                     tsubst_flags_t complain)
195238fd1498Szrj {
195338fd1498Szrj   tree type = TREE_TYPE (exp);
195438fd1498Szrj 
195538fd1498Szrj   gcc_assert (init != error_mark_node && type != error_mark_node);
195638fd1498Szrj   gcc_assert (building_stmt_list_p ());
195738fd1498Szrj 
195838fd1498Szrj   /* Use a function returning the desired type to initialize EXP for us.
195938fd1498Szrj      If the function is a constructor, and its first argument is
196038fd1498Szrj      NULL_TREE, know that it was meant for us--just slide exp on
196138fd1498Szrj      in and expand the constructor.  Constructors now come
196238fd1498Szrj      as TARGET_EXPRs.  */
196338fd1498Szrj 
196438fd1498Szrj   if (init && VAR_P (exp)
196538fd1498Szrj       && COMPOUND_LITERAL_P (init))
196638fd1498Szrj     {
196738fd1498Szrj       vec<tree, va_gc> *cleanups = NULL;
196838fd1498Szrj       /* If store_init_value returns NULL_TREE, the INIT has been
196938fd1498Szrj 	 recorded as the DECL_INITIAL for EXP.  That means there's
197038fd1498Szrj 	 nothing more we have to do.  */
197138fd1498Szrj       init = store_init_value (exp, init, &cleanups, flags);
197238fd1498Szrj       if (init)
197338fd1498Szrj 	finish_expr_stmt (init);
197438fd1498Szrj       gcc_assert (!cleanups);
197538fd1498Szrj       return;
197638fd1498Szrj     }
197738fd1498Szrj 
197838fd1498Szrj   /* List-initialization from {} becomes value-initialization for non-aggregate
197938fd1498Szrj      classes with default constructors.  Handle this here when we're
198038fd1498Szrj      initializing a base, so protected access works.  */
198138fd1498Szrj   if (exp != true_exp && init && TREE_CODE (init) == TREE_LIST)
198238fd1498Szrj     {
198338fd1498Szrj       tree elt = TREE_VALUE (init);
198438fd1498Szrj       if (DIRECT_LIST_INIT_P (elt)
198538fd1498Szrj 	  && CONSTRUCTOR_ELTS (elt) == 0
198638fd1498Szrj 	  && CLASSTYPE_NON_AGGREGATE (type)
198738fd1498Szrj 	  && TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
198838fd1498Szrj 	init = void_type_node;
198938fd1498Szrj     }
199038fd1498Szrj 
199138fd1498Szrj   /* If an explicit -- but empty -- initializer list was present,
199238fd1498Szrj      that's value-initialization.  */
199338fd1498Szrj   if (init == void_type_node)
199438fd1498Szrj     {
199538fd1498Szrj       /* If the type has data but no user-provided ctor, we need to zero
199638fd1498Szrj 	 out the object.  */
199738fd1498Szrj       if (!type_has_user_provided_constructor (type)
199838fd1498Szrj 	  && !is_really_empty_class (type))
199938fd1498Szrj 	{
200038fd1498Szrj 	  tree field_size = NULL_TREE;
200138fd1498Szrj 	  if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type)
200238fd1498Szrj 	    /* Don't clobber already initialized virtual bases.  */
200338fd1498Szrj 	    field_size = TYPE_SIZE (CLASSTYPE_AS_BASE (type));
200438fd1498Szrj 	  init = build_zero_init_1 (type, NULL_TREE, /*static_storage_p=*/false,
200538fd1498Szrj 				    field_size);
200638fd1498Szrj 	  init = build2 (INIT_EXPR, type, exp, init);
200738fd1498Szrj 	  finish_expr_stmt (init);
200838fd1498Szrj 	}
200938fd1498Szrj 
201038fd1498Szrj       /* If we don't need to mess with the constructor at all,
201138fd1498Szrj 	 then we're done.  */
201238fd1498Szrj       if (! type_build_ctor_call (type))
201338fd1498Szrj 	return;
201438fd1498Szrj 
201538fd1498Szrj       /* Otherwise fall through and call the constructor.  */
201638fd1498Szrj       init = NULL_TREE;
201738fd1498Szrj     }
201838fd1498Szrj 
201938fd1498Szrj   /* We know that expand_default_init can handle everything we want
202038fd1498Szrj      at this point.  */
202138fd1498Szrj   expand_default_init (binfo, true_exp, exp, init, flags, complain);
202238fd1498Szrj }
202338fd1498Szrj 
202438fd1498Szrj /* Report an error if TYPE is not a user-defined, class type.  If
202538fd1498Szrj    OR_ELSE is nonzero, give an error message.  */
202638fd1498Szrj 
202738fd1498Szrj int
is_class_type(tree type,int or_else)202838fd1498Szrj is_class_type (tree type, int or_else)
202938fd1498Szrj {
203038fd1498Szrj   if (type == error_mark_node)
203138fd1498Szrj     return 0;
203238fd1498Szrj 
203338fd1498Szrj   if (! CLASS_TYPE_P (type))
203438fd1498Szrj     {
203538fd1498Szrj       if (or_else)
203638fd1498Szrj 	error ("%qT is not a class type", type);
203738fd1498Szrj       return 0;
203838fd1498Szrj     }
203938fd1498Szrj   return 1;
204038fd1498Szrj }
204138fd1498Szrj 
204238fd1498Szrj tree
get_type_value(tree name)204338fd1498Szrj get_type_value (tree name)
204438fd1498Szrj {
204538fd1498Szrj   if (name == error_mark_node)
204638fd1498Szrj     return NULL_TREE;
204738fd1498Szrj 
204838fd1498Szrj   if (IDENTIFIER_HAS_TYPE_VALUE (name))
204938fd1498Szrj     return IDENTIFIER_TYPE_VALUE (name);
205038fd1498Szrj   else
205138fd1498Szrj     return NULL_TREE;
205238fd1498Szrj }
205338fd1498Szrj 
205438fd1498Szrj /* Build a reference to a member of an aggregate.  This is not a C++
205538fd1498Szrj    `&', but really something which can have its address taken, and
205638fd1498Szrj    then act as a pointer to member, for example TYPE :: FIELD can have
205738fd1498Szrj    its address taken by saying & TYPE :: FIELD.  ADDRESS_P is true if
205838fd1498Szrj    this expression is the operand of "&".
205938fd1498Szrj 
206038fd1498Szrj    @@ Prints out lousy diagnostics for operator <typename>
206138fd1498Szrj    @@ fields.
206238fd1498Szrj 
206338fd1498Szrj    @@ This function should be rewritten and placed in search.c.  */
206438fd1498Szrj 
206538fd1498Szrj tree
build_offset_ref(tree type,tree member,bool address_p,tsubst_flags_t complain)206638fd1498Szrj build_offset_ref (tree type, tree member, bool address_p,
206738fd1498Szrj 		  tsubst_flags_t complain)
206838fd1498Szrj {
206938fd1498Szrj   tree decl;
207038fd1498Szrj   tree basebinfo = NULL_TREE;
207138fd1498Szrj 
207238fd1498Szrj   /* class templates can come in as TEMPLATE_DECLs here.  */
207338fd1498Szrj   if (TREE_CODE (member) == TEMPLATE_DECL)
207438fd1498Szrj     return member;
207538fd1498Szrj 
207638fd1498Szrj   if (dependent_scope_p (type) || type_dependent_expression_p (member))
207738fd1498Szrj     return build_qualified_name (NULL_TREE, type, member,
207838fd1498Szrj 				  /*template_p=*/false);
207938fd1498Szrj 
208038fd1498Szrj   gcc_assert (TYPE_P (type));
208138fd1498Szrj   if (! is_class_type (type, 1))
208238fd1498Szrj     return error_mark_node;
208338fd1498Szrj 
208438fd1498Szrj   gcc_assert (DECL_P (member) || BASELINK_P (member));
208538fd1498Szrj   /* Callers should call mark_used before this point.  */
208638fd1498Szrj   gcc_assert (!DECL_P (member) || TREE_USED (member));
208738fd1498Szrj 
208838fd1498Szrj   type = TYPE_MAIN_VARIANT (type);
208938fd1498Szrj   if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type)))
209038fd1498Szrj     {
209138fd1498Szrj       if (complain & tf_error)
209238fd1498Szrj 	error ("incomplete type %qT does not have member %qD", type, member);
209338fd1498Szrj       return error_mark_node;
209438fd1498Szrj     }
209538fd1498Szrj 
209638fd1498Szrj   /* Entities other than non-static members need no further
209738fd1498Szrj      processing.  */
209838fd1498Szrj   if (TREE_CODE (member) == TYPE_DECL)
209938fd1498Szrj     return member;
210038fd1498Szrj   if (VAR_P (member) || TREE_CODE (member) == CONST_DECL)
210138fd1498Szrj     return convert_from_reference (member);
210238fd1498Szrj 
210338fd1498Szrj   if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
210438fd1498Szrj     {
210538fd1498Szrj       if (complain & tf_error)
210638fd1498Szrj 	error ("invalid pointer to bit-field %qD", member);
210738fd1498Szrj       return error_mark_node;
210838fd1498Szrj     }
210938fd1498Szrj 
211038fd1498Szrj   /* Set up BASEBINFO for member lookup.  */
211138fd1498Szrj   decl = maybe_dummy_object (type, &basebinfo);
211238fd1498Szrj 
211338fd1498Szrj   /* A lot of this logic is now handled in lookup_member.  */
211438fd1498Szrj   if (BASELINK_P (member))
211538fd1498Szrj     {
211638fd1498Szrj       /* Go from the TREE_BASELINK to the member function info.  */
211738fd1498Szrj       tree t = BASELINK_FUNCTIONS (member);
211838fd1498Szrj 
211938fd1498Szrj       if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
212038fd1498Szrj 	{
212138fd1498Szrj 	  /* Get rid of a potential OVERLOAD around it.  */
212238fd1498Szrj 	  t = OVL_FIRST (t);
212338fd1498Szrj 
212438fd1498Szrj 	  /* Unique functions are handled easily.  */
212538fd1498Szrj 
212638fd1498Szrj 	  /* For non-static member of base class, we need a special rule
212738fd1498Szrj 	     for access checking [class.protected]:
212838fd1498Szrj 
212938fd1498Szrj 	       If the access is to form a pointer to member, the
213038fd1498Szrj 	       nested-name-specifier shall name the derived class
213138fd1498Szrj 	       (or any class derived from that class).  */
213238fd1498Szrj 	  bool ok;
213338fd1498Szrj 	  if (address_p && DECL_P (t)
213438fd1498Szrj 	      && DECL_NONSTATIC_MEMBER_P (t))
213538fd1498Szrj 	    ok = perform_or_defer_access_check (TYPE_BINFO (type), t, t,
213638fd1498Szrj 						complain);
213738fd1498Szrj 	  else
213838fd1498Szrj 	    ok = perform_or_defer_access_check (basebinfo, t, t,
213938fd1498Szrj 						complain);
214038fd1498Szrj 	  if (!ok)
214138fd1498Szrj 	    return error_mark_node;
214238fd1498Szrj 	  if (DECL_STATIC_FUNCTION_P (t))
214338fd1498Szrj 	    return t;
214438fd1498Szrj 	  member = t;
214538fd1498Szrj 	}
214638fd1498Szrj       else
214738fd1498Szrj 	TREE_TYPE (member) = unknown_type_node;
214838fd1498Szrj     }
214938fd1498Szrj   else if (address_p && TREE_CODE (member) == FIELD_DECL)
215038fd1498Szrj     {
215138fd1498Szrj       /* We need additional test besides the one in
215238fd1498Szrj 	 check_accessibility_of_qualified_id in case it is
215338fd1498Szrj 	 a pointer to non-static member.  */
215438fd1498Szrj       if (!perform_or_defer_access_check (TYPE_BINFO (type), member, member,
215538fd1498Szrj 					  complain))
215638fd1498Szrj 	return error_mark_node;
215738fd1498Szrj     }
215838fd1498Szrj 
215938fd1498Szrj   if (!address_p)
216038fd1498Szrj     {
216138fd1498Szrj       /* If MEMBER is non-static, then the program has fallen afoul of
216238fd1498Szrj 	 [expr.prim]:
216338fd1498Szrj 
216438fd1498Szrj 	   An id-expression that denotes a nonstatic data member or
216538fd1498Szrj 	   nonstatic member function of a class can only be used:
216638fd1498Szrj 
216738fd1498Szrj 	   -- as part of a class member access (_expr.ref_) in which the
216838fd1498Szrj 	   object-expression refers to the member's class or a class
216938fd1498Szrj 	   derived from that class, or
217038fd1498Szrj 
217138fd1498Szrj 	   -- to form a pointer to member (_expr.unary.op_), or
217238fd1498Szrj 
217338fd1498Szrj 	   -- in the body of a nonstatic member function of that class or
217438fd1498Szrj 	   of a class derived from that class (_class.mfct.nonstatic_), or
217538fd1498Szrj 
217638fd1498Szrj 	   -- in a mem-initializer for a constructor for that class or for
217738fd1498Szrj 	   a class derived from that class (_class.base.init_).  */
217838fd1498Szrj       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
217938fd1498Szrj 	{
218038fd1498Szrj 	  /* Build a representation of the qualified name suitable
218138fd1498Szrj 	     for use as the operand to "&" -- even though the "&" is
218238fd1498Szrj 	     not actually present.  */
218338fd1498Szrj 	  member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
218438fd1498Szrj 	  /* In Microsoft mode, treat a non-static member function as if
218538fd1498Szrj 	     it were a pointer-to-member.  */
218638fd1498Szrj 	  if (flag_ms_extensions)
218738fd1498Szrj 	    {
218838fd1498Szrj 	      PTRMEM_OK_P (member) = 1;
218938fd1498Szrj 	      return cp_build_addr_expr (member, complain);
219038fd1498Szrj 	    }
219138fd1498Szrj 	  if (complain & tf_error)
219238fd1498Szrj 	    error ("invalid use of non-static member function %qD",
219338fd1498Szrj 		   TREE_OPERAND (member, 1));
219438fd1498Szrj 	  return error_mark_node;
219538fd1498Szrj 	}
219638fd1498Szrj       else if (TREE_CODE (member) == FIELD_DECL)
219738fd1498Szrj 	{
219838fd1498Szrj 	  if (complain & tf_error)
219938fd1498Szrj 	    error ("invalid use of non-static data member %qD", member);
220038fd1498Szrj 	  return error_mark_node;
220138fd1498Szrj 	}
220238fd1498Szrj       return member;
220338fd1498Szrj     }
220438fd1498Szrj 
220538fd1498Szrj   member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
220638fd1498Szrj   PTRMEM_OK_P (member) = 1;
220738fd1498Szrj   return member;
220838fd1498Szrj }
220938fd1498Szrj 
221038fd1498Szrj /* If DECL is a scalar enumeration constant or variable with a
221138fd1498Szrj    constant initializer, return the initializer (or, its initializers,
221238fd1498Szrj    recursively); otherwise, return DECL.  If STRICT_P, the
221338fd1498Szrj    initializer is only returned if DECL is a
221438fd1498Szrj    constant-expression.  If RETURN_AGGREGATE_CST_OK_P, it is ok to
221538fd1498Szrj    return an aggregate constant.  */
221638fd1498Szrj 
221738fd1498Szrj static tree
constant_value_1(tree decl,bool strict_p,bool return_aggregate_cst_ok_p)221838fd1498Szrj constant_value_1 (tree decl, bool strict_p, bool return_aggregate_cst_ok_p)
221938fd1498Szrj {
222038fd1498Szrj   while (TREE_CODE (decl) == CONST_DECL
222138fd1498Szrj 	 || decl_constant_var_p (decl)
222238fd1498Szrj 	 || (!strict_p && VAR_P (decl)
222338fd1498Szrj 	     && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))
222438fd1498Szrj     {
222538fd1498Szrj       tree init;
222638fd1498Szrj       /* If DECL is a static data member in a template
222738fd1498Szrj 	 specialization, we must instantiate it here.  The
222838fd1498Szrj 	 initializer for the static data member is not processed
222938fd1498Szrj 	 until needed; we need it now.  */
223038fd1498Szrj       mark_used (decl, tf_none);
223138fd1498Szrj       init = DECL_INITIAL (decl);
223238fd1498Szrj       if (init == error_mark_node)
223338fd1498Szrj 	{
223438fd1498Szrj 	  if (TREE_CODE (decl) == CONST_DECL
223538fd1498Szrj 	      || DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
223638fd1498Szrj 	    /* Treat the error as a constant to avoid cascading errors on
223738fd1498Szrj 	       excessively recursive template instantiation (c++/9335).  */
223838fd1498Szrj 	    return init;
223938fd1498Szrj 	  else
224038fd1498Szrj 	    return decl;
224138fd1498Szrj 	}
224238fd1498Szrj       /* Initializers in templates are generally expanded during
224338fd1498Szrj 	 instantiation, so before that for const int i(2)
224438fd1498Szrj 	 INIT is a TREE_LIST with the actual initializer as
224538fd1498Szrj 	 TREE_VALUE.  */
224638fd1498Szrj       if (processing_template_decl
224738fd1498Szrj 	  && init
224838fd1498Szrj 	  && TREE_CODE (init) == TREE_LIST
224938fd1498Szrj 	  && TREE_CHAIN (init) == NULL_TREE)
225038fd1498Szrj 	init = TREE_VALUE (init);
225138fd1498Szrj       /* Instantiate a non-dependent initializer for user variables.  We
225238fd1498Szrj 	 mustn't do this for the temporary for an array compound literal;
225338fd1498Szrj 	 trying to instatiate the initializer will keep creating new
225438fd1498Szrj 	 temporaries until we crash.  Probably it's not useful to do it for
225538fd1498Szrj 	 other artificial variables, either.  */
225638fd1498Szrj       if (!DECL_ARTIFICIAL (decl))
225738fd1498Szrj 	init = instantiate_non_dependent_or_null (init);
225838fd1498Szrj       if (!init
225938fd1498Szrj 	  || !TREE_TYPE (init)
226038fd1498Szrj 	  || !TREE_CONSTANT (init)
226138fd1498Szrj 	  || (!return_aggregate_cst_ok_p
226238fd1498Szrj 	      /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not
226338fd1498Szrj 		 return an aggregate constant (of which string
226438fd1498Szrj 		 literals are a special case), as we do not want
226538fd1498Szrj 		 to make inadvertent copies of such entities, and
226638fd1498Szrj 		 we must be sure that their addresses are the
226738fd1498Szrj  		 same everywhere.  */
226838fd1498Szrj 	      && (TREE_CODE (init) == CONSTRUCTOR
226938fd1498Szrj 		  || TREE_CODE (init) == STRING_CST)))
227038fd1498Szrj 	break;
227138fd1498Szrj       /* Don't return a CONSTRUCTOR for a variable with partial run-time
227238fd1498Szrj 	 initialization, since it doesn't represent the entire value.  */
227338fd1498Szrj       if (TREE_CODE (init) == CONSTRUCTOR
227438fd1498Szrj 	  && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
227538fd1498Szrj 	break;
227638fd1498Szrj       /* If the variable has a dynamic initializer, don't use its
227738fd1498Szrj 	 DECL_INITIAL which doesn't reflect the real value.  */
227838fd1498Szrj       if (VAR_P (decl)
227938fd1498Szrj 	  && TREE_STATIC (decl)
228038fd1498Szrj 	  && !DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)
228138fd1498Szrj 	  && DECL_NONTRIVIALLY_INITIALIZED_P (decl))
228238fd1498Szrj 	break;
228338fd1498Szrj       decl = unshare_expr (init);
228438fd1498Szrj     }
228538fd1498Szrj   return decl;
228638fd1498Szrj }
228738fd1498Szrj 
228838fd1498Szrj /* If DECL is a CONST_DECL, or a constant VAR_DECL initialized by constant
228938fd1498Szrj    of integral or enumeration type, or a constexpr variable of scalar type,
229038fd1498Szrj    then return that value.  These are those variables permitted in constant
229138fd1498Szrj    expressions by [5.19/1].  */
229238fd1498Szrj 
229338fd1498Szrj tree
scalar_constant_value(tree decl)229438fd1498Szrj scalar_constant_value (tree decl)
229538fd1498Szrj {
229638fd1498Szrj   return constant_value_1 (decl, /*strict_p=*/true,
229738fd1498Szrj 			   /*return_aggregate_cst_ok_p=*/false);
229838fd1498Szrj }
229938fd1498Szrj 
230038fd1498Szrj /* Like scalar_constant_value, but can also return aggregate initializers.  */
230138fd1498Szrj 
230238fd1498Szrj tree
decl_really_constant_value(tree decl)230338fd1498Szrj decl_really_constant_value (tree decl)
230438fd1498Szrj {
230538fd1498Szrj   return constant_value_1 (decl, /*strict_p=*/true,
230638fd1498Szrj 			   /*return_aggregate_cst_ok_p=*/true);
230738fd1498Szrj }
230838fd1498Szrj 
230938fd1498Szrj /* A more relaxed version of scalar_constant_value, used by the
231038fd1498Szrj    common C/C++ code.  */
231138fd1498Szrj 
231238fd1498Szrj tree
decl_constant_value(tree decl)231338fd1498Szrj decl_constant_value (tree decl)
231438fd1498Szrj {
231538fd1498Szrj   return constant_value_1 (decl, /*strict_p=*/processing_template_decl,
231638fd1498Szrj 			   /*return_aggregate_cst_ok_p=*/true);
231738fd1498Szrj }
231838fd1498Szrj 
231938fd1498Szrj /* Common subroutines of build_new and build_vec_delete.  */
232038fd1498Szrj 
232138fd1498Szrj /* Build and return a NEW_EXPR.  If NELTS is non-NULL, TYPE[NELTS] is
232238fd1498Szrj    the type of the object being allocated; otherwise, it's just TYPE.
232338fd1498Szrj    INIT is the initializer, if any.  USE_GLOBAL_NEW is true if the
232438fd1498Szrj    user explicitly wrote "::operator new".  PLACEMENT, if non-NULL, is
232538fd1498Szrj    a vector of arguments to be provided as arguments to a placement
232638fd1498Szrj    new operator.  This routine performs no semantic checks; it just
232738fd1498Szrj    creates and returns a NEW_EXPR.  */
232838fd1498Szrj 
232938fd1498Szrj static tree
build_raw_new_expr(vec<tree,va_gc> * placement,tree type,tree nelts,vec<tree,va_gc> * init,int use_global_new)233038fd1498Szrj build_raw_new_expr (vec<tree, va_gc> *placement, tree type, tree nelts,
233138fd1498Szrj 		    vec<tree, va_gc> *init, int use_global_new)
233238fd1498Szrj {
233338fd1498Szrj   tree init_list;
233438fd1498Szrj   tree new_expr;
233538fd1498Szrj 
233638fd1498Szrj   /* If INIT is NULL, the we want to store NULL_TREE in the NEW_EXPR.
233738fd1498Szrj      If INIT is not NULL, then we want to store VOID_ZERO_NODE.  This
233838fd1498Szrj      permits us to distinguish the case of a missing initializer "new
233938fd1498Szrj      int" from an empty initializer "new int()".  */
234038fd1498Szrj   if (init == NULL)
234138fd1498Szrj     init_list = NULL_TREE;
234238fd1498Szrj   else if (init->is_empty ())
234338fd1498Szrj     init_list = void_node;
234438fd1498Szrj   else
234538fd1498Szrj     {
234638fd1498Szrj       init_list = build_tree_list_vec (init);
234738fd1498Szrj       for (tree v = init_list; v; v = TREE_CHAIN (v))
234838fd1498Szrj 	if (TREE_CODE (TREE_VALUE (v)) == OVERLOAD)
234938fd1498Szrj 	  lookup_keep (TREE_VALUE (v), true);
235038fd1498Szrj     }
235138fd1498Szrj 
235238fd1498Szrj   new_expr = build4 (NEW_EXPR, build_pointer_type (type),
235338fd1498Szrj 		     build_tree_list_vec (placement), type, nelts,
235438fd1498Szrj 		     init_list);
235538fd1498Szrj   NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
235638fd1498Szrj   TREE_SIDE_EFFECTS (new_expr) = 1;
235738fd1498Szrj 
235838fd1498Szrj   return new_expr;
235938fd1498Szrj }
236038fd1498Szrj 
236138fd1498Szrj /* Diagnose uninitialized const members or reference members of type
236238fd1498Szrj    TYPE. USING_NEW is used to disambiguate the diagnostic between a
236338fd1498Szrj    new expression without a new-initializer and a declaration. Returns
236438fd1498Szrj    the error count. */
236538fd1498Szrj 
236638fd1498Szrj static int
diagnose_uninitialized_cst_or_ref_member_1(tree type,tree origin,bool using_new,bool complain)236738fd1498Szrj diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
236838fd1498Szrj 					    bool using_new, bool complain)
236938fd1498Szrj {
237038fd1498Szrj   tree field;
237138fd1498Szrj   int error_count = 0;
237238fd1498Szrj 
237338fd1498Szrj   if (type_has_user_provided_constructor (type))
237438fd1498Szrj     return 0;
237538fd1498Szrj 
237638fd1498Szrj   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
237738fd1498Szrj     {
237838fd1498Szrj       tree field_type;
237938fd1498Szrj 
238038fd1498Szrj       if (TREE_CODE (field) != FIELD_DECL)
238138fd1498Szrj 	continue;
238238fd1498Szrj 
238338fd1498Szrj       field_type = strip_array_types (TREE_TYPE (field));
238438fd1498Szrj 
238538fd1498Szrj       if (type_has_user_provided_constructor (field_type))
238638fd1498Szrj 	continue;
238738fd1498Szrj 
238838fd1498Szrj       if (TREE_CODE (field_type) == REFERENCE_TYPE)
238938fd1498Szrj 	{
239038fd1498Szrj 	  ++ error_count;
239138fd1498Szrj 	  if (complain)
239238fd1498Szrj 	    {
239338fd1498Szrj 	      if (DECL_CONTEXT (field) == origin)
239438fd1498Szrj 		{
239538fd1498Szrj 		  if (using_new)
239638fd1498Szrj 		    error ("uninitialized reference member in %q#T "
239738fd1498Szrj 			   "using %<new%> without new-initializer", origin);
239838fd1498Szrj 		  else
239938fd1498Szrj 		    error ("uninitialized reference member in %q#T", origin);
240038fd1498Szrj 		}
240138fd1498Szrj 	      else
240238fd1498Szrj 		{
240338fd1498Szrj 		  if (using_new)
240438fd1498Szrj 		    error ("uninitialized reference member in base %q#T "
240538fd1498Szrj 			   "of %q#T using %<new%> without new-initializer",
240638fd1498Szrj 			   DECL_CONTEXT (field), origin);
240738fd1498Szrj 		  else
240838fd1498Szrj 		    error ("uninitialized reference member in base %q#T "
240938fd1498Szrj 			   "of %q#T", DECL_CONTEXT (field), origin);
241038fd1498Szrj 		}
241138fd1498Szrj 	      inform (DECL_SOURCE_LOCATION (field),
241238fd1498Szrj 		      "%q#D should be initialized", field);
241338fd1498Szrj 	    }
241438fd1498Szrj 	}
241538fd1498Szrj 
241638fd1498Szrj       if (CP_TYPE_CONST_P (field_type))
241738fd1498Szrj 	{
241838fd1498Szrj 	  ++ error_count;
241938fd1498Szrj 	  if (complain)
242038fd1498Szrj 	    {
242138fd1498Szrj 	      if (DECL_CONTEXT (field) == origin)
242238fd1498Szrj 		{
242338fd1498Szrj 		  if (using_new)
242438fd1498Szrj 		    error ("uninitialized const member in %q#T "
242538fd1498Szrj 			   "using %<new%> without new-initializer", origin);
242638fd1498Szrj 		  else
242738fd1498Szrj 		    error ("uninitialized const member in %q#T", origin);
242838fd1498Szrj 		}
242938fd1498Szrj 	      else
243038fd1498Szrj 		{
243138fd1498Szrj 		  if (using_new)
243238fd1498Szrj 		    error ("uninitialized const member in base %q#T "
243338fd1498Szrj 			   "of %q#T using %<new%> without new-initializer",
243438fd1498Szrj 			   DECL_CONTEXT (field), origin);
243538fd1498Szrj 		  else
243638fd1498Szrj 		    error ("uninitialized const member in base %q#T "
243738fd1498Szrj 			   "of %q#T", DECL_CONTEXT (field), origin);
243838fd1498Szrj 		}
243938fd1498Szrj 	      inform (DECL_SOURCE_LOCATION (field),
244038fd1498Szrj 		      "%q#D should be initialized", field);
244138fd1498Szrj 	    }
244238fd1498Szrj 	}
244338fd1498Szrj 
244438fd1498Szrj       if (CLASS_TYPE_P (field_type))
244538fd1498Szrj 	error_count
244638fd1498Szrj 	  += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin,
244738fd1498Szrj 							 using_new, complain);
244838fd1498Szrj     }
244938fd1498Szrj   return error_count;
245038fd1498Szrj }
245138fd1498Szrj 
245238fd1498Szrj int
diagnose_uninitialized_cst_or_ref_member(tree type,bool using_new,bool complain)245338fd1498Szrj diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain)
245438fd1498Szrj {
245538fd1498Szrj   return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain);
245638fd1498Szrj }
245738fd1498Szrj 
245838fd1498Szrj /* Call __cxa_bad_array_new_length to indicate that the size calculation
245938fd1498Szrj    overflowed.  Pretend it returns sizetype so that it plays nicely in the
246038fd1498Szrj    COND_EXPR.  */
246138fd1498Szrj 
246238fd1498Szrj tree
throw_bad_array_new_length(void)246338fd1498Szrj throw_bad_array_new_length (void)
246438fd1498Szrj {
246538fd1498Szrj   if (!fn)
246638fd1498Szrj     {
246738fd1498Szrj       tree name = get_identifier ("__cxa_throw_bad_array_new_length");
246838fd1498Szrj 
246938fd1498Szrj       fn = get_global_binding (name);
247038fd1498Szrj       if (!fn)
247138fd1498Szrj 	fn = push_throw_library_fn
247238fd1498Szrj 	  (name, build_function_type_list (sizetype, NULL_TREE));
247338fd1498Szrj     }
247438fd1498Szrj 
247538fd1498Szrj   return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
247638fd1498Szrj }
247738fd1498Szrj 
247838fd1498Szrj /* Attempt to find the initializer for flexible array field T in the
247938fd1498Szrj    initializer INIT, when non-null.  Returns the initializer when
248038fd1498Szrj    successful and NULL otherwise.  */
248138fd1498Szrj static tree
find_flexarray_init(tree t,tree init)248238fd1498Szrj find_flexarray_init (tree t, tree init)
248338fd1498Szrj {
248438fd1498Szrj   if (!init || init == error_mark_node)
248538fd1498Szrj     return NULL_TREE;
248638fd1498Szrj 
248738fd1498Szrj   unsigned HOST_WIDE_INT idx;
248838fd1498Szrj   tree field, elt;
248938fd1498Szrj 
249038fd1498Szrj   /* Iterate over all top-level initializer elements.  */
249138fd1498Szrj   FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt)
249238fd1498Szrj     /* If the member T is found, return it.  */
249338fd1498Szrj     if (field == t)
249438fd1498Szrj       return elt;
249538fd1498Szrj 
249638fd1498Szrj   return NULL_TREE;
249738fd1498Szrj }
249838fd1498Szrj 
249938fd1498Szrj /* Attempt to verify that the argument, OPER, of a placement new expression
250038fd1498Szrj    refers to an object sufficiently large for an object of TYPE or an array
250138fd1498Szrj    of NELTS of such objects when NELTS is non-null, and issue a warning when
250238fd1498Szrj    it does not.  SIZE specifies the size needed to construct the object or
250338fd1498Szrj    array and captures the result of NELTS * sizeof (TYPE). (SIZE could be
250438fd1498Szrj    greater when the array under construction requires a cookie to store
250538fd1498Szrj    NELTS.  GCC's placement new expression stores the cookie when invoking
250638fd1498Szrj    a user-defined placement new operator function but not the default one.
250738fd1498Szrj    Placement new expressions with user-defined placement new operator are
250838fd1498Szrj    not diagnosed since we don't know how they use the buffer (this could
250938fd1498Szrj    be a future extension).  */
251038fd1498Szrj static void
warn_placement_new_too_small(tree type,tree nelts,tree size,tree oper)251138fd1498Szrj warn_placement_new_too_small (tree type, tree nelts, tree size, tree oper)
251238fd1498Szrj {
251338fd1498Szrj   location_t loc = EXPR_LOC_OR_LOC (oper, input_location);
251438fd1498Szrj 
251538fd1498Szrj   /* The number of bytes to add to or subtract from the size of the provided
251638fd1498Szrj      buffer based on an offset into an array or an array element reference.
251738fd1498Szrj      Although intermediate results may be negative (as in a[3] - 2) a valid
251838fd1498Szrj      final result cannot be.  */
251938fd1498Szrj   offset_int adjust = 0;
252038fd1498Szrj   /* True when the size of the entire destination object should be used
252138fd1498Szrj      to compute the possibly optimistic estimate of the available space.  */
252238fd1498Szrj   bool use_obj_size = false;
252338fd1498Szrj   /* True when the reference to the destination buffer is an ADDR_EXPR.  */
252438fd1498Szrj   bool addr_expr = false;
252538fd1498Szrj 
252638fd1498Szrj   STRIP_NOPS (oper);
252738fd1498Szrj 
252838fd1498Szrj   /* Using a function argument or a (non-array) variable as an argument
252938fd1498Szrj      to placement new is not checked since it's unknown what it might
253038fd1498Szrj      point to.  */
253138fd1498Szrj   if (TREE_CODE (oper) == PARM_DECL
253238fd1498Szrj       || VAR_P (oper)
253338fd1498Szrj       || TREE_CODE (oper) == COMPONENT_REF)
253438fd1498Szrj     return;
253538fd1498Szrj 
253638fd1498Szrj   /* Evaluate any constant expressions.  */
253738fd1498Szrj   size = fold_non_dependent_expr (size);
253838fd1498Szrj 
253938fd1498Szrj   /* Handle the common case of array + offset expression when the offset
254038fd1498Szrj      is a constant.  */
254138fd1498Szrj   if (TREE_CODE (oper) == POINTER_PLUS_EXPR)
254238fd1498Szrj     {
254338fd1498Szrj       /* If the offset is compile-time constant, use it to compute a more
254438fd1498Szrj 	 accurate estimate of the size of the buffer.  Since the operand
254538fd1498Szrj 	 of POINTER_PLUS_EXPR is represented as an unsigned type, convert
254638fd1498Szrj 	 it to signed first.
254738fd1498Szrj 	 Otherwise, use the size of the entire array as an optimistic
254838fd1498Szrj 	 estimate (this may lead to false negatives).  */
254938fd1498Szrj       tree adj = TREE_OPERAND (oper, 1);
255038fd1498Szrj       if (CONSTANT_CLASS_P (adj))
255138fd1498Szrj 	adjust += wi::to_offset (convert (ssizetype, adj));
255238fd1498Szrj       else
255338fd1498Szrj 	use_obj_size = true;
255438fd1498Szrj 
255538fd1498Szrj       oper = TREE_OPERAND (oper, 0);
255638fd1498Szrj 
255738fd1498Szrj       STRIP_NOPS (oper);
255838fd1498Szrj     }
255938fd1498Szrj 
256038fd1498Szrj   if (TREE_CODE (oper) == TARGET_EXPR)
256138fd1498Szrj     oper = TREE_OPERAND (oper, 1);
256238fd1498Szrj   else if (TREE_CODE (oper) == ADDR_EXPR)
256338fd1498Szrj     {
256438fd1498Szrj       addr_expr = true;
256538fd1498Szrj       oper = TREE_OPERAND (oper, 0);
256638fd1498Szrj     }
256738fd1498Szrj 
256838fd1498Szrj   STRIP_NOPS (oper);
256938fd1498Szrj 
257038fd1498Szrj   if (TREE_CODE (oper) == ARRAY_REF
257138fd1498Szrj       && (addr_expr || TREE_CODE (TREE_TYPE (oper)) == ARRAY_TYPE))
257238fd1498Szrj     {
257338fd1498Szrj       /* Similar to the offset computed above, see if the array index
257438fd1498Szrj 	 is a compile-time constant.  If so, and unless the offset was
257538fd1498Szrj 	 not a compile-time constant, use the index to determine the
257638fd1498Szrj 	 size of the buffer.  Otherwise, use the entire array as
257738fd1498Szrj 	 an optimistic estimate of the size.  */
257838fd1498Szrj       const_tree adj = fold_non_dependent_expr (TREE_OPERAND (oper, 1));
257938fd1498Szrj       if (!use_obj_size && CONSTANT_CLASS_P (adj))
258038fd1498Szrj 	adjust += wi::to_offset (adj);
258138fd1498Szrj       else
258238fd1498Szrj 	{
258338fd1498Szrj 	  use_obj_size = true;
258438fd1498Szrj 	  adjust = 0;
258538fd1498Szrj 	}
258638fd1498Szrj 
258738fd1498Szrj       oper = TREE_OPERAND (oper, 0);
258838fd1498Szrj     }
258938fd1498Szrj 
259038fd1498Szrj   /* Refers to the declared object that constains the subobject referenced
259138fd1498Szrj      by OPER.  When the object is initialized, makes it possible to determine
259238fd1498Szrj      the actual size of a flexible array member used as the buffer passed
259338fd1498Szrj      as OPER to placement new.  */
259438fd1498Szrj   tree var_decl = NULL_TREE;
259538fd1498Szrj   /* True when operand is a COMPONENT_REF, to distinguish flexible array
259638fd1498Szrj      members from arrays of unspecified size.  */
259738fd1498Szrj   bool compref = TREE_CODE (oper) == COMPONENT_REF;
259838fd1498Szrj 
259938fd1498Szrj   /* For COMPONENT_REF (i.e., a struct member) the size of the entire
260038fd1498Szrj      enclosing struct.  Used to validate the adjustment (offset) into
260138fd1498Szrj      an array at the end of a struct.  */
260238fd1498Szrj   offset_int compsize = 0;
260338fd1498Szrj 
260438fd1498Szrj   /* Descend into a struct or union to find the member whose address
260538fd1498Szrj      is being used as the argument.  */
260638fd1498Szrj   if (TREE_CODE (oper) == COMPONENT_REF)
260738fd1498Szrj     {
260838fd1498Szrj       tree comptype = TREE_TYPE (TREE_OPERAND (oper, 0));
260938fd1498Szrj       compsize = wi::to_offset (TYPE_SIZE_UNIT (comptype));
261038fd1498Szrj 
261138fd1498Szrj       tree op0 = oper;
261238fd1498Szrj       while (TREE_CODE (op0 = TREE_OPERAND (op0, 0)) == COMPONENT_REF);
261338fd1498Szrj       if (VAR_P (op0))
261438fd1498Szrj 	var_decl = op0;
261538fd1498Szrj       oper = TREE_OPERAND (oper, 1);
261638fd1498Szrj     }
261738fd1498Szrj 
261838fd1498Szrj   tree opertype = TREE_TYPE (oper);
261938fd1498Szrj   if ((addr_expr || !POINTER_TYPE_P (opertype))
262038fd1498Szrj       && (VAR_P (oper)
262138fd1498Szrj 	  || TREE_CODE (oper) == FIELD_DECL
262238fd1498Szrj 	  || TREE_CODE (oper) == PARM_DECL))
262338fd1498Szrj     {
262438fd1498Szrj       /* A possibly optimistic estimate of the number of bytes available
262538fd1498Szrj 	 in the destination buffer.  */
262638fd1498Szrj       offset_int bytes_avail = 0;
262738fd1498Szrj       /* True when the estimate above is in fact the exact size
262838fd1498Szrj 	 of the destination buffer rather than an estimate.  */
262938fd1498Szrj       bool exact_size = true;
263038fd1498Szrj 
263138fd1498Szrj       /* Treat members of unions and members of structs uniformly, even
263238fd1498Szrj 	 though the size of a member of a union may be viewed as extending
263338fd1498Szrj 	 to the end of the union itself (it is by __builtin_object_size).  */
263438fd1498Szrj       if ((VAR_P (oper) || use_obj_size)
263538fd1498Szrj 	  && DECL_SIZE_UNIT (oper)
263638fd1498Szrj 	  && tree_fits_uhwi_p (DECL_SIZE_UNIT (oper)))
263738fd1498Szrj 	{
263838fd1498Szrj 	  /* Use the size of the entire array object when the expression
263938fd1498Szrj 	     refers to a variable or its size depends on an expression
264038fd1498Szrj 	     that's not a compile-time constant.  */
264138fd1498Szrj 	  bytes_avail = wi::to_offset (DECL_SIZE_UNIT (oper));
264238fd1498Szrj 	  exact_size = !use_obj_size;
264338fd1498Szrj 	}
264438fd1498Szrj       else if (tree opersize = TYPE_SIZE_UNIT (opertype))
264538fd1498Szrj 	{
264638fd1498Szrj 	  /* Use the size of the type of the destination buffer object
264738fd1498Szrj 	     as the optimistic estimate of the available space in it.
264838fd1498Szrj 	     Use the maximum possible size for zero-size arrays and
264938fd1498Szrj 	     flexible array members (except of initialized objects
265038fd1498Szrj 	     thereof).  */
265138fd1498Szrj 	  if (TREE_CODE (opersize) == INTEGER_CST)
265238fd1498Szrj 	    bytes_avail = wi::to_offset (opersize);
265338fd1498Szrj 	}
265438fd1498Szrj 
265538fd1498Szrj       if (bytes_avail == 0)
265638fd1498Szrj 	{
265738fd1498Szrj 	  if (var_decl)
265838fd1498Szrj 	    {
265938fd1498Szrj 	      /* Constructing into a buffer provided by the flexible array
266038fd1498Szrj 		 member of a declared object (which is permitted as a G++
266138fd1498Szrj 		 extension).  If the array member has been initialized,
266238fd1498Szrj 		 determine its size from the initializer.  Otherwise,
266338fd1498Szrj 		 the array size is zero.  */
266438fd1498Szrj 	      if (tree init = find_flexarray_init (oper,
266538fd1498Szrj 						   DECL_INITIAL (var_decl)))
266638fd1498Szrj 		bytes_avail = wi::to_offset (TYPE_SIZE_UNIT (TREE_TYPE (init)));
266738fd1498Szrj 	    }
266838fd1498Szrj 	  else
266938fd1498Szrj 	    bytes_avail = (wi::to_offset (TYPE_MAX_VALUE (ptrdiff_type_node))
267038fd1498Szrj 			   - compsize);
267138fd1498Szrj 	}
267238fd1498Szrj 
267338fd1498Szrj       tree_code oper_code = TREE_CODE (opertype);
267438fd1498Szrj 
267538fd1498Szrj       if (compref && oper_code == ARRAY_TYPE)
267638fd1498Szrj 	{
267738fd1498Szrj 	  tree nelts = array_type_nelts_top (opertype);
267838fd1498Szrj 	  tree nelts_cst = maybe_constant_value (nelts);
267938fd1498Szrj 	  if (TREE_CODE (nelts_cst) == INTEGER_CST
268038fd1498Szrj 	      && integer_onep (nelts_cst)
268138fd1498Szrj 	      && !var_decl
268238fd1498Szrj 	      && warn_placement_new < 2)
268338fd1498Szrj 	    return;
268438fd1498Szrj 	}
268538fd1498Szrj 
268638fd1498Szrj       /* Reduce the size of the buffer by the adjustment computed above
268738fd1498Szrj 	 from the offset and/or the index into the array.  */
268838fd1498Szrj       if (bytes_avail < adjust || adjust < 0)
268938fd1498Szrj 	bytes_avail = 0;
269038fd1498Szrj       else
269138fd1498Szrj 	{
269238fd1498Szrj 	  tree elttype = (TREE_CODE (opertype) == ARRAY_TYPE
269338fd1498Szrj 			  ? TREE_TYPE (opertype) : opertype);
269438fd1498Szrj 	  if (tree eltsize = TYPE_SIZE_UNIT (elttype))
269538fd1498Szrj 	    {
269638fd1498Szrj 	      bytes_avail -= adjust * wi::to_offset (eltsize);
269738fd1498Szrj 	      if (bytes_avail < 0)
269838fd1498Szrj 		bytes_avail = 0;
269938fd1498Szrj 	    }
270038fd1498Szrj 	}
270138fd1498Szrj 
270238fd1498Szrj       /* The minimum amount of space needed for the allocation.  This
270338fd1498Szrj 	 is an optimistic estimate that makes it possible to detect
270438fd1498Szrj 	 placement new invocation for some undersize buffers but not
270538fd1498Szrj 	 others.  */
270638fd1498Szrj       offset_int bytes_need;
270738fd1498Szrj 
270838fd1498Szrj       if (CONSTANT_CLASS_P (size))
270938fd1498Szrj 	bytes_need = wi::to_offset (size);
271038fd1498Szrj       else if (nelts && CONSTANT_CLASS_P (nelts))
271138fd1498Szrj 	bytes_need = (wi::to_offset (nelts)
271238fd1498Szrj 		      * wi::to_offset (TYPE_SIZE_UNIT (type)));
271338fd1498Szrj       else if (tree_fits_uhwi_p (TYPE_SIZE_UNIT (type)))
271438fd1498Szrj 	bytes_need = wi::to_offset (TYPE_SIZE_UNIT (type));
271538fd1498Szrj       else
271638fd1498Szrj 	{
271738fd1498Szrj 	  /* The type is a VLA.  */
271838fd1498Szrj 	  return;
271938fd1498Szrj 	}
272038fd1498Szrj 
272138fd1498Szrj       if (bytes_avail < bytes_need)
272238fd1498Szrj 	{
272338fd1498Szrj 	  if (nelts)
272438fd1498Szrj 	    if (CONSTANT_CLASS_P (nelts))
272538fd1498Szrj 	      warning_at (loc, OPT_Wplacement_new_,
272638fd1498Szrj 			  exact_size ?
272738fd1498Szrj 			  "placement new constructing an object of type "
272838fd1498Szrj 			  "%<%T [%wu]%> and size %qwu in a region of type %qT "
272938fd1498Szrj 			  "and size %qwi"
273038fd1498Szrj 			  : "placement new constructing an object of type "
273138fd1498Szrj 			  "%<%T [%wu]%> and size %qwu in a region of type %qT "
273238fd1498Szrj 			  "and size at most %qwu",
273338fd1498Szrj 			  type, tree_to_uhwi (nelts), bytes_need.to_uhwi (),
273438fd1498Szrj 			  opertype, bytes_avail.to_uhwi ());
273538fd1498Szrj 	    else
273638fd1498Szrj 	      warning_at (loc, OPT_Wplacement_new_,
273738fd1498Szrj 			  exact_size ?
273838fd1498Szrj 			  "placement new constructing an array of objects "
273938fd1498Szrj 			  "of type %qT and size %qwu in a region of type %qT "
274038fd1498Szrj 			  "and size %qwi"
274138fd1498Szrj 			  : "placement new constructing an array of objects "
274238fd1498Szrj 			  "of type %qT and size %qwu in a region of type %qT "
274338fd1498Szrj 			  "and size at most %qwu",
274438fd1498Szrj 			  type, bytes_need.to_uhwi (), opertype,
274538fd1498Szrj 			  bytes_avail.to_uhwi ());
274638fd1498Szrj 	  else
274738fd1498Szrj 	    warning_at (loc, OPT_Wplacement_new_,
274838fd1498Szrj 			exact_size ?
274938fd1498Szrj 			"placement new constructing an object of type %qT "
275038fd1498Szrj 			"and size %qwu in a region of type %qT and size %qwi"
275138fd1498Szrj 			: "placement new constructing an object of type %qT "
275238fd1498Szrj 			"and size %qwu in a region of type %qT and size "
275338fd1498Szrj 			"at most %qwu",
275438fd1498Szrj 			type, bytes_need.to_uhwi (), opertype,
275538fd1498Szrj 			bytes_avail.to_uhwi ());
275638fd1498Szrj 	}
275738fd1498Szrj     }
275838fd1498Szrj }
275938fd1498Szrj 
276038fd1498Szrj /* True if alignof(T) > __STDCPP_DEFAULT_NEW_ALIGNMENT__.  */
276138fd1498Szrj 
276238fd1498Szrj bool
type_has_new_extended_alignment(tree t)276338fd1498Szrj type_has_new_extended_alignment (tree t)
276438fd1498Szrj {
276538fd1498Szrj   return (aligned_new_threshold
276638fd1498Szrj 	  && TYPE_ALIGN_UNIT (t) > (unsigned)aligned_new_threshold);
276738fd1498Szrj }
276838fd1498Szrj 
276938fd1498Szrj /* Return the alignment we expect malloc to guarantee.  This should just be
277038fd1498Szrj    MALLOC_ABI_ALIGNMENT, but that macro defaults to only BITS_PER_WORD for some
277138fd1498Szrj    reason, so don't let the threshold be smaller than max_align_t_align.  */
277238fd1498Szrj 
277338fd1498Szrj unsigned
malloc_alignment()277438fd1498Szrj malloc_alignment ()
277538fd1498Szrj {
277638fd1498Szrj   return MAX (max_align_t_align(), MALLOC_ABI_ALIGNMENT);
277738fd1498Szrj }
277838fd1498Szrj 
277938fd1498Szrj /* Determine whether an allocation function is a namespace-scope
278038fd1498Szrj    non-replaceable placement new function. See DR 1748.
278138fd1498Szrj    TODO: Enable in all standard modes.  */
278238fd1498Szrj static bool
std_placement_new_fn_p(tree alloc_fn)278338fd1498Szrj std_placement_new_fn_p (tree alloc_fn)
278438fd1498Szrj {
278538fd1498Szrj   if (DECL_NAMESPACE_SCOPE_P (alloc_fn))
278638fd1498Szrj     {
278738fd1498Szrj       tree first_arg = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (alloc_fn)));
278838fd1498Szrj       if ((TREE_VALUE (first_arg) == ptr_type_node)
278938fd1498Szrj 	  && TREE_CHAIN (first_arg) == void_list_node)
279038fd1498Szrj 	return true;
279138fd1498Szrj     }
279238fd1498Szrj   return false;
279338fd1498Szrj }
279438fd1498Szrj 
279538fd1498Szrj /* Generate code for a new-expression, including calling the "operator
279638fd1498Szrj    new" function, initializing the object, and, if an exception occurs
279738fd1498Szrj    during construction, cleaning up.  The arguments are as for
279838fd1498Szrj    build_raw_new_expr.  This may change PLACEMENT and INIT.
279938fd1498Szrj    TYPE is the type of the object being constructed, possibly an array
280038fd1498Szrj    of NELTS elements when NELTS is non-null (in "new T[NELTS]", T may
280138fd1498Szrj    be an array of the form U[inner], with the whole expression being
280238fd1498Szrj    "new U[NELTS][inner]").  */
280338fd1498Szrj 
280438fd1498Szrj static tree
build_new_1(vec<tree,va_gc> ** placement,tree type,tree nelts,vec<tree,va_gc> ** init,bool globally_qualified_p,tsubst_flags_t complain)280538fd1498Szrj build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
280638fd1498Szrj 	     vec<tree, va_gc> **init, bool globally_qualified_p,
280738fd1498Szrj 	     tsubst_flags_t complain)
280838fd1498Szrj {
280938fd1498Szrj   tree size, rval;
281038fd1498Szrj   /* True iff this is a call to "operator new[]" instead of just
281138fd1498Szrj      "operator new".  */
281238fd1498Szrj   bool array_p = false;
281338fd1498Szrj   /* If ARRAY_P is true, the element type of the array.  This is never
281438fd1498Szrj      an ARRAY_TYPE; for something like "new int[3][4]", the
281538fd1498Szrj      ELT_TYPE is "int".  If ARRAY_P is false, this is the same type as
281638fd1498Szrj      TYPE.  */
281738fd1498Szrj   tree elt_type;
281838fd1498Szrj   /* The type of the new-expression.  (This type is always a pointer
281938fd1498Szrj      type.)  */
282038fd1498Szrj   tree pointer_type;
282138fd1498Szrj   tree non_const_pointer_type;
282238fd1498Szrj   /* The most significant array bound in int[OUTER_NELTS][inner].  */
282338fd1498Szrj   tree outer_nelts = NULL_TREE;
282438fd1498Szrj   /* For arrays with a non-constant number of elements, a bounds checks
282538fd1498Szrj      on the NELTS parameter to avoid integer overflow at runtime. */
282638fd1498Szrj   tree outer_nelts_check = NULL_TREE;
282738fd1498Szrj   bool outer_nelts_from_type = false;
282838fd1498Szrj   /* Number of the "inner" elements in "new T[OUTER_NELTS][inner]".  */
282938fd1498Szrj   offset_int inner_nelts_count = 1;
283038fd1498Szrj   tree alloc_call, alloc_expr;
283138fd1498Szrj   /* Size of the inner array elements (those with constant dimensions). */
283238fd1498Szrj   offset_int inner_size;
283338fd1498Szrj   /* The address returned by the call to "operator new".  This node is
283438fd1498Szrj      a VAR_DECL and is therefore reusable.  */
283538fd1498Szrj   tree alloc_node;
283638fd1498Szrj   tree alloc_fn;
283738fd1498Szrj   tree cookie_expr, init_expr;
283838fd1498Szrj   int nothrow, check_new;
283938fd1498Szrj   /* If non-NULL, the number of extra bytes to allocate at the
284038fd1498Szrj      beginning of the storage allocated for an array-new expression in
284138fd1498Szrj      order to store the number of elements.  */
284238fd1498Szrj   tree cookie_size = NULL_TREE;
284338fd1498Szrj   tree placement_first;
284438fd1498Szrj   tree placement_expr = NULL_TREE;
284538fd1498Szrj   /* True if the function we are calling is a placement allocation
284638fd1498Szrj      function.  */
284738fd1498Szrj   bool placement_allocation_fn_p;
284838fd1498Szrj   /* True if the storage must be initialized, either by a constructor
284938fd1498Szrj      or due to an explicit new-initializer.  */
285038fd1498Szrj   bool is_initialized;
285138fd1498Szrj   /* The address of the thing allocated, not including any cookie.  In
285238fd1498Szrj      particular, if an array cookie is in use, DATA_ADDR is the
285338fd1498Szrj      address of the first array element.  This node is a VAR_DECL, and
285438fd1498Szrj      is therefore reusable.  */
285538fd1498Szrj   tree data_addr;
285638fd1498Szrj   tree init_preeval_expr = NULL_TREE;
285738fd1498Szrj   tree orig_type = type;
285838fd1498Szrj 
285938fd1498Szrj   if (nelts)
286038fd1498Szrj     {
286138fd1498Szrj       outer_nelts = nelts;
286238fd1498Szrj       array_p = true;
286338fd1498Szrj     }
286438fd1498Szrj   else if (TREE_CODE (type) == ARRAY_TYPE)
286538fd1498Szrj     {
286638fd1498Szrj       /* Transforms new (T[N]) to new T[N].  The former is a GNU
286738fd1498Szrj 	 extension for variable N.  (This also covers new T where T is
286838fd1498Szrj 	 a VLA typedef.)  */
286938fd1498Szrj       array_p = true;
287038fd1498Szrj       nelts = array_type_nelts_top (type);
287138fd1498Szrj       outer_nelts = nelts;
287238fd1498Szrj       type = TREE_TYPE (type);
287338fd1498Szrj       outer_nelts_from_type = true;
287438fd1498Szrj     }
287538fd1498Szrj 
2876*58e805e6Szrj   /* Lots of logic below depends on whether we have a constant number of
287738fd1498Szrj      elements, so go ahead and fold it now.  */
2878*58e805e6Szrj   const_tree cst_outer_nelts = fold_non_dependent_expr (outer_nelts);
287938fd1498Szrj 
288038fd1498Szrj   /* If our base type is an array, then make sure we know how many elements
288138fd1498Szrj      it has.  */
288238fd1498Szrj   for (elt_type = type;
288338fd1498Szrj        TREE_CODE (elt_type) == ARRAY_TYPE;
288438fd1498Szrj        elt_type = TREE_TYPE (elt_type))
288538fd1498Szrj     {
288638fd1498Szrj       tree inner_nelts = array_type_nelts_top (elt_type);
288738fd1498Szrj       tree inner_nelts_cst = maybe_constant_value (inner_nelts);
288838fd1498Szrj       if (TREE_CODE (inner_nelts_cst) == INTEGER_CST)
288938fd1498Szrj 	{
289038fd1498Szrj 	  bool overflow;
289138fd1498Szrj 	  offset_int result = wi::mul (wi::to_offset (inner_nelts_cst),
289238fd1498Szrj 				       inner_nelts_count, SIGNED, &overflow);
289338fd1498Szrj 	  if (overflow)
289438fd1498Szrj 	    {
289538fd1498Szrj 	      if (complain & tf_error)
289638fd1498Szrj 		error ("integer overflow in array size");
289738fd1498Szrj 	      nelts = error_mark_node;
289838fd1498Szrj 	    }
289938fd1498Szrj 	  inner_nelts_count = result;
290038fd1498Szrj 	}
290138fd1498Szrj       else
290238fd1498Szrj 	{
290338fd1498Szrj 	  if (complain & tf_error)
290438fd1498Szrj 	    {
290538fd1498Szrj 	      error_at (EXPR_LOC_OR_LOC (inner_nelts, input_location),
290638fd1498Szrj 			"array size in new-expression must be constant");
290738fd1498Szrj 	      cxx_constant_value(inner_nelts);
290838fd1498Szrj 	    }
290938fd1498Szrj 	  nelts = error_mark_node;
291038fd1498Szrj 	}
291138fd1498Szrj       if (nelts != error_mark_node)
291238fd1498Szrj 	nelts = cp_build_binary_op (input_location,
291338fd1498Szrj 				    MULT_EXPR, nelts,
291438fd1498Szrj 				    inner_nelts_cst,
291538fd1498Szrj 				    complain);
291638fd1498Szrj     }
291738fd1498Szrj 
291838fd1498Szrj   if (variably_modified_type_p (elt_type, NULL_TREE) && (complain & tf_error))
291938fd1498Szrj     {
292038fd1498Szrj       error ("variably modified type not allowed in new-expression");
292138fd1498Szrj       return error_mark_node;
292238fd1498Szrj     }
292338fd1498Szrj 
292438fd1498Szrj   if (nelts == error_mark_node)
292538fd1498Szrj     return error_mark_node;
292638fd1498Szrj 
292738fd1498Szrj   /* Warn if we performed the (T[N]) to T[N] transformation and N is
292838fd1498Szrj      variable.  */
292938fd1498Szrj   if (outer_nelts_from_type
2930*58e805e6Szrj       && !TREE_CONSTANT (cst_outer_nelts))
293138fd1498Szrj     {
293238fd1498Szrj       if (complain & tf_warning_or_error)
293338fd1498Szrj 	{
293438fd1498Szrj 	  pedwarn (EXPR_LOC_OR_LOC (outer_nelts, input_location), OPT_Wvla,
293538fd1498Szrj 		   typedef_variant_p (orig_type)
293638fd1498Szrj 		   ? G_("non-constant array new length must be specified "
293738fd1498Szrj 			"directly, not by typedef")
293838fd1498Szrj 		   : G_("non-constant array new length must be specified "
293938fd1498Szrj 			"without parentheses around the type-id"));
294038fd1498Szrj 	}
294138fd1498Szrj       else
294238fd1498Szrj 	return error_mark_node;
294338fd1498Szrj     }
294438fd1498Szrj 
294538fd1498Szrj   if (VOID_TYPE_P (elt_type))
294638fd1498Szrj     {
294738fd1498Szrj       if (complain & tf_error)
294838fd1498Szrj         error ("invalid type %<void%> for new");
294938fd1498Szrj       return error_mark_node;
295038fd1498Szrj     }
295138fd1498Szrj 
295238fd1498Szrj   if (abstract_virtuals_error_sfinae (ACU_NEW, elt_type, complain))
295338fd1498Szrj     return error_mark_node;
295438fd1498Szrj 
295538fd1498Szrj   is_initialized = (type_build_ctor_call (elt_type) || *init != NULL);
295638fd1498Szrj 
295738fd1498Szrj   if (*init == NULL && cxx_dialect < cxx11)
295838fd1498Szrj     {
295938fd1498Szrj       bool maybe_uninitialized_error = false;
296038fd1498Szrj       /* A program that calls for default-initialization [...] of an
296138fd1498Szrj 	 entity of reference type is ill-formed. */
296238fd1498Szrj       if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type))
296338fd1498Szrj 	maybe_uninitialized_error = true;
296438fd1498Szrj 
296538fd1498Szrj       /* A new-expression that creates an object of type T initializes
296638fd1498Szrj 	 that object as follows:
296738fd1498Szrj       - If the new-initializer is omitted:
296838fd1498Szrj         -- If T is a (possibly cv-qualified) non-POD class type
296938fd1498Szrj 	   (or array thereof), the object is default-initialized (8.5).
297038fd1498Szrj 	   [...]
297138fd1498Szrj         -- Otherwise, the object created has indeterminate
297238fd1498Szrj 	   value. If T is a const-qualified type, or a (possibly
297338fd1498Szrj 	   cv-qualified) POD class type (or array thereof)
297438fd1498Szrj 	   containing (directly or indirectly) a member of
297538fd1498Szrj 	   const-qualified type, the program is ill-formed; */
297638fd1498Szrj 
297738fd1498Szrj       if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type))
297838fd1498Szrj 	maybe_uninitialized_error = true;
297938fd1498Szrj 
298038fd1498Szrj       if (maybe_uninitialized_error
298138fd1498Szrj 	  && diagnose_uninitialized_cst_or_ref_member (elt_type,
298238fd1498Szrj 						       /*using_new=*/true,
298338fd1498Szrj 						       complain & tf_error))
298438fd1498Szrj 	return error_mark_node;
298538fd1498Szrj     }
298638fd1498Szrj 
298738fd1498Szrj   if (CP_TYPE_CONST_P (elt_type) && *init == NULL
298838fd1498Szrj       && default_init_uninitialized_part (elt_type))
298938fd1498Szrj     {
299038fd1498Szrj       if (complain & tf_error)
299138fd1498Szrj         error ("uninitialized const in %<new%> of %q#T", elt_type);
299238fd1498Szrj       return error_mark_node;
299338fd1498Szrj     }
299438fd1498Szrj 
299538fd1498Szrj   size = size_in_bytes (elt_type);
299638fd1498Szrj   if (array_p)
299738fd1498Szrj     {
299838fd1498Szrj       /* Maximum available size in bytes.  Half of the address space
299938fd1498Szrj 	 minus the cookie size.  */
300038fd1498Szrj       offset_int max_size
300138fd1498Szrj 	= wi::set_bit_in_zero <offset_int> (TYPE_PRECISION (sizetype) - 1);
300238fd1498Szrj       /* Maximum number of outer elements which can be allocated. */
300338fd1498Szrj       offset_int max_outer_nelts;
300438fd1498Szrj       tree max_outer_nelts_tree;
300538fd1498Szrj 
300638fd1498Szrj       gcc_assert (TREE_CODE (size) == INTEGER_CST);
300738fd1498Szrj       cookie_size = targetm.cxx.get_cookie_size (elt_type);
300838fd1498Szrj       gcc_assert (TREE_CODE (cookie_size) == INTEGER_CST);
300938fd1498Szrj       gcc_checking_assert (wi::ltu_p (wi::to_offset (cookie_size), max_size));
301038fd1498Szrj       /* Unconditionally subtract the cookie size.  This decreases the
301138fd1498Szrj 	 maximum object size and is safe even if we choose not to use
301238fd1498Szrj 	 a cookie after all.  */
301338fd1498Szrj       max_size -= wi::to_offset (cookie_size);
301438fd1498Szrj       bool overflow;
301538fd1498Szrj       inner_size = wi::mul (wi::to_offset (size), inner_nelts_count, SIGNED,
301638fd1498Szrj 			    &overflow);
301738fd1498Szrj       if (overflow || wi::gtu_p (inner_size, max_size))
301838fd1498Szrj 	{
301938fd1498Szrj 	  if (complain & tf_error)
302038fd1498Szrj 	    error ("size of array is too large");
302138fd1498Szrj 	  return error_mark_node;
302238fd1498Szrj 	}
302338fd1498Szrj 
302438fd1498Szrj       max_outer_nelts = wi::udiv_trunc (max_size, inner_size);
302538fd1498Szrj       max_outer_nelts_tree = wide_int_to_tree (sizetype, max_outer_nelts);
302638fd1498Szrj 
302738fd1498Szrj       size = size_binop (MULT_EXPR, size, fold_convert (sizetype, nelts));
302838fd1498Szrj 
3029*58e805e6Szrj       if (TREE_CODE (cst_outer_nelts) == INTEGER_CST)
303038fd1498Szrj 	{
3031*58e805e6Szrj 	  if (tree_int_cst_lt (max_outer_nelts_tree, cst_outer_nelts))
303238fd1498Szrj 	    {
303338fd1498Szrj 	      /* When the array size is constant, check it at compile time
303438fd1498Szrj 		 to make sure it doesn't exceed the implementation-defined
303538fd1498Szrj 		 maximum, as required by C++ 14 (in C++ 11 this requirement
303638fd1498Szrj 		 isn't explicitly stated but it's enforced anyway -- see
303738fd1498Szrj 		 grokdeclarator in cp/decl.c).  */
303838fd1498Szrj 	      if (complain & tf_error)
303938fd1498Szrj 		error ("size of array is too large");
304038fd1498Szrj 	      return error_mark_node;
304138fd1498Szrj 	    }
304238fd1498Szrj 	}
304338fd1498Szrj       else
304438fd1498Szrj  	{
304538fd1498Szrj 	  /* When a runtime check is necessary because the array size
304638fd1498Szrj 	     isn't constant, keep only the top-most seven bits (starting
304738fd1498Szrj 	     with the most significant non-zero bit) of the maximum size
304838fd1498Szrj 	     to compare the array size against, to simplify encoding the
304938fd1498Szrj 	     constant maximum size in the instruction stream.  */
305038fd1498Szrj 
305138fd1498Szrj 	  unsigned shift = (max_outer_nelts.get_precision ()) - 7
305238fd1498Szrj 	    - wi::clz (max_outer_nelts);
305338fd1498Szrj 	  max_outer_nelts = (max_outer_nelts >> shift) << shift;
305438fd1498Szrj 
305538fd1498Szrj           outer_nelts_check = fold_build2 (LE_EXPR, boolean_type_node,
305638fd1498Szrj 					   outer_nelts,
305738fd1498Szrj 					   max_outer_nelts_tree);
305838fd1498Szrj 	}
305938fd1498Szrj     }
306038fd1498Szrj 
306138fd1498Szrj   tree align_arg = NULL_TREE;
306238fd1498Szrj   if (type_has_new_extended_alignment (elt_type))
306338fd1498Szrj     align_arg = build_int_cst (align_type_node, TYPE_ALIGN_UNIT (elt_type));
306438fd1498Szrj 
306538fd1498Szrj   alloc_fn = NULL_TREE;
306638fd1498Szrj 
306738fd1498Szrj   /* If PLACEMENT is a single simple pointer type not passed by
306838fd1498Szrj      reference, prepare to capture it in a temporary variable.  Do
306938fd1498Szrj      this now, since PLACEMENT will change in the calls below.  */
307038fd1498Szrj   placement_first = NULL_TREE;
307138fd1498Szrj   if (vec_safe_length (*placement) == 1
307238fd1498Szrj       && (TYPE_PTR_P (TREE_TYPE ((**placement)[0]))))
307338fd1498Szrj     placement_first = (**placement)[0];
307438fd1498Szrj 
307538fd1498Szrj   bool member_new_p = false;
307638fd1498Szrj 
307738fd1498Szrj   /* Allocate the object.  */
307838fd1498Szrj   tree fnname;
307938fd1498Szrj   tree fns;
308038fd1498Szrj 
308138fd1498Szrj   fnname = ovl_op_identifier (false, array_p ? VEC_NEW_EXPR : NEW_EXPR);
308238fd1498Szrj 
308338fd1498Szrj   member_new_p = !globally_qualified_p
308438fd1498Szrj 		 && CLASS_TYPE_P (elt_type)
308538fd1498Szrj 		 && (array_p
308638fd1498Szrj 		     ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type)
308738fd1498Szrj 		     : TYPE_HAS_NEW_OPERATOR (elt_type));
308838fd1498Szrj 
308938fd1498Szrj   if (member_new_p)
309038fd1498Szrj     {
309138fd1498Szrj       /* Use a class-specific operator new.  */
309238fd1498Szrj       /* If a cookie is required, add some extra space.  */
309338fd1498Szrj       if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
309438fd1498Szrj 	size = size_binop (PLUS_EXPR, size, cookie_size);
309538fd1498Szrj       else
309638fd1498Szrj 	{
309738fd1498Szrj 	  cookie_size = NULL_TREE;
309838fd1498Szrj 	  /* No size arithmetic necessary, so the size check is
309938fd1498Szrj 	     not needed. */
310038fd1498Szrj 	  if (outer_nelts_check != NULL && inner_size == 1)
310138fd1498Szrj 	    outer_nelts_check = NULL_TREE;
310238fd1498Szrj 	}
310338fd1498Szrj       /* Perform the overflow check.  */
310438fd1498Szrj       tree errval = TYPE_MAX_VALUE (sizetype);
310538fd1498Szrj       if (cxx_dialect >= cxx11 && flag_exceptions)
310638fd1498Szrj 	errval = throw_bad_array_new_length ();
310738fd1498Szrj       if (outer_nelts_check != NULL_TREE)
310838fd1498Szrj 	size = fold_build3 (COND_EXPR, sizetype, outer_nelts_check,
310938fd1498Szrj 			    size, errval);
311038fd1498Szrj       /* Create the argument list.  */
311138fd1498Szrj       vec_safe_insert (*placement, 0, size);
311238fd1498Szrj       /* Do name-lookup to find the appropriate operator.  */
311338fd1498Szrj       fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
311438fd1498Szrj       if (fns == NULL_TREE)
311538fd1498Szrj 	{
311638fd1498Szrj 	  if (complain & tf_error)
311738fd1498Szrj 	    error ("no suitable %qD found in class %qT", fnname, elt_type);
311838fd1498Szrj 	  return error_mark_node;
311938fd1498Szrj 	}
312038fd1498Szrj       if (TREE_CODE (fns) == TREE_LIST)
312138fd1498Szrj 	{
312238fd1498Szrj 	  if (complain & tf_error)
312338fd1498Szrj 	    {
312438fd1498Szrj 	      error ("request for member %qD is ambiguous", fnname);
312538fd1498Szrj 	      print_candidates (fns);
312638fd1498Szrj 	    }
312738fd1498Szrj 	  return error_mark_node;
312838fd1498Szrj 	}
312938fd1498Szrj       tree dummy = build_dummy_object (elt_type);
313038fd1498Szrj       alloc_call = NULL_TREE;
313138fd1498Szrj       if (align_arg)
313238fd1498Szrj 	{
313338fd1498Szrj 	  vec<tree, va_gc> *align_args
313438fd1498Szrj 	    = vec_copy_and_insert (*placement, align_arg, 1);
313538fd1498Szrj 	  alloc_call
313638fd1498Szrj 	    = build_new_method_call (dummy, fns, &align_args,
313738fd1498Szrj 				     /*conversion_path=*/NULL_TREE,
313838fd1498Szrj 				     LOOKUP_NORMAL, &alloc_fn, tf_none);
313938fd1498Szrj 	  /* If no matching function is found and the allocated object type
314038fd1498Szrj 	     has new-extended alignment, the alignment argument is removed
314138fd1498Szrj 	     from the argument list, and overload resolution is performed
314238fd1498Szrj 	     again.  */
314338fd1498Szrj 	  if (alloc_call == error_mark_node)
314438fd1498Szrj 	    alloc_call = NULL_TREE;
314538fd1498Szrj 	}
314638fd1498Szrj       if (!alloc_call)
314738fd1498Szrj 	alloc_call = build_new_method_call (dummy, fns, placement,
314838fd1498Szrj 					    /*conversion_path=*/NULL_TREE,
314938fd1498Szrj 					    LOOKUP_NORMAL,
315038fd1498Szrj 					    &alloc_fn, complain);
315138fd1498Szrj     }
315238fd1498Szrj   else
315338fd1498Szrj     {
315438fd1498Szrj       /* Use a global operator new.  */
315538fd1498Szrj       /* See if a cookie might be required.  */
315638fd1498Szrj       if (!(array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type)))
315738fd1498Szrj 	{
315838fd1498Szrj 	  cookie_size = NULL_TREE;
315938fd1498Szrj 	  /* No size arithmetic necessary, so the size check is
316038fd1498Szrj 	     not needed. */
316138fd1498Szrj 	  if (outer_nelts_check != NULL && inner_size == 1)
316238fd1498Szrj 	    outer_nelts_check = NULL_TREE;
316338fd1498Szrj 	}
316438fd1498Szrj 
316538fd1498Szrj       alloc_call = build_operator_new_call (fnname, placement,
316638fd1498Szrj 					    &size, &cookie_size,
316738fd1498Szrj 					    align_arg, outer_nelts_check,
316838fd1498Szrj 					    &alloc_fn, complain);
316938fd1498Szrj     }
317038fd1498Szrj 
317138fd1498Szrj   if (alloc_call == error_mark_node)
317238fd1498Szrj     return error_mark_node;
317338fd1498Szrj 
317438fd1498Szrj   gcc_assert (alloc_fn != NULL_TREE);
317538fd1498Szrj 
317638fd1498Szrj   /* Now, check to see if this function is actually a placement
317738fd1498Szrj      allocation function.  This can happen even when PLACEMENT is NULL
317838fd1498Szrj      because we might have something like:
317938fd1498Szrj 
318038fd1498Szrj        struct S { void* operator new (size_t, int i = 0); };
318138fd1498Szrj 
318238fd1498Szrj      A call to `new S' will get this allocation function, even though
318338fd1498Szrj      there is no explicit placement argument.  If there is more than
318438fd1498Szrj      one argument, or there are variable arguments, then this is a
318538fd1498Szrj      placement allocation function.  */
318638fd1498Szrj   placement_allocation_fn_p
318738fd1498Szrj     = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
318838fd1498Szrj        || varargs_function_p (alloc_fn));
318938fd1498Szrj 
319038fd1498Szrj   if (warn_aligned_new
319138fd1498Szrj       && !placement_allocation_fn_p
319238fd1498Szrj       && TYPE_ALIGN (elt_type) > malloc_alignment ()
319338fd1498Szrj       && (warn_aligned_new > 1
319438fd1498Szrj 	  || CP_DECL_CONTEXT (alloc_fn) == global_namespace)
319538fd1498Szrj       && !aligned_allocation_fn_p (alloc_fn))
319638fd1498Szrj     {
319738fd1498Szrj       if (warning (OPT_Waligned_new_, "%<new%> of type %qT with extended "
319838fd1498Szrj 		   "alignment %d", elt_type, TYPE_ALIGN_UNIT (elt_type)))
319938fd1498Szrj 	{
320038fd1498Szrj 	  inform (input_location, "uses %qD, which does not have an alignment "
320138fd1498Szrj 		  "parameter", alloc_fn);
320238fd1498Szrj 	  if (!aligned_new_threshold)
320338fd1498Szrj 	    inform (input_location, "use %<-faligned-new%> to enable C++17 "
320438fd1498Szrj 				    "over-aligned new support");
320538fd1498Szrj 	}
320638fd1498Szrj     }
320738fd1498Szrj 
320838fd1498Szrj   /* If we found a simple case of PLACEMENT_EXPR above, then copy it
320938fd1498Szrj      into a temporary variable.  */
321038fd1498Szrj   if (!processing_template_decl
321138fd1498Szrj       && TREE_CODE (alloc_call) == CALL_EXPR
321238fd1498Szrj       && call_expr_nargs (alloc_call) == 2
321338fd1498Szrj       && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
321438fd1498Szrj       && TYPE_PTR_P (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 1))))
321538fd1498Szrj     {
321638fd1498Szrj       tree placement = CALL_EXPR_ARG (alloc_call, 1);
321738fd1498Szrj 
321838fd1498Szrj       if (placement_first != NULL_TREE
321938fd1498Szrj 	  && (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (TREE_TYPE (placement)))
322038fd1498Szrj 	      || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement)))))
322138fd1498Szrj 	{
322238fd1498Szrj 	  placement_expr = get_target_expr (placement_first);
322338fd1498Szrj 	  CALL_EXPR_ARG (alloc_call, 1)
322438fd1498Szrj 	    = fold_convert (TREE_TYPE (placement), placement_expr);
322538fd1498Szrj 	}
322638fd1498Szrj 
322738fd1498Szrj       if (!member_new_p
322838fd1498Szrj 	  && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 1)))))
322938fd1498Szrj 	{
323038fd1498Szrj 	  /* Attempt to make the warning point at the operator new argument.  */
323138fd1498Szrj 	  if (placement_first)
323238fd1498Szrj 	    placement = placement_first;
323338fd1498Szrj 
323438fd1498Szrj 	  warn_placement_new_too_small (orig_type, nelts, size, placement);
323538fd1498Szrj 	}
323638fd1498Szrj     }
323738fd1498Szrj 
323838fd1498Szrj   /* In the simple case, we can stop now.  */
323938fd1498Szrj   pointer_type = build_pointer_type (type);
324038fd1498Szrj   if (!cookie_size && !is_initialized)
324138fd1498Szrj     return build_nop (pointer_type, alloc_call);
324238fd1498Szrj 
324338fd1498Szrj   /* Store the result of the allocation call in a variable so that we can
324438fd1498Szrj      use it more than once.  */
324538fd1498Szrj   alloc_expr = get_target_expr (alloc_call);
324638fd1498Szrj   alloc_node = TARGET_EXPR_SLOT (alloc_expr);
324738fd1498Szrj 
324838fd1498Szrj   /* Strip any COMPOUND_EXPRs from ALLOC_CALL.  */
324938fd1498Szrj   while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
325038fd1498Szrj     alloc_call = TREE_OPERAND (alloc_call, 1);
325138fd1498Szrj 
325238fd1498Szrj   /* Preevaluate the placement args so that we don't reevaluate them for a
325338fd1498Szrj      placement delete.  */
325438fd1498Szrj   if (placement_allocation_fn_p)
325538fd1498Szrj     {
325638fd1498Szrj       tree inits;
325738fd1498Szrj       stabilize_call (alloc_call, &inits);
325838fd1498Szrj       if (inits)
325938fd1498Szrj 	alloc_expr = build2 (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
326038fd1498Szrj 			     alloc_expr);
326138fd1498Szrj     }
326238fd1498Szrj 
326338fd1498Szrj   /*        unless an allocation function is declared with an empty  excep-
326438fd1498Szrj      tion-specification  (_except.spec_),  throw(), it indicates failure to
326538fd1498Szrj      allocate storage by throwing a bad_alloc exception  (clause  _except_,
326638fd1498Szrj      _lib.bad.alloc_); it returns a non-null pointer otherwise If the allo-
326738fd1498Szrj      cation function is declared  with  an  empty  exception-specification,
326838fd1498Szrj      throw(), it returns null to indicate failure to allocate storage and a
326938fd1498Szrj      non-null pointer otherwise.
327038fd1498Szrj 
327138fd1498Szrj      So check for a null exception spec on the op new we just called.  */
327238fd1498Szrj 
327338fd1498Szrj   nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
327438fd1498Szrj   check_new
327538fd1498Szrj     = flag_check_new || (nothrow && !std_placement_new_fn_p (alloc_fn));
327638fd1498Szrj 
327738fd1498Szrj   if (cookie_size)
327838fd1498Szrj     {
327938fd1498Szrj       tree cookie;
328038fd1498Szrj       tree cookie_ptr;
328138fd1498Szrj       tree size_ptr_type;
328238fd1498Szrj 
328338fd1498Szrj       /* Adjust so we're pointing to the start of the object.  */
328438fd1498Szrj       data_addr = fold_build_pointer_plus (alloc_node, cookie_size);
328538fd1498Szrj 
328638fd1498Szrj       /* Store the number of bytes allocated so that we can know how
328738fd1498Szrj 	 many elements to destroy later.  We use the last sizeof
328838fd1498Szrj 	 (size_t) bytes to store the number of elements.  */
328938fd1498Szrj       cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
329038fd1498Szrj       cookie_ptr = fold_build_pointer_plus_loc (input_location,
329138fd1498Szrj 						alloc_node, cookie_ptr);
329238fd1498Szrj       size_ptr_type = build_pointer_type (sizetype);
329338fd1498Szrj       cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
329438fd1498Szrj       cookie = cp_build_fold_indirect_ref (cookie_ptr);
329538fd1498Szrj 
329638fd1498Szrj       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
329738fd1498Szrj 
329838fd1498Szrj       if (targetm.cxx.cookie_has_size ())
329938fd1498Szrj 	{
330038fd1498Szrj 	  /* Also store the element size.  */
330138fd1498Szrj 	  cookie_ptr = fold_build_pointer_plus (cookie_ptr,
330238fd1498Szrj 			       fold_build1_loc (input_location,
330338fd1498Szrj 						NEGATE_EXPR, sizetype,
330438fd1498Szrj 						size_in_bytes (sizetype)));
330538fd1498Szrj 
330638fd1498Szrj 	  cookie = cp_build_fold_indirect_ref (cookie_ptr);
330738fd1498Szrj 	  cookie = build2 (MODIFY_EXPR, sizetype, cookie,
330838fd1498Szrj 			   size_in_bytes (elt_type));
330938fd1498Szrj 	  cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
331038fd1498Szrj 				cookie, cookie_expr);
331138fd1498Szrj 	}
331238fd1498Szrj     }
331338fd1498Szrj   else
331438fd1498Szrj     {
331538fd1498Szrj       cookie_expr = NULL_TREE;
331638fd1498Szrj       data_addr = alloc_node;
331738fd1498Szrj     }
331838fd1498Szrj 
331938fd1498Szrj   /* Now use a pointer to the type we've actually allocated.  */
332038fd1498Szrj 
332138fd1498Szrj   /* But we want to operate on a non-const version to start with,
332238fd1498Szrj      since we'll be modifying the elements.  */
332338fd1498Szrj   non_const_pointer_type = build_pointer_type
332438fd1498Szrj     (cp_build_qualified_type (type, cp_type_quals (type) & ~TYPE_QUAL_CONST));
332538fd1498Szrj 
332638fd1498Szrj   data_addr = fold_convert (non_const_pointer_type, data_addr);
332738fd1498Szrj   /* Any further uses of alloc_node will want this type, too.  */
332838fd1498Szrj   alloc_node = fold_convert (non_const_pointer_type, alloc_node);
332938fd1498Szrj 
333038fd1498Szrj   /* Now initialize the allocated object.  Note that we preevaluate the
333138fd1498Szrj      initialization expression, apart from the actual constructor call or
333238fd1498Szrj      assignment--we do this because we want to delay the allocation as long
333338fd1498Szrj      as possible in order to minimize the size of the exception region for
333438fd1498Szrj      placement delete.  */
333538fd1498Szrj   if (is_initialized)
333638fd1498Szrj     {
333738fd1498Szrj       bool stable;
333838fd1498Szrj       bool explicit_value_init_p = false;
333938fd1498Szrj 
334038fd1498Szrj       if (*init != NULL && (*init)->is_empty ())
334138fd1498Szrj 	{
334238fd1498Szrj 	  *init = NULL;
334338fd1498Szrj 	  explicit_value_init_p = true;
334438fd1498Szrj 	}
334538fd1498Szrj 
334638fd1498Szrj       if (processing_template_decl && explicit_value_init_p)
334738fd1498Szrj 	{
334838fd1498Szrj 	  /* build_value_init doesn't work in templates, and we don't need
334938fd1498Szrj 	     the initializer anyway since we're going to throw it away and
335038fd1498Szrj 	     rebuild it at instantiation time, so just build up a single
335138fd1498Szrj 	     constructor call to get any appropriate diagnostics.  */
335238fd1498Szrj 	  init_expr = cp_build_fold_indirect_ref (data_addr);
335338fd1498Szrj 	  if (type_build_ctor_call (elt_type))
335438fd1498Szrj 	    init_expr = build_special_member_call (init_expr,
335538fd1498Szrj 						   complete_ctor_identifier,
335638fd1498Szrj 						   init, elt_type,
335738fd1498Szrj 						   LOOKUP_NORMAL,
335838fd1498Szrj 						   complain);
335938fd1498Szrj 	  stable = stabilize_init (init_expr, &init_preeval_expr);
336038fd1498Szrj 	}
336138fd1498Szrj       else if (array_p)
336238fd1498Szrj 	{
336338fd1498Szrj 	  tree vecinit = NULL_TREE;
336438fd1498Szrj 	  if (vec_safe_length (*init) == 1
336538fd1498Szrj 	      && DIRECT_LIST_INIT_P ((**init)[0]))
336638fd1498Szrj 	    {
336738fd1498Szrj 	      vecinit = (**init)[0];
336838fd1498Szrj 	      if (CONSTRUCTOR_NELTS (vecinit) == 0)
336938fd1498Szrj 		/* List-value-initialization, leave it alone.  */;
337038fd1498Szrj 	      else
337138fd1498Szrj 		{
337238fd1498Szrj 		  tree arraytype, domain;
337338fd1498Szrj 		  if (TREE_CONSTANT (nelts))
337438fd1498Szrj 		    domain = compute_array_index_type (NULL_TREE, nelts,
337538fd1498Szrj 						       complain);
337638fd1498Szrj 		  else
337738fd1498Szrj 		    /* We'll check the length at runtime.  */
337838fd1498Szrj 		    domain = NULL_TREE;
337938fd1498Szrj 		  arraytype = build_cplus_array_type (type, domain);
338038fd1498Szrj 		  vecinit = digest_init (arraytype, vecinit, complain);
338138fd1498Szrj 		}
338238fd1498Szrj 	    }
338338fd1498Szrj 	  else if (*init)
338438fd1498Szrj             {
338538fd1498Szrj               if (complain & tf_error)
338638fd1498Szrj                 error ("parenthesized initializer in array new");
338738fd1498Szrj 	      return error_mark_node;
338838fd1498Szrj             }
338938fd1498Szrj 	  init_expr
339038fd1498Szrj 	    = build_vec_init (data_addr,
339138fd1498Szrj 			      cp_build_binary_op (input_location,
339238fd1498Szrj 						  MINUS_EXPR, outer_nelts,
339338fd1498Szrj 						  integer_one_node,
339438fd1498Szrj 						  complain),
339538fd1498Szrj 			      vecinit,
339638fd1498Szrj 			      explicit_value_init_p,
339738fd1498Szrj 			      /*from_array=*/0,
339838fd1498Szrj                               complain);
339938fd1498Szrj 
340038fd1498Szrj 	  /* An array initialization is stable because the initialization
340138fd1498Szrj 	     of each element is a full-expression, so the temporaries don't
340238fd1498Szrj 	     leak out.  */
340338fd1498Szrj 	  stable = true;
340438fd1498Szrj 	}
340538fd1498Szrj       else
340638fd1498Szrj 	{
340738fd1498Szrj 	  init_expr = cp_build_fold_indirect_ref (data_addr);
340838fd1498Szrj 
340938fd1498Szrj 	  if (type_build_ctor_call (type) && !explicit_value_init_p)
341038fd1498Szrj 	    {
341138fd1498Szrj 	      init_expr = build_special_member_call (init_expr,
341238fd1498Szrj 						     complete_ctor_identifier,
341338fd1498Szrj 						     init, elt_type,
341438fd1498Szrj 						     LOOKUP_NORMAL,
341538fd1498Szrj                                                      complain);
341638fd1498Szrj 	    }
341738fd1498Szrj 	  else if (explicit_value_init_p)
341838fd1498Szrj 	    {
341938fd1498Szrj 	      /* Something like `new int()'.  NO_CLEANUP is needed so
342038fd1498Szrj 		 we don't try and build a (possibly ill-formed)
342138fd1498Szrj 		 destructor.  */
342238fd1498Szrj 	      tree val = build_value_init (type, complain | tf_no_cleanup);
342338fd1498Szrj 	      if (val == error_mark_node)
342438fd1498Szrj 		return error_mark_node;
342538fd1498Szrj 	      init_expr = build2 (INIT_EXPR, type, init_expr, val);
342638fd1498Szrj 	    }
342738fd1498Szrj 	  else
342838fd1498Szrj 	    {
342938fd1498Szrj 	      tree ie;
343038fd1498Szrj 
343138fd1498Szrj 	      /* We are processing something like `new int (10)', which
343238fd1498Szrj 		 means allocate an int, and initialize it with 10.  */
343338fd1498Szrj 
343438fd1498Szrj 	      ie = build_x_compound_expr_from_vec (*init, "new initializer",
343538fd1498Szrj 						   complain);
343638fd1498Szrj 	      init_expr = cp_build_modify_expr (input_location, init_expr,
343738fd1498Szrj 						INIT_EXPR, ie, complain);
343838fd1498Szrj 	    }
343938fd1498Szrj 	  /* If the initializer uses C++14 aggregate NSDMI that refer to the
344038fd1498Szrj 	     object being initialized, replace them now and don't try to
344138fd1498Szrj 	     preevaluate.  */
344238fd1498Szrj 	  bool had_placeholder = false;
344338fd1498Szrj 	  if (!processing_template_decl
344438fd1498Szrj 	      && TREE_CODE (init_expr) == INIT_EXPR)
344538fd1498Szrj 	    TREE_OPERAND (init_expr, 1)
344638fd1498Szrj 	      = replace_placeholders (TREE_OPERAND (init_expr, 1),
344738fd1498Szrj 				      TREE_OPERAND (init_expr, 0),
344838fd1498Szrj 				      &had_placeholder);
344938fd1498Szrj 	  stable = (!had_placeholder
345038fd1498Szrj 		    && stabilize_init (init_expr, &init_preeval_expr));
345138fd1498Szrj 	}
345238fd1498Szrj 
345338fd1498Szrj       if (init_expr == error_mark_node)
345438fd1498Szrj 	return error_mark_node;
345538fd1498Szrj 
345638fd1498Szrj       /* If any part of the object initialization terminates by throwing an
345738fd1498Szrj 	 exception and a suitable deallocation function can be found, the
345838fd1498Szrj 	 deallocation function is called to free the memory in which the
345938fd1498Szrj 	 object was being constructed, after which the exception continues
346038fd1498Szrj 	 to propagate in the context of the new-expression. If no
346138fd1498Szrj 	 unambiguous matching deallocation function can be found,
346238fd1498Szrj 	 propagating the exception does not cause the object's memory to be
346338fd1498Szrj 	 freed.  */
346438fd1498Szrj       if (flag_exceptions)
346538fd1498Szrj 	{
346638fd1498Szrj 	  enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR;
346738fd1498Szrj 	  tree cleanup;
346838fd1498Szrj 
346938fd1498Szrj 	  /* The Standard is unclear here, but the right thing to do
347038fd1498Szrj 	     is to use the same method for finding deallocation
347138fd1498Szrj 	     functions that we use for finding allocation functions.  */
347238fd1498Szrj 	  cleanup = (build_op_delete_call
347338fd1498Szrj 		     (dcode,
347438fd1498Szrj 		      alloc_node,
347538fd1498Szrj 		      size,
347638fd1498Szrj 		      globally_qualified_p,
347738fd1498Szrj 		      placement_allocation_fn_p ? alloc_call : NULL_TREE,
347838fd1498Szrj 		      alloc_fn,
347938fd1498Szrj 		      complain));
348038fd1498Szrj 
348138fd1498Szrj 	  if (!cleanup)
348238fd1498Szrj 	    /* We're done.  */;
348338fd1498Szrj 	  else if (stable)
348438fd1498Szrj 	    /* This is much simpler if we were able to preevaluate all of
348538fd1498Szrj 	       the arguments to the constructor call.  */
348638fd1498Szrj 	    {
348738fd1498Szrj 	      /* CLEANUP is compiler-generated, so no diagnostics.  */
348838fd1498Szrj 	      TREE_NO_WARNING (cleanup) = true;
348938fd1498Szrj 	      init_expr = build2 (TRY_CATCH_EXPR, void_type_node,
349038fd1498Szrj 				  init_expr, cleanup);
349138fd1498Szrj 	      /* Likewise, this try-catch is compiler-generated.  */
349238fd1498Szrj 	      TREE_NO_WARNING (init_expr) = true;
349338fd1498Szrj 	    }
349438fd1498Szrj 	  else
349538fd1498Szrj 	    /* Ack!  First we allocate the memory.  Then we set our sentry
349638fd1498Szrj 	       variable to true, and expand a cleanup that deletes the
349738fd1498Szrj 	       memory if sentry is true.  Then we run the constructor, and
349838fd1498Szrj 	       finally clear the sentry.
349938fd1498Szrj 
350038fd1498Szrj 	       We need to do this because we allocate the space first, so
350138fd1498Szrj 	       if there are any temporaries with cleanups in the
350238fd1498Szrj 	       constructor args and we weren't able to preevaluate them, we
350338fd1498Szrj 	       need this EH region to extend until end of full-expression
350438fd1498Szrj 	       to preserve nesting.  */
350538fd1498Szrj 	    {
350638fd1498Szrj 	      tree end, sentry, begin;
350738fd1498Szrj 
350838fd1498Szrj 	      begin = get_target_expr (boolean_true_node);
350938fd1498Szrj 	      CLEANUP_EH_ONLY (begin) = 1;
351038fd1498Szrj 
351138fd1498Szrj 	      sentry = TARGET_EXPR_SLOT (begin);
351238fd1498Szrj 
351338fd1498Szrj 	      /* CLEANUP is compiler-generated, so no diagnostics.  */
351438fd1498Szrj 	      TREE_NO_WARNING (cleanup) = true;
351538fd1498Szrj 
351638fd1498Szrj 	      TARGET_EXPR_CLEANUP (begin)
351738fd1498Szrj 		= build3 (COND_EXPR, void_type_node, sentry,
351838fd1498Szrj 			  cleanup, void_node);
351938fd1498Szrj 
352038fd1498Szrj 	      end = build2 (MODIFY_EXPR, TREE_TYPE (sentry),
352138fd1498Szrj 			    sentry, boolean_false_node);
352238fd1498Szrj 
352338fd1498Szrj 	      init_expr
352438fd1498Szrj 		= build2 (COMPOUND_EXPR, void_type_node, begin,
352538fd1498Szrj 			  build2 (COMPOUND_EXPR, void_type_node, init_expr,
352638fd1498Szrj 				  end));
352738fd1498Szrj 	      /* Likewise, this is compiler-generated.  */
352838fd1498Szrj 	      TREE_NO_WARNING (init_expr) = true;
352938fd1498Szrj 	    }
353038fd1498Szrj 	}
353138fd1498Szrj     }
353238fd1498Szrj   else
353338fd1498Szrj     init_expr = NULL_TREE;
353438fd1498Szrj 
353538fd1498Szrj   /* Now build up the return value in reverse order.  */
353638fd1498Szrj 
353738fd1498Szrj   rval = data_addr;
353838fd1498Szrj 
353938fd1498Szrj   if (init_expr)
354038fd1498Szrj     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval);
354138fd1498Szrj   if (cookie_expr)
354238fd1498Szrj     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
354338fd1498Szrj 
354438fd1498Szrj   if (rval == data_addr)
354538fd1498Szrj     /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
354638fd1498Szrj        and return the call (which doesn't need to be adjusted).  */
354738fd1498Szrj     rval = TARGET_EXPR_INITIAL (alloc_expr);
354838fd1498Szrj   else
354938fd1498Szrj     {
355038fd1498Szrj       if (check_new)
355138fd1498Szrj 	{
355238fd1498Szrj 	  tree ifexp = cp_build_binary_op (input_location,
355338fd1498Szrj 					   NE_EXPR, alloc_node,
355438fd1498Szrj 					   nullptr_node,
355538fd1498Szrj 					   complain);
355638fd1498Szrj 	  rval = build_conditional_expr (input_location, ifexp, rval,
355738fd1498Szrj 					 alloc_node, complain);
355838fd1498Szrj 	}
355938fd1498Szrj 
356038fd1498Szrj       /* Perform the allocation before anything else, so that ALLOC_NODE
356138fd1498Szrj 	 has been initialized before we start using it.  */
356238fd1498Szrj       rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
356338fd1498Szrj     }
356438fd1498Szrj 
356538fd1498Szrj   if (init_preeval_expr)
356638fd1498Szrj     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
356738fd1498Szrj 
356838fd1498Szrj   /* A new-expression is never an lvalue.  */
356938fd1498Szrj   gcc_assert (!obvalue_p (rval));
357038fd1498Szrj 
357138fd1498Szrj   return convert (pointer_type, rval);
357238fd1498Szrj }
357338fd1498Szrj 
357438fd1498Szrj /* Generate a representation for a C++ "new" expression.  *PLACEMENT
357538fd1498Szrj    is a vector of placement-new arguments (or NULL if none).  If NELTS
357638fd1498Szrj    is NULL, TYPE is the type of the storage to be allocated.  If NELTS
357738fd1498Szrj    is not NULL, then this is an array-new allocation; TYPE is the type
357838fd1498Szrj    of the elements in the array and NELTS is the number of elements in
357938fd1498Szrj    the array.  *INIT, if non-NULL, is the initializer for the new
358038fd1498Szrj    object, or an empty vector to indicate an initializer of "()".  If
358138fd1498Szrj    USE_GLOBAL_NEW is true, then the user explicitly wrote "::new"
358238fd1498Szrj    rather than just "new".  This may change PLACEMENT and INIT.  */
358338fd1498Szrj 
358438fd1498Szrj tree
build_new(vec<tree,va_gc> ** placement,tree type,tree nelts,vec<tree,va_gc> ** init,int use_global_new,tsubst_flags_t complain)358538fd1498Szrj build_new (vec<tree, va_gc> **placement, tree type, tree nelts,
358638fd1498Szrj 	   vec<tree, va_gc> **init, int use_global_new, tsubst_flags_t complain)
358738fd1498Szrj {
358838fd1498Szrj   tree rval;
358938fd1498Szrj   vec<tree, va_gc> *orig_placement = NULL;
359038fd1498Szrj   tree orig_nelts = NULL_TREE;
359138fd1498Szrj   vec<tree, va_gc> *orig_init = NULL;
359238fd1498Szrj 
359338fd1498Szrj   if (type == error_mark_node)
359438fd1498Szrj     return error_mark_node;
359538fd1498Szrj 
359638fd1498Szrj   if (nelts == NULL_TREE
359738fd1498Szrj       /* Don't do auto deduction where it might affect mangling.  */
359838fd1498Szrj       && (!processing_template_decl || at_function_scope_p ()))
359938fd1498Szrj     {
360038fd1498Szrj       tree auto_node = type_uses_auto (type);
360138fd1498Szrj       if (auto_node)
360238fd1498Szrj 	{
360338fd1498Szrj 	  tree d_init = NULL_TREE;
360438fd1498Szrj 	  if (vec_safe_length (*init) == 1)
360538fd1498Szrj 	    {
360638fd1498Szrj 	      d_init = (**init)[0];
360738fd1498Szrj 	      d_init = resolve_nondeduced_context (d_init, complain);
360838fd1498Szrj 	    }
360938fd1498Szrj 	  type = do_auto_deduction (type, d_init, auto_node, complain);
361038fd1498Szrj 	}
361138fd1498Szrj     }
361238fd1498Szrj 
361338fd1498Szrj   if (processing_template_decl)
361438fd1498Szrj     {
361538fd1498Szrj       if (dependent_type_p (type)
361638fd1498Szrj 	  || any_type_dependent_arguments_p (*placement)
361738fd1498Szrj 	  || (nelts && type_dependent_expression_p (nelts))
361838fd1498Szrj 	  || (nelts && *init)
361938fd1498Szrj 	  || any_type_dependent_arguments_p (*init))
362038fd1498Szrj 	return build_raw_new_expr (*placement, type, nelts, *init,
362138fd1498Szrj 				   use_global_new);
362238fd1498Szrj 
362338fd1498Szrj       orig_placement = make_tree_vector_copy (*placement);
362438fd1498Szrj       orig_nelts = nelts;
362538fd1498Szrj       if (*init)
362638fd1498Szrj 	{
362738fd1498Szrj 	  orig_init = make_tree_vector_copy (*init);
362838fd1498Szrj 	  /* Also copy any CONSTRUCTORs in *init, since reshape_init and
362938fd1498Szrj 	     digest_init clobber them in place.  */
363038fd1498Szrj 	  for (unsigned i = 0; i < orig_init->length(); ++i)
363138fd1498Szrj 	    {
363238fd1498Szrj 	      tree e = (**init)[i];
363338fd1498Szrj 	      if (TREE_CODE (e) == CONSTRUCTOR)
363438fd1498Szrj 		(**init)[i] = copy_node (e);
363538fd1498Szrj 	    }
363638fd1498Szrj 	}
363738fd1498Szrj 
363838fd1498Szrj       make_args_non_dependent (*placement);
363938fd1498Szrj       if (nelts)
364038fd1498Szrj 	nelts = build_non_dependent_expr (nelts);
364138fd1498Szrj       make_args_non_dependent (*init);
364238fd1498Szrj     }
364338fd1498Szrj 
364438fd1498Szrj   if (nelts)
364538fd1498Szrj     {
364638fd1498Szrj       if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
364738fd1498Szrj         {
364838fd1498Szrj           if (complain & tf_error)
364938fd1498Szrj             permerror (input_location, "size in array new must have integral type");
365038fd1498Szrj           else
365138fd1498Szrj             return error_mark_node;
365238fd1498Szrj         }
365338fd1498Szrj 
365438fd1498Szrj       /* Try to determine the constant value only for the purposes
365538fd1498Szrj 	 of the diagnostic below but continue to use the original
365638fd1498Szrj 	 value and handle const folding later.  */
3657*58e805e6Szrj       const_tree cst_nelts = fold_non_dependent_expr (nelts);
365838fd1498Szrj 
365938fd1498Szrj       /* The expression in a noptr-new-declarator is erroneous if it's of
366038fd1498Szrj 	 non-class type and its value before converting to std::size_t is
366138fd1498Szrj 	 less than zero. ... If the expression is a constant expression,
366238fd1498Szrj 	 the program is ill-fomed.  */
3663*58e805e6Szrj       if (TREE_CODE (cst_nelts) == INTEGER_CST
366438fd1498Szrj 	  && tree_int_cst_sgn (cst_nelts) == -1)
366538fd1498Szrj 	{
366638fd1498Szrj 	  if (complain & tf_error)
366738fd1498Szrj 	    error ("size of array is negative");
366838fd1498Szrj 	  return error_mark_node;
366938fd1498Szrj 	}
367038fd1498Szrj 
367138fd1498Szrj       nelts = mark_rvalue_use (nelts);
367238fd1498Szrj       nelts = cp_save_expr (cp_convert (sizetype, nelts, complain));
367338fd1498Szrj     }
367438fd1498Szrj 
367538fd1498Szrj   /* ``A reference cannot be created by the new operator.  A reference
367638fd1498Szrj      is not an object (8.2.2, 8.4.3), so a pointer to it could not be
367738fd1498Szrj      returned by new.'' ARM 5.3.3 */
367838fd1498Szrj   if (TREE_CODE (type) == REFERENCE_TYPE)
367938fd1498Szrj     {
368038fd1498Szrj       if (complain & tf_error)
368138fd1498Szrj         error ("new cannot be applied to a reference type");
368238fd1498Szrj       else
368338fd1498Szrj         return error_mark_node;
368438fd1498Szrj       type = TREE_TYPE (type);
368538fd1498Szrj     }
368638fd1498Szrj 
368738fd1498Szrj   if (TREE_CODE (type) == FUNCTION_TYPE)
368838fd1498Szrj     {
368938fd1498Szrj       if (complain & tf_error)
369038fd1498Szrj         error ("new cannot be applied to a function type");
369138fd1498Szrj       return error_mark_node;
369238fd1498Szrj     }
369338fd1498Szrj 
369438fd1498Szrj   /* The type allocated must be complete.  If the new-type-id was
369538fd1498Szrj      "T[N]" then we are just checking that "T" is complete here, but
369638fd1498Szrj      that is equivalent, since the value of "N" doesn't matter.  */
369738fd1498Szrj   if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
369838fd1498Szrj     return error_mark_node;
369938fd1498Szrj 
370038fd1498Szrj   rval = build_new_1 (placement, type, nelts, init, use_global_new, complain);
370138fd1498Szrj   if (rval == error_mark_node)
370238fd1498Szrj     return error_mark_node;
370338fd1498Szrj 
370438fd1498Szrj   if (processing_template_decl)
370538fd1498Szrj     {
370638fd1498Szrj       tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
370738fd1498Szrj 				     orig_init, use_global_new);
370838fd1498Szrj       release_tree_vector (orig_placement);
370938fd1498Szrj       release_tree_vector (orig_init);
371038fd1498Szrj       return ret;
371138fd1498Szrj     }
371238fd1498Szrj 
371338fd1498Szrj   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
371438fd1498Szrj   rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
371538fd1498Szrj   TREE_NO_WARNING (rval) = 1;
371638fd1498Szrj 
371738fd1498Szrj   return rval;
371838fd1498Szrj }
371938fd1498Szrj 
372038fd1498Szrj static tree
build_vec_delete_1(tree base,tree maxindex,tree type,special_function_kind auto_delete_vec,int use_global_delete,tsubst_flags_t complain)372138fd1498Szrj build_vec_delete_1 (tree base, tree maxindex, tree type,
372238fd1498Szrj 		    special_function_kind auto_delete_vec,
372338fd1498Szrj 		    int use_global_delete, tsubst_flags_t complain)
372438fd1498Szrj {
372538fd1498Szrj   tree virtual_size;
372638fd1498Szrj   tree ptype = build_pointer_type (type = complete_type (type));
372738fd1498Szrj   tree size_exp;
372838fd1498Szrj 
372938fd1498Szrj   /* Temporary variables used by the loop.  */
373038fd1498Szrj   tree tbase, tbase_init;
373138fd1498Szrj 
373238fd1498Szrj   /* This is the body of the loop that implements the deletion of a
373338fd1498Szrj      single element, and moves temp variables to next elements.  */
373438fd1498Szrj   tree body;
373538fd1498Szrj 
373638fd1498Szrj   /* This is the LOOP_EXPR that governs the deletion of the elements.  */
373738fd1498Szrj   tree loop = 0;
373838fd1498Szrj 
373938fd1498Szrj   /* This is the thing that governs what to do after the loop has run.  */
374038fd1498Szrj   tree deallocate_expr = 0;
374138fd1498Szrj 
374238fd1498Szrj   /* This is the BIND_EXPR which holds the outermost iterator of the
374338fd1498Szrj      loop.  It is convenient to set this variable up and test it before
374438fd1498Szrj      executing any other code in the loop.
374538fd1498Szrj      This is also the containing expression returned by this function.  */
374638fd1498Szrj   tree controller = NULL_TREE;
374738fd1498Szrj   tree tmp;
374838fd1498Szrj 
374938fd1498Szrj   /* We should only have 1-D arrays here.  */
375038fd1498Szrj   gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
375138fd1498Szrj 
375238fd1498Szrj   if (base == error_mark_node || maxindex == error_mark_node)
375338fd1498Szrj     return error_mark_node;
375438fd1498Szrj 
375538fd1498Szrj   if (!COMPLETE_TYPE_P (type))
375638fd1498Szrj     {
375738fd1498Szrj       if ((complain & tf_warning)
375838fd1498Szrj 	  && warning (OPT_Wdelete_incomplete,
375938fd1498Szrj 		      "possible problem detected in invocation of "
376038fd1498Szrj 		      "delete [] operator:"))
376138fd1498Szrj        {
376238fd1498Szrj          cxx_incomplete_type_diagnostic (base, type, DK_WARNING);
376338fd1498Szrj          inform (input_location, "neither the destructor nor the "
376438fd1498Szrj                  "class-specific operator delete [] will be called, "
376538fd1498Szrj                  "even if they are declared when the class is defined");
376638fd1498Szrj        }
376738fd1498Szrj       /* This size won't actually be used.  */
376838fd1498Szrj       size_exp = size_one_node;
376938fd1498Szrj       goto no_destructor;
377038fd1498Szrj     }
377138fd1498Szrj 
377238fd1498Szrj   size_exp = size_in_bytes (type);
377338fd1498Szrj 
377438fd1498Szrj   if (! MAYBE_CLASS_TYPE_P (type))
377538fd1498Szrj     goto no_destructor;
377638fd1498Szrj   else if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
377738fd1498Szrj     {
377838fd1498Szrj       /* Make sure the destructor is callable.  */
377938fd1498Szrj       if (type_build_dtor_call (type))
378038fd1498Szrj 	{
378138fd1498Szrj 	  tmp = build_delete (ptype, base, sfk_complete_destructor,
378238fd1498Szrj 			      LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
378338fd1498Szrj 			      complain);
378438fd1498Szrj 	  if (tmp == error_mark_node)
378538fd1498Szrj 	    return error_mark_node;
378638fd1498Szrj 	}
378738fd1498Szrj       goto no_destructor;
378838fd1498Szrj     }
378938fd1498Szrj 
379038fd1498Szrj   /* The below is short by the cookie size.  */
379138fd1498Szrj   virtual_size = size_binop (MULT_EXPR, size_exp,
379238fd1498Szrj 			     fold_convert (sizetype, maxindex));
379338fd1498Szrj 
379438fd1498Szrj   tbase = create_temporary_var (ptype);
379538fd1498Szrj   tbase_init
379638fd1498Szrj     = cp_build_modify_expr (input_location, tbase, NOP_EXPR,
379738fd1498Szrj 			    fold_build_pointer_plus_loc (input_location,
379838fd1498Szrj 							 fold_convert (ptype,
379938fd1498Szrj 								       base),
380038fd1498Szrj 							 virtual_size),
380138fd1498Szrj 			    complain);
380238fd1498Szrj   if (tbase_init == error_mark_node)
380338fd1498Szrj     return error_mark_node;
380438fd1498Szrj   controller = build3 (BIND_EXPR, void_type_node, tbase,
380538fd1498Szrj 		       NULL_TREE, NULL_TREE);
380638fd1498Szrj   TREE_SIDE_EFFECTS (controller) = 1;
380738fd1498Szrj 
380838fd1498Szrj   body = build1 (EXIT_EXPR, void_type_node,
380938fd1498Szrj 		 build2 (EQ_EXPR, boolean_type_node, tbase,
381038fd1498Szrj 			 fold_convert (ptype, base)));
381138fd1498Szrj   tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
381238fd1498Szrj   tmp = fold_build_pointer_plus (tbase, tmp);
381338fd1498Szrj   tmp = cp_build_modify_expr (input_location, tbase, NOP_EXPR, tmp, complain);
381438fd1498Szrj   if (tmp == error_mark_node)
381538fd1498Szrj     return error_mark_node;
381638fd1498Szrj   body = build_compound_expr (input_location, body, tmp);
381738fd1498Szrj   tmp = build_delete (ptype, tbase, sfk_complete_destructor,
381838fd1498Szrj 		      LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
381938fd1498Szrj 		      complain);
382038fd1498Szrj   if (tmp == error_mark_node)
382138fd1498Szrj     return error_mark_node;
382238fd1498Szrj   body = build_compound_expr (input_location, body, tmp);
382338fd1498Szrj 
382438fd1498Szrj   loop = build1 (LOOP_EXPR, void_type_node, body);
382538fd1498Szrj   loop = build_compound_expr (input_location, tbase_init, loop);
382638fd1498Szrj 
382738fd1498Szrj  no_destructor:
382838fd1498Szrj   /* Delete the storage if appropriate.  */
382938fd1498Szrj   if (auto_delete_vec == sfk_deleting_destructor)
383038fd1498Szrj     {
383138fd1498Szrj       tree base_tbd;
383238fd1498Szrj 
383338fd1498Szrj       /* The below is short by the cookie size.  */
383438fd1498Szrj       virtual_size = size_binop (MULT_EXPR, size_exp,
383538fd1498Szrj 				 fold_convert (sizetype, maxindex));
383638fd1498Szrj 
383738fd1498Szrj       if (! TYPE_VEC_NEW_USES_COOKIE (type))
383838fd1498Szrj 	/* no header */
383938fd1498Szrj 	base_tbd = base;
384038fd1498Szrj       else
384138fd1498Szrj 	{
384238fd1498Szrj 	  tree cookie_size;
384338fd1498Szrj 
384438fd1498Szrj 	  cookie_size = targetm.cxx.get_cookie_size (type);
384538fd1498Szrj 	  base_tbd = cp_build_binary_op (input_location,
384638fd1498Szrj 					 MINUS_EXPR,
384738fd1498Szrj 					 cp_convert (string_type_node,
384838fd1498Szrj 						     base, complain),
384938fd1498Szrj 					 cookie_size,
385038fd1498Szrj 					 complain);
385138fd1498Szrj 	  if (base_tbd == error_mark_node)
385238fd1498Szrj 	    return error_mark_node;
385338fd1498Szrj 	  base_tbd = cp_convert (ptype, base_tbd, complain);
385438fd1498Szrj 	  /* True size with header.  */
385538fd1498Szrj 	  virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
385638fd1498Szrj 	}
385738fd1498Szrj 
385838fd1498Szrj       deallocate_expr = build_op_delete_call (VEC_DELETE_EXPR,
385938fd1498Szrj 					      base_tbd, virtual_size,
386038fd1498Szrj 					      use_global_delete & 1,
386138fd1498Szrj 					      /*placement=*/NULL_TREE,
386238fd1498Szrj 					      /*alloc_fn=*/NULL_TREE,
386338fd1498Szrj 					      complain);
386438fd1498Szrj     }
386538fd1498Szrj 
386638fd1498Szrj   body = loop;
386738fd1498Szrj   if (!deallocate_expr)
386838fd1498Szrj     ;
386938fd1498Szrj   else if (!body)
387038fd1498Szrj     body = deallocate_expr;
387138fd1498Szrj   else
387238fd1498Szrj     /* The delete operator mist be called, even if a destructor
387338fd1498Szrj        throws.  */
387438fd1498Szrj     body = build2 (TRY_FINALLY_EXPR, void_type_node, body, deallocate_expr);
387538fd1498Szrj 
387638fd1498Szrj   if (!body)
387738fd1498Szrj     body = integer_zero_node;
387838fd1498Szrj 
387938fd1498Szrj   /* Outermost wrapper: If pointer is null, punt.  */
388038fd1498Szrj   tree cond = build2_loc (input_location, NE_EXPR, boolean_type_node, base,
388138fd1498Szrj 			  fold_convert (TREE_TYPE (base), nullptr_node));
388238fd1498Szrj   /* This is a compiler generated comparison, don't emit
388338fd1498Szrj      e.g. -Wnonnull-compare warning for it.  */
388438fd1498Szrj   TREE_NO_WARNING (cond) = 1;
388538fd1498Szrj   body = build3_loc (input_location, COND_EXPR, void_type_node,
388638fd1498Szrj 		     cond, body, integer_zero_node);
388738fd1498Szrj   COND_EXPR_IS_VEC_DELETE (body) = true;
388838fd1498Szrj   body = build1 (NOP_EXPR, void_type_node, body);
388938fd1498Szrj 
389038fd1498Szrj   if (controller)
389138fd1498Szrj     {
389238fd1498Szrj       TREE_OPERAND (controller, 1) = body;
389338fd1498Szrj       body = controller;
389438fd1498Szrj     }
389538fd1498Szrj 
389638fd1498Szrj   if (TREE_CODE (base) == SAVE_EXPR)
389738fd1498Szrj     /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR.  */
389838fd1498Szrj     body = build2 (COMPOUND_EXPR, void_type_node, base, body);
389938fd1498Szrj 
390038fd1498Szrj   return convert_to_void (body, ICV_CAST, complain);
390138fd1498Szrj }
390238fd1498Szrj 
390338fd1498Szrj /* Create an unnamed variable of the indicated TYPE.  */
390438fd1498Szrj 
390538fd1498Szrj tree
create_temporary_var(tree type)390638fd1498Szrj create_temporary_var (tree type)
390738fd1498Szrj {
390838fd1498Szrj   tree decl;
390938fd1498Szrj 
391038fd1498Szrj   decl = build_decl (input_location,
391138fd1498Szrj 		     VAR_DECL, NULL_TREE, type);
391238fd1498Szrj   TREE_USED (decl) = 1;
391338fd1498Szrj   DECL_ARTIFICIAL (decl) = 1;
391438fd1498Szrj   DECL_IGNORED_P (decl) = 1;
391538fd1498Szrj   DECL_CONTEXT (decl) = current_function_decl;
391638fd1498Szrj 
391738fd1498Szrj   return decl;
391838fd1498Szrj }
391938fd1498Szrj 
392038fd1498Szrj /* Create a new temporary variable of the indicated TYPE, initialized
392138fd1498Szrj    to INIT.
392238fd1498Szrj 
392338fd1498Szrj    It is not entered into current_binding_level, because that breaks
392438fd1498Szrj    things when it comes time to do final cleanups (which take place
392538fd1498Szrj    "outside" the binding contour of the function).  */
392638fd1498Szrj 
392738fd1498Szrj tree
get_temp_regvar(tree type,tree init)392838fd1498Szrj get_temp_regvar (tree type, tree init)
392938fd1498Szrj {
393038fd1498Szrj   tree decl;
393138fd1498Szrj 
393238fd1498Szrj   decl = create_temporary_var (type);
393338fd1498Szrj   add_decl_expr (decl);
393438fd1498Szrj 
393538fd1498Szrj   finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR,
393638fd1498Szrj 					  init, tf_warning_or_error));
393738fd1498Szrj 
393838fd1498Szrj   return decl;
393938fd1498Szrj }
394038fd1498Szrj 
394138fd1498Szrj /* Subroutine of build_vec_init.  Returns true if assigning to an array of
394238fd1498Szrj    INNER_ELT_TYPE from INIT is trivial.  */
394338fd1498Szrj 
394438fd1498Szrj static bool
vec_copy_assign_is_trivial(tree inner_elt_type,tree init)394538fd1498Szrj vec_copy_assign_is_trivial (tree inner_elt_type, tree init)
394638fd1498Szrj {
394738fd1498Szrj   tree fromtype = inner_elt_type;
394838fd1498Szrj   if (lvalue_p (init))
394938fd1498Szrj     fromtype = cp_build_reference_type (fromtype, /*rval*/false);
395038fd1498Szrj   return is_trivially_xible (MODIFY_EXPR, inner_elt_type, fromtype);
395138fd1498Szrj }
395238fd1498Szrj 
395338fd1498Szrj /* Subroutine of build_vec_init: Check that the array has at least N
395438fd1498Szrj    elements.  Other parameters are local variables in build_vec_init.  */
395538fd1498Szrj 
395638fd1498Szrj void
finish_length_check(tree atype,tree iterator,tree obase,unsigned n)395738fd1498Szrj finish_length_check (tree atype, tree iterator, tree obase, unsigned n)
395838fd1498Szrj {
395938fd1498Szrj   tree nelts = build_int_cst (ptrdiff_type_node, n - 1);
396038fd1498Szrj   if (TREE_CODE (atype) != ARRAY_TYPE)
396138fd1498Szrj     {
396238fd1498Szrj       if (flag_exceptions)
396338fd1498Szrj 	{
396438fd1498Szrj 	  tree c = fold_build2 (LT_EXPR, boolean_type_node, iterator,
396538fd1498Szrj 				nelts);
396638fd1498Szrj 	  c = build3 (COND_EXPR, void_type_node, c,
396738fd1498Szrj 		      throw_bad_array_new_length (), void_node);
396838fd1498Szrj 	  finish_expr_stmt (c);
396938fd1498Szrj 	}
397038fd1498Szrj       /* Don't check an array new when -fno-exceptions.  */
397138fd1498Szrj     }
397238fd1498Szrj   else if (sanitize_flags_p (SANITIZE_BOUNDS)
397338fd1498Szrj 	   && current_function_decl != NULL_TREE)
397438fd1498Szrj     {
397538fd1498Szrj       /* Make sure the last element of the initializer is in bounds. */
397638fd1498Szrj       finish_expr_stmt
397738fd1498Szrj 	(ubsan_instrument_bounds
397838fd1498Szrj 	 (input_location, obase, &nelts, /*ignore_off_by_one*/false));
397938fd1498Szrj     }
398038fd1498Szrj }
398138fd1498Szrj 
398238fd1498Szrj /* `build_vec_init' returns tree structure that performs
398338fd1498Szrj    initialization of a vector of aggregate types.
398438fd1498Szrj 
398538fd1498Szrj    BASE is a reference to the vector, of ARRAY_TYPE, or a pointer
398638fd1498Szrj      to the first element, of POINTER_TYPE.
398738fd1498Szrj    MAXINDEX is the maximum index of the array (one less than the
398838fd1498Szrj      number of elements).  It is only used if BASE is a pointer or
398938fd1498Szrj      TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
399038fd1498Szrj 
399138fd1498Szrj    INIT is the (possibly NULL) initializer.
399238fd1498Szrj 
399338fd1498Szrj    If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL.  All
399438fd1498Szrj    elements in the array are value-initialized.
399538fd1498Szrj 
399638fd1498Szrj    FROM_ARRAY is 0 if we should init everything with INIT
399738fd1498Szrj    (i.e., every element initialized from INIT).
399838fd1498Szrj    FROM_ARRAY is 1 if we should index into INIT in parallel
399938fd1498Szrj    with initialization of DECL.
400038fd1498Szrj    FROM_ARRAY is 2 if we should index into INIT in parallel,
400138fd1498Szrj    but use assignment instead of initialization.  */
400238fd1498Szrj 
400338fd1498Szrj tree
build_vec_init(tree base,tree maxindex,tree init,bool explicit_value_init_p,int from_array,tsubst_flags_t complain)400438fd1498Szrj build_vec_init (tree base, tree maxindex, tree init,
400538fd1498Szrj 		bool explicit_value_init_p,
400638fd1498Szrj 		int from_array, tsubst_flags_t complain)
400738fd1498Szrj {
400838fd1498Szrj   tree rval;
400938fd1498Szrj   tree base2 = NULL_TREE;
401038fd1498Szrj   tree itype = NULL_TREE;
401138fd1498Szrj   tree iterator;
401238fd1498Szrj   /* The type of BASE.  */
401338fd1498Szrj   tree atype = TREE_TYPE (base);
401438fd1498Szrj   /* The type of an element in the array.  */
401538fd1498Szrj   tree type = TREE_TYPE (atype);
401638fd1498Szrj   /* The element type reached after removing all outer array
401738fd1498Szrj      types.  */
401838fd1498Szrj   tree inner_elt_type;
401938fd1498Szrj   /* The type of a pointer to an element in the array.  */
402038fd1498Szrj   tree ptype;
402138fd1498Szrj   tree stmt_expr;
402238fd1498Szrj   tree compound_stmt;
402338fd1498Szrj   int destroy_temps;
402438fd1498Szrj   tree try_block = NULL_TREE;
4025*58e805e6Szrj   HOST_WIDE_INT num_initialized_elts = 0;
402638fd1498Szrj   bool is_global;
402738fd1498Szrj   tree obase = base;
402838fd1498Szrj   bool xvalue = false;
402938fd1498Szrj   bool errors = false;
403038fd1498Szrj   location_t loc = (init ? EXPR_LOC_OR_LOC (init, input_location)
403138fd1498Szrj 		    : location_of (base));
403238fd1498Szrj 
403338fd1498Szrj   if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
403438fd1498Szrj     maxindex = array_type_nelts (atype);
403538fd1498Szrj 
403638fd1498Szrj   if (maxindex == NULL_TREE || maxindex == error_mark_node)
403738fd1498Szrj     return error_mark_node;
403838fd1498Szrj 
403938fd1498Szrj   maxindex = maybe_constant_value (maxindex);
404038fd1498Szrj   if (explicit_value_init_p)
404138fd1498Szrj     gcc_assert (!init);
404238fd1498Szrj 
404338fd1498Szrj   inner_elt_type = strip_array_types (type);
404438fd1498Szrj 
404538fd1498Szrj   /* Look through the TARGET_EXPR around a compound literal.  */
404638fd1498Szrj   if (init && TREE_CODE (init) == TARGET_EXPR
404738fd1498Szrj       && TREE_CODE (TARGET_EXPR_INITIAL (init)) == CONSTRUCTOR
404838fd1498Szrj       && from_array != 2)
404938fd1498Szrj     init = TARGET_EXPR_INITIAL (init);
405038fd1498Szrj 
405138fd1498Szrj   bool direct_init = false;
405238fd1498Szrj   if (from_array && init && BRACE_ENCLOSED_INITIALIZER_P (init)
405338fd1498Szrj       && CONSTRUCTOR_NELTS (init) == 1)
405438fd1498Szrj     {
405538fd1498Szrj       tree elt = CONSTRUCTOR_ELT (init, 0)->value;
405638fd1498Szrj       if (TREE_CODE (TREE_TYPE (elt)) == ARRAY_TYPE)
405738fd1498Szrj 	{
405838fd1498Szrj 	  direct_init = DIRECT_LIST_INIT_P (init);
405938fd1498Szrj 	  init = elt;
406038fd1498Szrj 	}
406138fd1498Szrj     }
406238fd1498Szrj 
406338fd1498Szrj   /* If we have a braced-init-list or string constant, make sure that the array
406438fd1498Szrj      is big enough for all the initializers.  */
406538fd1498Szrj   bool length_check = (init
406638fd1498Szrj 		       && (TREE_CODE (init) == STRING_CST
406738fd1498Szrj 			   || (TREE_CODE (init) == CONSTRUCTOR
406838fd1498Szrj 			       && CONSTRUCTOR_NELTS (init) > 0))
406938fd1498Szrj 		       && !TREE_CONSTANT (maxindex));
407038fd1498Szrj 
407138fd1498Szrj   if (init
407238fd1498Szrj       && TREE_CODE (atype) == ARRAY_TYPE
407338fd1498Szrj       && TREE_CONSTANT (maxindex)
407438fd1498Szrj       && (from_array == 2
407538fd1498Szrj 	  ? vec_copy_assign_is_trivial (inner_elt_type, init)
407638fd1498Szrj 	  : !TYPE_NEEDS_CONSTRUCTING (type))
407738fd1498Szrj       && ((TREE_CODE (init) == CONSTRUCTOR
407838fd1498Szrj 	   && (BRACE_ENCLOSED_INITIALIZER_P (init)
407938fd1498Szrj 	       || (same_type_ignoring_top_level_qualifiers_p
408038fd1498Szrj 		   (atype, TREE_TYPE (init))))
408138fd1498Szrj 	   /* Don't do this if the CONSTRUCTOR might contain something
408238fd1498Szrj 	      that might throw and require us to clean up.  */
408338fd1498Szrj 	   && (vec_safe_is_empty (CONSTRUCTOR_ELTS (init))
408438fd1498Szrj 	       || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
408538fd1498Szrj 	  || from_array))
408638fd1498Szrj     {
408738fd1498Szrj       /* Do non-default initialization of trivial arrays resulting from
408838fd1498Szrj 	 brace-enclosed initializers.  In this case, digest_init and
408938fd1498Szrj 	 store_constructor will handle the semantics for us.  */
409038fd1498Szrj 
409138fd1498Szrj       if (BRACE_ENCLOSED_INITIALIZER_P (init))
409238fd1498Szrj 	init = digest_init (atype, init, complain);
409338fd1498Szrj       stmt_expr = build2 (INIT_EXPR, atype, base, init);
409438fd1498Szrj       return stmt_expr;
409538fd1498Szrj     }
409638fd1498Szrj 
409738fd1498Szrj   maxindex = cp_convert (ptrdiff_type_node, maxindex, complain);
409838fd1498Szrj   maxindex = fold_simple (maxindex);
409938fd1498Szrj 
410038fd1498Szrj   if (TREE_CODE (atype) == ARRAY_TYPE)
410138fd1498Szrj     {
410238fd1498Szrj       ptype = build_pointer_type (type);
410338fd1498Szrj       base = decay_conversion (base, complain);
410438fd1498Szrj       if (base == error_mark_node)
410538fd1498Szrj 	return error_mark_node;
410638fd1498Szrj       base = cp_convert (ptype, base, complain);
410738fd1498Szrj     }
410838fd1498Szrj   else
410938fd1498Szrj     ptype = atype;
411038fd1498Szrj 
411138fd1498Szrj   /* The code we are generating looks like:
411238fd1498Szrj      ({
411338fd1498Szrj        T* t1 = (T*) base;
411438fd1498Szrj        T* rval = t1;
411538fd1498Szrj        ptrdiff_t iterator = maxindex;
411638fd1498Szrj        try {
411738fd1498Szrj 	 for (; iterator != -1; --iterator) {
411838fd1498Szrj 	   ... initialize *t1 ...
411938fd1498Szrj 	   ++t1;
412038fd1498Szrj 	 }
412138fd1498Szrj        } catch (...) {
412238fd1498Szrj 	 ... destroy elements that were constructed ...
412338fd1498Szrj        }
412438fd1498Szrj        rval;
412538fd1498Szrj      })
412638fd1498Szrj 
412738fd1498Szrj      We can omit the try and catch blocks if we know that the
412838fd1498Szrj      initialization will never throw an exception, or if the array
412938fd1498Szrj      elements do not have destructors.  We can omit the loop completely if
413038fd1498Szrj      the elements of the array do not have constructors.
413138fd1498Szrj 
413238fd1498Szrj      We actually wrap the entire body of the above in a STMT_EXPR, for
413338fd1498Szrj      tidiness.
413438fd1498Szrj 
413538fd1498Szrj      When copying from array to another, when the array elements have
413638fd1498Szrj      only trivial copy constructors, we should use __builtin_memcpy
413738fd1498Szrj      rather than generating a loop.  That way, we could take advantage
413838fd1498Szrj      of whatever cleverness the back end has for dealing with copies
413938fd1498Szrj      of blocks of memory.  */
414038fd1498Szrj 
414138fd1498Szrj   is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
414238fd1498Szrj   destroy_temps = stmts_are_full_exprs_p ();
414338fd1498Szrj   current_stmt_tree ()->stmts_are_full_exprs_p = 0;
414438fd1498Szrj   rval = get_temp_regvar (ptype, base);
414538fd1498Szrj   base = get_temp_regvar (ptype, rval);
414638fd1498Szrj   iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
414738fd1498Szrj 
414838fd1498Szrj   /* If initializing one array from another, initialize element by
414938fd1498Szrj      element.  We rely upon the below calls to do the argument
415038fd1498Szrj      checking.  Evaluate the initializer before entering the try block.  */
415138fd1498Szrj   if (from_array && init && TREE_CODE (init) != CONSTRUCTOR)
415238fd1498Szrj     {
415338fd1498Szrj       if (lvalue_kind (init) & clk_rvalueref)
415438fd1498Szrj 	xvalue = true;
415538fd1498Szrj       base2 = decay_conversion (init, complain);
415638fd1498Szrj       if (base2 == error_mark_node)
415738fd1498Szrj 	return error_mark_node;
415838fd1498Szrj       itype = TREE_TYPE (base2);
415938fd1498Szrj       base2 = get_temp_regvar (itype, base2);
416038fd1498Szrj       itype = TREE_TYPE (itype);
416138fd1498Szrj     }
416238fd1498Szrj 
416338fd1498Szrj   /* Protect the entire array initialization so that we can destroy
416438fd1498Szrj      the partially constructed array if an exception is thrown.
416538fd1498Szrj      But don't do this if we're assigning.  */
416638fd1498Szrj   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
416738fd1498Szrj       && from_array != 2)
416838fd1498Szrj     {
416938fd1498Szrj       try_block = begin_try_block ();
417038fd1498Szrj     }
417138fd1498Szrj 
417238fd1498Szrj   /* Should we try to create a constant initializer?  */
417338fd1498Szrj   bool try_const = (TREE_CODE (atype) == ARRAY_TYPE
417438fd1498Szrj 		    && TREE_CONSTANT (maxindex)
417538fd1498Szrj 		    && (init ? TREE_CODE (init) == CONSTRUCTOR
417638fd1498Szrj 			: (type_has_constexpr_default_constructor
417738fd1498Szrj 			   (inner_elt_type)))
417838fd1498Szrj 		    && (literal_type_p (inner_elt_type)
417938fd1498Szrj 			|| TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)));
418038fd1498Szrj   vec<constructor_elt, va_gc> *const_vec = NULL;
418138fd1498Szrj   bool saw_non_const = false;
418238fd1498Szrj   /* If we're initializing a static array, we want to do static
418338fd1498Szrj      initialization of any elements with constant initializers even if
418438fd1498Szrj      some are non-constant.  */
418538fd1498Szrj   bool do_static_init = (DECL_P (obase) && TREE_STATIC (obase));
418638fd1498Szrj 
418738fd1498Szrj   bool empty_list = false;
418838fd1498Szrj   if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
418938fd1498Szrj       && CONSTRUCTOR_NELTS (init) == 0)
419038fd1498Szrj     /* Skip over the handling of non-empty init lists.  */
419138fd1498Szrj     empty_list = true;
419238fd1498Szrj 
419338fd1498Szrj   /* Maybe pull out constant value when from_array? */
419438fd1498Szrj 
419538fd1498Szrj   else if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
419638fd1498Szrj     {
419738fd1498Szrj       /* Do non-default initialization of non-trivial arrays resulting from
419838fd1498Szrj 	 brace-enclosed initializers.  */
419938fd1498Szrj       unsigned HOST_WIDE_INT idx;
420038fd1498Szrj       tree field, elt;
420138fd1498Szrj       /* If the constructor already has the array type, it's been through
420238fd1498Szrj 	 digest_init, so we shouldn't try to do anything more.  */
420338fd1498Szrj       bool digested = same_type_p (atype, TREE_TYPE (init));
420438fd1498Szrj       from_array = 0;
420538fd1498Szrj 
420638fd1498Szrj       if (length_check)
420738fd1498Szrj 	finish_length_check (atype, iterator, obase, CONSTRUCTOR_NELTS (init));
420838fd1498Szrj 
420938fd1498Szrj       if (try_const)
421038fd1498Szrj 	vec_alloc (const_vec, CONSTRUCTOR_NELTS (init));
421138fd1498Szrj 
421238fd1498Szrj       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt)
421338fd1498Szrj 	{
421438fd1498Szrj 	  tree baseref = build1 (INDIRECT_REF, type, base);
421538fd1498Szrj 	  tree one_init;
421638fd1498Szrj 
421738fd1498Szrj 	  num_initialized_elts++;
421838fd1498Szrj 
421938fd1498Szrj 	  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
422038fd1498Szrj 	  if (digested)
422138fd1498Szrj 	    one_init = build2 (INIT_EXPR, type, baseref, elt);
422238fd1498Szrj 	  else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
422338fd1498Szrj 	    one_init = build_aggr_init (baseref, elt, 0, complain);
422438fd1498Szrj 	  else
422538fd1498Szrj 	    one_init = cp_build_modify_expr (input_location, baseref,
422638fd1498Szrj 					     NOP_EXPR, elt, complain);
422738fd1498Szrj 	  if (one_init == error_mark_node)
422838fd1498Szrj 	    errors = true;
422938fd1498Szrj 	  if (try_const)
423038fd1498Szrj 	    {
423138fd1498Szrj 	      tree e = maybe_constant_init (one_init);
423238fd1498Szrj 	      if (reduced_constant_expression_p (e))
423338fd1498Szrj 		{
423438fd1498Szrj 		  CONSTRUCTOR_APPEND_ELT (const_vec, field, e);
423538fd1498Szrj 		  if (do_static_init)
423638fd1498Szrj 		    one_init = NULL_TREE;
423738fd1498Szrj 		  else
423838fd1498Szrj 		    one_init = build2 (INIT_EXPR, type, baseref, e);
423938fd1498Szrj 		}
424038fd1498Szrj 	      else
424138fd1498Szrj 		{
424238fd1498Szrj 		  if (do_static_init)
424338fd1498Szrj 		    {
424438fd1498Szrj 		      tree value = build_zero_init (TREE_TYPE (e), NULL_TREE,
424538fd1498Szrj 						    true);
424638fd1498Szrj 		      if (value)
424738fd1498Szrj 			CONSTRUCTOR_APPEND_ELT (const_vec, field, value);
424838fd1498Szrj 		    }
424938fd1498Szrj 		  saw_non_const = true;
425038fd1498Szrj 		}
425138fd1498Szrj 	    }
425238fd1498Szrj 
425338fd1498Szrj 	  if (one_init)
425438fd1498Szrj 	    finish_expr_stmt (one_init);
425538fd1498Szrj 	  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
425638fd1498Szrj 
425738fd1498Szrj 	  one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, false,
425838fd1498Szrj 					complain);
425938fd1498Szrj 	  if (one_init == error_mark_node)
426038fd1498Szrj 	    errors = true;
426138fd1498Szrj 	  else
426238fd1498Szrj 	    finish_expr_stmt (one_init);
426338fd1498Szrj 
426438fd1498Szrj 	  one_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, false,
426538fd1498Szrj 					complain);
426638fd1498Szrj 	  if (one_init == error_mark_node)
426738fd1498Szrj 	    errors = true;
426838fd1498Szrj 	  else
426938fd1498Szrj 	    finish_expr_stmt (one_init);
427038fd1498Szrj 	}
427138fd1498Szrj 
427238fd1498Szrj       /* Any elements without explicit initializers get T{}.  */
427338fd1498Szrj       empty_list = true;
427438fd1498Szrj     }
427538fd1498Szrj   else if (init && TREE_CODE (init) == STRING_CST)
427638fd1498Szrj     {
427738fd1498Szrj       /* Check that the array is at least as long as the string.  */
427838fd1498Szrj       if (length_check)
427938fd1498Szrj 	finish_length_check (atype, iterator, obase,
428038fd1498Szrj 			     TREE_STRING_LENGTH (init));
428138fd1498Szrj       tree length = build_int_cst (ptrdiff_type_node,
428238fd1498Szrj 				   TREE_STRING_LENGTH (init));
428338fd1498Szrj 
428438fd1498Szrj       /* Copy the string to the first part of the array.  */
428538fd1498Szrj       tree alias_set = build_int_cst (build_pointer_type (type), 0);
428638fd1498Szrj       tree lhs = build2 (MEM_REF, TREE_TYPE (init), base, alias_set);
428738fd1498Szrj       tree stmt = build2 (MODIFY_EXPR, void_type_node, lhs, init);
428838fd1498Szrj       finish_expr_stmt (stmt);
428938fd1498Szrj 
429038fd1498Szrj       /* Adjust the counter and pointer.  */
429138fd1498Szrj       stmt = cp_build_binary_op (loc, MINUS_EXPR, iterator, length, complain);
429238fd1498Szrj       stmt = build2 (MODIFY_EXPR, void_type_node, iterator, stmt);
429338fd1498Szrj       finish_expr_stmt (stmt);
429438fd1498Szrj 
429538fd1498Szrj       stmt = cp_build_binary_op (loc, PLUS_EXPR, base, length, complain);
429638fd1498Szrj       stmt = build2 (MODIFY_EXPR, void_type_node, base, stmt);
429738fd1498Szrj       finish_expr_stmt (stmt);
429838fd1498Szrj 
429938fd1498Szrj       /* And set the rest of the array to NUL.  */
430038fd1498Szrj       from_array = 0;
430138fd1498Szrj       explicit_value_init_p = true;
430238fd1498Szrj     }
430338fd1498Szrj   else if (from_array)
430438fd1498Szrj     {
430538fd1498Szrj       if (init)
430638fd1498Szrj 	/* OK, we set base2 above.  */;
430738fd1498Szrj       else if (CLASS_TYPE_P (type)
430838fd1498Szrj 	       && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
430938fd1498Szrj 	{
431038fd1498Szrj           if (complain & tf_error)
431138fd1498Szrj             error ("initializer ends prematurely");
431238fd1498Szrj 	  errors = true;
431338fd1498Szrj 	}
431438fd1498Szrj     }
431538fd1498Szrj 
431638fd1498Szrj   /* Now, default-initialize any remaining elements.  We don't need to
431738fd1498Szrj      do that if a) the type does not need constructing, or b) we've
431838fd1498Szrj      already initialized all the elements.
431938fd1498Szrj 
432038fd1498Szrj      We do need to keep going if we're copying an array.  */
432138fd1498Szrj 
432238fd1498Szrj   if (try_const && !init)
432338fd1498Szrj     /* With a constexpr default constructor, which we checked for when
432438fd1498Szrj        setting try_const above, default-initialization is equivalent to
432538fd1498Szrj        value-initialization, and build_value_init gives us something more
432638fd1498Szrj        friendly to maybe_constant_init.  */
432738fd1498Szrj     explicit_value_init_p = true;
432838fd1498Szrj   if (from_array
432938fd1498Szrj       || ((type_build_ctor_call (type) || init || explicit_value_init_p)
433038fd1498Szrj 	  && ! (tree_fits_shwi_p (maxindex)
433138fd1498Szrj 		&& (num_initialized_elts
433238fd1498Szrj 		    == tree_to_shwi (maxindex) + 1))))
433338fd1498Szrj     {
433438fd1498Szrj       /* If the ITERATOR is lesser or equal to -1, then we don't have to loop;
433538fd1498Szrj 	 we've already initialized all the elements.  */
433638fd1498Szrj       tree for_stmt;
433738fd1498Szrj       tree elt_init;
433838fd1498Szrj       tree to;
433938fd1498Szrj 
434038fd1498Szrj       for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
434138fd1498Szrj       finish_init_stmt (for_stmt);
434238fd1498Szrj       finish_for_cond (build2 (GT_EXPR, boolean_type_node, iterator,
434338fd1498Szrj 			       build_int_cst (TREE_TYPE (iterator), -1)),
434438fd1498Szrj 		       for_stmt, false, 0);
434538fd1498Szrj       elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, false,
434638fd1498Szrj 				    complain);
434738fd1498Szrj       if (elt_init == error_mark_node)
434838fd1498Szrj 	errors = true;
434938fd1498Szrj       finish_for_expr (elt_init, for_stmt);
435038fd1498Szrj 
435138fd1498Szrj       to = build1 (INDIRECT_REF, type, base);
435238fd1498Szrj 
435338fd1498Szrj       /* If the initializer is {}, then all elements are initialized from T{}.
435438fd1498Szrj 	 But for non-classes, that's the same as value-initialization.  */
435538fd1498Szrj       if (empty_list)
435638fd1498Szrj 	{
435738fd1498Szrj 	  if (cxx_dialect >= cxx11 && AGGREGATE_TYPE_P (type))
435838fd1498Szrj 	    {
435938fd1498Szrj 	      init = build_constructor (init_list_type_node, NULL);
436038fd1498Szrj 	    }
436138fd1498Szrj 	  else
436238fd1498Szrj 	    {
436338fd1498Szrj 	      init = NULL_TREE;
436438fd1498Szrj 	      explicit_value_init_p = true;
436538fd1498Szrj 	    }
436638fd1498Szrj 	}
436738fd1498Szrj 
436838fd1498Szrj       if (from_array)
436938fd1498Szrj 	{
437038fd1498Szrj 	  tree from;
437138fd1498Szrj 
437238fd1498Szrj 	  if (base2)
437338fd1498Szrj 	    {
437438fd1498Szrj 	      from = build1 (INDIRECT_REF, itype, base2);
437538fd1498Szrj 	      if (xvalue)
437638fd1498Szrj 		from = move (from);
437738fd1498Szrj 	      if (direct_init)
437838fd1498Szrj 		from = build_tree_list (NULL_TREE, from);
437938fd1498Szrj 	    }
438038fd1498Szrj 	  else
438138fd1498Szrj 	    from = NULL_TREE;
438238fd1498Szrj 
438338fd1498Szrj 	  if (TREE_CODE (type) == ARRAY_TYPE)
438438fd1498Szrj 	    elt_init = build_vec_init (to, NULL_TREE, from, /*val_init*/false,
438538fd1498Szrj 				       from_array, complain);
438638fd1498Szrj 	  else if (from_array == 2)
438738fd1498Szrj 	    elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR,
438838fd1498Szrj 					     from, complain);
438938fd1498Szrj 	  else if (type_build_ctor_call (type))
439038fd1498Szrj 	    elt_init = build_aggr_init (to, from, 0, complain);
439138fd1498Szrj 	  else if (from)
439238fd1498Szrj 	    elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR, from,
439338fd1498Szrj 					     complain);
439438fd1498Szrj 	  else
439538fd1498Szrj 	    gcc_unreachable ();
439638fd1498Szrj 	}
439738fd1498Szrj       else if (TREE_CODE (type) == ARRAY_TYPE)
439838fd1498Szrj 	{
439938fd1498Szrj 	  if (init && !BRACE_ENCLOSED_INITIALIZER_P (init))
440038fd1498Szrj 	    {
440138fd1498Szrj 	      if ((complain & tf_error))
440238fd1498Szrj 		error_at (loc, "array must be initialized "
440338fd1498Szrj 			  "with a brace-enclosed initializer");
440438fd1498Szrj 	      elt_init = error_mark_node;
440538fd1498Szrj 	    }
440638fd1498Szrj 	  else
440738fd1498Szrj 	    elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
440838fd1498Szrj 				       0, init,
440938fd1498Szrj 				       explicit_value_init_p,
441038fd1498Szrj 				       0, complain);
441138fd1498Szrj 	}
441238fd1498Szrj       else if (explicit_value_init_p)
441338fd1498Szrj 	{
441438fd1498Szrj 	  elt_init = build_value_init (type, complain);
441538fd1498Szrj 	  if (elt_init != error_mark_node)
441638fd1498Szrj 	    elt_init = build2 (INIT_EXPR, type, to, elt_init);
441738fd1498Szrj 	}
441838fd1498Szrj       else
441938fd1498Szrj 	{
442038fd1498Szrj 	  gcc_assert (type_build_ctor_call (type) || init);
442138fd1498Szrj 	  if (CLASS_TYPE_P (type))
442238fd1498Szrj 	    elt_init = build_aggr_init (to, init, 0, complain);
442338fd1498Szrj 	  else
442438fd1498Szrj 	    {
442538fd1498Szrj 	      if (TREE_CODE (init) == TREE_LIST)
442638fd1498Szrj 		init = build_x_compound_expr_from_list (init, ELK_INIT,
442738fd1498Szrj 							complain);
442838fd1498Szrj 	      elt_init = (init == error_mark_node
442938fd1498Szrj 			  ? error_mark_node
443038fd1498Szrj 			  : build2 (INIT_EXPR, type, to, init));
443138fd1498Szrj 	    }
443238fd1498Szrj 	}
443338fd1498Szrj 
443438fd1498Szrj       if (elt_init == error_mark_node)
443538fd1498Szrj 	errors = true;
443638fd1498Szrj 
443738fd1498Szrj       if (try_const)
443838fd1498Szrj 	{
443938fd1498Szrj 	  /* FIXME refs to earlier elts */
444038fd1498Szrj 	  tree e = maybe_constant_init (elt_init);
444138fd1498Szrj 	  if (reduced_constant_expression_p (e))
444238fd1498Szrj 	    {
444338fd1498Szrj 	      if (initializer_zerop (e))
444438fd1498Szrj 		/* Don't fill the CONSTRUCTOR with zeros.  */
444538fd1498Szrj 		e = NULL_TREE;
444638fd1498Szrj 	      if (do_static_init)
444738fd1498Szrj 		elt_init = NULL_TREE;
444838fd1498Szrj 	    }
444938fd1498Szrj 	  else
445038fd1498Szrj 	    {
445138fd1498Szrj 	      saw_non_const = true;
445238fd1498Szrj 	      if (do_static_init)
445338fd1498Szrj 		e = build_zero_init (TREE_TYPE (e), NULL_TREE, true);
445438fd1498Szrj 	      else
445538fd1498Szrj 		e = NULL_TREE;
445638fd1498Szrj 	    }
445738fd1498Szrj 
445838fd1498Szrj 	  if (e)
445938fd1498Szrj 	    {
4460*58e805e6Szrj 	      HOST_WIDE_INT last = tree_to_shwi (maxindex);
4461*58e805e6Szrj 	      if (num_initialized_elts <= last)
446238fd1498Szrj 		{
446338fd1498Szrj 		  tree field = size_int (num_initialized_elts);
4464*58e805e6Szrj 		  if (num_initialized_elts != last)
4465*58e805e6Szrj 		    field = build2 (RANGE_EXPR, sizetype, field,
4466*58e805e6Szrj 				    size_int (last));
446738fd1498Szrj 		  CONSTRUCTOR_APPEND_ELT (const_vec, field, e);
446838fd1498Szrj 		}
446938fd1498Szrj 	    }
447038fd1498Szrj 	}
447138fd1498Szrj 
447238fd1498Szrj       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
447338fd1498Szrj       if (elt_init && !errors)
447438fd1498Szrj 	finish_expr_stmt (elt_init);
447538fd1498Szrj       current_stmt_tree ()->stmts_are_full_exprs_p = 0;
447638fd1498Szrj 
447738fd1498Szrj       finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, false,
447838fd1498Szrj                                            complain));
447938fd1498Szrj       if (base2)
448038fd1498Szrj 	finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, false,
448138fd1498Szrj                                              complain));
448238fd1498Szrj 
448338fd1498Szrj       finish_for_stmt (for_stmt);
448438fd1498Szrj     }
448538fd1498Szrj 
448638fd1498Szrj   /* Make sure to cleanup any partially constructed elements.  */
448738fd1498Szrj   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
448838fd1498Szrj       && from_array != 2)
448938fd1498Szrj     {
449038fd1498Szrj       tree e;
449138fd1498Szrj       tree m = cp_build_binary_op (input_location,
449238fd1498Szrj 				   MINUS_EXPR, maxindex, iterator,
449338fd1498Szrj 				   complain);
449438fd1498Szrj 
449538fd1498Szrj       /* Flatten multi-dimensional array since build_vec_delete only
449638fd1498Szrj 	 expects one-dimensional array.  */
449738fd1498Szrj       if (TREE_CODE (type) == ARRAY_TYPE)
449838fd1498Szrj 	m = cp_build_binary_op (input_location,
449938fd1498Szrj 				MULT_EXPR, m,
450038fd1498Szrj 				/* Avoid mixing signed and unsigned.  */
450138fd1498Szrj 				convert (TREE_TYPE (m),
450238fd1498Szrj 					 array_type_nelts_total (type)),
450338fd1498Szrj 				complain);
450438fd1498Szrj 
450538fd1498Szrj       finish_cleanup_try_block (try_block);
450638fd1498Szrj       e = build_vec_delete_1 (rval, m,
450738fd1498Szrj 			      inner_elt_type, sfk_complete_destructor,
450838fd1498Szrj 			      /*use_global_delete=*/0, complain);
450938fd1498Szrj       if (e == error_mark_node)
451038fd1498Szrj 	errors = true;
451138fd1498Szrj       finish_cleanup (e, try_block);
451238fd1498Szrj     }
451338fd1498Szrj 
451438fd1498Szrj   /* The value of the array initialization is the array itself, RVAL
451538fd1498Szrj      is a pointer to the first element.  */
451638fd1498Szrj   finish_stmt_expr_expr (rval, stmt_expr);
451738fd1498Szrj 
451838fd1498Szrj   stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
451938fd1498Szrj 
452038fd1498Szrj   current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
452138fd1498Szrj 
452238fd1498Szrj   if (errors)
452338fd1498Szrj     return error_mark_node;
452438fd1498Szrj 
452538fd1498Szrj   if (try_const)
452638fd1498Szrj     {
452738fd1498Szrj       if (!saw_non_const)
452838fd1498Szrj 	{
452938fd1498Szrj 	  tree const_init = build_constructor (atype, const_vec);
453038fd1498Szrj 	  return build2 (INIT_EXPR, atype, obase, const_init);
453138fd1498Szrj 	}
453238fd1498Szrj       else if (do_static_init && !vec_safe_is_empty (const_vec))
453338fd1498Szrj 	DECL_INITIAL (obase) = build_constructor (atype, const_vec);
453438fd1498Szrj       else
453538fd1498Szrj 	vec_free (const_vec);
453638fd1498Szrj     }
453738fd1498Szrj 
453838fd1498Szrj   /* Now make the result have the correct type.  */
453938fd1498Szrj   if (TREE_CODE (atype) == ARRAY_TYPE)
454038fd1498Szrj     {
454138fd1498Szrj       atype = build_pointer_type (atype);
454238fd1498Szrj       stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
454338fd1498Szrj       stmt_expr = cp_build_fold_indirect_ref (stmt_expr);
454438fd1498Szrj       TREE_NO_WARNING (stmt_expr) = 1;
454538fd1498Szrj     }
454638fd1498Szrj 
454738fd1498Szrj   return stmt_expr;
454838fd1498Szrj }
454938fd1498Szrj 
455038fd1498Szrj /* Call the DTOR_KIND destructor for EXP.  FLAGS are as for
455138fd1498Szrj    build_delete.  */
455238fd1498Szrj 
455338fd1498Szrj static tree
build_dtor_call(tree exp,special_function_kind dtor_kind,int flags,tsubst_flags_t complain)455438fd1498Szrj build_dtor_call (tree exp, special_function_kind dtor_kind, int flags,
455538fd1498Szrj 		 tsubst_flags_t complain)
455638fd1498Szrj {
455738fd1498Szrj   tree name;
455838fd1498Szrj   tree fn;
455938fd1498Szrj   switch (dtor_kind)
456038fd1498Szrj     {
456138fd1498Szrj     case sfk_complete_destructor:
456238fd1498Szrj       name = complete_dtor_identifier;
456338fd1498Szrj       break;
456438fd1498Szrj 
456538fd1498Szrj     case sfk_base_destructor:
456638fd1498Szrj       name = base_dtor_identifier;
456738fd1498Szrj       break;
456838fd1498Szrj 
456938fd1498Szrj     case sfk_deleting_destructor:
457038fd1498Szrj       name = deleting_dtor_identifier;
457138fd1498Szrj       break;
457238fd1498Szrj 
457338fd1498Szrj     default:
457438fd1498Szrj       gcc_unreachable ();
457538fd1498Szrj     }
457638fd1498Szrj   fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
457738fd1498Szrj   return build_new_method_call (exp, fn,
457838fd1498Szrj 				/*args=*/NULL,
457938fd1498Szrj 				/*conversion_path=*/NULL_TREE,
458038fd1498Szrj 				flags,
458138fd1498Szrj 				/*fn_p=*/NULL,
458238fd1498Szrj 				complain);
458338fd1498Szrj }
458438fd1498Szrj 
458538fd1498Szrj /* Generate a call to a destructor. TYPE is the type to cast ADDR to.
458638fd1498Szrj    ADDR is an expression which yields the store to be destroyed.
458738fd1498Szrj    AUTO_DELETE is the name of the destructor to call, i.e., either
458838fd1498Szrj    sfk_complete_destructor, sfk_base_destructor, or
458938fd1498Szrj    sfk_deleting_destructor.
459038fd1498Szrj 
459138fd1498Szrj    FLAGS is the logical disjunction of zero or more LOOKUP_
459238fd1498Szrj    flags.  See cp-tree.h for more info.  */
459338fd1498Szrj 
459438fd1498Szrj tree
build_delete(tree otype,tree addr,special_function_kind auto_delete,int flags,int use_global_delete,tsubst_flags_t complain)459538fd1498Szrj build_delete (tree otype, tree addr, special_function_kind auto_delete,
459638fd1498Szrj 	      int flags, int use_global_delete, tsubst_flags_t complain)
459738fd1498Szrj {
459838fd1498Szrj   tree expr;
459938fd1498Szrj 
460038fd1498Szrj   if (addr == error_mark_node)
460138fd1498Szrj     return error_mark_node;
460238fd1498Szrj 
460338fd1498Szrj   tree type = TYPE_MAIN_VARIANT (otype);
460438fd1498Szrj 
460538fd1498Szrj   /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
460638fd1498Szrj      set to `error_mark_node' before it gets properly cleaned up.  */
460738fd1498Szrj   if (type == error_mark_node)
460838fd1498Szrj     return error_mark_node;
460938fd1498Szrj 
461038fd1498Szrj   if (TREE_CODE (type) == POINTER_TYPE)
461138fd1498Szrj     type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
461238fd1498Szrj 
461338fd1498Szrj   if (TREE_CODE (type) == ARRAY_TYPE)
461438fd1498Szrj     {
461538fd1498Szrj       if (TYPE_DOMAIN (type) == NULL_TREE)
461638fd1498Szrj 	{
461738fd1498Szrj 	  if (complain & tf_error)
461838fd1498Szrj 	    error ("unknown array size in delete");
461938fd1498Szrj 	  return error_mark_node;
462038fd1498Szrj 	}
462138fd1498Szrj       return build_vec_delete (addr, array_type_nelts (type),
462238fd1498Szrj 			       auto_delete, use_global_delete, complain);
462338fd1498Szrj     }
462438fd1498Szrj 
462538fd1498Szrj   if (TYPE_PTR_P (otype))
462638fd1498Szrj     {
462738fd1498Szrj       addr = mark_rvalue_use (addr);
462838fd1498Szrj 
462938fd1498Szrj       /* We don't want to warn about delete of void*, only other
463038fd1498Szrj 	  incomplete types.  Deleting other incomplete types
463138fd1498Szrj 	  invokes undefined behavior, but it is not ill-formed, so
463238fd1498Szrj 	  compile to something that would even do The Right Thing
463338fd1498Szrj 	  (TM) should the type have a trivial dtor and no delete
463438fd1498Szrj 	  operator.  */
463538fd1498Szrj       if (!VOID_TYPE_P (type))
463638fd1498Szrj 	{
463738fd1498Szrj 	  complete_type (type);
463838fd1498Szrj 	  if (!COMPLETE_TYPE_P (type))
463938fd1498Szrj 	    {
464038fd1498Szrj 	      if ((complain & tf_warning)
464138fd1498Szrj 		  && warning (OPT_Wdelete_incomplete,
464238fd1498Szrj 			      "possible problem detected in invocation of "
464338fd1498Szrj 			      "delete operator:"))
464438fd1498Szrj 		{
464538fd1498Szrj 		  cxx_incomplete_type_diagnostic (addr, type, DK_WARNING);
464638fd1498Szrj 		  inform (input_location,
464738fd1498Szrj 			  "neither the destructor nor the class-specific "
464838fd1498Szrj 			  "operator delete will be called, even if they are "
464938fd1498Szrj 			  "declared when the class is defined");
465038fd1498Szrj 		}
465138fd1498Szrj 	    }
465238fd1498Szrj 	  else if (auto_delete == sfk_deleting_destructor && warn_delnonvdtor
465338fd1498Szrj 	           && MAYBE_CLASS_TYPE_P (type) && !CLASSTYPE_FINAL (type)
465438fd1498Szrj 		   && TYPE_POLYMORPHIC_P (type))
465538fd1498Szrj 	    {
465638fd1498Szrj 	      tree dtor = CLASSTYPE_DESTRUCTOR (type);
465738fd1498Szrj 	      if (!dtor || !DECL_VINDEX (dtor))
465838fd1498Szrj 		{
465938fd1498Szrj 		  if (CLASSTYPE_PURE_VIRTUALS (type))
466038fd1498Szrj 		    warning (OPT_Wdelete_non_virtual_dtor,
466138fd1498Szrj 			     "deleting object of abstract class type %qT"
466238fd1498Szrj 			     " which has non-virtual destructor"
466338fd1498Szrj 			     " will cause undefined behavior", type);
466438fd1498Szrj 		  else
466538fd1498Szrj 		    warning (OPT_Wdelete_non_virtual_dtor,
466638fd1498Szrj 			     "deleting object of polymorphic class type %qT"
466738fd1498Szrj 			     " which has non-virtual destructor"
466838fd1498Szrj 			     " might cause undefined behavior", type);
466938fd1498Szrj 		}
467038fd1498Szrj 	    }
467138fd1498Szrj 	}
467238fd1498Szrj       if (TREE_SIDE_EFFECTS (addr))
467338fd1498Szrj 	addr = save_expr (addr);
467438fd1498Szrj 
467538fd1498Szrj       /* Throw away const and volatile on target type of addr.  */
467638fd1498Szrj       addr = convert_force (build_pointer_type (type), addr, 0, complain);
467738fd1498Szrj     }
467838fd1498Szrj   else
467938fd1498Szrj     {
468038fd1498Szrj       /* Don't check PROTECT here; leave that decision to the
468138fd1498Szrj 	 destructor.  If the destructor is accessible, call it,
468238fd1498Szrj 	 else report error.  */
468338fd1498Szrj       addr = cp_build_addr_expr (addr, complain);
468438fd1498Szrj       if (addr == error_mark_node)
468538fd1498Szrj 	return error_mark_node;
468638fd1498Szrj       if (TREE_SIDE_EFFECTS (addr))
468738fd1498Szrj 	addr = save_expr (addr);
468838fd1498Szrj 
468938fd1498Szrj       addr = convert_force (build_pointer_type (type), addr, 0, complain);
469038fd1498Szrj     }
469138fd1498Szrj 
469238fd1498Szrj   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
469338fd1498Szrj     {
469438fd1498Szrj       /* Make sure the destructor is callable.  */
469538fd1498Szrj       if (type_build_dtor_call (type))
469638fd1498Szrj 	{
469738fd1498Szrj 	  expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
469838fd1498Szrj 				  sfk_complete_destructor, flags, complain);
469938fd1498Szrj 	  if (expr == error_mark_node)
470038fd1498Szrj 	    return error_mark_node;
470138fd1498Szrj 	}
470238fd1498Szrj 
470338fd1498Szrj       if (auto_delete != sfk_deleting_destructor)
470438fd1498Szrj 	return void_node;
470538fd1498Szrj 
470638fd1498Szrj       return build_op_delete_call (DELETE_EXPR, addr,
470738fd1498Szrj 				   cxx_sizeof_nowarn (type),
470838fd1498Szrj 				   use_global_delete,
470938fd1498Szrj 				   /*placement=*/NULL_TREE,
471038fd1498Szrj 				   /*alloc_fn=*/NULL_TREE,
471138fd1498Szrj 				   complain);
471238fd1498Szrj     }
471338fd1498Szrj   else
471438fd1498Szrj     {
471538fd1498Szrj       tree head = NULL_TREE;
471638fd1498Szrj       tree do_delete = NULL_TREE;
471738fd1498Szrj       tree ifexp;
471838fd1498Szrj 
471938fd1498Szrj       if (CLASSTYPE_LAZY_DESTRUCTOR (type))
472038fd1498Szrj 	lazily_declare_fn (sfk_destructor, type);
472138fd1498Szrj 
472238fd1498Szrj       /* For `::delete x', we must not use the deleting destructor
472338fd1498Szrj 	 since then we would not be sure to get the global `operator
472438fd1498Szrj 	 delete'.  */
472538fd1498Szrj       if (use_global_delete && auto_delete == sfk_deleting_destructor)
472638fd1498Szrj 	{
472738fd1498Szrj 	  /* We will use ADDR multiple times so we must save it.  */
472838fd1498Szrj 	  addr = save_expr (addr);
472938fd1498Szrj 	  head = get_target_expr (build_headof (addr));
473038fd1498Szrj 	  /* Delete the object.  */
473138fd1498Szrj 	  do_delete = build_op_delete_call (DELETE_EXPR,
473238fd1498Szrj 					    head,
473338fd1498Szrj 					    cxx_sizeof_nowarn (type),
473438fd1498Szrj 					    /*global_p=*/true,
473538fd1498Szrj 					    /*placement=*/NULL_TREE,
473638fd1498Szrj 					    /*alloc_fn=*/NULL_TREE,
473738fd1498Szrj 					    complain);
473838fd1498Szrj 	  /* Otherwise, treat this like a complete object destructor
473938fd1498Szrj 	     call.  */
474038fd1498Szrj 	  auto_delete = sfk_complete_destructor;
474138fd1498Szrj 	}
474238fd1498Szrj       /* If the destructor is non-virtual, there is no deleting
474338fd1498Szrj 	 variant.  Instead, we must explicitly call the appropriate
474438fd1498Szrj 	 `operator delete' here.  */
474538fd1498Szrj       else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTOR (type))
474638fd1498Szrj 	       && auto_delete == sfk_deleting_destructor)
474738fd1498Szrj 	{
474838fd1498Szrj 	  /* We will use ADDR multiple times so we must save it.  */
474938fd1498Szrj 	  addr = save_expr (addr);
475038fd1498Szrj 	  /* Build the call.  */
475138fd1498Szrj 	  do_delete = build_op_delete_call (DELETE_EXPR,
475238fd1498Szrj 					    addr,
475338fd1498Szrj 					    cxx_sizeof_nowarn (type),
475438fd1498Szrj 					    /*global_p=*/false,
475538fd1498Szrj 					    /*placement=*/NULL_TREE,
475638fd1498Szrj 					    /*alloc_fn=*/NULL_TREE,
475738fd1498Szrj 					    complain);
475838fd1498Szrj 	  /* Call the complete object destructor.  */
475938fd1498Szrj 	  auto_delete = sfk_complete_destructor;
476038fd1498Szrj 	}
476138fd1498Szrj       else if (auto_delete == sfk_deleting_destructor
476238fd1498Szrj 	       && TYPE_GETS_REG_DELETE (type))
476338fd1498Szrj 	{
476438fd1498Szrj 	  /* Make sure we have access to the member op delete, even though
476538fd1498Szrj 	     we'll actually be calling it from the destructor.  */
476638fd1498Szrj 	  build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
476738fd1498Szrj 				/*global_p=*/false,
476838fd1498Szrj 				/*placement=*/NULL_TREE,
476938fd1498Szrj 				/*alloc_fn=*/NULL_TREE,
477038fd1498Szrj 				complain);
477138fd1498Szrj 	}
477238fd1498Szrj 
477338fd1498Szrj       expr = build_dtor_call (cp_build_fold_indirect_ref (addr),
477438fd1498Szrj 			      auto_delete, flags, complain);
477538fd1498Szrj       if (expr == error_mark_node)
477638fd1498Szrj 	return error_mark_node;
477738fd1498Szrj       if (do_delete)
477838fd1498Szrj 	/* The delete operator must be called, regardless of whether
477938fd1498Szrj 	   the destructor throws.
478038fd1498Szrj 
478138fd1498Szrj 	   [expr.delete]/7 The deallocation function is called
478238fd1498Szrj 	   regardless of whether the destructor for the object or some
478338fd1498Szrj 	   element of the array throws an exception.  */
478438fd1498Szrj 	expr = build2 (TRY_FINALLY_EXPR, void_type_node, expr, do_delete);
478538fd1498Szrj 
478638fd1498Szrj       /* We need to calculate this before the dtor changes the vptr.  */
478738fd1498Szrj       if (head)
478838fd1498Szrj 	expr = build2 (COMPOUND_EXPR, void_type_node, head, expr);
478938fd1498Szrj 
479038fd1498Szrj       if (flags & LOOKUP_DESTRUCTOR)
479138fd1498Szrj 	/* Explicit destructor call; don't check for null pointer.  */
479238fd1498Szrj 	ifexp = integer_one_node;
479338fd1498Szrj       else
479438fd1498Szrj 	{
479538fd1498Szrj 	  /* Handle deleting a null pointer.  */
479638fd1498Szrj 	  warning_sentinel s (warn_address);
479738fd1498Szrj 	  ifexp = cp_build_binary_op (input_location, NE_EXPR, addr,
479838fd1498Szrj 				      nullptr_node, complain);
479938fd1498Szrj 	  if (ifexp == error_mark_node)
480038fd1498Szrj 	    return error_mark_node;
480138fd1498Szrj 	  /* This is a compiler generated comparison, don't emit
480238fd1498Szrj 	     e.g. -Wnonnull-compare warning for it.  */
480338fd1498Szrj 	  else if (TREE_CODE (ifexp) == NE_EXPR)
480438fd1498Szrj 	    TREE_NO_WARNING (ifexp) = 1;
480538fd1498Szrj 	}
480638fd1498Szrj 
480738fd1498Szrj       if (ifexp != integer_one_node)
480838fd1498Szrj 	expr = build3 (COND_EXPR, void_type_node, ifexp, expr, void_node);
480938fd1498Szrj 
481038fd1498Szrj       return expr;
481138fd1498Szrj     }
481238fd1498Szrj }
481338fd1498Szrj 
481438fd1498Szrj /* At the beginning of a destructor, push cleanups that will call the
481538fd1498Szrj    destructors for our base classes and members.
481638fd1498Szrj 
481738fd1498Szrj    Called from begin_destructor_body.  */
481838fd1498Szrj 
481938fd1498Szrj void
push_base_cleanups(void)482038fd1498Szrj push_base_cleanups (void)
482138fd1498Szrj {
482238fd1498Szrj   tree binfo, base_binfo;
482338fd1498Szrj   int i;
482438fd1498Szrj   tree member;
482538fd1498Szrj   tree expr;
482638fd1498Szrj   vec<tree, va_gc> *vbases;
482738fd1498Szrj 
482838fd1498Szrj   /* Run destructors for all virtual baseclasses.  */
482938fd1498Szrj   if (!ABSTRACT_CLASS_TYPE_P (current_class_type)
483038fd1498Szrj       && CLASSTYPE_VBASECLASSES (current_class_type))
483138fd1498Szrj     {
483238fd1498Szrj       tree cond = (condition_conversion
483338fd1498Szrj 		   (build2 (BIT_AND_EXPR, integer_type_node,
483438fd1498Szrj 			    current_in_charge_parm,
483538fd1498Szrj 			    integer_two_node)));
483638fd1498Szrj 
483738fd1498Szrj       /* The CLASSTYPE_VBASECLASSES vector is in initialization
483838fd1498Szrj 	 order, which is also the right order for pushing cleanups.  */
483938fd1498Szrj       for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
484038fd1498Szrj 	   vec_safe_iterate (vbases, i, &base_binfo); i++)
484138fd1498Szrj 	{
484238fd1498Szrj 	  if (type_build_dtor_call (BINFO_TYPE (base_binfo)))
484338fd1498Szrj 	    {
484438fd1498Szrj 	      expr = build_special_member_call (current_class_ref,
484538fd1498Szrj 						base_dtor_identifier,
484638fd1498Szrj 						NULL,
484738fd1498Szrj 						base_binfo,
484838fd1498Szrj 						(LOOKUP_NORMAL
484938fd1498Szrj 						 | LOOKUP_NONVIRTUAL),
485038fd1498Szrj 						tf_warning_or_error);
485138fd1498Szrj 	      if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
485238fd1498Szrj 		{
485338fd1498Szrj 		  expr = build3 (COND_EXPR, void_type_node, cond,
485438fd1498Szrj 				 expr, void_node);
485538fd1498Szrj 		  finish_decl_cleanup (NULL_TREE, expr);
485638fd1498Szrj 		}
485738fd1498Szrj 	    }
485838fd1498Szrj 	}
485938fd1498Szrj     }
486038fd1498Szrj 
486138fd1498Szrj   /* Take care of the remaining baseclasses.  */
486238fd1498Szrj   for (binfo = TYPE_BINFO (current_class_type), i = 0;
486338fd1498Szrj        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
486438fd1498Szrj     {
486538fd1498Szrj       if (BINFO_VIRTUAL_P (base_binfo)
486638fd1498Szrj 	  || !type_build_dtor_call (BINFO_TYPE (base_binfo)))
486738fd1498Szrj 	continue;
486838fd1498Szrj 
486938fd1498Szrj       expr = build_special_member_call (current_class_ref,
487038fd1498Szrj 					base_dtor_identifier,
487138fd1498Szrj 					NULL, base_binfo,
487238fd1498Szrj 					LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
487338fd1498Szrj                                         tf_warning_or_error);
487438fd1498Szrj       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
487538fd1498Szrj 	finish_decl_cleanup (NULL_TREE, expr);
487638fd1498Szrj     }
487738fd1498Szrj 
487838fd1498Szrj   /* Don't automatically destroy union members.  */
487938fd1498Szrj   if (TREE_CODE (current_class_type) == UNION_TYPE)
488038fd1498Szrj     return;
488138fd1498Szrj 
488238fd1498Szrj   for (member = TYPE_FIELDS (current_class_type); member;
488338fd1498Szrj        member = DECL_CHAIN (member))
488438fd1498Szrj     {
488538fd1498Szrj       tree this_type = TREE_TYPE (member);
488638fd1498Szrj       if (this_type == error_mark_node
488738fd1498Szrj 	  || TREE_CODE (member) != FIELD_DECL
488838fd1498Szrj 	  || DECL_ARTIFICIAL (member))
488938fd1498Szrj 	continue;
489038fd1498Szrj       if (ANON_AGGR_TYPE_P (this_type))
489138fd1498Szrj 	continue;
489238fd1498Szrj       if (type_build_dtor_call (this_type))
489338fd1498Szrj 	{
489438fd1498Szrj 	  tree this_member = (build_class_member_access_expr
489538fd1498Szrj 			      (current_class_ref, member,
489638fd1498Szrj 			       /*access_path=*/NULL_TREE,
489738fd1498Szrj 			       /*preserve_reference=*/false,
489838fd1498Szrj 			       tf_warning_or_error));
489938fd1498Szrj 	  expr = build_delete (this_type, this_member,
490038fd1498Szrj 			       sfk_complete_destructor,
490138fd1498Szrj 			       LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
490238fd1498Szrj 			       0, tf_warning_or_error);
490338fd1498Szrj 	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
490438fd1498Szrj 	    finish_decl_cleanup (NULL_TREE, expr);
490538fd1498Szrj 	}
490638fd1498Szrj     }
490738fd1498Szrj }
490838fd1498Szrj 
490938fd1498Szrj /* Build a C++ vector delete expression.
491038fd1498Szrj    MAXINDEX is the number of elements to be deleted.
491138fd1498Szrj    ELT_SIZE is the nominal size of each element in the vector.
491238fd1498Szrj    BASE is the expression that should yield the store to be deleted.
491338fd1498Szrj    This function expands (or synthesizes) these calls itself.
491438fd1498Szrj    AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
491538fd1498Szrj 
491638fd1498Szrj    This also calls delete for virtual baseclasses of elements of the vector.
491738fd1498Szrj 
491838fd1498Szrj    Update: MAXINDEX is no longer needed.  The size can be extracted from the
491938fd1498Szrj    start of the vector for pointers, and from the type for arrays.  We still
492038fd1498Szrj    use MAXINDEX for arrays because it happens to already have one of the
492138fd1498Szrj    values we'd have to extract.  (We could use MAXINDEX with pointers to
492238fd1498Szrj    confirm the size, and trap if the numbers differ; not clear that it'd
492338fd1498Szrj    be worth bothering.)  */
492438fd1498Szrj 
492538fd1498Szrj tree
build_vec_delete(tree base,tree maxindex,special_function_kind auto_delete_vec,int use_global_delete,tsubst_flags_t complain)492638fd1498Szrj build_vec_delete (tree base, tree maxindex,
492738fd1498Szrj 		  special_function_kind auto_delete_vec,
492838fd1498Szrj 		  int use_global_delete, tsubst_flags_t complain)
492938fd1498Szrj {
493038fd1498Szrj   tree type;
493138fd1498Szrj   tree rval;
493238fd1498Szrj   tree base_init = NULL_TREE;
493338fd1498Szrj 
493438fd1498Szrj   type = TREE_TYPE (base);
493538fd1498Szrj 
493638fd1498Szrj   if (TYPE_PTR_P (type))
493738fd1498Szrj     {
493838fd1498Szrj       /* Step back one from start of vector, and read dimension.  */
493938fd1498Szrj       tree cookie_addr;
494038fd1498Szrj       tree size_ptr_type = build_pointer_type (sizetype);
494138fd1498Szrj 
494238fd1498Szrj       base = mark_rvalue_use (base);
494338fd1498Szrj       if (TREE_SIDE_EFFECTS (base))
494438fd1498Szrj 	{
494538fd1498Szrj 	  base_init = get_target_expr (base);
494638fd1498Szrj 	  base = TARGET_EXPR_SLOT (base_init);
494738fd1498Szrj 	}
494838fd1498Szrj       type = strip_array_types (TREE_TYPE (type));
494938fd1498Szrj       cookie_addr = fold_build1_loc (input_location, NEGATE_EXPR,
495038fd1498Szrj 				 sizetype, TYPE_SIZE_UNIT (sizetype));
495138fd1498Szrj       cookie_addr = fold_build_pointer_plus (fold_convert (size_ptr_type, base),
495238fd1498Szrj 					     cookie_addr);
495338fd1498Szrj       maxindex = cp_build_fold_indirect_ref (cookie_addr);
495438fd1498Szrj     }
495538fd1498Szrj   else if (TREE_CODE (type) == ARRAY_TYPE)
495638fd1498Szrj     {
495738fd1498Szrj       /* Get the total number of things in the array, maxindex is a
495838fd1498Szrj 	 bad name.  */
495938fd1498Szrj       maxindex = array_type_nelts_total (type);
496038fd1498Szrj       type = strip_array_types (type);
496138fd1498Szrj       base = decay_conversion (base, complain);
496238fd1498Szrj       if (base == error_mark_node)
496338fd1498Szrj 	return error_mark_node;
496438fd1498Szrj       if (TREE_SIDE_EFFECTS (base))
496538fd1498Szrj 	{
496638fd1498Szrj 	  base_init = get_target_expr (base);
496738fd1498Szrj 	  base = TARGET_EXPR_SLOT (base_init);
496838fd1498Szrj 	}
496938fd1498Szrj     }
497038fd1498Szrj   else
497138fd1498Szrj     {
497238fd1498Szrj       if (base != error_mark_node && !(complain & tf_error))
497338fd1498Szrj 	error ("type to vector delete is neither pointer or array type");
497438fd1498Szrj       return error_mark_node;
497538fd1498Szrj     }
497638fd1498Szrj 
497738fd1498Szrj   rval = build_vec_delete_1 (base, maxindex, type, auto_delete_vec,
497838fd1498Szrj 			     use_global_delete, complain);
497938fd1498Szrj   if (base_init && rval != error_mark_node)
498038fd1498Szrj     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), base_init, rval);
498138fd1498Szrj 
498238fd1498Szrj   return rval;
498338fd1498Szrj }
498438fd1498Szrj 
498538fd1498Szrj #include "gt-cp-init.h"
4986