xref: /dflybsd-src/contrib/gcc-4.7/gcc/cp/init.c (revision 0a8dc9fc45f4d0b236341a473fac4a486375f60c)
1e4b17023SJohn Marino /* Handle initialization things in C++.
2e4b17023SJohn Marino    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
3e4b17023SJohn Marino    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
4e4b17023SJohn Marino    2011 Free Software Foundation, Inc.
5e4b17023SJohn Marino    Contributed by Michael Tiemann (tiemann@cygnus.com)
6e4b17023SJohn Marino 
7e4b17023SJohn Marino This file is part of GCC.
8e4b17023SJohn Marino 
9e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify
10e4b17023SJohn Marino it under the terms of the GNU General Public License as published by
11e4b17023SJohn Marino the Free Software Foundation; either version 3, or (at your option)
12e4b17023SJohn Marino any later version.
13e4b17023SJohn Marino 
14e4b17023SJohn Marino GCC is distributed in the hope that it will be useful,
15e4b17023SJohn Marino but WITHOUT ANY WARRANTY; without even the implied warranty of
16e4b17023SJohn Marino MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17e4b17023SJohn Marino GNU General Public License for more details.
18e4b17023SJohn Marino 
19e4b17023SJohn Marino You should have received a copy of the GNU General Public License
20e4b17023SJohn Marino along with GCC; see the file COPYING3.  If not see
21e4b17023SJohn Marino <http://www.gnu.org/licenses/>.  */
22e4b17023SJohn Marino 
23e4b17023SJohn Marino /* High-level class interface.  */
24e4b17023SJohn Marino 
25e4b17023SJohn Marino #include "config.h"
26e4b17023SJohn Marino #include "system.h"
27e4b17023SJohn Marino #include "coretypes.h"
28e4b17023SJohn Marino #include "tm.h"
29e4b17023SJohn Marino #include "tree.h"
30e4b17023SJohn Marino #include "cp-tree.h"
31e4b17023SJohn Marino #include "flags.h"
32e4b17023SJohn Marino #include "output.h"
33e4b17023SJohn Marino #include "target.h"
34e4b17023SJohn Marino 
35e4b17023SJohn Marino static bool begin_init_stmts (tree *, tree *);
36e4b17023SJohn Marino static tree finish_init_stmts (bool, tree, tree);
37e4b17023SJohn Marino static void construct_virtual_base (tree, tree);
38e4b17023SJohn Marino static void expand_aggr_init_1 (tree, tree, tree, tree, int, tsubst_flags_t);
39e4b17023SJohn Marino static void expand_default_init (tree, tree, tree, tree, int, tsubst_flags_t);
40e4b17023SJohn Marino static void perform_member_init (tree, tree);
41e4b17023SJohn Marino static tree build_builtin_delete_call (tree);
42e4b17023SJohn Marino static int member_init_ok_or_else (tree, tree, tree);
43e4b17023SJohn Marino static void expand_virtual_init (tree, tree);
44e4b17023SJohn Marino static tree sort_mem_initializers (tree, tree);
45e4b17023SJohn Marino static tree initializing_context (tree);
46e4b17023SJohn Marino static void expand_cleanup_for_base (tree, tree);
47e4b17023SJohn Marino static tree dfs_initialize_vtbl_ptrs (tree, void *);
48e4b17023SJohn Marino static tree build_field_list (tree, tree, int *);
49e4b17023SJohn Marino static tree build_vtbl_address (tree);
50e4b17023SJohn Marino static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool);
51e4b17023SJohn Marino 
52e4b17023SJohn Marino /* We are about to generate some complex initialization code.
53e4b17023SJohn Marino    Conceptually, it is all a single expression.  However, we may want
54e4b17023SJohn Marino    to include conditionals, loops, and other such statement-level
55e4b17023SJohn Marino    constructs.  Therefore, we build the initialization code inside a
56e4b17023SJohn Marino    statement-expression.  This function starts such an expression.
57e4b17023SJohn Marino    STMT_EXPR_P and COMPOUND_STMT_P are filled in by this function;
58e4b17023SJohn Marino    pass them back to finish_init_stmts when the expression is
59e4b17023SJohn Marino    complete.  */
60e4b17023SJohn Marino 
61e4b17023SJohn Marino static bool
begin_init_stmts(tree * stmt_expr_p,tree * compound_stmt_p)62e4b17023SJohn Marino begin_init_stmts (tree *stmt_expr_p, tree *compound_stmt_p)
63e4b17023SJohn Marino {
64e4b17023SJohn Marino   bool is_global = !building_stmt_list_p ();
65e4b17023SJohn Marino 
66e4b17023SJohn Marino   *stmt_expr_p = begin_stmt_expr ();
67e4b17023SJohn Marino   *compound_stmt_p = begin_compound_stmt (BCS_NO_SCOPE);
68e4b17023SJohn Marino 
69e4b17023SJohn Marino   return is_global;
70e4b17023SJohn Marino }
71e4b17023SJohn Marino 
72e4b17023SJohn Marino /* Finish out the statement-expression begun by the previous call to
73e4b17023SJohn Marino    begin_init_stmts.  Returns the statement-expression itself.  */
74e4b17023SJohn Marino 
75e4b17023SJohn Marino static tree
finish_init_stmts(bool is_global,tree stmt_expr,tree compound_stmt)76e4b17023SJohn Marino finish_init_stmts (bool is_global, tree stmt_expr, tree compound_stmt)
77e4b17023SJohn Marino {
78e4b17023SJohn Marino   finish_compound_stmt (compound_stmt);
79e4b17023SJohn Marino 
80e4b17023SJohn Marino   stmt_expr = finish_stmt_expr (stmt_expr, true);
81e4b17023SJohn Marino 
82e4b17023SJohn Marino   gcc_assert (!building_stmt_list_p () == is_global);
83e4b17023SJohn Marino 
84e4b17023SJohn Marino   return stmt_expr;
85e4b17023SJohn Marino }
86e4b17023SJohn Marino 
87e4b17023SJohn Marino /* Constructors */
88e4b17023SJohn Marino 
89e4b17023SJohn Marino /* Called from initialize_vtbl_ptrs via dfs_walk.  BINFO is the base
90e4b17023SJohn Marino    which we want to initialize the vtable pointer for, DATA is
91e4b17023SJohn Marino    TREE_LIST whose TREE_VALUE is the this ptr expression.  */
92e4b17023SJohn Marino 
93e4b17023SJohn Marino static tree
dfs_initialize_vtbl_ptrs(tree binfo,void * data)94e4b17023SJohn Marino dfs_initialize_vtbl_ptrs (tree binfo, void *data)
95e4b17023SJohn Marino {
96e4b17023SJohn Marino   if (!TYPE_CONTAINS_VPTR_P (BINFO_TYPE (binfo)))
97e4b17023SJohn Marino     return dfs_skip_bases;
98e4b17023SJohn Marino 
99e4b17023SJohn Marino   if (!BINFO_PRIMARY_P (binfo) || BINFO_VIRTUAL_P (binfo))
100e4b17023SJohn Marino     {
101e4b17023SJohn Marino       tree base_ptr = TREE_VALUE ((tree) data);
102e4b17023SJohn Marino 
103e4b17023SJohn Marino       base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1,
104e4b17023SJohn Marino 				  tf_warning_or_error);
105e4b17023SJohn Marino 
106e4b17023SJohn Marino       expand_virtual_init (binfo, base_ptr);
107e4b17023SJohn Marino     }
108e4b17023SJohn Marino 
109e4b17023SJohn Marino   return NULL_TREE;
110e4b17023SJohn Marino }
111e4b17023SJohn Marino 
112e4b17023SJohn Marino /* Initialize all the vtable pointers in the object pointed to by
113e4b17023SJohn Marino    ADDR.  */
114e4b17023SJohn Marino 
115e4b17023SJohn Marino void
initialize_vtbl_ptrs(tree addr)116e4b17023SJohn Marino initialize_vtbl_ptrs (tree addr)
117e4b17023SJohn Marino {
118e4b17023SJohn Marino   tree list;
119e4b17023SJohn Marino   tree type;
120e4b17023SJohn Marino 
121e4b17023SJohn Marino   type = TREE_TYPE (TREE_TYPE (addr));
122e4b17023SJohn Marino   list = build_tree_list (type, addr);
123e4b17023SJohn Marino 
124e4b17023SJohn Marino   /* Walk through the hierarchy, initializing the vptr in each base
125e4b17023SJohn Marino      class.  We do these in pre-order because we can't find the virtual
126e4b17023SJohn Marino      bases for a class until we've initialized the vtbl for that
127e4b17023SJohn Marino      class.  */
128e4b17023SJohn Marino   dfs_walk_once (TYPE_BINFO (type), dfs_initialize_vtbl_ptrs, NULL, list);
129e4b17023SJohn Marino }
130e4b17023SJohn Marino 
131e4b17023SJohn Marino /* Return an expression for the zero-initialization of an object with
132e4b17023SJohn Marino    type T.  This expression will either be a constant (in the case
133e4b17023SJohn Marino    that T is a scalar), or a CONSTRUCTOR (in the case that T is an
134e4b17023SJohn Marino    aggregate), or NULL (in the case that T does not require
135e4b17023SJohn Marino    initialization).  In either case, the value can be used as
136e4b17023SJohn Marino    DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
137e4b17023SJohn Marino    initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
138e4b17023SJohn Marino    is the number of elements in the array.  If STATIC_STORAGE_P is
139e4b17023SJohn Marino    TRUE, initializers are only generated for entities for which
140e4b17023SJohn Marino    zero-initialization does not simply mean filling the storage with
141e4b17023SJohn Marino    zero bytes.  FIELD_SIZE, if non-NULL, is the bit size of the field,
142e4b17023SJohn Marino    subfields with bit positions at or above that bit size shouldn't
143e4b17023SJohn Marino    be added.  Note that this only works when the result is assigned
144e4b17023SJohn Marino    to a base COMPONENT_REF; if we only have a pointer to the base subobject,
145e4b17023SJohn Marino    expand_assignment will end up clearing the full size of TYPE.  */
146e4b17023SJohn Marino 
147e4b17023SJohn Marino static tree
build_zero_init_1(tree type,tree nelts,bool static_storage_p,tree field_size)148e4b17023SJohn Marino build_zero_init_1 (tree type, tree nelts, bool static_storage_p,
149e4b17023SJohn Marino 		   tree field_size)
150e4b17023SJohn Marino {
151e4b17023SJohn Marino   tree init = NULL_TREE;
152e4b17023SJohn Marino 
153e4b17023SJohn Marino   /* [dcl.init]
154e4b17023SJohn Marino 
155e4b17023SJohn Marino      To zero-initialize an object of type T means:
156e4b17023SJohn Marino 
157e4b17023SJohn Marino      -- if T is a scalar type, the storage is set to the value of zero
158e4b17023SJohn Marino 	converted to T.
159e4b17023SJohn Marino 
160e4b17023SJohn Marino      -- if T is a non-union class type, the storage for each nonstatic
161e4b17023SJohn Marino 	data member and each base-class subobject is zero-initialized.
162e4b17023SJohn Marino 
163e4b17023SJohn Marino      -- if T is a union type, the storage for its first data member is
164e4b17023SJohn Marino 	zero-initialized.
165e4b17023SJohn Marino 
166e4b17023SJohn Marino      -- if T is an array type, the storage for each element is
167e4b17023SJohn Marino 	zero-initialized.
168e4b17023SJohn Marino 
169e4b17023SJohn Marino      -- if T is a reference type, no initialization is performed.  */
170e4b17023SJohn Marino 
171e4b17023SJohn Marino   gcc_assert (nelts == NULL_TREE || TREE_CODE (nelts) == INTEGER_CST);
172e4b17023SJohn Marino 
173e4b17023SJohn Marino   if (type == error_mark_node)
174e4b17023SJohn Marino     ;
175e4b17023SJohn Marino   else if (static_storage_p && zero_init_p (type))
176e4b17023SJohn Marino     /* In order to save space, we do not explicitly build initializers
177e4b17023SJohn Marino        for items that do not need them.  GCC's semantics are that
178e4b17023SJohn Marino        items with static storage duration that are not otherwise
179e4b17023SJohn Marino        initialized are initialized to zero.  */
180e4b17023SJohn Marino     ;
181e4b17023SJohn Marino   else if (TYPE_PTR_P (type) || TYPE_PTR_TO_MEMBER_P (type))
182e4b17023SJohn Marino     init = convert (type, nullptr_node);
183e4b17023SJohn Marino   else if (SCALAR_TYPE_P (type))
184e4b17023SJohn Marino     init = convert (type, integer_zero_node);
1855ce9237cSJohn Marino   else if (RECORD_OR_UNION_CODE_P (TREE_CODE (type)))
186e4b17023SJohn Marino     {
187e4b17023SJohn Marino       tree field;
188e4b17023SJohn Marino       VEC(constructor_elt,gc) *v = NULL;
189e4b17023SJohn Marino 
190e4b17023SJohn Marino       /* Iterate over the fields, building initializations.  */
191e4b17023SJohn Marino       for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
192e4b17023SJohn Marino 	{
193e4b17023SJohn Marino 	  if (TREE_CODE (field) != FIELD_DECL)
194e4b17023SJohn Marino 	    continue;
195e4b17023SJohn Marino 
196e4b17023SJohn Marino 	  /* Don't add virtual bases for base classes if they are beyond
197e4b17023SJohn Marino 	     the size of the current field, that means it is present
198e4b17023SJohn Marino 	     somewhere else in the object.  */
199e4b17023SJohn Marino 	  if (field_size)
200e4b17023SJohn Marino 	    {
201e4b17023SJohn Marino 	      tree bitpos = bit_position (field);
202e4b17023SJohn Marino 	      if (TREE_CODE (bitpos) == INTEGER_CST
203e4b17023SJohn Marino 		  && !tree_int_cst_lt (bitpos, field_size))
204e4b17023SJohn Marino 		continue;
205e4b17023SJohn Marino 	    }
206e4b17023SJohn Marino 
207e4b17023SJohn Marino 	  /* Note that for class types there will be FIELD_DECLs
208e4b17023SJohn Marino 	     corresponding to base classes as well.  Thus, iterating
209e4b17023SJohn Marino 	     over TYPE_FIELDs will result in correct initialization of
210e4b17023SJohn Marino 	     all of the subobjects.  */
211e4b17023SJohn Marino 	  if (!static_storage_p || !zero_init_p (TREE_TYPE (field)))
212e4b17023SJohn Marino 	    {
213e4b17023SJohn Marino 	      tree new_field_size
214e4b17023SJohn Marino 		= (DECL_FIELD_IS_BASE (field)
215e4b17023SJohn Marino 		   && DECL_SIZE (field)
216e4b17023SJohn Marino 		   && TREE_CODE (DECL_SIZE (field)) == INTEGER_CST)
217e4b17023SJohn Marino 		  ? DECL_SIZE (field) : NULL_TREE;
218e4b17023SJohn Marino 	      tree value = build_zero_init_1 (TREE_TYPE (field),
219e4b17023SJohn Marino 					      /*nelts=*/NULL_TREE,
220e4b17023SJohn Marino 					      static_storage_p,
221e4b17023SJohn Marino 					      new_field_size);
222e4b17023SJohn Marino 	      if (value)
223e4b17023SJohn Marino 		CONSTRUCTOR_APPEND_ELT(v, field, value);
224e4b17023SJohn Marino 	    }
225e4b17023SJohn Marino 
226e4b17023SJohn Marino 	  /* For unions, only the first field is initialized.  */
227e4b17023SJohn Marino 	  if (TREE_CODE (type) == UNION_TYPE)
228e4b17023SJohn Marino 	    break;
229e4b17023SJohn Marino 	}
230e4b17023SJohn Marino 
231e4b17023SJohn Marino       /* Build a constructor to contain the initializations.  */
232e4b17023SJohn Marino       init = build_constructor (type, v);
233e4b17023SJohn Marino     }
234e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE)
235e4b17023SJohn Marino     {
236e4b17023SJohn Marino       tree max_index;
237e4b17023SJohn Marino       VEC(constructor_elt,gc) *v = NULL;
238e4b17023SJohn Marino 
239e4b17023SJohn Marino       /* Iterate over the array elements, building initializations.  */
240e4b17023SJohn Marino       if (nelts)
241e4b17023SJohn Marino 	max_index = fold_build2_loc (input_location,
242e4b17023SJohn Marino 				 MINUS_EXPR, TREE_TYPE (nelts),
243e4b17023SJohn Marino 				 nelts, integer_one_node);
244e4b17023SJohn Marino       else
245e4b17023SJohn Marino 	max_index = array_type_nelts (type);
246e4b17023SJohn Marino 
247e4b17023SJohn Marino       /* If we have an error_mark here, we should just return error mark
248e4b17023SJohn Marino 	 as we don't know the size of the array yet.  */
249e4b17023SJohn Marino       if (max_index == error_mark_node)
250e4b17023SJohn Marino 	return error_mark_node;
251e4b17023SJohn Marino       gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
252e4b17023SJohn Marino 
253e4b17023SJohn Marino       /* A zero-sized array, which is accepted as an extension, will
254e4b17023SJohn Marino 	 have an upper bound of -1.  */
255e4b17023SJohn Marino       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
256e4b17023SJohn Marino 	{
2575ce9237cSJohn Marino 	  constructor_elt ce;
258e4b17023SJohn Marino 
259e4b17023SJohn Marino 	  /* If this is a one element array, we just use a regular init.  */
260e4b17023SJohn Marino 	  if (tree_int_cst_equal (size_zero_node, max_index))
2615ce9237cSJohn Marino 	    ce.index = size_zero_node;
262e4b17023SJohn Marino 	  else
2635ce9237cSJohn Marino 	    ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
264e4b17023SJohn Marino 			       max_index);
265e4b17023SJohn Marino 
2665ce9237cSJohn Marino 	  ce.value = build_zero_init_1 (TREE_TYPE (type),
267e4b17023SJohn Marino 					/*nelts=*/NULL_TREE,
268e4b17023SJohn Marino 					static_storage_p, NULL_TREE);
2695ce9237cSJohn Marino 	  if (ce.value)
2705ce9237cSJohn Marino 	    {
2715ce9237cSJohn Marino 	      v = VEC_alloc (constructor_elt, gc, 1);
2725ce9237cSJohn Marino 	      *VEC_quick_push (constructor_elt, v, NULL) = ce;
2735ce9237cSJohn Marino 	    }
274e4b17023SJohn Marino 	}
275e4b17023SJohn Marino 
276e4b17023SJohn Marino       /* Build a constructor to contain the initializations.  */
277e4b17023SJohn Marino       init = build_constructor (type, v);
278e4b17023SJohn Marino     }
279e4b17023SJohn Marino   else if (TREE_CODE (type) == VECTOR_TYPE)
280e4b17023SJohn Marino     init = build_zero_cst (type);
281e4b17023SJohn Marino   else
282e4b17023SJohn Marino     gcc_assert (TREE_CODE (type) == REFERENCE_TYPE);
283e4b17023SJohn Marino 
284e4b17023SJohn Marino   /* In all cases, the initializer is a constant.  */
285e4b17023SJohn Marino   if (init)
286e4b17023SJohn Marino     TREE_CONSTANT (init) = 1;
287e4b17023SJohn Marino 
288e4b17023SJohn Marino   return init;
289e4b17023SJohn Marino }
290e4b17023SJohn Marino 
291e4b17023SJohn Marino /* Return an expression for the zero-initialization of an object with
292e4b17023SJohn Marino    type T.  This expression will either be a constant (in the case
293e4b17023SJohn Marino    that T is a scalar), or a CONSTRUCTOR (in the case that T is an
294e4b17023SJohn Marino    aggregate), or NULL (in the case that T does not require
295e4b17023SJohn Marino    initialization).  In either case, the value can be used as
296e4b17023SJohn Marino    DECL_INITIAL for a decl of the indicated TYPE; it is a valid static
297e4b17023SJohn Marino    initializer. If NELTS is non-NULL, and TYPE is an ARRAY_TYPE, NELTS
298e4b17023SJohn Marino    is the number of elements in the array.  If STATIC_STORAGE_P is
299e4b17023SJohn Marino    TRUE, initializers are only generated for entities for which
300e4b17023SJohn Marino    zero-initialization does not simply mean filling the storage with
301e4b17023SJohn Marino    zero bytes.  */
302e4b17023SJohn Marino 
303e4b17023SJohn Marino tree
build_zero_init(tree type,tree nelts,bool static_storage_p)304e4b17023SJohn Marino build_zero_init (tree type, tree nelts, bool static_storage_p)
305e4b17023SJohn Marino {
306e4b17023SJohn Marino   return build_zero_init_1 (type, nelts, static_storage_p, NULL_TREE);
307e4b17023SJohn Marino }
308e4b17023SJohn Marino 
309e4b17023SJohn Marino /* Return a suitable initializer for value-initializing an object of type
310e4b17023SJohn Marino    TYPE, as described in [dcl.init].  */
311e4b17023SJohn Marino 
312e4b17023SJohn Marino tree
build_value_init(tree type,tsubst_flags_t complain)313e4b17023SJohn Marino build_value_init (tree type, tsubst_flags_t complain)
314e4b17023SJohn Marino {
315e4b17023SJohn Marino   /* [dcl.init]
316e4b17023SJohn Marino 
317e4b17023SJohn Marino      To value-initialize an object of type T means:
318e4b17023SJohn Marino 
319e4b17023SJohn Marino      - if T is a class type (clause 9) with a user-provided constructor
320e4b17023SJohn Marino        (12.1), then the default constructor for T is called (and the
321e4b17023SJohn Marino        initialization is ill-formed if T has no accessible default
322e4b17023SJohn Marino        constructor);
323e4b17023SJohn Marino 
324e4b17023SJohn Marino      - if T is a non-union class type without a user-provided constructor,
325e4b17023SJohn Marino        then every non-static data member and base-class component of T is
326e4b17023SJohn Marino        value-initialized;92)
327e4b17023SJohn Marino 
328e4b17023SJohn Marino      - if T is an array type, then each element is value-initialized;
329e4b17023SJohn Marino 
330e4b17023SJohn Marino      - otherwise, the object is zero-initialized.
331e4b17023SJohn Marino 
332e4b17023SJohn Marino      A program that calls for default-initialization or
333e4b17023SJohn Marino      value-initialization of an entity of reference type is ill-formed.
334e4b17023SJohn Marino 
335e4b17023SJohn Marino      92) Value-initialization for such a class object may be implemented by
336e4b17023SJohn Marino      zero-initializing the object and then calling the default
337e4b17023SJohn Marino      constructor.  */
338e4b17023SJohn Marino 
339e4b17023SJohn Marino   /* The AGGR_INIT_EXPR tweaking below breaks in templates.  */
340e4b17023SJohn Marino   gcc_assert (!processing_template_decl
341e4b17023SJohn Marino 	      || (SCALAR_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE));
342e4b17023SJohn Marino 
343e4b17023SJohn Marino   if (CLASS_TYPE_P (type))
344e4b17023SJohn Marino     {
345e4b17023SJohn Marino       /* Instead of the above, only consider the user-providedness of the
346e4b17023SJohn Marino 	 default constructor itself so value-initializing a class with an
347e4b17023SJohn Marino 	 explicitly defaulted default constructor and another user-provided
348e4b17023SJohn Marino 	 constructor works properly (c++std-core-19883).  */
349e4b17023SJohn Marino       if (type_has_user_provided_default_constructor (type)
350e4b17023SJohn Marino 	  || (!TYPE_HAS_DEFAULT_CONSTRUCTOR (type)
351e4b17023SJohn Marino 	      && type_has_user_provided_constructor (type)))
352e4b17023SJohn Marino 	return build_aggr_init_expr
353e4b17023SJohn Marino 	  (type,
354e4b17023SJohn Marino 	   build_special_member_call (NULL_TREE, complete_ctor_identifier,
355e4b17023SJohn Marino 				      NULL, type, LOOKUP_NORMAL,
356e4b17023SJohn Marino 				      complain),
357e4b17023SJohn Marino 	   complain);
358e4b17023SJohn Marino       else if (TYPE_HAS_COMPLEX_DFLT (type))
359e4b17023SJohn Marino 	{
360e4b17023SJohn Marino 	  /* This is a class that needs constructing, but doesn't have
361e4b17023SJohn Marino 	     a user-provided constructor.  So we need to zero-initialize
362e4b17023SJohn Marino 	     the object and then call the implicitly defined ctor.
363e4b17023SJohn Marino 	     This will be handled in simplify_aggr_init_expr.  */
364e4b17023SJohn Marino 	  tree ctor = build_special_member_call
365e4b17023SJohn Marino 	    (NULL_TREE, complete_ctor_identifier,
366e4b17023SJohn Marino 	     NULL, type, LOOKUP_NORMAL, complain);
367e4b17023SJohn Marino 	  ctor = build_aggr_init_expr (type, ctor, complain);
368e4b17023SJohn Marino 	  if (ctor != error_mark_node)
369e4b17023SJohn Marino 	    AGGR_INIT_ZERO_FIRST (ctor) = 1;
370e4b17023SJohn Marino 	  return ctor;
371e4b17023SJohn Marino 	}
372e4b17023SJohn Marino     }
373e4b17023SJohn Marino   return build_value_init_noctor (type, complain);
374e4b17023SJohn Marino }
375e4b17023SJohn Marino 
376e4b17023SJohn Marino /* Like build_value_init, but don't call the constructor for TYPE.  Used
377e4b17023SJohn Marino    for base initializers.  */
378e4b17023SJohn Marino 
379e4b17023SJohn Marino tree
build_value_init_noctor(tree type,tsubst_flags_t complain)380e4b17023SJohn Marino build_value_init_noctor (tree type, tsubst_flags_t complain)
381e4b17023SJohn Marino {
382e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (type))
383e4b17023SJohn Marino     {
384e4b17023SJohn Marino       if (complain & tf_error)
385e4b17023SJohn Marino 	error ("value-initialization of incomplete type %qT", type);
386e4b17023SJohn Marino       return error_mark_node;
387e4b17023SJohn Marino     }
388e4b17023SJohn Marino   /* FIXME the class and array cases should just use digest_init once it is
389e4b17023SJohn Marino      SFINAE-enabled.  */
390e4b17023SJohn Marino   if (CLASS_TYPE_P (type))
391e4b17023SJohn Marino     {
392e4b17023SJohn Marino       gcc_assert (!TYPE_HAS_COMPLEX_DFLT (type));
393e4b17023SJohn Marino 
394e4b17023SJohn Marino       if (TREE_CODE (type) != UNION_TYPE)
395e4b17023SJohn Marino 	{
396e4b17023SJohn Marino 	  tree field;
397e4b17023SJohn Marino 	  VEC(constructor_elt,gc) *v = NULL;
398e4b17023SJohn Marino 
399e4b17023SJohn Marino 	  /* Iterate over the fields, building initializations.  */
400e4b17023SJohn Marino 	  for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
401e4b17023SJohn Marino 	    {
402e4b17023SJohn Marino 	      tree ftype, value;
403e4b17023SJohn Marino 
404e4b17023SJohn Marino 	      if (TREE_CODE (field) != FIELD_DECL)
405e4b17023SJohn Marino 		continue;
406e4b17023SJohn Marino 
407e4b17023SJohn Marino 	      ftype = TREE_TYPE (field);
408e4b17023SJohn Marino 
409e4b17023SJohn Marino 	      /* We could skip vfields and fields of types with
410e4b17023SJohn Marino 		 user-defined constructors, but I think that won't improve
411e4b17023SJohn Marino 		 performance at all; it should be simpler in general just
412e4b17023SJohn Marino 		 to zero out the entire object than try to only zero the
413e4b17023SJohn Marino 		 bits that actually need it.  */
414e4b17023SJohn Marino 
415e4b17023SJohn Marino 	      /* Note that for class types there will be FIELD_DECLs
416e4b17023SJohn Marino 		 corresponding to base classes as well.  Thus, iterating
417e4b17023SJohn Marino 		 over TYPE_FIELDs will result in correct initialization of
418e4b17023SJohn Marino 		 all of the subobjects.  */
419e4b17023SJohn Marino 	      value = build_value_init (ftype, complain);
420e4b17023SJohn Marino 
421e4b17023SJohn Marino 	      if (value == error_mark_node)
422e4b17023SJohn Marino 		return error_mark_node;
423e4b17023SJohn Marino 
424e4b17023SJohn Marino 	      if (value)
425e4b17023SJohn Marino 		CONSTRUCTOR_APPEND_ELT(v, field, value);
426e4b17023SJohn Marino 	    }
427e4b17023SJohn Marino 
428e4b17023SJohn Marino 	  /* Build a constructor to contain the zero- initializations.  */
429e4b17023SJohn Marino 	  return build_constructor (type, v);
430e4b17023SJohn Marino 	}
431e4b17023SJohn Marino     }
432e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE)
433e4b17023SJohn Marino     {
434e4b17023SJohn Marino       VEC(constructor_elt,gc) *v = NULL;
435e4b17023SJohn Marino 
436e4b17023SJohn Marino       /* Iterate over the array elements, building initializations.  */
437e4b17023SJohn Marino       tree max_index = array_type_nelts (type);
438e4b17023SJohn Marino 
439e4b17023SJohn Marino       /* If we have an error_mark here, we should just return error mark
440e4b17023SJohn Marino 	 as we don't know the size of the array yet.  */
441e4b17023SJohn Marino       if (max_index == error_mark_node)
442e4b17023SJohn Marino 	{
443e4b17023SJohn Marino 	  if (complain & tf_error)
444e4b17023SJohn Marino 	    error ("cannot value-initialize array of unknown bound %qT",
445e4b17023SJohn Marino 		   type);
446e4b17023SJohn Marino 	  return error_mark_node;
447e4b17023SJohn Marino 	}
448e4b17023SJohn Marino       gcc_assert (TREE_CODE (max_index) == INTEGER_CST);
449e4b17023SJohn Marino 
450e4b17023SJohn Marino       /* A zero-sized array, which is accepted as an extension, will
451e4b17023SJohn Marino 	 have an upper bound of -1.  */
452e4b17023SJohn Marino       if (!tree_int_cst_equal (max_index, integer_minus_one_node))
453e4b17023SJohn Marino 	{
4545ce9237cSJohn Marino 	  constructor_elt ce;
455e4b17023SJohn Marino 
456e4b17023SJohn Marino 	  /* If this is a one element array, we just use a regular init.  */
457e4b17023SJohn Marino 	  if (tree_int_cst_equal (size_zero_node, max_index))
4585ce9237cSJohn Marino 	    ce.index = size_zero_node;
459e4b17023SJohn Marino 	  else
4605ce9237cSJohn Marino 	    ce.index = build2 (RANGE_EXPR, sizetype, size_zero_node,
461e4b17023SJohn Marino 			       max_index);
462e4b17023SJohn Marino 
4635ce9237cSJohn Marino 	  ce.value = build_value_init (TREE_TYPE (type), complain);
464e4b17023SJohn Marino 
4655ce9237cSJohn Marino 	  if (ce.value)
4665ce9237cSJohn Marino 	    {
4675ce9237cSJohn Marino 	      if (ce.value == error_mark_node)
468e4b17023SJohn Marino 		return error_mark_node;
469e4b17023SJohn Marino 
4705ce9237cSJohn Marino 	      v = VEC_alloc (constructor_elt, gc, 1);
4715ce9237cSJohn Marino 	      *VEC_quick_push (constructor_elt, v, NULL) = ce;
4725ce9237cSJohn Marino 
473e4b17023SJohn Marino 	      /* We shouldn't have gotten here for anything that would need
474e4b17023SJohn Marino 		 non-trivial initialization, and gimplify_init_ctor_preeval
475e4b17023SJohn Marino 		 would need to be fixed to allow it.  */
4765ce9237cSJohn Marino 	      gcc_assert (TREE_CODE (ce.value) != TARGET_EXPR
4775ce9237cSJohn Marino 			  && TREE_CODE (ce.value) != AGGR_INIT_EXPR);
4785ce9237cSJohn Marino 	    }
479e4b17023SJohn Marino 	}
480e4b17023SJohn Marino 
481e4b17023SJohn Marino       /* Build a constructor to contain the initializations.  */
482e4b17023SJohn Marino       return build_constructor (type, v);
483e4b17023SJohn Marino     }
484e4b17023SJohn Marino   else if (TREE_CODE (type) == FUNCTION_TYPE)
485e4b17023SJohn Marino     {
486e4b17023SJohn Marino       if (complain & tf_error)
487e4b17023SJohn Marino 	error ("value-initialization of function type %qT", type);
488e4b17023SJohn Marino       return error_mark_node;
489e4b17023SJohn Marino     }
490e4b17023SJohn Marino   else if (TREE_CODE (type) == REFERENCE_TYPE)
491e4b17023SJohn Marino     {
492e4b17023SJohn Marino       if (complain & tf_error)
493e4b17023SJohn Marino 	error ("value-initialization of reference type %qT", type);
494e4b17023SJohn Marino       return error_mark_node;
495e4b17023SJohn Marino     }
496e4b17023SJohn Marino 
497e4b17023SJohn Marino   return build_zero_init (type, NULL_TREE, /*static_storage_p=*/false);
498e4b17023SJohn Marino }
499e4b17023SJohn Marino 
500e4b17023SJohn Marino /* Initialize current class with INIT, a TREE_LIST of
501e4b17023SJohn Marino    arguments for a target constructor. If TREE_LIST is void_type_node,
502e4b17023SJohn Marino    an empty initializer list was given.  */
503e4b17023SJohn Marino 
504e4b17023SJohn Marino static void
perform_target_ctor(tree init)505e4b17023SJohn Marino perform_target_ctor (tree init)
506e4b17023SJohn Marino {
507e4b17023SJohn Marino   tree decl = current_class_ref;
508e4b17023SJohn Marino   tree type = current_class_type;
509e4b17023SJohn Marino 
510e4b17023SJohn Marino   finish_expr_stmt (build_aggr_init (decl, init, LOOKUP_NORMAL,
511e4b17023SJohn Marino                                      tf_warning_or_error));
512e4b17023SJohn Marino   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
513e4b17023SJohn Marino     {
514e4b17023SJohn Marino       tree expr = build_delete (type, decl, sfk_complete_destructor,
515e4b17023SJohn Marino 				LOOKUP_NORMAL
516e4b17023SJohn Marino 				|LOOKUP_NONVIRTUAL
517e4b17023SJohn Marino 				|LOOKUP_DESTRUCTOR,
518e4b17023SJohn Marino 				0, tf_warning_or_error);
519e4b17023SJohn Marino       if (expr != error_mark_node)
520e4b17023SJohn Marino 	finish_eh_cleanup (expr);
521e4b17023SJohn Marino     }
522e4b17023SJohn Marino }
523e4b17023SJohn Marino 
524e4b17023SJohn Marino /* Initialize MEMBER, a FIELD_DECL, with INIT, a TREE_LIST of
525e4b17023SJohn Marino    arguments.  If TREE_LIST is void_type_node, an empty initializer
526e4b17023SJohn Marino    list was given; if NULL_TREE no initializer was given.  */
527e4b17023SJohn Marino 
528e4b17023SJohn Marino static void
perform_member_init(tree member,tree init)529e4b17023SJohn Marino perform_member_init (tree member, tree init)
530e4b17023SJohn Marino {
531e4b17023SJohn Marino   tree decl;
532e4b17023SJohn Marino   tree type = TREE_TYPE (member);
533e4b17023SJohn Marino 
534e4b17023SJohn Marino   /* Use the non-static data member initializer if there was no
535e4b17023SJohn Marino      mem-initializer for this field.  */
536e4b17023SJohn Marino   if (init == NULL_TREE)
537e4b17023SJohn Marino     {
538e4b17023SJohn Marino       if (DECL_LANG_SPECIFIC (member) && DECL_TEMPLATE_INFO (member))
539e4b17023SJohn Marino 	/* Do deferred instantiation of the NSDMI.  */
540e4b17023SJohn Marino 	init = (tsubst_copy_and_build
541e4b17023SJohn Marino 		(DECL_INITIAL (DECL_TI_TEMPLATE (member)),
542e4b17023SJohn Marino 		 DECL_TI_ARGS (member),
543e4b17023SJohn Marino 		 tf_warning_or_error, member, /*function_p=*/false,
544e4b17023SJohn Marino 		 /*integral_constant_expression_p=*/false));
545e4b17023SJohn Marino       else
546e4b17023SJohn Marino 	{
547e4b17023SJohn Marino 	  init = DECL_INITIAL (member);
548e4b17023SJohn Marino 	  /* Strip redundant TARGET_EXPR so we don't need to remap it, and
549e4b17023SJohn Marino 	     so the aggregate init code below will see a CONSTRUCTOR.  */
550e4b17023SJohn Marino 	  if (init && TREE_CODE (init) == TARGET_EXPR
551e4b17023SJohn Marino 	      && !VOID_TYPE_P (TREE_TYPE (TARGET_EXPR_INITIAL (init))))
552e4b17023SJohn Marino 	    init = TARGET_EXPR_INITIAL (init);
553e4b17023SJohn Marino 	  init = break_out_target_exprs (init);
554e4b17023SJohn Marino 	}
555e4b17023SJohn Marino     }
556e4b17023SJohn Marino 
557e4b17023SJohn Marino   if (init == error_mark_node)
558e4b17023SJohn Marino     return;
559e4b17023SJohn Marino 
560e4b17023SJohn Marino   /* Effective C++ rule 12 requires that all data members be
561e4b17023SJohn Marino      initialized.  */
562e4b17023SJohn Marino   if (warn_ecpp && init == NULL_TREE && TREE_CODE (type) != ARRAY_TYPE)
563e4b17023SJohn Marino     warning_at (DECL_SOURCE_LOCATION (current_function_decl), OPT_Weffc__,
564e4b17023SJohn Marino 		"%qD should be initialized in the member initialization list",
565e4b17023SJohn Marino 		member);
566e4b17023SJohn Marino 
567e4b17023SJohn Marino   /* Get an lvalue for the data member.  */
568e4b17023SJohn Marino   decl = build_class_member_access_expr (current_class_ref, member,
569e4b17023SJohn Marino 					 /*access_path=*/NULL_TREE,
570e4b17023SJohn Marino 					 /*preserve_reference=*/true,
571e4b17023SJohn Marino 					 tf_warning_or_error);
572e4b17023SJohn Marino   if (decl == error_mark_node)
573e4b17023SJohn Marino     return;
574e4b17023SJohn Marino 
575e4b17023SJohn Marino   if (warn_init_self && init && TREE_CODE (init) == TREE_LIST
576e4b17023SJohn Marino       && TREE_CHAIN (init) == NULL_TREE)
577e4b17023SJohn Marino     {
578e4b17023SJohn Marino       tree val = TREE_VALUE (init);
579e4b17023SJohn Marino       if (TREE_CODE (val) == COMPONENT_REF && TREE_OPERAND (val, 1) == member
580e4b17023SJohn Marino 	  && TREE_OPERAND (val, 0) == current_class_ref)
581e4b17023SJohn Marino 	warning_at (DECL_SOURCE_LOCATION (current_function_decl),
582e4b17023SJohn Marino 		    OPT_Wuninitialized, "%qD is initialized with itself",
583e4b17023SJohn Marino 		    member);
584e4b17023SJohn Marino     }
585e4b17023SJohn Marino 
586e4b17023SJohn Marino   if (init == void_type_node)
587e4b17023SJohn Marino     {
588e4b17023SJohn Marino       /* mem() means value-initialization.  */
589e4b17023SJohn Marino       if (TREE_CODE (type) == ARRAY_TYPE)
590e4b17023SJohn Marino 	{
591e4b17023SJohn Marino 	  init = build_vec_init_expr (type, init, tf_warning_or_error);
592e4b17023SJohn Marino 	  init = build2 (INIT_EXPR, type, decl, init);
593e4b17023SJohn Marino 	  finish_expr_stmt (init);
594e4b17023SJohn Marino 	}
595e4b17023SJohn Marino       else
596e4b17023SJohn Marino 	{
597e4b17023SJohn Marino 	  tree value = build_value_init (type, tf_warning_or_error);
598e4b17023SJohn Marino 	  if (value == error_mark_node)
599e4b17023SJohn Marino 	    return;
600e4b17023SJohn Marino 	  init = build2 (INIT_EXPR, type, decl, value);
601e4b17023SJohn Marino 	  finish_expr_stmt (init);
602e4b17023SJohn Marino 	}
603e4b17023SJohn Marino     }
604e4b17023SJohn Marino   /* Deal with this here, as we will get confused if we try to call the
605e4b17023SJohn Marino      assignment op for an anonymous union.  This can happen in a
606e4b17023SJohn Marino      synthesized copy constructor.  */
607e4b17023SJohn Marino   else if (ANON_AGGR_TYPE_P (type))
608e4b17023SJohn Marino     {
609e4b17023SJohn Marino       if (init)
610e4b17023SJohn Marino 	{
611e4b17023SJohn Marino 	  init = build2 (INIT_EXPR, type, decl, TREE_VALUE (init));
612e4b17023SJohn Marino 	  finish_expr_stmt (init);
613e4b17023SJohn Marino 	}
614e4b17023SJohn Marino     }
615e4b17023SJohn Marino   else if (init
616e4b17023SJohn Marino 	   && (TREE_CODE (type) == REFERENCE_TYPE
617e4b17023SJohn Marino 	       /* Pre-digested NSDMI.  */
618e4b17023SJohn Marino 	       || (((TREE_CODE (init) == CONSTRUCTOR
619e4b17023SJohn Marino 		     && TREE_TYPE (init) == type)
620e4b17023SJohn Marino 		    /* { } mem-initializer.  */
621e4b17023SJohn Marino 		    || (TREE_CODE (init) == TREE_LIST
622e4b17023SJohn Marino 			&& TREE_CODE (TREE_VALUE (init)) == CONSTRUCTOR
623e4b17023SJohn Marino 			&& CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init))))
624e4b17023SJohn Marino 		   && (CP_AGGREGATE_TYPE_P (type)
625e4b17023SJohn Marino 		       || is_std_init_list (type)))))
626e4b17023SJohn Marino     {
627e4b17023SJohn Marino       /* With references and list-initialization, we need to deal with
628e4b17023SJohn Marino 	 extending temporary lifetimes.  12.2p5: "A temporary bound to a
629e4b17023SJohn Marino 	 reference member in a constructor’s ctor-initializer (12.6.2)
630e4b17023SJohn Marino 	 persists until the constructor exits."  */
631e4b17023SJohn Marino       unsigned i; tree t;
632e4b17023SJohn Marino       VEC(tree,gc) *cleanups = make_tree_vector ();
633e4b17023SJohn Marino       if (TREE_CODE (init) == TREE_LIST)
634e4b17023SJohn Marino 	init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
635e4b17023SJohn Marino 						tf_warning_or_error);
636e4b17023SJohn Marino       if (TREE_TYPE (init) != type)
637e4b17023SJohn Marino 	init = digest_init (type, init, tf_warning_or_error);
638e4b17023SJohn Marino       if (init == error_mark_node)
639e4b17023SJohn Marino 	return;
640e4b17023SJohn Marino       /* A FIELD_DECL doesn't really have a suitable lifetime, but
641e4b17023SJohn Marino 	 make_temporary_var_for_ref_to_temp will treat it as automatic and
642e4b17023SJohn Marino 	 set_up_extended_ref_temp wants to use the decl in a warning.  */
643e4b17023SJohn Marino       init = extend_ref_init_temps (member, init, &cleanups);
644e4b17023SJohn Marino       if (TREE_CODE (type) == ARRAY_TYPE
645e4b17023SJohn Marino 	  && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (type)))
646e4b17023SJohn Marino 	init = build_vec_init_expr (type, init, tf_warning_or_error);
647e4b17023SJohn Marino       init = build2 (INIT_EXPR, type, decl, init);
648e4b17023SJohn Marino       finish_expr_stmt (init);
649e4b17023SJohn Marino       FOR_EACH_VEC_ELT (tree, cleanups, i, t)
650e4b17023SJohn Marino 	push_cleanup (decl, t, false);
651e4b17023SJohn Marino       release_tree_vector (cleanups);
652e4b17023SJohn Marino     }
653e4b17023SJohn Marino   else if (type_build_ctor_call (type)
654e4b17023SJohn Marino 	   || (init && CLASS_TYPE_P (strip_array_types (type))))
655e4b17023SJohn Marino     {
656e4b17023SJohn Marino       if (TREE_CODE (type) == ARRAY_TYPE)
657e4b17023SJohn Marino 	{
658e4b17023SJohn Marino 	  if (init)
659e4b17023SJohn Marino 	    {
660e4b17023SJohn Marino 	      if (TREE_CHAIN (init))
661e4b17023SJohn Marino 		init = error_mark_node;
662e4b17023SJohn Marino 	      else
663e4b17023SJohn Marino 		init = TREE_VALUE (init);
664e4b17023SJohn Marino 	      if (BRACE_ENCLOSED_INITIALIZER_P (init))
665e4b17023SJohn Marino 		init = digest_init (type, init, tf_warning_or_error);
666e4b17023SJohn Marino 	    }
667e4b17023SJohn Marino 	  if (init == NULL_TREE
668e4b17023SJohn Marino 	      || same_type_ignoring_top_level_qualifiers_p (type,
669e4b17023SJohn Marino 							    TREE_TYPE (init)))
670e4b17023SJohn Marino 	    {
671e4b17023SJohn Marino 	      init = build_vec_init_expr (type, init, tf_warning_or_error);
672e4b17023SJohn Marino 	      init = build2 (INIT_EXPR, type, decl, init);
673e4b17023SJohn Marino 	      finish_expr_stmt (init);
674e4b17023SJohn Marino 	    }
675e4b17023SJohn Marino 	  else
676e4b17023SJohn Marino 	    error ("invalid initializer for array member %q#D", member);
677e4b17023SJohn Marino 	}
678e4b17023SJohn Marino       else
679e4b17023SJohn Marino 	{
680e4b17023SJohn Marino 	  int flags = LOOKUP_NORMAL;
681e4b17023SJohn Marino 	  if (DECL_DEFAULTED_FN (current_function_decl))
682e4b17023SJohn Marino 	    flags |= LOOKUP_DEFAULTED;
683e4b17023SJohn Marino 	  if (CP_TYPE_CONST_P (type)
684e4b17023SJohn Marino 	      && init == NULL_TREE
685e4b17023SJohn Marino 	      && default_init_uninitialized_part (type))
686e4b17023SJohn Marino 	    /* TYPE_NEEDS_CONSTRUCTING can be set just because we have a
687e4b17023SJohn Marino 	       vtable; still give this diagnostic.  */
688e4b17023SJohn Marino 	    permerror (DECL_SOURCE_LOCATION (current_function_decl),
689e4b17023SJohn Marino 		       "uninitialized member %qD with %<const%> type %qT",
690e4b17023SJohn Marino 		       member, type);
691e4b17023SJohn Marino 	  finish_expr_stmt (build_aggr_init (decl, init, flags,
692e4b17023SJohn Marino 					     tf_warning_or_error));
693e4b17023SJohn Marino 	}
694e4b17023SJohn Marino     }
695e4b17023SJohn Marino   else
696e4b17023SJohn Marino     {
697e4b17023SJohn Marino       if (init == NULL_TREE)
698e4b17023SJohn Marino 	{
699e4b17023SJohn Marino 	  tree core_type;
700e4b17023SJohn Marino 	  /* member traversal: note it leaves init NULL */
701e4b17023SJohn Marino 	  if (TREE_CODE (type) == REFERENCE_TYPE)
702e4b17023SJohn Marino 	    permerror (DECL_SOURCE_LOCATION (current_function_decl),
703e4b17023SJohn Marino 		       "uninitialized reference member %qD",
704e4b17023SJohn Marino 		       member);
705e4b17023SJohn Marino 	  else if (CP_TYPE_CONST_P (type))
706e4b17023SJohn Marino 	    permerror (DECL_SOURCE_LOCATION (current_function_decl),
707e4b17023SJohn Marino 		       "uninitialized member %qD with %<const%> type %qT",
708e4b17023SJohn Marino 		       member, type);
709e4b17023SJohn Marino 
710e4b17023SJohn Marino 	  core_type = strip_array_types (type);
711e4b17023SJohn Marino 
712e4b17023SJohn Marino 	  if (CLASS_TYPE_P (core_type)
713e4b17023SJohn Marino 	      && (CLASSTYPE_READONLY_FIELDS_NEED_INIT (core_type)
714e4b17023SJohn Marino 		  || CLASSTYPE_REF_FIELDS_NEED_INIT (core_type)))
715e4b17023SJohn Marino 	    diagnose_uninitialized_cst_or_ref_member (core_type,
716e4b17023SJohn Marino 						      /*using_new=*/false,
717e4b17023SJohn Marino 						      /*complain=*/true);
718e4b17023SJohn Marino 	}
719e4b17023SJohn Marino       else if (TREE_CODE (init) == TREE_LIST)
720e4b17023SJohn Marino 	/* There was an explicit member initialization.  Do some work
721e4b17023SJohn Marino 	   in that case.  */
722e4b17023SJohn Marino 	init = build_x_compound_expr_from_list (init, ELK_MEM_INIT,
723e4b17023SJohn Marino 						tf_warning_or_error);
724e4b17023SJohn Marino 
725e4b17023SJohn Marino       if (init)
726e4b17023SJohn Marino 	finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
727e4b17023SJohn Marino 						tf_warning_or_error));
728e4b17023SJohn Marino     }
729e4b17023SJohn Marino 
730e4b17023SJohn Marino   if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
731e4b17023SJohn Marino     {
732e4b17023SJohn Marino       tree expr;
733e4b17023SJohn Marino 
734e4b17023SJohn Marino       expr = build_class_member_access_expr (current_class_ref, member,
735e4b17023SJohn Marino 					     /*access_path=*/NULL_TREE,
736e4b17023SJohn Marino 					     /*preserve_reference=*/false,
737e4b17023SJohn Marino 					     tf_warning_or_error);
738e4b17023SJohn Marino       expr = build_delete (type, expr, sfk_complete_destructor,
739e4b17023SJohn Marino 			   LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0,
740e4b17023SJohn Marino 			   tf_warning_or_error);
741e4b17023SJohn Marino 
742e4b17023SJohn Marino       if (expr != error_mark_node)
743e4b17023SJohn Marino 	finish_eh_cleanup (expr);
744e4b17023SJohn Marino     }
745e4b17023SJohn Marino }
746e4b17023SJohn Marino 
747e4b17023SJohn Marino /* Returns a TREE_LIST containing (as the TREE_PURPOSE of each node) all
748e4b17023SJohn Marino    the FIELD_DECLs on the TYPE_FIELDS list for T, in reverse order.  */
749e4b17023SJohn Marino 
750e4b17023SJohn Marino static tree
build_field_list(tree t,tree list,int * uses_unions_p)751e4b17023SJohn Marino build_field_list (tree t, tree list, int *uses_unions_p)
752e4b17023SJohn Marino {
753e4b17023SJohn Marino   tree fields;
754e4b17023SJohn Marino 
755e4b17023SJohn Marino   /* Note whether or not T is a union.  */
756e4b17023SJohn Marino   if (TREE_CODE (t) == UNION_TYPE)
757e4b17023SJohn Marino     *uses_unions_p = 1;
758e4b17023SJohn Marino 
759e4b17023SJohn Marino   for (fields = TYPE_FIELDS (t); fields; fields = DECL_CHAIN (fields))
760e4b17023SJohn Marino     {
761e4b17023SJohn Marino       tree fieldtype;
762e4b17023SJohn Marino 
763e4b17023SJohn Marino       /* Skip CONST_DECLs for enumeration constants and so forth.  */
764e4b17023SJohn Marino       if (TREE_CODE (fields) != FIELD_DECL || DECL_ARTIFICIAL (fields))
765e4b17023SJohn Marino 	continue;
766e4b17023SJohn Marino 
767e4b17023SJohn Marino       fieldtype = TREE_TYPE (fields);
768e4b17023SJohn Marino       /* Keep track of whether or not any fields are unions.  */
769e4b17023SJohn Marino       if (TREE_CODE (fieldtype) == UNION_TYPE)
770e4b17023SJohn Marino 	*uses_unions_p = 1;
771e4b17023SJohn Marino 
772e4b17023SJohn Marino       /* For an anonymous struct or union, we must recursively
773e4b17023SJohn Marino 	 consider the fields of the anonymous type.  They can be
774e4b17023SJohn Marino 	 directly initialized from the constructor.  */
775e4b17023SJohn Marino       if (ANON_AGGR_TYPE_P (fieldtype))
776e4b17023SJohn Marino 	{
777e4b17023SJohn Marino 	  /* Add this field itself.  Synthesized copy constructors
778e4b17023SJohn Marino 	     initialize the entire aggregate.  */
779e4b17023SJohn Marino 	  list = tree_cons (fields, NULL_TREE, list);
780e4b17023SJohn Marino 	  /* And now add the fields in the anonymous aggregate.  */
781e4b17023SJohn Marino 	  list = build_field_list (fieldtype, list, uses_unions_p);
782e4b17023SJohn Marino 	}
783e4b17023SJohn Marino       /* Add this field.  */
784e4b17023SJohn Marino       else if (DECL_NAME (fields))
785e4b17023SJohn Marino 	list = tree_cons (fields, NULL_TREE, list);
786e4b17023SJohn Marino     }
787e4b17023SJohn Marino 
788e4b17023SJohn Marino   return list;
789e4b17023SJohn Marino }
790e4b17023SJohn Marino 
791e4b17023SJohn Marino /* The MEM_INITS are a TREE_LIST.  The TREE_PURPOSE of each list gives
792e4b17023SJohn Marino    a FIELD_DECL or BINFO in T that needs initialization.  The
793e4b17023SJohn Marino    TREE_VALUE gives the initializer, or list of initializer arguments.
794e4b17023SJohn Marino 
795e4b17023SJohn Marino    Return a TREE_LIST containing all of the initializations required
796e4b17023SJohn Marino    for T, in the order in which they should be performed.  The output
797e4b17023SJohn Marino    list has the same format as the input.  */
798e4b17023SJohn Marino 
799e4b17023SJohn Marino static tree
sort_mem_initializers(tree t,tree mem_inits)800e4b17023SJohn Marino sort_mem_initializers (tree t, tree mem_inits)
801e4b17023SJohn Marino {
802e4b17023SJohn Marino   tree init;
803e4b17023SJohn Marino   tree base, binfo, base_binfo;
804e4b17023SJohn Marino   tree sorted_inits;
805e4b17023SJohn Marino   tree next_subobject;
806e4b17023SJohn Marino   VEC(tree,gc) *vbases;
807e4b17023SJohn Marino   int i;
808e4b17023SJohn Marino   int uses_unions_p = 0;
809e4b17023SJohn Marino 
810e4b17023SJohn Marino   /* Build up a list of initializations.  The TREE_PURPOSE of entry
811e4b17023SJohn Marino      will be the subobject (a FIELD_DECL or BINFO) to initialize.  The
812e4b17023SJohn Marino      TREE_VALUE will be the constructor arguments, or NULL if no
813e4b17023SJohn Marino      explicit initialization was provided.  */
814e4b17023SJohn Marino   sorted_inits = NULL_TREE;
815e4b17023SJohn Marino 
816e4b17023SJohn Marino   /* Process the virtual bases.  */
817e4b17023SJohn Marino   for (vbases = CLASSTYPE_VBASECLASSES (t), i = 0;
818e4b17023SJohn Marino        VEC_iterate (tree, vbases, i, base); i++)
819e4b17023SJohn Marino     sorted_inits = tree_cons (base, NULL_TREE, sorted_inits);
820e4b17023SJohn Marino 
821e4b17023SJohn Marino   /* Process the direct bases.  */
822e4b17023SJohn Marino   for (binfo = TYPE_BINFO (t), i = 0;
823e4b17023SJohn Marino        BINFO_BASE_ITERATE (binfo, i, base_binfo); ++i)
824e4b17023SJohn Marino     if (!BINFO_VIRTUAL_P (base_binfo))
825e4b17023SJohn Marino       sorted_inits = tree_cons (base_binfo, NULL_TREE, sorted_inits);
826e4b17023SJohn Marino 
827e4b17023SJohn Marino   /* Process the non-static data members.  */
828e4b17023SJohn Marino   sorted_inits = build_field_list (t, sorted_inits, &uses_unions_p);
829e4b17023SJohn Marino   /* Reverse the entire list of initializations, so that they are in
830e4b17023SJohn Marino      the order that they will actually be performed.  */
831e4b17023SJohn Marino   sorted_inits = nreverse (sorted_inits);
832e4b17023SJohn Marino 
833e4b17023SJohn Marino   /* If the user presented the initializers in an order different from
834e4b17023SJohn Marino      that in which they will actually occur, we issue a warning.  Keep
835e4b17023SJohn Marino      track of the next subobject which can be explicitly initialized
836e4b17023SJohn Marino      without issuing a warning.  */
837e4b17023SJohn Marino   next_subobject = sorted_inits;
838e4b17023SJohn Marino 
839e4b17023SJohn Marino   /* Go through the explicit initializers, filling in TREE_PURPOSE in
840e4b17023SJohn Marino      the SORTED_INITS.  */
841e4b17023SJohn Marino   for (init = mem_inits; init; init = TREE_CHAIN (init))
842e4b17023SJohn Marino     {
843e4b17023SJohn Marino       tree subobject;
844e4b17023SJohn Marino       tree subobject_init;
845e4b17023SJohn Marino 
846e4b17023SJohn Marino       subobject = TREE_PURPOSE (init);
847e4b17023SJohn Marino 
848e4b17023SJohn Marino       /* If the explicit initializers are in sorted order, then
849e4b17023SJohn Marino 	 SUBOBJECT will be NEXT_SUBOBJECT, or something following
850e4b17023SJohn Marino 	 it.  */
851e4b17023SJohn Marino       for (subobject_init = next_subobject;
852e4b17023SJohn Marino 	   subobject_init;
853e4b17023SJohn Marino 	   subobject_init = TREE_CHAIN (subobject_init))
854e4b17023SJohn Marino 	if (TREE_PURPOSE (subobject_init) == subobject)
855e4b17023SJohn Marino 	  break;
856e4b17023SJohn Marino 
857e4b17023SJohn Marino       /* Issue a warning if the explicit initializer order does not
858e4b17023SJohn Marino 	 match that which will actually occur.
859e4b17023SJohn Marino 	 ??? Are all these on the correct lines?  */
860e4b17023SJohn Marino       if (warn_reorder && !subobject_init)
861e4b17023SJohn Marino 	{
862e4b17023SJohn Marino 	  if (TREE_CODE (TREE_PURPOSE (next_subobject)) == FIELD_DECL)
863e4b17023SJohn Marino 	    warning (OPT_Wreorder, "%q+D will be initialized after",
864e4b17023SJohn Marino 		     TREE_PURPOSE (next_subobject));
865e4b17023SJohn Marino 	  else
866e4b17023SJohn Marino 	    warning (OPT_Wreorder, "base %qT will be initialized after",
867e4b17023SJohn Marino 		     TREE_PURPOSE (next_subobject));
868e4b17023SJohn Marino 	  if (TREE_CODE (subobject) == FIELD_DECL)
869e4b17023SJohn Marino 	    warning (OPT_Wreorder, "  %q+#D", subobject);
870e4b17023SJohn Marino 	  else
871e4b17023SJohn Marino 	    warning (OPT_Wreorder, "  base %qT", subobject);
872e4b17023SJohn Marino 	  warning_at (DECL_SOURCE_LOCATION (current_function_decl),
873e4b17023SJohn Marino 		      OPT_Wreorder, "  when initialized here");
874e4b17023SJohn Marino 	}
875e4b17023SJohn Marino 
876e4b17023SJohn Marino       /* Look again, from the beginning of the list.  */
877e4b17023SJohn Marino       if (!subobject_init)
878e4b17023SJohn Marino 	{
879e4b17023SJohn Marino 	  subobject_init = sorted_inits;
880e4b17023SJohn Marino 	  while (TREE_PURPOSE (subobject_init) != subobject)
881e4b17023SJohn Marino 	    subobject_init = TREE_CHAIN (subobject_init);
882e4b17023SJohn Marino 	}
883e4b17023SJohn Marino 
884e4b17023SJohn Marino       /* It is invalid to initialize the same subobject more than
885e4b17023SJohn Marino 	 once.  */
886e4b17023SJohn Marino       if (TREE_VALUE (subobject_init))
887e4b17023SJohn Marino 	{
888e4b17023SJohn Marino 	  if (TREE_CODE (subobject) == FIELD_DECL)
889e4b17023SJohn Marino 	    error_at (DECL_SOURCE_LOCATION (current_function_decl),
890e4b17023SJohn Marino 		      "multiple initializations given for %qD",
891e4b17023SJohn Marino 		      subobject);
892e4b17023SJohn Marino 	  else
893e4b17023SJohn Marino 	    error_at (DECL_SOURCE_LOCATION (current_function_decl),
894e4b17023SJohn Marino 		      "multiple initializations given for base %qT",
895e4b17023SJohn Marino 		      subobject);
896e4b17023SJohn Marino 	}
897e4b17023SJohn Marino 
898e4b17023SJohn Marino       /* Record the initialization.  */
899e4b17023SJohn Marino       TREE_VALUE (subobject_init) = TREE_VALUE (init);
900e4b17023SJohn Marino       next_subobject = subobject_init;
901e4b17023SJohn Marino     }
902e4b17023SJohn Marino 
903e4b17023SJohn Marino   /* [class.base.init]
904e4b17023SJohn Marino 
905e4b17023SJohn Marino      If a ctor-initializer specifies more than one mem-initializer for
906e4b17023SJohn Marino      multiple members of the same union (including members of
907e4b17023SJohn Marino      anonymous unions), the ctor-initializer is ill-formed.
908e4b17023SJohn Marino 
909e4b17023SJohn Marino      Here we also splice out uninitialized union members.  */
910e4b17023SJohn Marino   if (uses_unions_p)
911e4b17023SJohn Marino     {
912e4b17023SJohn Marino       tree last_field = NULL_TREE;
913e4b17023SJohn Marino       tree *p;
914e4b17023SJohn Marino       for (p = &sorted_inits; *p; )
915e4b17023SJohn Marino 	{
916e4b17023SJohn Marino 	  tree field;
917e4b17023SJohn Marino 	  tree ctx;
918e4b17023SJohn Marino 	  int done;
919e4b17023SJohn Marino 
920e4b17023SJohn Marino 	  init = *p;
921e4b17023SJohn Marino 
922e4b17023SJohn Marino 	  field = TREE_PURPOSE (init);
923e4b17023SJohn Marino 
924e4b17023SJohn Marino 	  /* Skip base classes.  */
925e4b17023SJohn Marino 	  if (TREE_CODE (field) != FIELD_DECL)
926e4b17023SJohn Marino 	    goto next;
927e4b17023SJohn Marino 
928e4b17023SJohn Marino 	  /* If this is an anonymous union with no explicit initializer,
929e4b17023SJohn Marino 	     splice it out.  */
930e4b17023SJohn Marino 	  if (!TREE_VALUE (init) && ANON_UNION_TYPE_P (TREE_TYPE (field)))
931e4b17023SJohn Marino 	    goto splice;
932e4b17023SJohn Marino 
933e4b17023SJohn Marino 	  /* See if this field is a member of a union, or a member of a
934e4b17023SJohn Marino 	     structure contained in a union, etc.  */
935e4b17023SJohn Marino 	  for (ctx = DECL_CONTEXT (field);
936e4b17023SJohn Marino 	       !same_type_p (ctx, t);
937e4b17023SJohn Marino 	       ctx = TYPE_CONTEXT (ctx))
938e4b17023SJohn Marino 	    if (TREE_CODE (ctx) == UNION_TYPE)
939e4b17023SJohn Marino 	      break;
940e4b17023SJohn Marino 	  /* If this field is not a member of a union, skip it.  */
941e4b17023SJohn Marino 	  if (TREE_CODE (ctx) != UNION_TYPE)
942e4b17023SJohn Marino 	    goto next;
943e4b17023SJohn Marino 
944e4b17023SJohn Marino 	  /* If this union member has no explicit initializer, splice
945e4b17023SJohn Marino 	     it out.  */
946e4b17023SJohn Marino 	  if (!TREE_VALUE (init))
947e4b17023SJohn Marino 	    goto splice;
948e4b17023SJohn Marino 
949e4b17023SJohn Marino 	  /* It's only an error if we have two initializers for the same
950e4b17023SJohn Marino 	     union type.  */
951e4b17023SJohn Marino 	  if (!last_field)
952e4b17023SJohn Marino 	    {
953e4b17023SJohn Marino 	      last_field = field;
954e4b17023SJohn Marino 	      goto next;
955e4b17023SJohn Marino 	    }
956e4b17023SJohn Marino 
957e4b17023SJohn Marino 	  /* See if LAST_FIELD and the field initialized by INIT are
958e4b17023SJohn Marino 	     members of the same union.  If so, there's a problem,
959e4b17023SJohn Marino 	     unless they're actually members of the same structure
960e4b17023SJohn Marino 	     which is itself a member of a union.  For example, given:
961e4b17023SJohn Marino 
962e4b17023SJohn Marino 	       union { struct { int i; int j; }; };
963e4b17023SJohn Marino 
964e4b17023SJohn Marino 	     initializing both `i' and `j' makes sense.  */
965e4b17023SJohn Marino 	  ctx = DECL_CONTEXT (field);
966e4b17023SJohn Marino 	  done = 0;
967e4b17023SJohn Marino 	  do
968e4b17023SJohn Marino 	    {
969e4b17023SJohn Marino 	      tree last_ctx;
970e4b17023SJohn Marino 
971e4b17023SJohn Marino 	      last_ctx = DECL_CONTEXT (last_field);
972e4b17023SJohn Marino 	      while (1)
973e4b17023SJohn Marino 		{
974e4b17023SJohn Marino 		  if (same_type_p (last_ctx, ctx))
975e4b17023SJohn Marino 		    {
976e4b17023SJohn Marino 		      if (TREE_CODE (ctx) == UNION_TYPE)
977e4b17023SJohn Marino 			error_at (DECL_SOURCE_LOCATION (current_function_decl),
978e4b17023SJohn Marino 				  "initializations for multiple members of %qT",
979e4b17023SJohn Marino 				  last_ctx);
980e4b17023SJohn Marino 		      done = 1;
981e4b17023SJohn Marino 		      break;
982e4b17023SJohn Marino 		    }
983e4b17023SJohn Marino 
984e4b17023SJohn Marino 		  if (same_type_p (last_ctx, t))
985e4b17023SJohn Marino 		    break;
986e4b17023SJohn Marino 
987e4b17023SJohn Marino 		  last_ctx = TYPE_CONTEXT (last_ctx);
988e4b17023SJohn Marino 		}
989e4b17023SJohn Marino 
990e4b17023SJohn Marino 	      /* If we've reached the outermost class, then we're
991e4b17023SJohn Marino 		 done.  */
992e4b17023SJohn Marino 	      if (same_type_p (ctx, t))
993e4b17023SJohn Marino 		break;
994e4b17023SJohn Marino 
995e4b17023SJohn Marino 	      ctx = TYPE_CONTEXT (ctx);
996e4b17023SJohn Marino 	    }
997e4b17023SJohn Marino 	  while (!done);
998e4b17023SJohn Marino 
999e4b17023SJohn Marino 	  last_field = field;
1000e4b17023SJohn Marino 
1001e4b17023SJohn Marino 	next:
1002e4b17023SJohn Marino 	  p = &TREE_CHAIN (*p);
1003e4b17023SJohn Marino 	  continue;
1004e4b17023SJohn Marino 	splice:
1005e4b17023SJohn Marino 	  *p = TREE_CHAIN (*p);
1006e4b17023SJohn Marino 	  continue;
1007e4b17023SJohn Marino 	}
1008e4b17023SJohn Marino     }
1009e4b17023SJohn Marino 
1010e4b17023SJohn Marino   return sorted_inits;
1011e4b17023SJohn Marino }
1012e4b17023SJohn Marino 
1013e4b17023SJohn Marino /* Initialize all bases and members of CURRENT_CLASS_TYPE.  MEM_INITS
1014e4b17023SJohn Marino    is a TREE_LIST giving the explicit mem-initializer-list for the
1015e4b17023SJohn Marino    constructor.  The TREE_PURPOSE of each entry is a subobject (a
1016e4b17023SJohn Marino    FIELD_DECL or a BINFO) of the CURRENT_CLASS_TYPE.  The TREE_VALUE
1017e4b17023SJohn Marino    is a TREE_LIST giving the arguments to the constructor or
1018e4b17023SJohn Marino    void_type_node for an empty list of arguments.  */
1019e4b17023SJohn Marino 
1020e4b17023SJohn Marino void
emit_mem_initializers(tree mem_inits)1021e4b17023SJohn Marino emit_mem_initializers (tree mem_inits)
1022e4b17023SJohn Marino {
1023e4b17023SJohn Marino   int flags = LOOKUP_NORMAL;
1024e4b17023SJohn Marino 
1025e4b17023SJohn Marino   /* We will already have issued an error message about the fact that
1026e4b17023SJohn Marino      the type is incomplete.  */
1027e4b17023SJohn Marino   if (!COMPLETE_TYPE_P (current_class_type))
1028e4b17023SJohn Marino     return;
1029e4b17023SJohn Marino 
1030e4b17023SJohn Marino   if (mem_inits
1031e4b17023SJohn Marino       && TYPE_P (TREE_PURPOSE (mem_inits))
1032e4b17023SJohn Marino       && same_type_p (TREE_PURPOSE (mem_inits), current_class_type))
1033e4b17023SJohn Marino     {
1034e4b17023SJohn Marino       /* Delegating constructor. */
1035e4b17023SJohn Marino       gcc_assert (TREE_CHAIN (mem_inits) == NULL_TREE);
1036e4b17023SJohn Marino       perform_target_ctor (TREE_VALUE (mem_inits));
1037e4b17023SJohn Marino       return;
1038e4b17023SJohn Marino     }
1039e4b17023SJohn Marino 
1040e4b17023SJohn Marino   if (DECL_DEFAULTED_FN (current_function_decl))
1041e4b17023SJohn Marino     flags |= LOOKUP_DEFAULTED;
1042e4b17023SJohn Marino 
1043e4b17023SJohn Marino   /* Sort the mem-initializers into the order in which the
1044e4b17023SJohn Marino      initializations should be performed.  */
1045e4b17023SJohn Marino   mem_inits = sort_mem_initializers (current_class_type, mem_inits);
1046e4b17023SJohn Marino 
1047e4b17023SJohn Marino   in_base_initializer = 1;
1048e4b17023SJohn Marino 
1049e4b17023SJohn Marino   /* Initialize base classes.  */
1050e4b17023SJohn Marino   while (mem_inits
1051e4b17023SJohn Marino 	 && TREE_CODE (TREE_PURPOSE (mem_inits)) != FIELD_DECL)
1052e4b17023SJohn Marino     {
1053e4b17023SJohn Marino       tree subobject = TREE_PURPOSE (mem_inits);
1054e4b17023SJohn Marino       tree arguments = TREE_VALUE (mem_inits);
1055e4b17023SJohn Marino 
1056e4b17023SJohn Marino       if (arguments == NULL_TREE)
1057e4b17023SJohn Marino 	{
1058e4b17023SJohn Marino 	  /* If these initializations are taking place in a copy constructor,
1059e4b17023SJohn Marino 	     the base class should probably be explicitly initialized if there
1060e4b17023SJohn Marino 	     is a user-defined constructor in the base class (other than the
1061e4b17023SJohn Marino 	     default constructor, which will be called anyway).  */
1062e4b17023SJohn Marino 	  if (extra_warnings
1063e4b17023SJohn Marino 	      && DECL_COPY_CONSTRUCTOR_P (current_function_decl)
1064e4b17023SJohn Marino 	      && type_has_user_nondefault_constructor (BINFO_TYPE (subobject)))
1065e4b17023SJohn Marino 	    warning_at (DECL_SOURCE_LOCATION (current_function_decl),
1066e4b17023SJohn Marino 			OPT_Wextra, "base class %q#T should be explicitly "
1067e4b17023SJohn Marino 			"initialized in the copy constructor",
1068e4b17023SJohn Marino 			BINFO_TYPE (subobject));
1069e4b17023SJohn Marino 	}
1070e4b17023SJohn Marino 
1071e4b17023SJohn Marino       /* Initialize the base.  */
1072e4b17023SJohn Marino       if (BINFO_VIRTUAL_P (subobject))
1073e4b17023SJohn Marino 	construct_virtual_base (subobject, arguments);
1074e4b17023SJohn Marino       else
1075e4b17023SJohn Marino 	{
1076e4b17023SJohn Marino 	  tree base_addr;
1077e4b17023SJohn Marino 
1078e4b17023SJohn Marino 	  base_addr = build_base_path (PLUS_EXPR, current_class_ptr,
1079e4b17023SJohn Marino 				       subobject, 1, tf_warning_or_error);
1080e4b17023SJohn Marino 	  expand_aggr_init_1 (subobject, NULL_TREE,
1081e4b17023SJohn Marino 			      cp_build_indirect_ref (base_addr, RO_NULL,
1082e4b17023SJohn Marino                                                      tf_warning_or_error),
1083e4b17023SJohn Marino 			      arguments,
1084e4b17023SJohn Marino 			      flags,
1085e4b17023SJohn Marino                               tf_warning_or_error);
1086e4b17023SJohn Marino 	  expand_cleanup_for_base (subobject, NULL_TREE);
1087e4b17023SJohn Marino 	}
1088e4b17023SJohn Marino 
1089e4b17023SJohn Marino       mem_inits = TREE_CHAIN (mem_inits);
1090e4b17023SJohn Marino     }
1091e4b17023SJohn Marino   in_base_initializer = 0;
1092e4b17023SJohn Marino 
1093e4b17023SJohn Marino   /* Initialize the vptrs.  */
1094e4b17023SJohn Marino   initialize_vtbl_ptrs (current_class_ptr);
1095e4b17023SJohn Marino 
1096e4b17023SJohn Marino   /* Initialize the data members.  */
1097e4b17023SJohn Marino   while (mem_inits)
1098e4b17023SJohn Marino     {
1099e4b17023SJohn Marino       perform_member_init (TREE_PURPOSE (mem_inits),
1100e4b17023SJohn Marino 			   TREE_VALUE (mem_inits));
1101e4b17023SJohn Marino       mem_inits = TREE_CHAIN (mem_inits);
1102e4b17023SJohn Marino     }
1103e4b17023SJohn Marino }
1104e4b17023SJohn Marino 
1105e4b17023SJohn Marino /* Returns the address of the vtable (i.e., the value that should be
1106e4b17023SJohn Marino    assigned to the vptr) for BINFO.  */
1107e4b17023SJohn Marino 
1108e4b17023SJohn Marino static tree
build_vtbl_address(tree binfo)1109e4b17023SJohn Marino build_vtbl_address (tree binfo)
1110e4b17023SJohn Marino {
1111e4b17023SJohn Marino   tree binfo_for = binfo;
1112e4b17023SJohn Marino   tree vtbl;
1113e4b17023SJohn Marino 
1114e4b17023SJohn Marino   if (BINFO_VPTR_INDEX (binfo) && BINFO_VIRTUAL_P (binfo))
1115e4b17023SJohn Marino     /* If this is a virtual primary base, then the vtable we want to store
1116e4b17023SJohn Marino        is that for the base this is being used as the primary base of.  We
1117e4b17023SJohn Marino        can't simply skip the initialization, because we may be expanding the
1118e4b17023SJohn Marino        inits of a subobject constructor where the virtual base layout
1119e4b17023SJohn Marino        can be different.  */
1120e4b17023SJohn Marino     while (BINFO_PRIMARY_P (binfo_for))
1121e4b17023SJohn Marino       binfo_for = BINFO_INHERITANCE_CHAIN (binfo_for);
1122e4b17023SJohn Marino 
1123e4b17023SJohn Marino   /* Figure out what vtable BINFO's vtable is based on, and mark it as
1124e4b17023SJohn Marino      used.  */
1125e4b17023SJohn Marino   vtbl = get_vtbl_decl_for_binfo (binfo_for);
1126e4b17023SJohn Marino   TREE_USED (vtbl) = 1;
1127e4b17023SJohn Marino 
1128e4b17023SJohn Marino   /* Now compute the address to use when initializing the vptr.  */
1129e4b17023SJohn Marino   vtbl = unshare_expr (BINFO_VTABLE (binfo_for));
1130e4b17023SJohn Marino   if (TREE_CODE (vtbl) == VAR_DECL)
1131e4b17023SJohn Marino     vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl);
1132e4b17023SJohn Marino 
1133e4b17023SJohn Marino   return vtbl;
1134e4b17023SJohn Marino }
1135e4b17023SJohn Marino 
1136e4b17023SJohn Marino /* This code sets up the virtual function tables appropriate for
1137e4b17023SJohn Marino    the pointer DECL.  It is a one-ply initialization.
1138e4b17023SJohn Marino 
1139e4b17023SJohn Marino    BINFO is the exact type that DECL is supposed to be.  In
1140e4b17023SJohn Marino    multiple inheritance, this might mean "C's A" if C : A, B.  */
1141e4b17023SJohn Marino 
1142e4b17023SJohn Marino static void
expand_virtual_init(tree binfo,tree decl)1143e4b17023SJohn Marino expand_virtual_init (tree binfo, tree decl)
1144e4b17023SJohn Marino {
1145e4b17023SJohn Marino   tree vtbl, vtbl_ptr;
1146e4b17023SJohn Marino   tree vtt_index;
1147e4b17023SJohn Marino 
1148e4b17023SJohn Marino   /* Compute the initializer for vptr.  */
1149e4b17023SJohn Marino   vtbl = build_vtbl_address (binfo);
1150e4b17023SJohn Marino 
1151e4b17023SJohn Marino   /* We may get this vptr from a VTT, if this is a subobject
1152e4b17023SJohn Marino      constructor or subobject destructor.  */
1153e4b17023SJohn Marino   vtt_index = BINFO_VPTR_INDEX (binfo);
1154e4b17023SJohn Marino   if (vtt_index)
1155e4b17023SJohn Marino     {
1156e4b17023SJohn Marino       tree vtbl2;
1157e4b17023SJohn Marino       tree vtt_parm;
1158e4b17023SJohn Marino 
1159e4b17023SJohn Marino       /* Compute the value to use, when there's a VTT.  */
1160e4b17023SJohn Marino       vtt_parm = current_vtt_parm;
1161e4b17023SJohn Marino       vtbl2 = fold_build_pointer_plus (vtt_parm, vtt_index);
1162e4b17023SJohn Marino       vtbl2 = cp_build_indirect_ref (vtbl2, RO_NULL, tf_warning_or_error);
1163e4b17023SJohn Marino       vtbl2 = convert (TREE_TYPE (vtbl), vtbl2);
1164e4b17023SJohn Marino 
1165e4b17023SJohn Marino       /* The actual initializer is the VTT value only in the subobject
1166e4b17023SJohn Marino 	 constructor.  In maybe_clone_body we'll substitute NULL for
1167e4b17023SJohn Marino 	 the vtt_parm in the case of the non-subobject constructor.  */
1168e4b17023SJohn Marino       vtbl = build3 (COND_EXPR,
1169e4b17023SJohn Marino 		     TREE_TYPE (vtbl),
1170e4b17023SJohn Marino 		     build2 (EQ_EXPR, boolean_type_node,
1171e4b17023SJohn Marino 			     current_in_charge_parm, integer_zero_node),
1172e4b17023SJohn Marino 		     vtbl2,
1173e4b17023SJohn Marino 		     vtbl);
1174e4b17023SJohn Marino     }
1175e4b17023SJohn Marino 
1176e4b17023SJohn Marino   /* Compute the location of the vtpr.  */
1177e4b17023SJohn Marino   vtbl_ptr = build_vfield_ref (cp_build_indirect_ref (decl, RO_NULL,
1178e4b17023SJohn Marino                                                       tf_warning_or_error),
1179e4b17023SJohn Marino 			       TREE_TYPE (binfo));
1180e4b17023SJohn Marino   gcc_assert (vtbl_ptr != error_mark_node);
1181e4b17023SJohn Marino 
1182e4b17023SJohn Marino   /* Assign the vtable to the vptr.  */
1183e4b17023SJohn Marino   vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0);
1184e4b17023SJohn Marino   finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
1185e4b17023SJohn Marino 					  tf_warning_or_error));
1186e4b17023SJohn Marino }
1187e4b17023SJohn Marino 
1188e4b17023SJohn Marino /* If an exception is thrown in a constructor, those base classes already
1189e4b17023SJohn Marino    constructed must be destroyed.  This function creates the cleanup
1190e4b17023SJohn Marino    for BINFO, which has just been constructed.  If FLAG is non-NULL,
1191e4b17023SJohn Marino    it is a DECL which is nonzero when this base needs to be
1192e4b17023SJohn Marino    destroyed.  */
1193e4b17023SJohn Marino 
1194e4b17023SJohn Marino static void
expand_cleanup_for_base(tree binfo,tree flag)1195e4b17023SJohn Marino expand_cleanup_for_base (tree binfo, tree flag)
1196e4b17023SJohn Marino {
1197e4b17023SJohn Marino   tree expr;
1198e4b17023SJohn Marino 
1199e4b17023SJohn Marino   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (binfo)))
1200e4b17023SJohn Marino     return;
1201e4b17023SJohn Marino 
1202e4b17023SJohn Marino   /* Call the destructor.  */
1203e4b17023SJohn Marino   expr = build_special_member_call (current_class_ref,
1204e4b17023SJohn Marino 				    base_dtor_identifier,
1205e4b17023SJohn Marino 				    NULL,
1206e4b17023SJohn Marino 				    binfo,
1207e4b17023SJohn Marino 				    LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
1208e4b17023SJohn Marino                                     tf_warning_or_error);
1209e4b17023SJohn Marino   if (flag)
1210e4b17023SJohn Marino     expr = fold_build3_loc (input_location,
1211e4b17023SJohn Marino 			COND_EXPR, void_type_node,
1212e4b17023SJohn Marino 			c_common_truthvalue_conversion (input_location, flag),
1213e4b17023SJohn Marino 			expr, integer_zero_node);
1214e4b17023SJohn Marino 
1215e4b17023SJohn Marino   finish_eh_cleanup (expr);
1216e4b17023SJohn Marino }
1217e4b17023SJohn Marino 
1218e4b17023SJohn Marino /* Construct the virtual base-class VBASE passing the ARGUMENTS to its
1219e4b17023SJohn Marino    constructor.  */
1220e4b17023SJohn Marino 
1221e4b17023SJohn Marino static void
construct_virtual_base(tree vbase,tree arguments)1222e4b17023SJohn Marino construct_virtual_base (tree vbase, tree arguments)
1223e4b17023SJohn Marino {
1224e4b17023SJohn Marino   tree inner_if_stmt;
1225e4b17023SJohn Marino   tree exp;
1226e4b17023SJohn Marino   tree flag;
1227e4b17023SJohn Marino 
1228e4b17023SJohn Marino   /* If there are virtual base classes with destructors, we need to
1229e4b17023SJohn Marino      emit cleanups to destroy them if an exception is thrown during
1230e4b17023SJohn Marino      the construction process.  These exception regions (i.e., the
1231e4b17023SJohn Marino      period during which the cleanups must occur) begin from the time
1232e4b17023SJohn Marino      the construction is complete to the end of the function.  If we
1233e4b17023SJohn Marino      create a conditional block in which to initialize the
1234e4b17023SJohn Marino      base-classes, then the cleanup region for the virtual base begins
1235e4b17023SJohn Marino      inside a block, and ends outside of that block.  This situation
1236e4b17023SJohn Marino      confuses the sjlj exception-handling code.  Therefore, we do not
1237e4b17023SJohn Marino      create a single conditional block, but one for each
1238e4b17023SJohn Marino      initialization.  (That way the cleanup regions always begin
1239e4b17023SJohn Marino      in the outer block.)  We trust the back end to figure out
1240e4b17023SJohn Marino      that the FLAG will not change across initializations, and
1241e4b17023SJohn Marino      avoid doing multiple tests.  */
1242e4b17023SJohn Marino   flag = DECL_CHAIN (DECL_ARGUMENTS (current_function_decl));
1243e4b17023SJohn Marino   inner_if_stmt = begin_if_stmt ();
1244e4b17023SJohn Marino   finish_if_stmt_cond (flag, inner_if_stmt);
1245e4b17023SJohn Marino 
1246e4b17023SJohn Marino   /* Compute the location of the virtual base.  If we're
1247e4b17023SJohn Marino      constructing virtual bases, then we must be the most derived
1248e4b17023SJohn Marino      class.  Therefore, we don't have to look up the virtual base;
1249e4b17023SJohn Marino      we already know where it is.  */
1250e4b17023SJohn Marino   exp = convert_to_base_statically (current_class_ref, vbase);
1251e4b17023SJohn Marino 
1252e4b17023SJohn Marino   expand_aggr_init_1 (vbase, current_class_ref, exp, arguments,
1253e4b17023SJohn Marino 		      LOOKUP_COMPLAIN, tf_warning_or_error);
1254e4b17023SJohn Marino   finish_then_clause (inner_if_stmt);
1255e4b17023SJohn Marino   finish_if_stmt (inner_if_stmt);
1256e4b17023SJohn Marino 
1257e4b17023SJohn Marino   expand_cleanup_for_base (vbase, flag);
1258e4b17023SJohn Marino }
1259e4b17023SJohn Marino 
1260e4b17023SJohn Marino /* Find the context in which this FIELD can be initialized.  */
1261e4b17023SJohn Marino 
1262e4b17023SJohn Marino static tree
initializing_context(tree field)1263e4b17023SJohn Marino initializing_context (tree field)
1264e4b17023SJohn Marino {
1265e4b17023SJohn Marino   tree t = DECL_CONTEXT (field);
1266e4b17023SJohn Marino 
1267e4b17023SJohn Marino   /* Anonymous union members can be initialized in the first enclosing
1268e4b17023SJohn Marino      non-anonymous union context.  */
1269e4b17023SJohn Marino   while (t && ANON_AGGR_TYPE_P (t))
1270e4b17023SJohn Marino     t = TYPE_CONTEXT (t);
1271e4b17023SJohn Marino   return t;
1272e4b17023SJohn Marino }
1273e4b17023SJohn Marino 
1274e4b17023SJohn Marino /* Function to give error message if member initialization specification
1275e4b17023SJohn Marino    is erroneous.  FIELD is the member we decided to initialize.
1276e4b17023SJohn Marino    TYPE is the type for which the initialization is being performed.
1277e4b17023SJohn Marino    FIELD must be a member of TYPE.
1278e4b17023SJohn Marino 
1279e4b17023SJohn Marino    MEMBER_NAME is the name of the member.  */
1280e4b17023SJohn Marino 
1281e4b17023SJohn Marino static int
member_init_ok_or_else(tree field,tree type,tree member_name)1282e4b17023SJohn Marino member_init_ok_or_else (tree field, tree type, tree member_name)
1283e4b17023SJohn Marino {
1284e4b17023SJohn Marino   if (field == error_mark_node)
1285e4b17023SJohn Marino     return 0;
1286e4b17023SJohn Marino   if (!field)
1287e4b17023SJohn Marino     {
1288e4b17023SJohn Marino       error ("class %qT does not have any field named %qD", type,
1289e4b17023SJohn Marino 	     member_name);
1290e4b17023SJohn Marino       return 0;
1291e4b17023SJohn Marino     }
1292e4b17023SJohn Marino   if (TREE_CODE (field) == VAR_DECL)
1293e4b17023SJohn Marino     {
1294e4b17023SJohn Marino       error ("%q#D is a static data member; it can only be "
1295e4b17023SJohn Marino 	     "initialized at its definition",
1296e4b17023SJohn Marino 	     field);
1297e4b17023SJohn Marino       return 0;
1298e4b17023SJohn Marino     }
1299e4b17023SJohn Marino   if (TREE_CODE (field) != FIELD_DECL)
1300e4b17023SJohn Marino     {
1301e4b17023SJohn Marino       error ("%q#D is not a non-static data member of %qT",
1302e4b17023SJohn Marino 	     field, type);
1303e4b17023SJohn Marino       return 0;
1304e4b17023SJohn Marino     }
1305e4b17023SJohn Marino   if (initializing_context (field) != type)
1306e4b17023SJohn Marino     {
1307e4b17023SJohn Marino       error ("class %qT does not have any field named %qD", type,
1308e4b17023SJohn Marino 		member_name);
1309e4b17023SJohn Marino       return 0;
1310e4b17023SJohn Marino     }
1311e4b17023SJohn Marino 
1312e4b17023SJohn Marino   return 1;
1313e4b17023SJohn Marino }
1314e4b17023SJohn Marino 
1315e4b17023SJohn Marino /* NAME is a FIELD_DECL, an IDENTIFIER_NODE which names a field, or it
1316e4b17023SJohn Marino    is a _TYPE node or TYPE_DECL which names a base for that type.
1317e4b17023SJohn Marino    Check the validity of NAME, and return either the base _TYPE, base
1318e4b17023SJohn Marino    binfo, or the FIELD_DECL of the member.  If NAME is invalid, return
1319e4b17023SJohn Marino    NULL_TREE and issue a diagnostic.
1320e4b17023SJohn Marino 
1321e4b17023SJohn Marino    An old style unnamed direct single base construction is permitted,
1322e4b17023SJohn Marino    where NAME is NULL.  */
1323e4b17023SJohn Marino 
1324e4b17023SJohn Marino tree
expand_member_init(tree name)1325e4b17023SJohn Marino expand_member_init (tree name)
1326e4b17023SJohn Marino {
1327e4b17023SJohn Marino   tree basetype;
1328e4b17023SJohn Marino   tree field;
1329e4b17023SJohn Marino 
1330e4b17023SJohn Marino   if (!current_class_ref)
1331e4b17023SJohn Marino     return NULL_TREE;
1332e4b17023SJohn Marino 
1333e4b17023SJohn Marino   if (!name)
1334e4b17023SJohn Marino     {
1335e4b17023SJohn Marino       /* This is an obsolete unnamed base class initializer.  The
1336e4b17023SJohn Marino 	 parser will already have warned about its use.  */
1337e4b17023SJohn Marino       switch (BINFO_N_BASE_BINFOS (TYPE_BINFO (current_class_type)))
1338e4b17023SJohn Marino 	{
1339e4b17023SJohn Marino 	case 0:
1340e4b17023SJohn Marino 	  error ("unnamed initializer for %qT, which has no base classes",
1341e4b17023SJohn Marino 		 current_class_type);
1342e4b17023SJohn Marino 	  return NULL_TREE;
1343e4b17023SJohn Marino 	case 1:
1344e4b17023SJohn Marino 	  basetype = BINFO_TYPE
1345e4b17023SJohn Marino 	    (BINFO_BASE_BINFO (TYPE_BINFO (current_class_type), 0));
1346e4b17023SJohn Marino 	  break;
1347e4b17023SJohn Marino 	default:
1348e4b17023SJohn Marino 	  error ("unnamed initializer for %qT, which uses multiple inheritance",
1349e4b17023SJohn Marino 		 current_class_type);
1350e4b17023SJohn Marino 	  return NULL_TREE;
1351e4b17023SJohn Marino       }
1352e4b17023SJohn Marino     }
1353e4b17023SJohn Marino   else if (TYPE_P (name))
1354e4b17023SJohn Marino     {
1355e4b17023SJohn Marino       basetype = TYPE_MAIN_VARIANT (name);
1356e4b17023SJohn Marino       name = TYPE_NAME (name);
1357e4b17023SJohn Marino     }
1358e4b17023SJohn Marino   else if (TREE_CODE (name) == TYPE_DECL)
1359e4b17023SJohn Marino     basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name));
1360e4b17023SJohn Marino   else
1361e4b17023SJohn Marino     basetype = NULL_TREE;
1362e4b17023SJohn Marino 
1363e4b17023SJohn Marino   if (basetype)
1364e4b17023SJohn Marino     {
1365e4b17023SJohn Marino       tree class_binfo;
1366e4b17023SJohn Marino       tree direct_binfo;
1367e4b17023SJohn Marino       tree virtual_binfo;
1368e4b17023SJohn Marino       int i;
1369e4b17023SJohn Marino 
1370e4b17023SJohn Marino       if (same_type_p (basetype, current_class_type)
1371e4b17023SJohn Marino 	  || current_template_parms)
1372e4b17023SJohn Marino 	  return basetype;
1373e4b17023SJohn Marino 
1374e4b17023SJohn Marino       class_binfo = TYPE_BINFO (current_class_type);
1375e4b17023SJohn Marino       direct_binfo = NULL_TREE;
1376e4b17023SJohn Marino       virtual_binfo = NULL_TREE;
1377e4b17023SJohn Marino 
1378e4b17023SJohn Marino       /* Look for a direct base.  */
1379e4b17023SJohn Marino       for (i = 0; BINFO_BASE_ITERATE (class_binfo, i, direct_binfo); ++i)
1380e4b17023SJohn Marino 	if (SAME_BINFO_TYPE_P (BINFO_TYPE (direct_binfo), basetype))
1381e4b17023SJohn Marino 	  break;
1382e4b17023SJohn Marino 
1383e4b17023SJohn Marino       /* Look for a virtual base -- unless the direct base is itself
1384e4b17023SJohn Marino 	 virtual.  */
1385e4b17023SJohn Marino       if (!direct_binfo || !BINFO_VIRTUAL_P (direct_binfo))
1386e4b17023SJohn Marino 	virtual_binfo = binfo_for_vbase (basetype, current_class_type);
1387e4b17023SJohn Marino 
1388e4b17023SJohn Marino       /* [class.base.init]
1389e4b17023SJohn Marino 
1390e4b17023SJohn Marino 	 If a mem-initializer-id is ambiguous because it designates
1391e4b17023SJohn Marino 	 both a direct non-virtual base class and an inherited virtual
1392e4b17023SJohn Marino 	 base class, the mem-initializer is ill-formed.  */
1393e4b17023SJohn Marino       if (direct_binfo && virtual_binfo)
1394e4b17023SJohn Marino 	{
1395e4b17023SJohn Marino 	  error ("%qD is both a direct base and an indirect virtual base",
1396e4b17023SJohn Marino 		 basetype);
1397e4b17023SJohn Marino 	  return NULL_TREE;
1398e4b17023SJohn Marino 	}
1399e4b17023SJohn Marino 
1400e4b17023SJohn Marino       if (!direct_binfo && !virtual_binfo)
1401e4b17023SJohn Marino 	{
1402e4b17023SJohn Marino 	  if (CLASSTYPE_VBASECLASSES (current_class_type))
1403e4b17023SJohn Marino 	    error ("type %qT is not a direct or virtual base of %qT",
1404e4b17023SJohn Marino 		   basetype, current_class_type);
1405e4b17023SJohn Marino 	  else
1406e4b17023SJohn Marino 	    error ("type %qT is not a direct base of %qT",
1407e4b17023SJohn Marino 		   basetype, current_class_type);
1408e4b17023SJohn Marino 	  return NULL_TREE;
1409e4b17023SJohn Marino 	}
1410e4b17023SJohn Marino 
1411e4b17023SJohn Marino       return direct_binfo ? direct_binfo : virtual_binfo;
1412e4b17023SJohn Marino     }
1413e4b17023SJohn Marino   else
1414e4b17023SJohn Marino     {
1415e4b17023SJohn Marino       if (TREE_CODE (name) == IDENTIFIER_NODE)
1416e4b17023SJohn Marino 	field = lookup_field (current_class_type, name, 1, false);
1417e4b17023SJohn Marino       else
1418e4b17023SJohn Marino 	field = name;
1419e4b17023SJohn Marino 
1420e4b17023SJohn Marino       if (member_init_ok_or_else (field, current_class_type, name))
1421e4b17023SJohn Marino 	return field;
1422e4b17023SJohn Marino     }
1423e4b17023SJohn Marino 
1424e4b17023SJohn Marino   return NULL_TREE;
1425e4b17023SJohn Marino }
1426e4b17023SJohn Marino 
1427e4b17023SJohn Marino /* This is like `expand_member_init', only it stores one aggregate
1428e4b17023SJohn Marino    value into another.
1429e4b17023SJohn Marino 
1430e4b17023SJohn Marino    INIT comes in two flavors: it is either a value which
1431e4b17023SJohn Marino    is to be stored in EXP, or it is a parameter list
1432e4b17023SJohn Marino    to go to a constructor, which will operate on EXP.
1433e4b17023SJohn Marino    If INIT is not a parameter list for a constructor, then set
1434e4b17023SJohn Marino    LOOKUP_ONLYCONVERTING.
1435e4b17023SJohn Marino    If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of
1436e4b17023SJohn Marino    the initializer, if FLAGS is 0, then it is the (init) form.
1437e4b17023SJohn Marino    If `init' is a CONSTRUCTOR, then we emit a warning message,
1438e4b17023SJohn Marino    explaining that such initializations are invalid.
1439e4b17023SJohn Marino 
1440e4b17023SJohn Marino    If INIT resolves to a CALL_EXPR which happens to return
1441e4b17023SJohn Marino    something of the type we are looking for, then we know
1442e4b17023SJohn Marino    that we can safely use that call to perform the
1443e4b17023SJohn Marino    initialization.
1444e4b17023SJohn Marino 
1445e4b17023SJohn Marino    The virtual function table pointer cannot be set up here, because
1446e4b17023SJohn Marino    we do not really know its type.
1447e4b17023SJohn Marino 
1448e4b17023SJohn Marino    This never calls operator=().
1449e4b17023SJohn Marino 
1450e4b17023SJohn Marino    When initializing, nothing is CONST.
1451e4b17023SJohn Marino 
1452e4b17023SJohn Marino    A default copy constructor may have to be used to perform the
1453e4b17023SJohn Marino    initialization.
1454e4b17023SJohn Marino 
1455e4b17023SJohn Marino    A constructor or a conversion operator may have to be used to
1456e4b17023SJohn Marino    perform the initialization, but not both, as it would be ambiguous.  */
1457e4b17023SJohn Marino 
1458e4b17023SJohn Marino tree
build_aggr_init(tree exp,tree init,int flags,tsubst_flags_t complain)1459e4b17023SJohn Marino build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
1460e4b17023SJohn Marino {
1461e4b17023SJohn Marino   tree stmt_expr;
1462e4b17023SJohn Marino   tree compound_stmt;
1463e4b17023SJohn Marino   int destroy_temps;
1464e4b17023SJohn Marino   tree type = TREE_TYPE (exp);
1465e4b17023SJohn Marino   int was_const = TREE_READONLY (exp);
1466e4b17023SJohn Marino   int was_volatile = TREE_THIS_VOLATILE (exp);
1467e4b17023SJohn Marino   int is_global;
1468e4b17023SJohn Marino 
1469e4b17023SJohn Marino   if (init == error_mark_node)
1470e4b17023SJohn Marino     return error_mark_node;
1471e4b17023SJohn Marino 
1472e4b17023SJohn Marino   TREE_READONLY (exp) = 0;
1473e4b17023SJohn Marino   TREE_THIS_VOLATILE (exp) = 0;
1474e4b17023SJohn Marino 
1475e4b17023SJohn Marino   if (init && TREE_CODE (init) != TREE_LIST
1476e4b17023SJohn Marino       && !(TREE_CODE (init) == TARGET_EXPR
1477e4b17023SJohn Marino 	   && TARGET_EXPR_DIRECT_INIT_P (init))
1478e4b17023SJohn Marino       && !(BRACE_ENCLOSED_INITIALIZER_P (init)
1479e4b17023SJohn Marino 	   && CONSTRUCTOR_IS_DIRECT_INIT (init)))
1480e4b17023SJohn Marino     flags |= LOOKUP_ONLYCONVERTING;
1481e4b17023SJohn Marino 
1482e4b17023SJohn Marino   if (TREE_CODE (type) == ARRAY_TYPE)
1483e4b17023SJohn Marino     {
1484e4b17023SJohn Marino       tree itype;
1485e4b17023SJohn Marino 
1486e4b17023SJohn Marino       /* An array may not be initialized use the parenthesized
1487e4b17023SJohn Marino 	 initialization form -- unless the initializer is "()".  */
1488e4b17023SJohn Marino       if (init && TREE_CODE (init) == TREE_LIST)
1489e4b17023SJohn Marino 	{
1490e4b17023SJohn Marino           if (complain & tf_error)
1491e4b17023SJohn Marino             error ("bad array initializer");
1492e4b17023SJohn Marino 	  return error_mark_node;
1493e4b17023SJohn Marino 	}
1494e4b17023SJohn Marino       /* Must arrange to initialize each element of EXP
1495e4b17023SJohn Marino 	 from elements of INIT.  */
1496e4b17023SJohn Marino       itype = init ? TREE_TYPE (init) : NULL_TREE;
1497e4b17023SJohn Marino       if (cv_qualified_p (type))
1498e4b17023SJohn Marino 	TREE_TYPE (exp) = cv_unqualified (type);
1499e4b17023SJohn Marino       if (itype && cv_qualified_p (itype))
1500e4b17023SJohn Marino 	TREE_TYPE (init) = cv_unqualified (itype);
1501e4b17023SJohn Marino       stmt_expr = build_vec_init (exp, NULL_TREE, init,
1502e4b17023SJohn Marino 				  /*explicit_value_init_p=*/false,
1503e4b17023SJohn Marino 				  itype && same_type_p (TREE_TYPE (init),
1504e4b17023SJohn Marino 							TREE_TYPE (exp)),
1505e4b17023SJohn Marino                                   complain);
1506e4b17023SJohn Marino       TREE_READONLY (exp) = was_const;
1507e4b17023SJohn Marino       TREE_THIS_VOLATILE (exp) = was_volatile;
1508e4b17023SJohn Marino       TREE_TYPE (exp) = type;
1509e4b17023SJohn Marino       if (init)
1510e4b17023SJohn Marino 	TREE_TYPE (init) = itype;
1511e4b17023SJohn Marino       return stmt_expr;
1512e4b17023SJohn Marino     }
1513e4b17023SJohn Marino 
1514e4b17023SJohn Marino   if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL)
1515e4b17023SJohn Marino     /* Just know that we've seen something for this node.  */
1516e4b17023SJohn Marino     TREE_USED (exp) = 1;
1517e4b17023SJohn Marino 
1518e4b17023SJohn Marino   is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
1519e4b17023SJohn Marino   destroy_temps = stmts_are_full_exprs_p ();
1520e4b17023SJohn Marino   current_stmt_tree ()->stmts_are_full_exprs_p = 0;
1521e4b17023SJohn Marino   expand_aggr_init_1 (TYPE_BINFO (type), exp, exp,
1522e4b17023SJohn Marino 		      init, LOOKUP_NORMAL|flags, complain);
1523e4b17023SJohn Marino   stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
1524e4b17023SJohn Marino   current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
1525e4b17023SJohn Marino   TREE_READONLY (exp) = was_const;
1526e4b17023SJohn Marino   TREE_THIS_VOLATILE (exp) = was_volatile;
1527e4b17023SJohn Marino 
1528e4b17023SJohn Marino   return stmt_expr;
1529e4b17023SJohn Marino }
1530e4b17023SJohn Marino 
1531e4b17023SJohn Marino static void
expand_default_init(tree binfo,tree true_exp,tree exp,tree init,int flags,tsubst_flags_t complain)1532e4b17023SJohn Marino expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
1533e4b17023SJohn Marino                      tsubst_flags_t complain)
1534e4b17023SJohn Marino {
1535e4b17023SJohn Marino   tree type = TREE_TYPE (exp);
1536e4b17023SJohn Marino   tree ctor_name;
1537e4b17023SJohn Marino 
1538e4b17023SJohn Marino   /* It fails because there may not be a constructor which takes
1539e4b17023SJohn Marino      its own type as the first (or only parameter), but which does
1540e4b17023SJohn Marino      take other types via a conversion.  So, if the thing initializing
1541e4b17023SJohn Marino      the expression is a unit element of type X, first try X(X&),
1542e4b17023SJohn Marino      followed by initialization by X.  If neither of these work
1543e4b17023SJohn Marino      out, then look hard.  */
1544e4b17023SJohn Marino   tree rval;
1545e4b17023SJohn Marino   VEC(tree,gc) *parms;
1546e4b17023SJohn Marino 
1547e4b17023SJohn Marino   /* If we have direct-initialization from an initializer list, pull
1548e4b17023SJohn Marino      it out of the TREE_LIST so the code below can see it.  */
1549e4b17023SJohn Marino   if (init && TREE_CODE (init) == TREE_LIST
1550e4b17023SJohn Marino       && BRACE_ENCLOSED_INITIALIZER_P (TREE_VALUE (init))
1551e4b17023SJohn Marino       && CONSTRUCTOR_IS_DIRECT_INIT (TREE_VALUE (init)))
1552e4b17023SJohn Marino     {
1553e4b17023SJohn Marino       gcc_checking_assert ((flags & LOOKUP_ONLYCONVERTING) == 0
1554e4b17023SJohn Marino 			   && TREE_CHAIN (init) == NULL_TREE);
1555e4b17023SJohn Marino       init = TREE_VALUE (init);
1556e4b17023SJohn Marino     }
1557e4b17023SJohn Marino 
1558e4b17023SJohn Marino   if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
1559e4b17023SJohn Marino       && CP_AGGREGATE_TYPE_P (type))
1560e4b17023SJohn Marino     /* A brace-enclosed initializer for an aggregate.  In C++0x this can
1561e4b17023SJohn Marino        happen for direct-initialization, too.  */
1562e4b17023SJohn Marino     init = digest_init (type, init, complain);
1563e4b17023SJohn Marino 
1564e4b17023SJohn Marino   /* A CONSTRUCTOR of the target's type is a previously digested
1565e4b17023SJohn Marino      initializer, whether that happened just above or in
1566e4b17023SJohn Marino      cp_parser_late_parsing_nsdmi.
1567e4b17023SJohn Marino 
1568e4b17023SJohn Marino      A TARGET_EXPR with TARGET_EXPR_DIRECT_INIT_P or TARGET_EXPR_LIST_INIT_P
1569e4b17023SJohn Marino      set represents the whole initialization, so we shouldn't build up
1570e4b17023SJohn Marino      another ctor call.  */
1571e4b17023SJohn Marino   if (init
1572e4b17023SJohn Marino       && (TREE_CODE (init) == CONSTRUCTOR
1573e4b17023SJohn Marino 	  || (TREE_CODE (init) == TARGET_EXPR
1574e4b17023SJohn Marino 	      && (TARGET_EXPR_DIRECT_INIT_P (init)
1575e4b17023SJohn Marino 		  || TARGET_EXPR_LIST_INIT_P (init))))
1576e4b17023SJohn Marino       && same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (init), type))
1577e4b17023SJohn Marino     {
1578e4b17023SJohn Marino       /* Early initialization via a TARGET_EXPR only works for
1579e4b17023SJohn Marino 	 complete objects.  */
1580e4b17023SJohn Marino       gcc_assert (TREE_CODE (init) == CONSTRUCTOR || true_exp == exp);
1581e4b17023SJohn Marino 
1582e4b17023SJohn Marino       init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
1583e4b17023SJohn Marino       TREE_SIDE_EFFECTS (init) = 1;
1584e4b17023SJohn Marino       finish_expr_stmt (init);
1585e4b17023SJohn Marino       return;
1586e4b17023SJohn Marino     }
1587e4b17023SJohn Marino 
1588e4b17023SJohn Marino   if (init && TREE_CODE (init) != TREE_LIST
1589e4b17023SJohn Marino       && (flags & LOOKUP_ONLYCONVERTING))
1590e4b17023SJohn Marino     {
1591e4b17023SJohn Marino       /* Base subobjects should only get direct-initialization.  */
1592e4b17023SJohn Marino       gcc_assert (true_exp == exp);
1593e4b17023SJohn Marino 
1594e4b17023SJohn Marino       if (flags & DIRECT_BIND)
1595e4b17023SJohn Marino 	/* Do nothing.  We hit this in two cases:  Reference initialization,
1596e4b17023SJohn Marino 	   where we aren't initializing a real variable, so we don't want
1597e4b17023SJohn Marino 	   to run a new constructor; and catching an exception, where we
1598e4b17023SJohn Marino 	   have already built up the constructor call so we could wrap it
1599e4b17023SJohn Marino 	   in an exception region.  */;
1600e4b17023SJohn Marino       else
1601e4b17023SJohn Marino 	init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags);
1602e4b17023SJohn Marino 
1603e4b17023SJohn Marino       if (TREE_CODE (init) == MUST_NOT_THROW_EXPR)
1604e4b17023SJohn Marino 	/* We need to protect the initialization of a catch parm with a
1605e4b17023SJohn Marino 	   call to terminate(), which shows up as a MUST_NOT_THROW_EXPR
1606e4b17023SJohn Marino 	   around the TARGET_EXPR for the copy constructor.  See
1607e4b17023SJohn Marino 	   initialize_handler_parm.  */
1608e4b17023SJohn Marino 	{
1609e4b17023SJohn Marino 	  TREE_OPERAND (init, 0) = build2 (INIT_EXPR, TREE_TYPE (exp), exp,
1610e4b17023SJohn Marino 					   TREE_OPERAND (init, 0));
1611e4b17023SJohn Marino 	  TREE_TYPE (init) = void_type_node;
1612e4b17023SJohn Marino 	}
1613e4b17023SJohn Marino       else
1614e4b17023SJohn Marino 	init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
1615e4b17023SJohn Marino       TREE_SIDE_EFFECTS (init) = 1;
1616e4b17023SJohn Marino       finish_expr_stmt (init);
1617e4b17023SJohn Marino       return;
1618e4b17023SJohn Marino     }
1619e4b17023SJohn Marino 
1620e4b17023SJohn Marino   if (init == NULL_TREE)
1621e4b17023SJohn Marino     parms = NULL;
1622e4b17023SJohn Marino   else if (TREE_CODE (init) == TREE_LIST && !TREE_TYPE (init))
1623e4b17023SJohn Marino     {
1624e4b17023SJohn Marino       parms = make_tree_vector ();
1625e4b17023SJohn Marino       for (; init != NULL_TREE; init = TREE_CHAIN (init))
1626e4b17023SJohn Marino 	VEC_safe_push (tree, gc, parms, TREE_VALUE (init));
1627e4b17023SJohn Marino     }
1628e4b17023SJohn Marino   else
1629e4b17023SJohn Marino     parms = make_tree_vector_single (init);
1630e4b17023SJohn Marino 
1631e4b17023SJohn Marino   if (exp == current_class_ref && current_function_decl
1632e4b17023SJohn Marino       && DECL_HAS_IN_CHARGE_PARM_P (current_function_decl))
1633e4b17023SJohn Marino     {
1634e4b17023SJohn Marino       /* Delegating constructor. */
1635e4b17023SJohn Marino       tree complete;
1636e4b17023SJohn Marino       tree base;
1637e4b17023SJohn Marino       tree elt; unsigned i;
1638e4b17023SJohn Marino 
1639e4b17023SJohn Marino       /* Unshare the arguments for the second call.  */
1640e4b17023SJohn Marino       VEC(tree,gc) *parms2 = make_tree_vector ();
1641e4b17023SJohn Marino       FOR_EACH_VEC_ELT (tree, parms, i, elt)
1642e4b17023SJohn Marino 	{
1643e4b17023SJohn Marino 	  elt = break_out_target_exprs (elt);
1644e4b17023SJohn Marino 	  VEC_safe_push (tree, gc, parms2, elt);
1645e4b17023SJohn Marino 	}
1646e4b17023SJohn Marino       complete = build_special_member_call (exp, complete_ctor_identifier,
1647e4b17023SJohn Marino 					    &parms2, binfo, flags,
1648e4b17023SJohn Marino 					    complain);
1649e4b17023SJohn Marino       complete = fold_build_cleanup_point_expr (void_type_node, complete);
1650e4b17023SJohn Marino       release_tree_vector (parms2);
1651e4b17023SJohn Marino 
1652e4b17023SJohn Marino       base = build_special_member_call (exp, base_ctor_identifier,
1653e4b17023SJohn Marino 					&parms, binfo, flags,
1654e4b17023SJohn Marino 					complain);
1655e4b17023SJohn Marino       base = fold_build_cleanup_point_expr (void_type_node, base);
1656e4b17023SJohn Marino       rval = build3 (COND_EXPR, void_type_node,
1657e4b17023SJohn Marino 		     build2 (EQ_EXPR, boolean_type_node,
1658e4b17023SJohn Marino 			     current_in_charge_parm, integer_zero_node),
1659e4b17023SJohn Marino 		     base,
1660e4b17023SJohn Marino 		     complete);
1661e4b17023SJohn Marino     }
1662e4b17023SJohn Marino    else
1663e4b17023SJohn Marino     {
1664e4b17023SJohn Marino       if (true_exp == exp)
1665e4b17023SJohn Marino 	ctor_name = complete_ctor_identifier;
1666e4b17023SJohn Marino       else
1667e4b17023SJohn Marino 	ctor_name = base_ctor_identifier;
1668e4b17023SJohn Marino       rval = build_special_member_call (exp, ctor_name, &parms, binfo, flags,
1669e4b17023SJohn Marino 					complain);
1670e4b17023SJohn Marino   }
1671e4b17023SJohn Marino 
1672e4b17023SJohn Marino   if (parms != NULL)
1673e4b17023SJohn Marino     release_tree_vector (parms);
1674e4b17023SJohn Marino 
1675e4b17023SJohn Marino   if (exp == true_exp && TREE_CODE (rval) == CALL_EXPR)
1676e4b17023SJohn Marino     {
1677e4b17023SJohn Marino       tree fn = get_callee_fndecl (rval);
1678e4b17023SJohn Marino       if (fn && DECL_DECLARED_CONSTEXPR_P (fn))
1679e4b17023SJohn Marino 	{
1680e4b17023SJohn Marino 	  tree e = maybe_constant_init (rval);
1681e4b17023SJohn Marino 	  if (TREE_CONSTANT (e))
1682e4b17023SJohn Marino 	    rval = build2 (INIT_EXPR, type, exp, e);
1683e4b17023SJohn Marino 	}
1684e4b17023SJohn Marino     }
1685e4b17023SJohn Marino 
1686e4b17023SJohn Marino   /* FIXME put back convert_to_void?  */
1687e4b17023SJohn Marino   if (TREE_SIDE_EFFECTS (rval))
1688e4b17023SJohn Marino     finish_expr_stmt (rval);
1689e4b17023SJohn Marino }
1690e4b17023SJohn Marino 
1691e4b17023SJohn Marino /* This function is responsible for initializing EXP with INIT
1692e4b17023SJohn Marino    (if any).
1693e4b17023SJohn Marino 
1694e4b17023SJohn Marino    BINFO is the binfo of the type for who we are performing the
1695e4b17023SJohn Marino    initialization.  For example, if W is a virtual base class of A and B,
1696e4b17023SJohn Marino    and C : A, B.
1697e4b17023SJohn Marino    If we are initializing B, then W must contain B's W vtable, whereas
1698e4b17023SJohn Marino    were we initializing C, W must contain C's W vtable.
1699e4b17023SJohn Marino 
1700e4b17023SJohn Marino    TRUE_EXP is nonzero if it is the true expression being initialized.
1701e4b17023SJohn Marino    In this case, it may be EXP, or may just contain EXP.  The reason we
1702e4b17023SJohn Marino    need this is because if EXP is a base element of TRUE_EXP, we
1703e4b17023SJohn Marino    don't necessarily know by looking at EXP where its virtual
1704e4b17023SJohn Marino    baseclass fields should really be pointing.  But we do know
1705e4b17023SJohn Marino    from TRUE_EXP.  In constructors, we don't know anything about
1706e4b17023SJohn Marino    the value being initialized.
1707e4b17023SJohn Marino 
1708e4b17023SJohn Marino    FLAGS is just passed to `build_new_method_call'.  See that function
1709e4b17023SJohn Marino    for its description.  */
1710e4b17023SJohn Marino 
1711e4b17023SJohn Marino static void
expand_aggr_init_1(tree binfo,tree true_exp,tree exp,tree init,int flags,tsubst_flags_t complain)1712e4b17023SJohn Marino expand_aggr_init_1 (tree binfo, tree true_exp, tree exp, tree init, int flags,
1713e4b17023SJohn Marino                     tsubst_flags_t complain)
1714e4b17023SJohn Marino {
1715e4b17023SJohn Marino   tree type = TREE_TYPE (exp);
1716e4b17023SJohn Marino 
1717e4b17023SJohn Marino   gcc_assert (init != error_mark_node && type != error_mark_node);
1718e4b17023SJohn Marino   gcc_assert (building_stmt_list_p ());
1719e4b17023SJohn Marino 
1720e4b17023SJohn Marino   /* Use a function returning the desired type to initialize EXP for us.
1721e4b17023SJohn Marino      If the function is a constructor, and its first argument is
1722e4b17023SJohn Marino      NULL_TREE, know that it was meant for us--just slide exp on
1723e4b17023SJohn Marino      in and expand the constructor.  Constructors now come
1724e4b17023SJohn Marino      as TARGET_EXPRs.  */
1725e4b17023SJohn Marino 
1726e4b17023SJohn Marino   if (init && TREE_CODE (exp) == VAR_DECL
1727e4b17023SJohn Marino       && COMPOUND_LITERAL_P (init))
1728e4b17023SJohn Marino     {
1729e4b17023SJohn Marino       VEC(tree,gc)* cleanups = NULL;
1730e4b17023SJohn Marino       /* If store_init_value returns NULL_TREE, the INIT has been
1731e4b17023SJohn Marino 	 recorded as the DECL_INITIAL for EXP.  That means there's
1732e4b17023SJohn Marino 	 nothing more we have to do.  */
1733e4b17023SJohn Marino       init = store_init_value (exp, init, &cleanups, flags);
1734e4b17023SJohn Marino       if (init)
1735e4b17023SJohn Marino 	finish_expr_stmt (init);
1736e4b17023SJohn Marino       gcc_assert (!cleanups);
1737e4b17023SJohn Marino       return;
1738e4b17023SJohn Marino     }
1739e4b17023SJohn Marino 
1740e4b17023SJohn Marino   /* If an explicit -- but empty -- initializer list was present,
1741e4b17023SJohn Marino      that's value-initialization.  */
1742e4b17023SJohn Marino   if (init == void_type_node)
1743e4b17023SJohn Marino     {
1744e4b17023SJohn Marino       /* If the type has data but no user-provided ctor, we need to zero
1745e4b17023SJohn Marino 	 out the object.  */
1746e4b17023SJohn Marino       if (!type_has_user_provided_constructor (type)
1747e4b17023SJohn Marino 	  && !is_really_empty_class (type))
1748e4b17023SJohn Marino 	{
1749e4b17023SJohn Marino 	  tree field_size = NULL_TREE;
1750e4b17023SJohn Marino 	  if (exp != true_exp && CLASSTYPE_AS_BASE (type) != type)
1751e4b17023SJohn Marino 	    /* Don't clobber already initialized virtual bases.  */
1752e4b17023SJohn Marino 	    field_size = TYPE_SIZE (CLASSTYPE_AS_BASE (type));
1753e4b17023SJohn Marino 	  init = build_zero_init_1 (type, NULL_TREE, /*static_storage_p=*/false,
1754e4b17023SJohn Marino 				    field_size);
1755e4b17023SJohn Marino 	  init = build2 (INIT_EXPR, type, exp, init);
1756e4b17023SJohn Marino 	  finish_expr_stmt (init);
1757e4b17023SJohn Marino 	}
1758e4b17023SJohn Marino 
1759e4b17023SJohn Marino       /* If we don't need to mess with the constructor at all,
1760e4b17023SJohn Marino 	 then we're done.  */
1761e4b17023SJohn Marino       if (! type_build_ctor_call (type))
1762e4b17023SJohn Marino 	return;
1763e4b17023SJohn Marino 
1764e4b17023SJohn Marino       /* Otherwise fall through and call the constructor.  */
1765e4b17023SJohn Marino       init = NULL_TREE;
1766e4b17023SJohn Marino     }
1767e4b17023SJohn Marino 
1768e4b17023SJohn Marino   /* We know that expand_default_init can handle everything we want
1769e4b17023SJohn Marino      at this point.  */
1770e4b17023SJohn Marino   expand_default_init (binfo, true_exp, exp, init, flags, complain);
1771e4b17023SJohn Marino }
1772e4b17023SJohn Marino 
1773e4b17023SJohn Marino /* Report an error if TYPE is not a user-defined, class type.  If
1774e4b17023SJohn Marino    OR_ELSE is nonzero, give an error message.  */
1775e4b17023SJohn Marino 
1776e4b17023SJohn Marino int
is_class_type(tree type,int or_else)1777e4b17023SJohn Marino is_class_type (tree type, int or_else)
1778e4b17023SJohn Marino {
1779e4b17023SJohn Marino   if (type == error_mark_node)
1780e4b17023SJohn Marino     return 0;
1781e4b17023SJohn Marino 
1782e4b17023SJohn Marino   if (! CLASS_TYPE_P (type))
1783e4b17023SJohn Marino     {
1784e4b17023SJohn Marino       if (or_else)
1785e4b17023SJohn Marino 	error ("%qT is not a class type", type);
1786e4b17023SJohn Marino       return 0;
1787e4b17023SJohn Marino     }
1788e4b17023SJohn Marino   return 1;
1789e4b17023SJohn Marino }
1790e4b17023SJohn Marino 
1791e4b17023SJohn Marino tree
get_type_value(tree name)1792e4b17023SJohn Marino get_type_value (tree name)
1793e4b17023SJohn Marino {
1794e4b17023SJohn Marino   if (name == error_mark_node)
1795e4b17023SJohn Marino     return NULL_TREE;
1796e4b17023SJohn Marino 
1797e4b17023SJohn Marino   if (IDENTIFIER_HAS_TYPE_VALUE (name))
1798e4b17023SJohn Marino     return IDENTIFIER_TYPE_VALUE (name);
1799e4b17023SJohn Marino   else
1800e4b17023SJohn Marino     return NULL_TREE;
1801e4b17023SJohn Marino }
1802e4b17023SJohn Marino 
1803e4b17023SJohn Marino /* Build a reference to a member of an aggregate.  This is not a C++
1804e4b17023SJohn Marino    `&', but really something which can have its address taken, and
1805e4b17023SJohn Marino    then act as a pointer to member, for example TYPE :: FIELD can have
1806e4b17023SJohn Marino    its address taken by saying & TYPE :: FIELD.  ADDRESS_P is true if
1807e4b17023SJohn Marino    this expression is the operand of "&".
1808e4b17023SJohn Marino 
1809e4b17023SJohn Marino    @@ Prints out lousy diagnostics for operator <typename>
1810e4b17023SJohn Marino    @@ fields.
1811e4b17023SJohn Marino 
1812e4b17023SJohn Marino    @@ This function should be rewritten and placed in search.c.  */
1813e4b17023SJohn Marino 
1814e4b17023SJohn Marino tree
build_offset_ref(tree type,tree member,bool address_p)1815e4b17023SJohn Marino build_offset_ref (tree type, tree member, bool address_p)
1816e4b17023SJohn Marino {
1817e4b17023SJohn Marino   tree decl;
1818e4b17023SJohn Marino   tree basebinfo = NULL_TREE;
1819e4b17023SJohn Marino 
1820e4b17023SJohn Marino   /* class templates can come in as TEMPLATE_DECLs here.  */
1821e4b17023SJohn Marino   if (TREE_CODE (member) == TEMPLATE_DECL)
1822e4b17023SJohn Marino     return member;
1823e4b17023SJohn Marino 
1824e4b17023SJohn Marino   if (dependent_scope_p (type) || type_dependent_expression_p (member))
1825e4b17023SJohn Marino     return build_qualified_name (NULL_TREE, type, member,
1826e4b17023SJohn Marino 				  /*template_p=*/false);
1827e4b17023SJohn Marino 
1828e4b17023SJohn Marino   gcc_assert (TYPE_P (type));
1829e4b17023SJohn Marino   if (! is_class_type (type, 1))
1830e4b17023SJohn Marino     return error_mark_node;
1831e4b17023SJohn Marino 
1832e4b17023SJohn Marino   gcc_assert (DECL_P (member) || BASELINK_P (member));
1833e4b17023SJohn Marino   /* Callers should call mark_used before this point.  */
1834e4b17023SJohn Marino   gcc_assert (!DECL_P (member) || TREE_USED (member));
1835e4b17023SJohn Marino 
1836e4b17023SJohn Marino   type = TYPE_MAIN_VARIANT (type);
1837e4b17023SJohn Marino   if (!COMPLETE_OR_OPEN_TYPE_P (complete_type (type)))
1838e4b17023SJohn Marino     {
1839e4b17023SJohn Marino       error ("incomplete type %qT does not have member %qD", type, member);
1840e4b17023SJohn Marino       return error_mark_node;
1841e4b17023SJohn Marino     }
1842e4b17023SJohn Marino 
1843e4b17023SJohn Marino   /* Entities other than non-static members need no further
1844e4b17023SJohn Marino      processing.  */
1845e4b17023SJohn Marino   if (TREE_CODE (member) == TYPE_DECL)
1846e4b17023SJohn Marino     return member;
1847e4b17023SJohn Marino   if (TREE_CODE (member) == VAR_DECL || TREE_CODE (member) == CONST_DECL)
1848e4b17023SJohn Marino     return convert_from_reference (member);
1849e4b17023SJohn Marino 
1850e4b17023SJohn Marino   if (TREE_CODE (member) == FIELD_DECL && DECL_C_BIT_FIELD (member))
1851e4b17023SJohn Marino     {
1852e4b17023SJohn Marino       error ("invalid pointer to bit-field %qD", member);
1853e4b17023SJohn Marino       return error_mark_node;
1854e4b17023SJohn Marino     }
1855e4b17023SJohn Marino 
1856e4b17023SJohn Marino   /* Set up BASEBINFO for member lookup.  */
1857e4b17023SJohn Marino   decl = maybe_dummy_object (type, &basebinfo);
1858e4b17023SJohn Marino 
1859e4b17023SJohn Marino   /* A lot of this logic is now handled in lookup_member.  */
1860e4b17023SJohn Marino   if (BASELINK_P (member))
1861e4b17023SJohn Marino     {
1862e4b17023SJohn Marino       /* Go from the TREE_BASELINK to the member function info.  */
1863e4b17023SJohn Marino       tree t = BASELINK_FUNCTIONS (member);
1864e4b17023SJohn Marino 
1865e4b17023SJohn Marino       if (TREE_CODE (t) != TEMPLATE_ID_EXPR && !really_overloaded_fn (t))
1866e4b17023SJohn Marino 	{
1867e4b17023SJohn Marino 	  /* Get rid of a potential OVERLOAD around it.  */
1868e4b17023SJohn Marino 	  t = OVL_CURRENT (t);
1869e4b17023SJohn Marino 
1870e4b17023SJohn Marino 	  /* Unique functions are handled easily.  */
1871e4b17023SJohn Marino 
1872e4b17023SJohn Marino 	  /* For non-static member of base class, we need a special rule
1873e4b17023SJohn Marino 	     for access checking [class.protected]:
1874e4b17023SJohn Marino 
1875e4b17023SJohn Marino 	       If the access is to form a pointer to member, the
1876e4b17023SJohn Marino 	       nested-name-specifier shall name the derived class
1877e4b17023SJohn Marino 	       (or any class derived from that class).  */
1878e4b17023SJohn Marino 	  if (address_p && DECL_P (t)
1879e4b17023SJohn Marino 	      && DECL_NONSTATIC_MEMBER_P (t))
1880e4b17023SJohn Marino 	    perform_or_defer_access_check (TYPE_BINFO (type), t, t);
1881e4b17023SJohn Marino 	  else
1882e4b17023SJohn Marino 	    perform_or_defer_access_check (basebinfo, t, t);
1883e4b17023SJohn Marino 
1884e4b17023SJohn Marino 	  if (DECL_STATIC_FUNCTION_P (t))
1885e4b17023SJohn Marino 	    return t;
1886e4b17023SJohn Marino 	  member = t;
1887e4b17023SJohn Marino 	}
1888e4b17023SJohn Marino       else
1889e4b17023SJohn Marino 	TREE_TYPE (member) = unknown_type_node;
1890e4b17023SJohn Marino     }
1891e4b17023SJohn Marino   else if (address_p && TREE_CODE (member) == FIELD_DECL)
1892e4b17023SJohn Marino     /* We need additional test besides the one in
1893e4b17023SJohn Marino        check_accessibility_of_qualified_id in case it is
1894e4b17023SJohn Marino        a pointer to non-static member.  */
1895e4b17023SJohn Marino     perform_or_defer_access_check (TYPE_BINFO (type), member, member);
1896e4b17023SJohn Marino 
1897e4b17023SJohn Marino   if (!address_p)
1898e4b17023SJohn Marino     {
1899e4b17023SJohn Marino       /* If MEMBER is non-static, then the program has fallen afoul of
1900e4b17023SJohn Marino 	 [expr.prim]:
1901e4b17023SJohn Marino 
1902e4b17023SJohn Marino 	   An id-expression that denotes a nonstatic data member or
1903e4b17023SJohn Marino 	   nonstatic member function of a class can only be used:
1904e4b17023SJohn Marino 
1905e4b17023SJohn Marino 	   -- as part of a class member access (_expr.ref_) in which the
1906e4b17023SJohn Marino 	   object-expression refers to the member's class or a class
1907e4b17023SJohn Marino 	   derived from that class, or
1908e4b17023SJohn Marino 
1909e4b17023SJohn Marino 	   -- to form a pointer to member (_expr.unary.op_), or
1910e4b17023SJohn Marino 
1911e4b17023SJohn Marino 	   -- in the body of a nonstatic member function of that class or
1912e4b17023SJohn Marino 	   of a class derived from that class (_class.mfct.nonstatic_), or
1913e4b17023SJohn Marino 
1914e4b17023SJohn Marino 	   -- in a mem-initializer for a constructor for that class or for
1915e4b17023SJohn Marino 	   a class derived from that class (_class.base.init_).  */
1916e4b17023SJohn Marino       if (DECL_NONSTATIC_MEMBER_FUNCTION_P (member))
1917e4b17023SJohn Marino 	{
1918e4b17023SJohn Marino 	  /* Build a representation of the qualified name suitable
1919e4b17023SJohn Marino 	     for use as the operand to "&" -- even though the "&" is
1920e4b17023SJohn Marino 	     not actually present.  */
1921e4b17023SJohn Marino 	  member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
1922e4b17023SJohn Marino 	  /* In Microsoft mode, treat a non-static member function as if
1923e4b17023SJohn Marino 	     it were a pointer-to-member.  */
1924e4b17023SJohn Marino 	  if (flag_ms_extensions)
1925e4b17023SJohn Marino 	    {
1926e4b17023SJohn Marino 	      PTRMEM_OK_P (member) = 1;
1927e4b17023SJohn Marino 	      return cp_build_addr_expr (member, tf_warning_or_error);
1928e4b17023SJohn Marino 	    }
1929e4b17023SJohn Marino 	  error ("invalid use of non-static member function %qD",
1930e4b17023SJohn Marino 		 TREE_OPERAND (member, 1));
1931e4b17023SJohn Marino 	  return error_mark_node;
1932e4b17023SJohn Marino 	}
1933e4b17023SJohn Marino       else if (TREE_CODE (member) == FIELD_DECL)
1934e4b17023SJohn Marino 	{
1935e4b17023SJohn Marino 	  error ("invalid use of non-static data member %qD", member);
1936e4b17023SJohn Marino 	  return error_mark_node;
1937e4b17023SJohn Marino 	}
1938e4b17023SJohn Marino       return member;
1939e4b17023SJohn Marino     }
1940e4b17023SJohn Marino 
1941e4b17023SJohn Marino   member = build2 (OFFSET_REF, TREE_TYPE (member), decl, member);
1942e4b17023SJohn Marino   PTRMEM_OK_P (member) = 1;
1943e4b17023SJohn Marino   return member;
1944e4b17023SJohn Marino }
1945e4b17023SJohn Marino 
1946e4b17023SJohn Marino /* If DECL is a scalar enumeration constant or variable with a
1947e4b17023SJohn Marino    constant initializer, return the initializer (or, its initializers,
1948e4b17023SJohn Marino    recursively); otherwise, return DECL.  If INTEGRAL_P, the
1949e4b17023SJohn Marino    initializer is only returned if DECL is an integral
1950e4b17023SJohn Marino    constant-expression.  If RETURN_AGGREGATE_CST_OK_P, it is ok to
1951e4b17023SJohn Marino    return an aggregate constant.  */
1952e4b17023SJohn Marino 
1953e4b17023SJohn Marino static tree
constant_value_1(tree decl,bool integral_p,bool return_aggregate_cst_ok_p)1954e4b17023SJohn Marino constant_value_1 (tree decl, bool integral_p, bool return_aggregate_cst_ok_p)
1955e4b17023SJohn Marino {
1956e4b17023SJohn Marino   while (TREE_CODE (decl) == CONST_DECL
1957e4b17023SJohn Marino 	 || (integral_p
1958e4b17023SJohn Marino 	     ? decl_constant_var_p (decl)
1959e4b17023SJohn Marino 	     : (TREE_CODE (decl) == VAR_DECL
1960e4b17023SJohn Marino 		&& CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl)))))
1961e4b17023SJohn Marino     {
1962e4b17023SJohn Marino       tree init;
1963e4b17023SJohn Marino       /* If DECL is a static data member in a template
1964e4b17023SJohn Marino 	 specialization, we must instantiate it here.  The
1965e4b17023SJohn Marino 	 initializer for the static data member is not processed
1966e4b17023SJohn Marino 	 until needed; we need it now.  */
1967e4b17023SJohn Marino       mark_used (decl);
1968e4b17023SJohn Marino       mark_rvalue_use (decl);
1969e4b17023SJohn Marino       init = DECL_INITIAL (decl);
1970e4b17023SJohn Marino       if (init == error_mark_node)
1971e4b17023SJohn Marino 	{
1972e4b17023SJohn Marino 	  if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl))
1973e4b17023SJohn Marino 	    /* Treat the error as a constant to avoid cascading errors on
1974e4b17023SJohn Marino 	       excessively recursive template instantiation (c++/9335).  */
1975e4b17023SJohn Marino 	    return init;
1976e4b17023SJohn Marino 	  else
1977e4b17023SJohn Marino 	    return decl;
1978e4b17023SJohn Marino 	}
1979e4b17023SJohn Marino       /* Initializers in templates are generally expanded during
1980e4b17023SJohn Marino 	 instantiation, so before that for const int i(2)
1981e4b17023SJohn Marino 	 INIT is a TREE_LIST with the actual initializer as
1982e4b17023SJohn Marino 	 TREE_VALUE.  */
1983e4b17023SJohn Marino       if (processing_template_decl
1984e4b17023SJohn Marino 	  && init
1985e4b17023SJohn Marino 	  && TREE_CODE (init) == TREE_LIST
1986e4b17023SJohn Marino 	  && TREE_CHAIN (init) == NULL_TREE)
1987e4b17023SJohn Marino 	init = TREE_VALUE (init);
1988e4b17023SJohn Marino       if (!init
1989e4b17023SJohn Marino 	  || !TREE_TYPE (init)
1990e4b17023SJohn Marino 	  || !TREE_CONSTANT (init)
1991e4b17023SJohn Marino 	  || (!integral_p && !return_aggregate_cst_ok_p
1992e4b17023SJohn Marino 	      /* Unless RETURN_AGGREGATE_CST_OK_P is true, do not
1993e4b17023SJohn Marino 		 return an aggregate constant (of which string
1994e4b17023SJohn Marino 		 literals are a special case), as we do not want
1995e4b17023SJohn Marino 		 to make inadvertent copies of such entities, and
1996e4b17023SJohn Marino 		 we must be sure that their addresses are the
1997e4b17023SJohn Marino  		 same everywhere.  */
1998e4b17023SJohn Marino 	      && (TREE_CODE (init) == CONSTRUCTOR
1999e4b17023SJohn Marino 		  || TREE_CODE (init) == STRING_CST)))
2000e4b17023SJohn Marino 	break;
2001e4b17023SJohn Marino       decl = unshare_expr (init);
2002e4b17023SJohn Marino     }
2003e4b17023SJohn Marino   return decl;
2004e4b17023SJohn Marino }
2005e4b17023SJohn Marino 
2006e4b17023SJohn Marino /* If DECL is a CONST_DECL, or a constant VAR_DECL initialized by
2007e4b17023SJohn Marino    constant of integral or enumeration type, then return that value.
2008e4b17023SJohn Marino    These are those variables permitted in constant expressions by
2009e4b17023SJohn Marino    [5.19/1].  */
2010e4b17023SJohn Marino 
2011e4b17023SJohn Marino tree
integral_constant_value(tree decl)2012e4b17023SJohn Marino integral_constant_value (tree decl)
2013e4b17023SJohn Marino {
2014e4b17023SJohn Marino   return constant_value_1 (decl, /*integral_p=*/true,
2015e4b17023SJohn Marino 			   /*return_aggregate_cst_ok_p=*/false);
2016e4b17023SJohn Marino }
2017e4b17023SJohn Marino 
2018e4b17023SJohn Marino /* A more relaxed version of integral_constant_value, used by the
2019e4b17023SJohn Marino    common C/C++ code.  */
2020e4b17023SJohn Marino 
2021e4b17023SJohn Marino tree
decl_constant_value(tree decl)2022e4b17023SJohn Marino decl_constant_value (tree decl)
2023e4b17023SJohn Marino {
2024e4b17023SJohn Marino   return constant_value_1 (decl, /*integral_p=*/processing_template_decl,
2025e4b17023SJohn Marino 			   /*return_aggregate_cst_ok_p=*/true);
2026e4b17023SJohn Marino }
2027e4b17023SJohn Marino 
2028e4b17023SJohn Marino /* A version of integral_constant_value used by the C++ front end for
2029e4b17023SJohn Marino    optimization purposes.  */
2030e4b17023SJohn Marino 
2031e4b17023SJohn Marino tree
decl_constant_value_safe(tree decl)2032e4b17023SJohn Marino decl_constant_value_safe (tree decl)
2033e4b17023SJohn Marino {
2034e4b17023SJohn Marino   return constant_value_1 (decl, /*integral_p=*/processing_template_decl,
2035e4b17023SJohn Marino 			   /*return_aggregate_cst_ok_p=*/false);
2036e4b17023SJohn Marino }
2037e4b17023SJohn Marino 
2038e4b17023SJohn Marino /* Common subroutines of build_new and build_vec_delete.  */
2039e4b17023SJohn Marino 
2040e4b17023SJohn Marino /* Call the global __builtin_delete to delete ADDR.  */
2041e4b17023SJohn Marino 
2042e4b17023SJohn Marino static tree
build_builtin_delete_call(tree addr)2043e4b17023SJohn Marino build_builtin_delete_call (tree addr)
2044e4b17023SJohn Marino {
2045e4b17023SJohn Marino   mark_used (global_delete_fndecl);
2046e4b17023SJohn Marino   return build_call_n (global_delete_fndecl, 1, addr);
2047e4b17023SJohn Marino }
2048e4b17023SJohn Marino 
2049e4b17023SJohn Marino /* Build and return a NEW_EXPR.  If NELTS is non-NULL, TYPE[NELTS] is
2050e4b17023SJohn Marino    the type of the object being allocated; otherwise, it's just TYPE.
2051e4b17023SJohn Marino    INIT is the initializer, if any.  USE_GLOBAL_NEW is true if the
2052e4b17023SJohn Marino    user explicitly wrote "::operator new".  PLACEMENT, if non-NULL, is
2053e4b17023SJohn Marino    a vector of arguments to be provided as arguments to a placement
2054e4b17023SJohn Marino    new operator.  This routine performs no semantic checks; it just
2055e4b17023SJohn Marino    creates and returns a NEW_EXPR.  */
2056e4b17023SJohn Marino 
2057e4b17023SJohn Marino static tree
build_raw_new_expr(VEC (tree,gc)* placement,tree type,tree nelts,VEC (tree,gc)* init,int use_global_new)2058e4b17023SJohn Marino build_raw_new_expr (VEC(tree,gc) *placement, tree type, tree nelts,
2059e4b17023SJohn Marino 		    VEC(tree,gc) *init, int use_global_new)
2060e4b17023SJohn Marino {
2061e4b17023SJohn Marino   tree init_list;
2062e4b17023SJohn Marino   tree new_expr;
2063e4b17023SJohn Marino 
2064e4b17023SJohn Marino   /* If INIT is NULL, the we want to store NULL_TREE in the NEW_EXPR.
2065e4b17023SJohn Marino      If INIT is not NULL, then we want to store VOID_ZERO_NODE.  This
2066e4b17023SJohn Marino      permits us to distinguish the case of a missing initializer "new
2067e4b17023SJohn Marino      int" from an empty initializer "new int()".  */
2068e4b17023SJohn Marino   if (init == NULL)
2069e4b17023SJohn Marino     init_list = NULL_TREE;
2070e4b17023SJohn Marino   else if (VEC_empty (tree, init))
2071e4b17023SJohn Marino     init_list = void_zero_node;
2072e4b17023SJohn Marino   else
2073e4b17023SJohn Marino     init_list = build_tree_list_vec (init);
2074e4b17023SJohn Marino 
2075e4b17023SJohn Marino   new_expr = build4 (NEW_EXPR, build_pointer_type (type),
2076e4b17023SJohn Marino 		     build_tree_list_vec (placement), type, nelts,
2077e4b17023SJohn Marino 		     init_list);
2078e4b17023SJohn Marino   NEW_EXPR_USE_GLOBAL (new_expr) = use_global_new;
2079e4b17023SJohn Marino   TREE_SIDE_EFFECTS (new_expr) = 1;
2080e4b17023SJohn Marino 
2081e4b17023SJohn Marino   return new_expr;
2082e4b17023SJohn Marino }
2083e4b17023SJohn Marino 
2084e4b17023SJohn Marino /* Diagnose uninitialized const members or reference members of type
2085e4b17023SJohn Marino    TYPE. USING_NEW is used to disambiguate the diagnostic between a
2086e4b17023SJohn Marino    new expression without a new-initializer and a declaration. Returns
2087e4b17023SJohn Marino    the error count. */
2088e4b17023SJohn Marino 
2089e4b17023SJohn Marino static int
diagnose_uninitialized_cst_or_ref_member_1(tree type,tree origin,bool using_new,bool complain)2090e4b17023SJohn Marino diagnose_uninitialized_cst_or_ref_member_1 (tree type, tree origin,
2091e4b17023SJohn Marino 					    bool using_new, bool complain)
2092e4b17023SJohn Marino {
2093e4b17023SJohn Marino   tree field;
2094e4b17023SJohn Marino   int error_count = 0;
2095e4b17023SJohn Marino 
2096e4b17023SJohn Marino   if (type_has_user_provided_constructor (type))
2097e4b17023SJohn Marino     return 0;
2098e4b17023SJohn Marino 
2099e4b17023SJohn Marino   for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2100e4b17023SJohn Marino     {
2101e4b17023SJohn Marino       tree field_type;
2102e4b17023SJohn Marino 
2103e4b17023SJohn Marino       if (TREE_CODE (field) != FIELD_DECL)
2104e4b17023SJohn Marino 	continue;
2105e4b17023SJohn Marino 
2106e4b17023SJohn Marino       field_type = strip_array_types (TREE_TYPE (field));
2107e4b17023SJohn Marino 
2108e4b17023SJohn Marino       if (type_has_user_provided_constructor (field_type))
2109e4b17023SJohn Marino 	continue;
2110e4b17023SJohn Marino 
2111e4b17023SJohn Marino       if (TREE_CODE (field_type) == REFERENCE_TYPE)
2112e4b17023SJohn Marino 	{
2113e4b17023SJohn Marino 	  ++ error_count;
2114e4b17023SJohn Marino 	  if (complain)
2115e4b17023SJohn Marino 	    {
2116e4b17023SJohn Marino 	      if (using_new)
2117e4b17023SJohn Marino 		error ("uninitialized reference member in %q#T "
2118e4b17023SJohn Marino 		       "using %<new%> without new-initializer", origin);
2119e4b17023SJohn Marino 	      else
2120e4b17023SJohn Marino 		error ("uninitialized reference member in %q#T", origin);
2121e4b17023SJohn Marino 	      inform (DECL_SOURCE_LOCATION (field),
2122e4b17023SJohn Marino 		      "%qD should be initialized", field);
2123e4b17023SJohn Marino 	    }
2124e4b17023SJohn Marino 	}
2125e4b17023SJohn Marino 
2126e4b17023SJohn Marino       if (CP_TYPE_CONST_P (field_type))
2127e4b17023SJohn Marino 	{
2128e4b17023SJohn Marino 	  ++ error_count;
2129e4b17023SJohn Marino 	  if (complain)
2130e4b17023SJohn Marino 	    {
2131e4b17023SJohn Marino 	      if (using_new)
2132e4b17023SJohn Marino 		error ("uninitialized const member in %q#T "
2133e4b17023SJohn Marino 		       "using %<new%> without new-initializer", origin);
2134e4b17023SJohn Marino 	      else
2135e4b17023SJohn Marino 		error ("uninitialized const member in %q#T", origin);
2136e4b17023SJohn Marino 	      inform (DECL_SOURCE_LOCATION (field),
2137e4b17023SJohn Marino 		      "%qD should be initialized", field);
2138e4b17023SJohn Marino 	    }
2139e4b17023SJohn Marino 	}
2140e4b17023SJohn Marino 
2141e4b17023SJohn Marino       if (CLASS_TYPE_P (field_type))
2142e4b17023SJohn Marino 	error_count
2143e4b17023SJohn Marino 	  += diagnose_uninitialized_cst_or_ref_member_1 (field_type, origin,
2144e4b17023SJohn Marino 							 using_new, complain);
2145e4b17023SJohn Marino     }
2146e4b17023SJohn Marino   return error_count;
2147e4b17023SJohn Marino }
2148e4b17023SJohn Marino 
2149e4b17023SJohn Marino int
diagnose_uninitialized_cst_or_ref_member(tree type,bool using_new,bool complain)2150e4b17023SJohn Marino diagnose_uninitialized_cst_or_ref_member (tree type, bool using_new, bool complain)
2151e4b17023SJohn Marino {
2152e4b17023SJohn Marino   return diagnose_uninitialized_cst_or_ref_member_1 (type, type, using_new, complain);
2153e4b17023SJohn Marino }
2154e4b17023SJohn Marino 
2155e4b17023SJohn Marino /* Generate code for a new-expression, including calling the "operator
2156e4b17023SJohn Marino    new" function, initializing the object, and, if an exception occurs
2157e4b17023SJohn Marino    during construction, cleaning up.  The arguments are as for
2158e4b17023SJohn Marino    build_raw_new_expr.  This may change PLACEMENT and INIT.  */
2159e4b17023SJohn Marino 
2160e4b17023SJohn Marino static tree
build_new_1(VEC (tree,gc)** placement,tree type,tree nelts,VEC (tree,gc)** init,bool globally_qualified_p,tsubst_flags_t complain)2161e4b17023SJohn Marino build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
2162e4b17023SJohn Marino 	     VEC(tree,gc) **init, bool globally_qualified_p,
2163e4b17023SJohn Marino 	     tsubst_flags_t complain)
2164e4b17023SJohn Marino {
2165e4b17023SJohn Marino   tree size, rval;
2166e4b17023SJohn Marino   /* True iff this is a call to "operator new[]" instead of just
2167e4b17023SJohn Marino      "operator new".  */
2168e4b17023SJohn Marino   bool array_p = false;
2169e4b17023SJohn Marino   /* If ARRAY_P is true, the element type of the array.  This is never
2170e4b17023SJohn Marino      an ARRAY_TYPE; for something like "new int[3][4]", the
2171e4b17023SJohn Marino      ELT_TYPE is "int".  If ARRAY_P is false, this is the same type as
2172e4b17023SJohn Marino      TYPE.  */
2173e4b17023SJohn Marino   tree elt_type;
2174e4b17023SJohn Marino   /* The type of the new-expression.  (This type is always a pointer
2175e4b17023SJohn Marino      type.)  */
2176e4b17023SJohn Marino   tree pointer_type;
2177e4b17023SJohn Marino   tree non_const_pointer_type;
2178e4b17023SJohn Marino   tree outer_nelts = NULL_TREE;
2179e4b17023SJohn Marino   tree alloc_call, alloc_expr;
2180e4b17023SJohn Marino   /* The address returned by the call to "operator new".  This node is
2181e4b17023SJohn Marino      a VAR_DECL and is therefore reusable.  */
2182e4b17023SJohn Marino   tree alloc_node;
2183e4b17023SJohn Marino   tree alloc_fn;
2184e4b17023SJohn Marino   tree cookie_expr, init_expr;
2185e4b17023SJohn Marino   int nothrow, check_new;
2186e4b17023SJohn Marino   int use_java_new = 0;
2187e4b17023SJohn Marino   /* If non-NULL, the number of extra bytes to allocate at the
2188e4b17023SJohn Marino      beginning of the storage allocated for an array-new expression in
2189e4b17023SJohn Marino      order to store the number of elements.  */
2190e4b17023SJohn Marino   tree cookie_size = NULL_TREE;
2191e4b17023SJohn Marino   tree placement_first;
2192e4b17023SJohn Marino   tree placement_expr = NULL_TREE;
2193e4b17023SJohn Marino   /* True if the function we are calling is a placement allocation
2194e4b17023SJohn Marino      function.  */
2195e4b17023SJohn Marino   bool placement_allocation_fn_p;
2196e4b17023SJohn Marino   /* True if the storage must be initialized, either by a constructor
2197e4b17023SJohn Marino      or due to an explicit new-initializer.  */
2198e4b17023SJohn Marino   bool is_initialized;
2199e4b17023SJohn Marino   /* The address of the thing allocated, not including any cookie.  In
2200e4b17023SJohn Marino      particular, if an array cookie is in use, DATA_ADDR is the
2201e4b17023SJohn Marino      address of the first array element.  This node is a VAR_DECL, and
2202e4b17023SJohn Marino      is therefore reusable.  */
2203e4b17023SJohn Marino   tree data_addr;
2204e4b17023SJohn Marino   tree init_preeval_expr = NULL_TREE;
2205e4b17023SJohn Marino 
2206e4b17023SJohn Marino   if (nelts)
2207e4b17023SJohn Marino     {
2208e4b17023SJohn Marino       outer_nelts = nelts;
2209e4b17023SJohn Marino       array_p = true;
2210e4b17023SJohn Marino     }
2211e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE)
2212e4b17023SJohn Marino     {
2213e4b17023SJohn Marino       array_p = true;
2214e4b17023SJohn Marino       nelts = array_type_nelts_top (type);
2215e4b17023SJohn Marino       outer_nelts = nelts;
2216e4b17023SJohn Marino       type = TREE_TYPE (type);
2217e4b17023SJohn Marino     }
2218e4b17023SJohn Marino 
2219e4b17023SJohn Marino   /* If our base type is an array, then make sure we know how many elements
2220e4b17023SJohn Marino      it has.  */
2221e4b17023SJohn Marino   for (elt_type = type;
2222e4b17023SJohn Marino        TREE_CODE (elt_type) == ARRAY_TYPE;
2223e4b17023SJohn Marino        elt_type = TREE_TYPE (elt_type))
2224e4b17023SJohn Marino     nelts = cp_build_binary_op (input_location,
2225e4b17023SJohn Marino 				MULT_EXPR, nelts,
2226e4b17023SJohn Marino 				array_type_nelts_top (elt_type),
2227e4b17023SJohn Marino 				complain);
2228e4b17023SJohn Marino 
2229e4b17023SJohn Marino   if (TREE_CODE (elt_type) == VOID_TYPE)
2230e4b17023SJohn Marino     {
2231e4b17023SJohn Marino       if (complain & tf_error)
2232e4b17023SJohn Marino         error ("invalid type %<void%> for new");
2233e4b17023SJohn Marino       return error_mark_node;
2234e4b17023SJohn Marino     }
2235e4b17023SJohn Marino 
2236e4b17023SJohn Marino   if (abstract_virtuals_error_sfinae (NULL_TREE, elt_type, complain))
2237e4b17023SJohn Marino     return error_mark_node;
2238e4b17023SJohn Marino 
2239e4b17023SJohn Marino   is_initialized = (type_build_ctor_call (elt_type) || *init != NULL);
2240e4b17023SJohn Marino 
2241e4b17023SJohn Marino   if (*init == NULL)
2242e4b17023SJohn Marino     {
2243e4b17023SJohn Marino       bool maybe_uninitialized_error = false;
2244e4b17023SJohn Marino       /* A program that calls for default-initialization [...] of an
2245e4b17023SJohn Marino 	 entity of reference type is ill-formed. */
2246e4b17023SJohn Marino       if (CLASSTYPE_REF_FIELDS_NEED_INIT (elt_type))
2247e4b17023SJohn Marino 	maybe_uninitialized_error = true;
2248e4b17023SJohn Marino 
2249e4b17023SJohn Marino       /* A new-expression that creates an object of type T initializes
2250e4b17023SJohn Marino 	 that object as follows:
2251e4b17023SJohn Marino       - If the new-initializer is omitted:
2252e4b17023SJohn Marino         -- If T is a (possibly cv-qualified) non-POD class type
2253e4b17023SJohn Marino 	   (or array thereof), the object is default-initialized (8.5).
2254e4b17023SJohn Marino 	   [...]
2255e4b17023SJohn Marino         -- Otherwise, the object created has indeterminate
2256e4b17023SJohn Marino 	   value. If T is a const-qualified type, or a (possibly
2257e4b17023SJohn Marino 	   cv-qualified) POD class type (or array thereof)
2258e4b17023SJohn Marino 	   containing (directly or indirectly) a member of
2259e4b17023SJohn Marino 	   const-qualified type, the program is ill-formed; */
2260e4b17023SJohn Marino 
2261e4b17023SJohn Marino       if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (elt_type))
2262e4b17023SJohn Marino 	maybe_uninitialized_error = true;
2263e4b17023SJohn Marino 
2264e4b17023SJohn Marino       if (maybe_uninitialized_error
2265e4b17023SJohn Marino 	  && diagnose_uninitialized_cst_or_ref_member (elt_type,
2266e4b17023SJohn Marino 						       /*using_new=*/true,
2267e4b17023SJohn Marino 						       complain & tf_error))
2268e4b17023SJohn Marino 	return error_mark_node;
2269e4b17023SJohn Marino     }
2270e4b17023SJohn Marino 
2271e4b17023SJohn Marino   if (CP_TYPE_CONST_P (elt_type) && *init == NULL
2272e4b17023SJohn Marino       && default_init_uninitialized_part (elt_type))
2273e4b17023SJohn Marino     {
2274e4b17023SJohn Marino       if (complain & tf_error)
2275e4b17023SJohn Marino         error ("uninitialized const in %<new%> of %q#T", elt_type);
2276e4b17023SJohn Marino       return error_mark_node;
2277e4b17023SJohn Marino     }
2278e4b17023SJohn Marino 
2279e4b17023SJohn Marino   size = size_in_bytes (elt_type);
2280e4b17023SJohn Marino   if (array_p)
2281e4b17023SJohn Marino     size = size_binop (MULT_EXPR, size, convert (sizetype, nelts));
2282e4b17023SJohn Marino 
2283e4b17023SJohn Marino   alloc_fn = NULL_TREE;
2284e4b17023SJohn Marino 
2285e4b17023SJohn Marino   /* If PLACEMENT is a single simple pointer type not passed by
2286e4b17023SJohn Marino      reference, prepare to capture it in a temporary variable.  Do
2287e4b17023SJohn Marino      this now, since PLACEMENT will change in the calls below.  */
2288e4b17023SJohn Marino   placement_first = NULL_TREE;
2289e4b17023SJohn Marino   if (VEC_length (tree, *placement) == 1
2290e4b17023SJohn Marino       && (TREE_CODE (TREE_TYPE (VEC_index (tree, *placement, 0)))
2291e4b17023SJohn Marino 	  == POINTER_TYPE))
2292e4b17023SJohn Marino     placement_first = VEC_index (tree, *placement, 0);
2293e4b17023SJohn Marino 
2294e4b17023SJohn Marino   /* Allocate the object.  */
2295e4b17023SJohn Marino   if (VEC_empty (tree, *placement) && TYPE_FOR_JAVA (elt_type))
2296e4b17023SJohn Marino     {
2297e4b17023SJohn Marino       tree class_addr;
2298e4b17023SJohn Marino       tree class_decl = build_java_class_ref (elt_type);
2299e4b17023SJohn Marino       static const char alloc_name[] = "_Jv_AllocObject";
2300e4b17023SJohn Marino 
2301e4b17023SJohn Marino       if (class_decl == error_mark_node)
2302e4b17023SJohn Marino 	return error_mark_node;
2303e4b17023SJohn Marino 
2304e4b17023SJohn Marino       use_java_new = 1;
2305e4b17023SJohn Marino       if (!get_global_value_if_present (get_identifier (alloc_name),
2306e4b17023SJohn Marino 					&alloc_fn))
2307e4b17023SJohn Marino 	{
2308e4b17023SJohn Marino           if (complain & tf_error)
2309e4b17023SJohn Marino             error ("call to Java constructor with %qs undefined", alloc_name);
2310e4b17023SJohn Marino 	  return error_mark_node;
2311e4b17023SJohn Marino 	}
2312e4b17023SJohn Marino       else if (really_overloaded_fn (alloc_fn))
2313e4b17023SJohn Marino 	{
2314e4b17023SJohn Marino           if (complain & tf_error)
2315e4b17023SJohn Marino             error ("%qD should never be overloaded", alloc_fn);
2316e4b17023SJohn Marino 	  return error_mark_node;
2317e4b17023SJohn Marino 	}
2318e4b17023SJohn Marino       alloc_fn = OVL_CURRENT (alloc_fn);
2319e4b17023SJohn Marino       class_addr = build1 (ADDR_EXPR, jclass_node, class_decl);
2320e4b17023SJohn Marino       alloc_call = cp_build_function_call_nary (alloc_fn, complain,
2321e4b17023SJohn Marino 						class_addr, NULL_TREE);
2322e4b17023SJohn Marino     }
2323e4b17023SJohn Marino   else if (TYPE_FOR_JAVA (elt_type) && MAYBE_CLASS_TYPE_P (elt_type))
2324e4b17023SJohn Marino     {
2325e4b17023SJohn Marino       error ("Java class %q#T object allocated using placement new", elt_type);
2326e4b17023SJohn Marino       return error_mark_node;
2327e4b17023SJohn Marino     }
2328e4b17023SJohn Marino   else
2329e4b17023SJohn Marino     {
2330e4b17023SJohn Marino       tree fnname;
2331e4b17023SJohn Marino       tree fns;
2332e4b17023SJohn Marino 
2333e4b17023SJohn Marino       fnname = ansi_opname (array_p ? VEC_NEW_EXPR : NEW_EXPR);
2334e4b17023SJohn Marino 
2335e4b17023SJohn Marino       if (!globally_qualified_p
2336e4b17023SJohn Marino 	  && CLASS_TYPE_P (elt_type)
2337e4b17023SJohn Marino 	  && (array_p
2338e4b17023SJohn Marino 	      ? TYPE_HAS_ARRAY_NEW_OPERATOR (elt_type)
2339e4b17023SJohn Marino 	      : TYPE_HAS_NEW_OPERATOR (elt_type)))
2340e4b17023SJohn Marino 	{
2341e4b17023SJohn Marino 	  /* Use a class-specific operator new.  */
2342e4b17023SJohn Marino 	  /* If a cookie is required, add some extra space.  */
2343e4b17023SJohn Marino 	  if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
2344e4b17023SJohn Marino 	    {
2345e4b17023SJohn Marino 	      cookie_size = targetm.cxx.get_cookie_size (elt_type);
2346e4b17023SJohn Marino 	      size = size_binop (PLUS_EXPR, size, cookie_size);
2347e4b17023SJohn Marino 	    }
2348e4b17023SJohn Marino 	  /* Create the argument list.  */
2349e4b17023SJohn Marino 	  VEC_safe_insert (tree, gc, *placement, 0, size);
2350e4b17023SJohn Marino 	  /* Do name-lookup to find the appropriate operator.  */
2351e4b17023SJohn Marino 	  fns = lookup_fnfields (elt_type, fnname, /*protect=*/2);
2352e4b17023SJohn Marino 	  if (fns == NULL_TREE)
2353e4b17023SJohn Marino 	    {
2354e4b17023SJohn Marino               if (complain & tf_error)
2355e4b17023SJohn Marino                 error ("no suitable %qD found in class %qT", fnname, elt_type);
2356e4b17023SJohn Marino 	      return error_mark_node;
2357e4b17023SJohn Marino 	    }
2358e4b17023SJohn Marino 	  if (TREE_CODE (fns) == TREE_LIST)
2359e4b17023SJohn Marino 	    {
2360e4b17023SJohn Marino               if (complain & tf_error)
2361e4b17023SJohn Marino                 {
2362e4b17023SJohn Marino                   error ("request for member %qD is ambiguous", fnname);
2363e4b17023SJohn Marino                   print_candidates (fns);
2364e4b17023SJohn Marino                 }
2365e4b17023SJohn Marino 	      return error_mark_node;
2366e4b17023SJohn Marino 	    }
2367e4b17023SJohn Marino 	  alloc_call = build_new_method_call (build_dummy_object (elt_type),
2368e4b17023SJohn Marino 					      fns, placement,
2369e4b17023SJohn Marino 					      /*conversion_path=*/NULL_TREE,
2370e4b17023SJohn Marino 					      LOOKUP_NORMAL,
2371e4b17023SJohn Marino 					      &alloc_fn,
2372e4b17023SJohn Marino 					      complain);
2373e4b17023SJohn Marino 	}
2374e4b17023SJohn Marino       else
2375e4b17023SJohn Marino 	{
2376e4b17023SJohn Marino 	  /* Use a global operator new.  */
2377e4b17023SJohn Marino 	  /* See if a cookie might be required.  */
2378e4b17023SJohn Marino 	  if (array_p && TYPE_VEC_NEW_USES_COOKIE (elt_type))
2379e4b17023SJohn Marino 	    cookie_size = targetm.cxx.get_cookie_size (elt_type);
2380e4b17023SJohn Marino 	  else
2381e4b17023SJohn Marino 	    cookie_size = NULL_TREE;
2382e4b17023SJohn Marino 
2383e4b17023SJohn Marino 	  alloc_call = build_operator_new_call (fnname, placement,
2384e4b17023SJohn Marino 						&size, &cookie_size,
2385e4b17023SJohn Marino 						&alloc_fn);
2386e4b17023SJohn Marino 	}
2387e4b17023SJohn Marino     }
2388e4b17023SJohn Marino 
2389e4b17023SJohn Marino   if (alloc_call == error_mark_node)
2390e4b17023SJohn Marino     return error_mark_node;
2391e4b17023SJohn Marino 
2392e4b17023SJohn Marino   gcc_assert (alloc_fn != NULL_TREE);
2393e4b17023SJohn Marino 
2394e4b17023SJohn Marino   /* If we found a simple case of PLACEMENT_EXPR above, then copy it
2395e4b17023SJohn Marino      into a temporary variable.  */
2396e4b17023SJohn Marino   if (!processing_template_decl
2397e4b17023SJohn Marino       && placement_first != NULL_TREE
2398e4b17023SJohn Marino       && TREE_CODE (alloc_call) == CALL_EXPR
2399e4b17023SJohn Marino       && call_expr_nargs (alloc_call) == 2
2400e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 0))) == INTEGER_TYPE
2401e4b17023SJohn Marino       && TREE_CODE (TREE_TYPE (CALL_EXPR_ARG (alloc_call, 1))) == POINTER_TYPE)
2402e4b17023SJohn Marino     {
2403e4b17023SJohn Marino       tree placement_arg = CALL_EXPR_ARG (alloc_call, 1);
2404e4b17023SJohn Marino 
2405e4b17023SJohn Marino       if (INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg)))
2406e4b17023SJohn Marino 	  || VOID_TYPE_P (TREE_TYPE (TREE_TYPE (placement_arg))))
2407e4b17023SJohn Marino 	{
2408e4b17023SJohn Marino 	  placement_expr = get_target_expr (placement_first);
2409e4b17023SJohn Marino 	  CALL_EXPR_ARG (alloc_call, 1)
2410e4b17023SJohn Marino 	    = convert (TREE_TYPE (placement_arg), placement_expr);
2411e4b17023SJohn Marino 	}
2412e4b17023SJohn Marino     }
2413e4b17023SJohn Marino 
2414e4b17023SJohn Marino   /* In the simple case, we can stop now.  */
2415e4b17023SJohn Marino   pointer_type = build_pointer_type (type);
2416e4b17023SJohn Marino   if (!cookie_size && !is_initialized)
2417e4b17023SJohn Marino     return build_nop (pointer_type, alloc_call);
2418e4b17023SJohn Marino 
2419e4b17023SJohn Marino   /* Store the result of the allocation call in a variable so that we can
2420e4b17023SJohn Marino      use it more than once.  */
2421e4b17023SJohn Marino   alloc_expr = get_target_expr (alloc_call);
2422e4b17023SJohn Marino   alloc_node = TARGET_EXPR_SLOT (alloc_expr);
2423e4b17023SJohn Marino 
2424e4b17023SJohn Marino   /* Strip any COMPOUND_EXPRs from ALLOC_CALL.  */
2425e4b17023SJohn Marino   while (TREE_CODE (alloc_call) == COMPOUND_EXPR)
2426e4b17023SJohn Marino     alloc_call = TREE_OPERAND (alloc_call, 1);
2427e4b17023SJohn Marino 
2428e4b17023SJohn Marino   /* Now, check to see if this function is actually a placement
2429e4b17023SJohn Marino      allocation function.  This can happen even when PLACEMENT is NULL
2430e4b17023SJohn Marino      because we might have something like:
2431e4b17023SJohn Marino 
2432e4b17023SJohn Marino        struct S { void* operator new (size_t, int i = 0); };
2433e4b17023SJohn Marino 
2434e4b17023SJohn Marino      A call to `new S' will get this allocation function, even though
2435e4b17023SJohn Marino      there is no explicit placement argument.  If there is more than
2436e4b17023SJohn Marino      one argument, or there are variable arguments, then this is a
2437e4b17023SJohn Marino      placement allocation function.  */
2438e4b17023SJohn Marino   placement_allocation_fn_p
2439e4b17023SJohn Marino     = (type_num_arguments (TREE_TYPE (alloc_fn)) > 1
2440e4b17023SJohn Marino        || varargs_function_p (alloc_fn));
2441e4b17023SJohn Marino 
2442e4b17023SJohn Marino   /* Preevaluate the placement args so that we don't reevaluate them for a
2443e4b17023SJohn Marino      placement delete.  */
2444e4b17023SJohn Marino   if (placement_allocation_fn_p)
2445e4b17023SJohn Marino     {
2446e4b17023SJohn Marino       tree inits;
2447e4b17023SJohn Marino       stabilize_call (alloc_call, &inits);
2448e4b17023SJohn Marino       if (inits)
2449e4b17023SJohn Marino 	alloc_expr = build2 (COMPOUND_EXPR, TREE_TYPE (alloc_expr), inits,
2450e4b17023SJohn Marino 			     alloc_expr);
2451e4b17023SJohn Marino     }
2452e4b17023SJohn Marino 
2453e4b17023SJohn Marino   /*        unless an allocation function is declared with an empty  excep-
2454e4b17023SJohn Marino      tion-specification  (_except.spec_),  throw(), it indicates failure to
2455e4b17023SJohn Marino      allocate storage by throwing a bad_alloc exception  (clause  _except_,
2456e4b17023SJohn Marino      _lib.bad.alloc_); it returns a non-null pointer otherwise If the allo-
2457e4b17023SJohn Marino      cation function is declared  with  an  empty  exception-specification,
2458e4b17023SJohn Marino      throw(), it returns null to indicate failure to allocate storage and a
2459e4b17023SJohn Marino      non-null pointer otherwise.
2460e4b17023SJohn Marino 
2461e4b17023SJohn Marino      So check for a null exception spec on the op new we just called.  */
2462e4b17023SJohn Marino 
2463e4b17023SJohn Marino   nothrow = TYPE_NOTHROW_P (TREE_TYPE (alloc_fn));
2464e4b17023SJohn Marino   check_new = (flag_check_new || nothrow) && ! use_java_new;
2465e4b17023SJohn Marino 
2466e4b17023SJohn Marino   if (cookie_size)
2467e4b17023SJohn Marino     {
2468e4b17023SJohn Marino       tree cookie;
2469e4b17023SJohn Marino       tree cookie_ptr;
2470e4b17023SJohn Marino       tree size_ptr_type;
2471e4b17023SJohn Marino 
2472e4b17023SJohn Marino       /* Adjust so we're pointing to the start of the object.  */
2473e4b17023SJohn Marino       data_addr = fold_build_pointer_plus (alloc_node, cookie_size);
2474e4b17023SJohn Marino 
2475e4b17023SJohn Marino       /* Store the number of bytes allocated so that we can know how
2476e4b17023SJohn Marino 	 many elements to destroy later.  We use the last sizeof
2477e4b17023SJohn Marino 	 (size_t) bytes to store the number of elements.  */
2478e4b17023SJohn Marino       cookie_ptr = size_binop (MINUS_EXPR, cookie_size, size_in_bytes (sizetype));
2479e4b17023SJohn Marino       cookie_ptr = fold_build_pointer_plus_loc (input_location,
2480e4b17023SJohn Marino 						alloc_node, cookie_ptr);
2481e4b17023SJohn Marino       size_ptr_type = build_pointer_type (sizetype);
2482e4b17023SJohn Marino       cookie_ptr = fold_convert (size_ptr_type, cookie_ptr);
2483e4b17023SJohn Marino       cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
2484e4b17023SJohn Marino 
2485e4b17023SJohn Marino       cookie_expr = build2 (MODIFY_EXPR, sizetype, cookie, nelts);
2486e4b17023SJohn Marino 
2487e4b17023SJohn Marino       if (targetm.cxx.cookie_has_size ())
2488e4b17023SJohn Marino 	{
2489e4b17023SJohn Marino 	  /* Also store the element size.  */
2490e4b17023SJohn Marino 	  cookie_ptr = fold_build_pointer_plus (cookie_ptr,
2491e4b17023SJohn Marino 			       fold_build1_loc (input_location,
2492e4b17023SJohn Marino 						NEGATE_EXPR, sizetype,
2493e4b17023SJohn Marino 						size_in_bytes (sizetype)));
2494e4b17023SJohn Marino 
2495e4b17023SJohn Marino 	  cookie = cp_build_indirect_ref (cookie_ptr, RO_NULL, complain);
2496e4b17023SJohn Marino 	  cookie = build2 (MODIFY_EXPR, sizetype, cookie,
2497e4b17023SJohn Marino 			   size_in_bytes (elt_type));
2498e4b17023SJohn Marino 	  cookie_expr = build2 (COMPOUND_EXPR, TREE_TYPE (cookie_expr),
2499e4b17023SJohn Marino 				cookie, cookie_expr);
2500e4b17023SJohn Marino 	}
2501e4b17023SJohn Marino     }
2502e4b17023SJohn Marino   else
2503e4b17023SJohn Marino     {
2504e4b17023SJohn Marino       cookie_expr = NULL_TREE;
2505e4b17023SJohn Marino       data_addr = alloc_node;
2506e4b17023SJohn Marino     }
2507e4b17023SJohn Marino 
2508e4b17023SJohn Marino   /* Now use a pointer to the type we've actually allocated.  */
2509e4b17023SJohn Marino 
2510e4b17023SJohn Marino   /* But we want to operate on a non-const version to start with,
2511e4b17023SJohn Marino      since we'll be modifying the elements.  */
2512e4b17023SJohn Marino   non_const_pointer_type = build_pointer_type
2513e4b17023SJohn Marino     (cp_build_qualified_type (type, cp_type_quals (type) & ~TYPE_QUAL_CONST));
2514e4b17023SJohn Marino 
2515e4b17023SJohn Marino   data_addr = fold_convert (non_const_pointer_type, data_addr);
2516e4b17023SJohn Marino   /* Any further uses of alloc_node will want this type, too.  */
2517e4b17023SJohn Marino   alloc_node = fold_convert (non_const_pointer_type, alloc_node);
2518e4b17023SJohn Marino 
2519e4b17023SJohn Marino   /* Now initialize the allocated object.  Note that we preevaluate the
2520e4b17023SJohn Marino      initialization expression, apart from the actual constructor call or
2521e4b17023SJohn Marino      assignment--we do this because we want to delay the allocation as long
2522e4b17023SJohn Marino      as possible in order to minimize the size of the exception region for
2523e4b17023SJohn Marino      placement delete.  */
2524e4b17023SJohn Marino   if (is_initialized)
2525e4b17023SJohn Marino     {
2526e4b17023SJohn Marino       bool stable;
2527e4b17023SJohn Marino       bool explicit_value_init_p = false;
2528e4b17023SJohn Marino 
2529e4b17023SJohn Marino       if (*init != NULL && VEC_empty (tree, *init))
2530e4b17023SJohn Marino 	{
2531e4b17023SJohn Marino 	  *init = NULL;
2532e4b17023SJohn Marino 	  explicit_value_init_p = true;
2533e4b17023SJohn Marino 	}
2534e4b17023SJohn Marino 
2535e4b17023SJohn Marino       if (processing_template_decl && explicit_value_init_p)
2536e4b17023SJohn Marino 	{
2537e4b17023SJohn Marino 	  /* build_value_init doesn't work in templates, and we don't need
2538e4b17023SJohn Marino 	     the initializer anyway since we're going to throw it away and
2539e4b17023SJohn Marino 	     rebuild it at instantiation time, so just build up a single
2540e4b17023SJohn Marino 	     constructor call to get any appropriate diagnostics.  */
2541e4b17023SJohn Marino 	  init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
2542e4b17023SJohn Marino 	  if (type_build_ctor_call (elt_type))
2543e4b17023SJohn Marino 	    init_expr = build_special_member_call (init_expr,
2544e4b17023SJohn Marino 						   complete_ctor_identifier,
2545e4b17023SJohn Marino 						   init, elt_type,
2546e4b17023SJohn Marino 						   LOOKUP_NORMAL,
2547e4b17023SJohn Marino 						   complain);
2548e4b17023SJohn Marino 	  stable = stabilize_init (init_expr, &init_preeval_expr);
2549e4b17023SJohn Marino 	}
2550e4b17023SJohn Marino       else if (array_p)
2551e4b17023SJohn Marino 	{
2552e4b17023SJohn Marino 	  tree vecinit = NULL_TREE;
2553e4b17023SJohn Marino 	  if (*init && VEC_length (tree, *init) == 1
2554e4b17023SJohn Marino 	      && BRACE_ENCLOSED_INITIALIZER_P (VEC_index (tree, *init, 0))
2555e4b17023SJohn Marino 	      && CONSTRUCTOR_IS_DIRECT_INIT (VEC_index (tree, *init, 0)))
2556e4b17023SJohn Marino 	    {
2557e4b17023SJohn Marino 	      vecinit = VEC_index (tree, *init, 0);
2558e4b17023SJohn Marino 	      if (CONSTRUCTOR_NELTS (vecinit) == 0)
2559e4b17023SJohn Marino 		/* List-value-initialization, leave it alone.  */;
2560e4b17023SJohn Marino 	      else
2561e4b17023SJohn Marino 		{
2562e4b17023SJohn Marino 		  tree arraytype, domain;
2563e4b17023SJohn Marino 		  if (TREE_CONSTANT (nelts))
2564e4b17023SJohn Marino 		    domain = compute_array_index_type (NULL_TREE, nelts,
2565e4b17023SJohn Marino 						       complain);
2566e4b17023SJohn Marino 		  else
2567e4b17023SJohn Marino 		    {
2568e4b17023SJohn Marino 		      domain = NULL_TREE;
2569e4b17023SJohn Marino 		      if (CONSTRUCTOR_NELTS (vecinit) > 0)
2570e4b17023SJohn Marino 			warning (0, "non-constant array size in new, unable "
2571e4b17023SJohn Marino 				 "to verify length of initializer-list");
2572e4b17023SJohn Marino 		    }
2573e4b17023SJohn Marino 		  arraytype = build_cplus_array_type (type, domain);
2574e4b17023SJohn Marino 		  vecinit = digest_init (arraytype, vecinit, complain);
2575e4b17023SJohn Marino 		}
2576e4b17023SJohn Marino 	    }
2577e4b17023SJohn Marino 	  else if (*init)
2578e4b17023SJohn Marino             {
2579e4b17023SJohn Marino               if (complain & tf_error)
2580e4b17023SJohn Marino                 permerror (input_location,
2581e4b17023SJohn Marino 			   "parenthesized initializer in array new");
2582e4b17023SJohn Marino               else
2583e4b17023SJohn Marino                 return error_mark_node;
2584e4b17023SJohn Marino 	      vecinit = build_tree_list_vec (*init);
2585e4b17023SJohn Marino             }
2586e4b17023SJohn Marino 	  init_expr
2587e4b17023SJohn Marino 	    = build_vec_init (data_addr,
2588e4b17023SJohn Marino 			      cp_build_binary_op (input_location,
2589e4b17023SJohn Marino 						  MINUS_EXPR, outer_nelts,
2590e4b17023SJohn Marino 						  integer_one_node,
2591e4b17023SJohn Marino 						  complain),
2592e4b17023SJohn Marino 			      vecinit,
2593e4b17023SJohn Marino 			      explicit_value_init_p,
2594e4b17023SJohn Marino 			      /*from_array=*/0,
2595e4b17023SJohn Marino                               complain);
2596e4b17023SJohn Marino 
2597e4b17023SJohn Marino 	  /* An array initialization is stable because the initialization
2598e4b17023SJohn Marino 	     of each element is a full-expression, so the temporaries don't
2599e4b17023SJohn Marino 	     leak out.  */
2600e4b17023SJohn Marino 	  stable = true;
2601e4b17023SJohn Marino 	}
2602e4b17023SJohn Marino       else
2603e4b17023SJohn Marino 	{
2604e4b17023SJohn Marino 	  init_expr = cp_build_indirect_ref (data_addr, RO_NULL, complain);
2605e4b17023SJohn Marino 
2606e4b17023SJohn Marino 	  if (type_build_ctor_call (type) && !explicit_value_init_p)
2607e4b17023SJohn Marino 	    {
2608e4b17023SJohn Marino 	      init_expr = build_special_member_call (init_expr,
2609e4b17023SJohn Marino 						     complete_ctor_identifier,
2610e4b17023SJohn Marino 						     init, elt_type,
2611e4b17023SJohn Marino 						     LOOKUP_NORMAL,
2612e4b17023SJohn Marino                                                      complain);
2613e4b17023SJohn Marino 	    }
2614e4b17023SJohn Marino 	  else if (explicit_value_init_p)
2615e4b17023SJohn Marino 	    {
2616e4b17023SJohn Marino 	      /* Something like `new int()'.  */
2617e4b17023SJohn Marino 	      tree val = build_value_init (type, complain);
2618e4b17023SJohn Marino 	      if (val == error_mark_node)
2619e4b17023SJohn Marino 		return error_mark_node;
2620e4b17023SJohn Marino 	      init_expr = build2 (INIT_EXPR, type, init_expr, val);
2621e4b17023SJohn Marino 	    }
2622e4b17023SJohn Marino 	  else
2623e4b17023SJohn Marino 	    {
2624e4b17023SJohn Marino 	      tree ie;
2625e4b17023SJohn Marino 
2626e4b17023SJohn Marino 	      /* We are processing something like `new int (10)', which
2627e4b17023SJohn Marino 		 means allocate an int, and initialize it with 10.  */
2628e4b17023SJohn Marino 
2629e4b17023SJohn Marino 	      ie = build_x_compound_expr_from_vec (*init, "new initializer");
2630e4b17023SJohn Marino 	      init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
2631e4b17023SJohn Marino 						complain);
2632e4b17023SJohn Marino 	    }
2633e4b17023SJohn Marino 	  stable = stabilize_init (init_expr, &init_preeval_expr);
2634e4b17023SJohn Marino 	}
2635e4b17023SJohn Marino 
2636e4b17023SJohn Marino       if (init_expr == error_mark_node)
2637e4b17023SJohn Marino 	return error_mark_node;
2638e4b17023SJohn Marino 
2639e4b17023SJohn Marino       /* If any part of the object initialization terminates by throwing an
2640e4b17023SJohn Marino 	 exception and a suitable deallocation function can be found, the
2641e4b17023SJohn Marino 	 deallocation function is called to free the memory in which the
2642e4b17023SJohn Marino 	 object was being constructed, after which the exception continues
2643e4b17023SJohn Marino 	 to propagate in the context of the new-expression. If no
2644e4b17023SJohn Marino 	 unambiguous matching deallocation function can be found,
2645e4b17023SJohn Marino 	 propagating the exception does not cause the object's memory to be
2646e4b17023SJohn Marino 	 freed.  */
2647e4b17023SJohn Marino       if (flag_exceptions && ! use_java_new)
2648e4b17023SJohn Marino 	{
2649e4b17023SJohn Marino 	  enum tree_code dcode = array_p ? VEC_DELETE_EXPR : DELETE_EXPR;
2650e4b17023SJohn Marino 	  tree cleanup;
2651e4b17023SJohn Marino 
2652e4b17023SJohn Marino 	  /* The Standard is unclear here, but the right thing to do
2653e4b17023SJohn Marino 	     is to use the same method for finding deallocation
2654e4b17023SJohn Marino 	     functions that we use for finding allocation functions.  */
2655e4b17023SJohn Marino 	  cleanup = (build_op_delete_call
2656e4b17023SJohn Marino 		     (dcode,
2657e4b17023SJohn Marino 		      alloc_node,
2658e4b17023SJohn Marino 		      size,
2659e4b17023SJohn Marino 		      globally_qualified_p,
2660e4b17023SJohn Marino 		      placement_allocation_fn_p ? alloc_call : NULL_TREE,
2661e4b17023SJohn Marino 		      alloc_fn));
2662e4b17023SJohn Marino 
2663e4b17023SJohn Marino 	  if (!cleanup)
2664e4b17023SJohn Marino 	    /* We're done.  */;
2665e4b17023SJohn Marino 	  else if (stable)
2666e4b17023SJohn Marino 	    /* This is much simpler if we were able to preevaluate all of
2667e4b17023SJohn Marino 	       the arguments to the constructor call.  */
2668e4b17023SJohn Marino 	    {
2669e4b17023SJohn Marino 	      /* CLEANUP is compiler-generated, so no diagnostics.  */
2670e4b17023SJohn Marino 	      TREE_NO_WARNING (cleanup) = true;
2671e4b17023SJohn Marino 	      init_expr = build2 (TRY_CATCH_EXPR, void_type_node,
2672e4b17023SJohn Marino 				  init_expr, cleanup);
2673e4b17023SJohn Marino 	      /* Likewise, this try-catch is compiler-generated.  */
2674e4b17023SJohn Marino 	      TREE_NO_WARNING (init_expr) = true;
2675e4b17023SJohn Marino 	    }
2676e4b17023SJohn Marino 	  else
2677e4b17023SJohn Marino 	    /* Ack!  First we allocate the memory.  Then we set our sentry
2678e4b17023SJohn Marino 	       variable to true, and expand a cleanup that deletes the
2679e4b17023SJohn Marino 	       memory if sentry is true.  Then we run the constructor, and
2680e4b17023SJohn Marino 	       finally clear the sentry.
2681e4b17023SJohn Marino 
2682e4b17023SJohn Marino 	       We need to do this because we allocate the space first, so
2683e4b17023SJohn Marino 	       if there are any temporaries with cleanups in the
2684e4b17023SJohn Marino 	       constructor args and we weren't able to preevaluate them, we
2685e4b17023SJohn Marino 	       need this EH region to extend until end of full-expression
2686e4b17023SJohn Marino 	       to preserve nesting.  */
2687e4b17023SJohn Marino 	    {
2688e4b17023SJohn Marino 	      tree end, sentry, begin;
2689e4b17023SJohn Marino 
2690e4b17023SJohn Marino 	      begin = get_target_expr (boolean_true_node);
2691e4b17023SJohn Marino 	      CLEANUP_EH_ONLY (begin) = 1;
2692e4b17023SJohn Marino 
2693e4b17023SJohn Marino 	      sentry = TARGET_EXPR_SLOT (begin);
2694e4b17023SJohn Marino 
2695e4b17023SJohn Marino 	      /* CLEANUP is compiler-generated, so no diagnostics.  */
2696e4b17023SJohn Marino 	      TREE_NO_WARNING (cleanup) = true;
2697e4b17023SJohn Marino 
2698e4b17023SJohn Marino 	      TARGET_EXPR_CLEANUP (begin)
2699e4b17023SJohn Marino 		= build3 (COND_EXPR, void_type_node, sentry,
2700e4b17023SJohn Marino 			  cleanup, void_zero_node);
2701e4b17023SJohn Marino 
2702e4b17023SJohn Marino 	      end = build2 (MODIFY_EXPR, TREE_TYPE (sentry),
2703e4b17023SJohn Marino 			    sentry, boolean_false_node);
2704e4b17023SJohn Marino 
2705e4b17023SJohn Marino 	      init_expr
2706e4b17023SJohn Marino 		= build2 (COMPOUND_EXPR, void_type_node, begin,
2707e4b17023SJohn Marino 			  build2 (COMPOUND_EXPR, void_type_node, init_expr,
2708e4b17023SJohn Marino 				  end));
2709e4b17023SJohn Marino 	      /* Likewise, this is compiler-generated.  */
2710e4b17023SJohn Marino 	      TREE_NO_WARNING (init_expr) = true;
2711e4b17023SJohn Marino 	    }
2712e4b17023SJohn Marino 	}
2713e4b17023SJohn Marino     }
2714e4b17023SJohn Marino   else
2715e4b17023SJohn Marino     init_expr = NULL_TREE;
2716e4b17023SJohn Marino 
2717e4b17023SJohn Marino   /* Now build up the return value in reverse order.  */
2718e4b17023SJohn Marino 
2719e4b17023SJohn Marino   rval = data_addr;
2720e4b17023SJohn Marino 
2721e4b17023SJohn Marino   if (init_expr)
2722e4b17023SJohn Marino     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_expr, rval);
2723e4b17023SJohn Marino   if (cookie_expr)
2724e4b17023SJohn Marino     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), cookie_expr, rval);
2725e4b17023SJohn Marino 
2726e4b17023SJohn Marino   if (rval == data_addr)
2727e4b17023SJohn Marino     /* If we don't have an initializer or a cookie, strip the TARGET_EXPR
2728e4b17023SJohn Marino        and return the call (which doesn't need to be adjusted).  */
2729e4b17023SJohn Marino     rval = TARGET_EXPR_INITIAL (alloc_expr);
2730e4b17023SJohn Marino   else
2731e4b17023SJohn Marino     {
2732e4b17023SJohn Marino       if (check_new)
2733e4b17023SJohn Marino 	{
2734e4b17023SJohn Marino 	  tree ifexp = cp_build_binary_op (input_location,
2735e4b17023SJohn Marino 					   NE_EXPR, alloc_node,
2736e4b17023SJohn Marino 					   nullptr_node,
2737e4b17023SJohn Marino 					   complain);
2738e4b17023SJohn Marino 	  rval = build_conditional_expr (ifexp, rval, alloc_node,
2739e4b17023SJohn Marino                                          complain);
2740e4b17023SJohn Marino 	}
2741e4b17023SJohn Marino 
2742e4b17023SJohn Marino       /* Perform the allocation before anything else, so that ALLOC_NODE
2743e4b17023SJohn Marino 	 has been initialized before we start using it.  */
2744e4b17023SJohn Marino       rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval);
2745e4b17023SJohn Marino     }
2746e4b17023SJohn Marino 
2747e4b17023SJohn Marino   if (init_preeval_expr)
2748e4b17023SJohn Marino     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), init_preeval_expr, rval);
2749e4b17023SJohn Marino 
2750e4b17023SJohn Marino   /* A new-expression is never an lvalue.  */
2751e4b17023SJohn Marino   gcc_assert (!lvalue_p (rval));
2752e4b17023SJohn Marino 
2753e4b17023SJohn Marino   return convert (pointer_type, rval);
2754e4b17023SJohn Marino }
2755e4b17023SJohn Marino 
2756e4b17023SJohn Marino /* Generate a representation for a C++ "new" expression.  *PLACEMENT
2757e4b17023SJohn Marino    is a vector of placement-new arguments (or NULL if none).  If NELTS
2758e4b17023SJohn Marino    is NULL, TYPE is the type of the storage to be allocated.  If NELTS
2759e4b17023SJohn Marino    is not NULL, then this is an array-new allocation; TYPE is the type
2760e4b17023SJohn Marino    of the elements in the array and NELTS is the number of elements in
2761e4b17023SJohn Marino    the array.  *INIT, if non-NULL, is the initializer for the new
2762e4b17023SJohn Marino    object, or an empty vector to indicate an initializer of "()".  If
2763e4b17023SJohn Marino    USE_GLOBAL_NEW is true, then the user explicitly wrote "::new"
2764e4b17023SJohn Marino    rather than just "new".  This may change PLACEMENT and INIT.  */
2765e4b17023SJohn Marino 
2766e4b17023SJohn Marino tree
build_new(VEC (tree,gc)** placement,tree type,tree nelts,VEC (tree,gc)** init,int use_global_new,tsubst_flags_t complain)2767e4b17023SJohn Marino build_new (VEC(tree,gc) **placement, tree type, tree nelts,
2768e4b17023SJohn Marino 	   VEC(tree,gc) **init, int use_global_new, tsubst_flags_t complain)
2769e4b17023SJohn Marino {
2770e4b17023SJohn Marino   tree rval;
2771e4b17023SJohn Marino   VEC(tree,gc) *orig_placement = NULL;
2772e4b17023SJohn Marino   tree orig_nelts = NULL_TREE;
2773e4b17023SJohn Marino   VEC(tree,gc) *orig_init = NULL;
2774e4b17023SJohn Marino 
2775e4b17023SJohn Marino   if (type == error_mark_node)
2776e4b17023SJohn Marino     return error_mark_node;
2777e4b17023SJohn Marino 
2778e4b17023SJohn Marino   if (nelts == NULL_TREE && VEC_length (tree, *init) == 1
2779e4b17023SJohn Marino       /* Don't do auto deduction where it might affect mangling.  */
2780e4b17023SJohn Marino       && (!processing_template_decl || at_function_scope_p ()))
2781e4b17023SJohn Marino     {
2782e4b17023SJohn Marino       tree auto_node = type_uses_auto (type);
2783e4b17023SJohn Marino       if (auto_node)
2784e4b17023SJohn Marino 	{
2785e4b17023SJohn Marino 	  tree d_init = VEC_index (tree, *init, 0);
2786e4b17023SJohn Marino 	  d_init = resolve_nondeduced_context (d_init);
2787e4b17023SJohn Marino 	  type = do_auto_deduction (type, d_init, auto_node);
2788e4b17023SJohn Marino 	}
2789e4b17023SJohn Marino     }
2790e4b17023SJohn Marino 
2791e4b17023SJohn Marino   if (processing_template_decl)
2792e4b17023SJohn Marino     {
2793e4b17023SJohn Marino       if (dependent_type_p (type)
2794e4b17023SJohn Marino 	  || any_type_dependent_arguments_p (*placement)
2795e4b17023SJohn Marino 	  || (nelts && type_dependent_expression_p (nelts))
2796e4b17023SJohn Marino 	  || any_type_dependent_arguments_p (*init))
2797e4b17023SJohn Marino 	return build_raw_new_expr (*placement, type, nelts, *init,
2798e4b17023SJohn Marino 				   use_global_new);
2799e4b17023SJohn Marino 
2800e4b17023SJohn Marino       orig_placement = make_tree_vector_copy (*placement);
2801e4b17023SJohn Marino       orig_nelts = nelts;
28025ce9237cSJohn Marino       if (*init)
2803e4b17023SJohn Marino 	orig_init = make_tree_vector_copy (*init);
2804e4b17023SJohn Marino 
2805e4b17023SJohn Marino       make_args_non_dependent (*placement);
2806e4b17023SJohn Marino       if (nelts)
2807e4b17023SJohn Marino 	nelts = build_non_dependent_expr (nelts);
2808e4b17023SJohn Marino       make_args_non_dependent (*init);
2809e4b17023SJohn Marino     }
2810e4b17023SJohn Marino 
2811e4b17023SJohn Marino   if (nelts)
2812e4b17023SJohn Marino     {
2813e4b17023SJohn Marino       if (!build_expr_type_conversion (WANT_INT | WANT_ENUM, nelts, false))
2814e4b17023SJohn Marino         {
2815e4b17023SJohn Marino           if (complain & tf_error)
2816e4b17023SJohn Marino             permerror (input_location, "size in array new must have integral type");
2817e4b17023SJohn Marino           else
2818e4b17023SJohn Marino             return error_mark_node;
2819e4b17023SJohn Marino         }
2820e4b17023SJohn Marino       nelts = mark_rvalue_use (nelts);
2821e4b17023SJohn Marino       nelts = cp_save_expr (cp_convert (sizetype, nelts));
2822e4b17023SJohn Marino     }
2823e4b17023SJohn Marino 
2824e4b17023SJohn Marino   /* ``A reference cannot be created by the new operator.  A reference
2825e4b17023SJohn Marino      is not an object (8.2.2, 8.4.3), so a pointer to it could not be
2826e4b17023SJohn Marino      returned by new.'' ARM 5.3.3 */
2827e4b17023SJohn Marino   if (TREE_CODE (type) == REFERENCE_TYPE)
2828e4b17023SJohn Marino     {
2829e4b17023SJohn Marino       if (complain & tf_error)
2830e4b17023SJohn Marino         error ("new cannot be applied to a reference type");
2831e4b17023SJohn Marino       else
2832e4b17023SJohn Marino         return error_mark_node;
2833e4b17023SJohn Marino       type = TREE_TYPE (type);
2834e4b17023SJohn Marino     }
2835e4b17023SJohn Marino 
2836e4b17023SJohn Marino   if (TREE_CODE (type) == FUNCTION_TYPE)
2837e4b17023SJohn Marino     {
2838e4b17023SJohn Marino       if (complain & tf_error)
2839e4b17023SJohn Marino         error ("new cannot be applied to a function type");
2840e4b17023SJohn Marino       return error_mark_node;
2841e4b17023SJohn Marino     }
2842e4b17023SJohn Marino 
2843e4b17023SJohn Marino   /* The type allocated must be complete.  If the new-type-id was
2844e4b17023SJohn Marino      "T[N]" then we are just checking that "T" is complete here, but
2845e4b17023SJohn Marino      that is equivalent, since the value of "N" doesn't matter.  */
2846e4b17023SJohn Marino   if (!complete_type_or_maybe_complain (type, NULL_TREE, complain))
2847e4b17023SJohn Marino     return error_mark_node;
2848e4b17023SJohn Marino 
2849e4b17023SJohn Marino   rval = build_new_1 (placement, type, nelts, init, use_global_new, complain);
2850e4b17023SJohn Marino   if (rval == error_mark_node)
2851e4b17023SJohn Marino     return error_mark_node;
2852e4b17023SJohn Marino 
2853e4b17023SJohn Marino   if (processing_template_decl)
2854e4b17023SJohn Marino     {
2855e4b17023SJohn Marino       tree ret = build_raw_new_expr (orig_placement, type, orig_nelts,
2856e4b17023SJohn Marino 				     orig_init, use_global_new);
2857e4b17023SJohn Marino       release_tree_vector (orig_placement);
2858e4b17023SJohn Marino       release_tree_vector (orig_init);
2859e4b17023SJohn Marino       return ret;
2860e4b17023SJohn Marino     }
2861e4b17023SJohn Marino 
2862e4b17023SJohn Marino   /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain.  */
2863e4b17023SJohn Marino   rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
2864e4b17023SJohn Marino   TREE_NO_WARNING (rval) = 1;
2865e4b17023SJohn Marino 
2866e4b17023SJohn Marino   return rval;
2867e4b17023SJohn Marino }
2868e4b17023SJohn Marino 
2869e4b17023SJohn Marino /* Given a Java class, return a decl for the corresponding java.lang.Class.  */
2870e4b17023SJohn Marino 
2871e4b17023SJohn Marino tree
build_java_class_ref(tree type)2872e4b17023SJohn Marino build_java_class_ref (tree type)
2873e4b17023SJohn Marino {
2874e4b17023SJohn Marino   tree name = NULL_TREE, class_decl;
2875e4b17023SJohn Marino   static tree CL_suffix = NULL_TREE;
2876e4b17023SJohn Marino   if (CL_suffix == NULL_TREE)
2877e4b17023SJohn Marino     CL_suffix = get_identifier("class$");
2878e4b17023SJohn Marino   if (jclass_node == NULL_TREE)
2879e4b17023SJohn Marino     {
2880e4b17023SJohn Marino       jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier ("jclass"));
2881e4b17023SJohn Marino       if (jclass_node == NULL_TREE)
2882e4b17023SJohn Marino 	{
2883e4b17023SJohn Marino 	  error ("call to Java constructor, while %<jclass%> undefined");
2884e4b17023SJohn Marino 	  return error_mark_node;
2885e4b17023SJohn Marino 	}
2886e4b17023SJohn Marino       jclass_node = TREE_TYPE (jclass_node);
2887e4b17023SJohn Marino     }
2888e4b17023SJohn Marino 
2889e4b17023SJohn Marino   /* Mangle the class$ field.  */
2890e4b17023SJohn Marino   {
2891e4b17023SJohn Marino     tree field;
2892e4b17023SJohn Marino     for (field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
2893e4b17023SJohn Marino       if (DECL_NAME (field) == CL_suffix)
2894e4b17023SJohn Marino 	{
2895e4b17023SJohn Marino 	  mangle_decl (field);
2896e4b17023SJohn Marino 	  name = DECL_ASSEMBLER_NAME (field);
2897e4b17023SJohn Marino 	  break;
2898e4b17023SJohn Marino 	}
2899e4b17023SJohn Marino     if (!field)
2900e4b17023SJohn Marino       {
2901e4b17023SJohn Marino 	error ("can%'t find %<class$%> in %qT", type);
2902e4b17023SJohn Marino 	return error_mark_node;
2903e4b17023SJohn Marino       }
2904e4b17023SJohn Marino   }
2905e4b17023SJohn Marino 
2906e4b17023SJohn Marino   class_decl = IDENTIFIER_GLOBAL_VALUE (name);
2907e4b17023SJohn Marino   if (class_decl == NULL_TREE)
2908e4b17023SJohn Marino     {
2909e4b17023SJohn Marino       class_decl = build_decl (input_location,
2910e4b17023SJohn Marino 			       VAR_DECL, name, TREE_TYPE (jclass_node));
2911e4b17023SJohn Marino       TREE_STATIC (class_decl) = 1;
2912e4b17023SJohn Marino       DECL_EXTERNAL (class_decl) = 1;
2913e4b17023SJohn Marino       TREE_PUBLIC (class_decl) = 1;
2914e4b17023SJohn Marino       DECL_ARTIFICIAL (class_decl) = 1;
2915e4b17023SJohn Marino       DECL_IGNORED_P (class_decl) = 1;
2916e4b17023SJohn Marino       pushdecl_top_level (class_decl);
2917e4b17023SJohn Marino       make_decl_rtl (class_decl);
2918e4b17023SJohn Marino     }
2919e4b17023SJohn Marino   return class_decl;
2920e4b17023SJohn Marino }
2921e4b17023SJohn Marino 
2922e4b17023SJohn Marino 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)2923e4b17023SJohn Marino build_vec_delete_1 (tree base, tree maxindex, tree type,
2924e4b17023SJohn Marino 		    special_function_kind auto_delete_vec,
2925e4b17023SJohn Marino 		    int use_global_delete, tsubst_flags_t complain)
2926e4b17023SJohn Marino {
2927e4b17023SJohn Marino   tree virtual_size;
2928e4b17023SJohn Marino   tree ptype = build_pointer_type (type = complete_type (type));
2929e4b17023SJohn Marino   tree size_exp = size_in_bytes (type);
2930e4b17023SJohn Marino 
2931e4b17023SJohn Marino   /* Temporary variables used by the loop.  */
2932e4b17023SJohn Marino   tree tbase, tbase_init;
2933e4b17023SJohn Marino 
2934e4b17023SJohn Marino   /* This is the body of the loop that implements the deletion of a
2935e4b17023SJohn Marino      single element, and moves temp variables to next elements.  */
2936e4b17023SJohn Marino   tree body;
2937e4b17023SJohn Marino 
2938e4b17023SJohn Marino   /* This is the LOOP_EXPR that governs the deletion of the elements.  */
2939e4b17023SJohn Marino   tree loop = 0;
2940e4b17023SJohn Marino 
2941e4b17023SJohn Marino   /* This is the thing that governs what to do after the loop has run.  */
2942e4b17023SJohn Marino   tree deallocate_expr = 0;
2943e4b17023SJohn Marino 
2944e4b17023SJohn Marino   /* This is the BIND_EXPR which holds the outermost iterator of the
2945e4b17023SJohn Marino      loop.  It is convenient to set this variable up and test it before
2946e4b17023SJohn Marino      executing any other code in the loop.
2947e4b17023SJohn Marino      This is also the containing expression returned by this function.  */
2948e4b17023SJohn Marino   tree controller = NULL_TREE;
2949e4b17023SJohn Marino   tree tmp;
2950e4b17023SJohn Marino 
2951e4b17023SJohn Marino   /* We should only have 1-D arrays here.  */
2952e4b17023SJohn Marino   gcc_assert (TREE_CODE (type) != ARRAY_TYPE);
2953e4b17023SJohn Marino 
2954e4b17023SJohn Marino   if (base == error_mark_node || maxindex == error_mark_node)
2955e4b17023SJohn Marino     return error_mark_node;
2956e4b17023SJohn Marino 
2957e4b17023SJohn Marino   if (! MAYBE_CLASS_TYPE_P (type) || TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
2958e4b17023SJohn Marino     goto no_destructor;
2959e4b17023SJohn Marino 
2960e4b17023SJohn Marino   /* The below is short by the cookie size.  */
2961e4b17023SJohn Marino   virtual_size = size_binop (MULT_EXPR, size_exp,
2962e4b17023SJohn Marino 			     convert (sizetype, maxindex));
2963e4b17023SJohn Marino 
2964e4b17023SJohn Marino   tbase = create_temporary_var (ptype);
2965e4b17023SJohn Marino   tbase_init
2966e4b17023SJohn Marino     = cp_build_modify_expr (tbase, NOP_EXPR,
2967e4b17023SJohn Marino 			    fold_build_pointer_plus_loc (input_location,
2968e4b17023SJohn Marino 							 fold_convert (ptype,
2969e4b17023SJohn Marino 								       base),
2970e4b17023SJohn Marino 							 virtual_size),
2971e4b17023SJohn Marino 			    complain);
2972e4b17023SJohn Marino   if (tbase_init == error_mark_node)
2973e4b17023SJohn Marino     return error_mark_node;
2974e4b17023SJohn Marino   controller = build3 (BIND_EXPR, void_type_node, tbase,
2975e4b17023SJohn Marino 		       NULL_TREE, NULL_TREE);
2976e4b17023SJohn Marino   TREE_SIDE_EFFECTS (controller) = 1;
2977e4b17023SJohn Marino 
2978e4b17023SJohn Marino   body = build1 (EXIT_EXPR, void_type_node,
2979e4b17023SJohn Marino 		 build2 (EQ_EXPR, boolean_type_node, tbase,
2980e4b17023SJohn Marino 			 fold_convert (ptype, base)));
2981e4b17023SJohn Marino   tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
2982e4b17023SJohn Marino   tmp = fold_build_pointer_plus (tbase, tmp);
2983e4b17023SJohn Marino   tmp = cp_build_modify_expr (tbase, NOP_EXPR, tmp, complain);
2984e4b17023SJohn Marino   if (tmp == error_mark_node)
2985e4b17023SJohn Marino     return error_mark_node;
2986e4b17023SJohn Marino   body = build_compound_expr (input_location, body, tmp);
2987e4b17023SJohn Marino   tmp = build_delete (ptype, tbase, sfk_complete_destructor,
2988e4b17023SJohn Marino 		      LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1,
2989e4b17023SJohn Marino 		      complain);
2990e4b17023SJohn Marino   if (tmp == error_mark_node)
2991e4b17023SJohn Marino     return error_mark_node;
2992e4b17023SJohn Marino   body = build_compound_expr (input_location, body, tmp);
2993e4b17023SJohn Marino 
2994e4b17023SJohn Marino   loop = build1 (LOOP_EXPR, void_type_node, body);
2995e4b17023SJohn Marino   loop = build_compound_expr (input_location, tbase_init, loop);
2996e4b17023SJohn Marino 
2997e4b17023SJohn Marino  no_destructor:
2998e4b17023SJohn Marino   /* Delete the storage if appropriate.  */
2999e4b17023SJohn Marino   if (auto_delete_vec == sfk_deleting_destructor)
3000e4b17023SJohn Marino     {
3001e4b17023SJohn Marino       tree base_tbd;
3002e4b17023SJohn Marino 
3003e4b17023SJohn Marino       /* The below is short by the cookie size.  */
3004e4b17023SJohn Marino       virtual_size = size_binop (MULT_EXPR, size_exp,
3005e4b17023SJohn Marino 				 convert (sizetype, maxindex));
3006e4b17023SJohn Marino 
3007e4b17023SJohn Marino       if (! TYPE_VEC_NEW_USES_COOKIE (type))
3008e4b17023SJohn Marino 	/* no header */
3009e4b17023SJohn Marino 	base_tbd = base;
3010e4b17023SJohn Marino       else
3011e4b17023SJohn Marino 	{
3012e4b17023SJohn Marino 	  tree cookie_size;
3013e4b17023SJohn Marino 
3014e4b17023SJohn Marino 	  cookie_size = targetm.cxx.get_cookie_size (type);
3015e4b17023SJohn Marino 	  base_tbd = cp_build_binary_op (input_location,
3016e4b17023SJohn Marino 					 MINUS_EXPR,
3017e4b17023SJohn Marino 					 cp_convert (string_type_node,
3018e4b17023SJohn Marino 						     base),
3019e4b17023SJohn Marino 					 cookie_size,
3020e4b17023SJohn Marino 					 complain);
3021e4b17023SJohn Marino 	  if (base_tbd == error_mark_node)
3022e4b17023SJohn Marino 	    return error_mark_node;
3023e4b17023SJohn Marino 	  base_tbd = cp_convert (ptype, base_tbd);
3024e4b17023SJohn Marino 	  /* True size with header.  */
3025e4b17023SJohn Marino 	  virtual_size = size_binop (PLUS_EXPR, virtual_size, cookie_size);
3026e4b17023SJohn Marino 	}
3027e4b17023SJohn Marino 
3028e4b17023SJohn Marino       deallocate_expr = build_op_delete_call (VEC_DELETE_EXPR,
3029e4b17023SJohn Marino 					      base_tbd, virtual_size,
3030e4b17023SJohn Marino 					      use_global_delete & 1,
3031e4b17023SJohn Marino 					      /*placement=*/NULL_TREE,
3032e4b17023SJohn Marino 					      /*alloc_fn=*/NULL_TREE);
3033e4b17023SJohn Marino     }
3034e4b17023SJohn Marino 
3035e4b17023SJohn Marino   body = loop;
3036e4b17023SJohn Marino   if (!deallocate_expr)
3037e4b17023SJohn Marino     ;
3038e4b17023SJohn Marino   else if (!body)
3039e4b17023SJohn Marino     body = deallocate_expr;
3040e4b17023SJohn Marino   else
3041e4b17023SJohn Marino     body = build_compound_expr (input_location, body, deallocate_expr);
3042e4b17023SJohn Marino 
3043e4b17023SJohn Marino   if (!body)
3044e4b17023SJohn Marino     body = integer_zero_node;
3045e4b17023SJohn Marino 
3046e4b17023SJohn Marino   /* Outermost wrapper: If pointer is null, punt.  */
3047e4b17023SJohn Marino   body = fold_build3_loc (input_location, COND_EXPR, void_type_node,
3048e4b17023SJohn Marino 		      fold_build2_loc (input_location,
3049e4b17023SJohn Marino 				   NE_EXPR, boolean_type_node, base,
3050e4b17023SJohn Marino 				   convert (TREE_TYPE (base),
3051e4b17023SJohn Marino 					    nullptr_node)),
3052e4b17023SJohn Marino 		      body, integer_zero_node);
3053e4b17023SJohn Marino   body = build1 (NOP_EXPR, void_type_node, body);
3054e4b17023SJohn Marino 
3055e4b17023SJohn Marino   if (controller)
3056e4b17023SJohn Marino     {
3057e4b17023SJohn Marino       TREE_OPERAND (controller, 1) = body;
3058e4b17023SJohn Marino       body = controller;
3059e4b17023SJohn Marino     }
3060e4b17023SJohn Marino 
3061e4b17023SJohn Marino   if (TREE_CODE (base) == SAVE_EXPR)
3062e4b17023SJohn Marino     /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR.  */
3063e4b17023SJohn Marino     body = build2 (COMPOUND_EXPR, void_type_node, base, body);
3064e4b17023SJohn Marino 
3065e4b17023SJohn Marino   return convert_to_void (body, ICV_CAST, complain);
3066e4b17023SJohn Marino }
3067e4b17023SJohn Marino 
3068e4b17023SJohn Marino /* Create an unnamed variable of the indicated TYPE.  */
3069e4b17023SJohn Marino 
3070e4b17023SJohn Marino tree
create_temporary_var(tree type)3071e4b17023SJohn Marino create_temporary_var (tree type)
3072e4b17023SJohn Marino {
3073e4b17023SJohn Marino   tree decl;
3074e4b17023SJohn Marino 
3075e4b17023SJohn Marino   decl = build_decl (input_location,
3076e4b17023SJohn Marino 		     VAR_DECL, NULL_TREE, type);
3077e4b17023SJohn Marino   TREE_USED (decl) = 1;
3078e4b17023SJohn Marino   DECL_ARTIFICIAL (decl) = 1;
3079e4b17023SJohn Marino   DECL_IGNORED_P (decl) = 1;
3080e4b17023SJohn Marino   DECL_CONTEXT (decl) = current_function_decl;
3081e4b17023SJohn Marino 
3082e4b17023SJohn Marino   return decl;
3083e4b17023SJohn Marino }
3084e4b17023SJohn Marino 
3085e4b17023SJohn Marino /* Create a new temporary variable of the indicated TYPE, initialized
3086e4b17023SJohn Marino    to INIT.
3087e4b17023SJohn Marino 
3088e4b17023SJohn Marino    It is not entered into current_binding_level, because that breaks
3089e4b17023SJohn Marino    things when it comes time to do final cleanups (which take place
3090e4b17023SJohn Marino    "outside" the binding contour of the function).  */
3091e4b17023SJohn Marino 
3092e4b17023SJohn Marino tree
get_temp_regvar(tree type,tree init)3093e4b17023SJohn Marino get_temp_regvar (tree type, tree init)
3094e4b17023SJohn Marino {
3095e4b17023SJohn Marino   tree decl;
3096e4b17023SJohn Marino 
3097e4b17023SJohn Marino   decl = create_temporary_var (type);
3098e4b17023SJohn Marino   add_decl_expr (decl);
3099e4b17023SJohn Marino 
3100e4b17023SJohn Marino   finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
3101e4b17023SJohn Marino 					  tf_warning_or_error));
3102e4b17023SJohn Marino 
3103e4b17023SJohn Marino   return decl;
3104e4b17023SJohn Marino }
3105e4b17023SJohn Marino 
3106e4b17023SJohn Marino /* `build_vec_init' returns tree structure that performs
3107e4b17023SJohn Marino    initialization of a vector of aggregate types.
3108e4b17023SJohn Marino 
3109e4b17023SJohn Marino    BASE is a reference to the vector, of ARRAY_TYPE, or a pointer
3110e4b17023SJohn Marino      to the first element, of POINTER_TYPE.
3111e4b17023SJohn Marino    MAXINDEX is the maximum index of the array (one less than the
3112e4b17023SJohn Marino      number of elements).  It is only used if BASE is a pointer or
3113e4b17023SJohn Marino      TYPE_DOMAIN (TREE_TYPE (BASE)) == NULL_TREE.
3114e4b17023SJohn Marino 
3115e4b17023SJohn Marino    INIT is the (possibly NULL) initializer.
3116e4b17023SJohn Marino 
3117e4b17023SJohn Marino    If EXPLICIT_VALUE_INIT_P is true, then INIT must be NULL.  All
3118e4b17023SJohn Marino    elements in the array are value-initialized.
3119e4b17023SJohn Marino 
3120e4b17023SJohn Marino    FROM_ARRAY is 0 if we should init everything with INIT
3121e4b17023SJohn Marino    (i.e., every element initialized from INIT).
3122e4b17023SJohn Marino    FROM_ARRAY is 1 if we should index into INIT in parallel
3123e4b17023SJohn Marino    with initialization of DECL.
3124e4b17023SJohn Marino    FROM_ARRAY is 2 if we should index into INIT in parallel,
3125e4b17023SJohn Marino    but use assignment instead of initialization.  */
3126e4b17023SJohn Marino 
3127e4b17023SJohn Marino tree
build_vec_init(tree base,tree maxindex,tree init,bool explicit_value_init_p,int from_array,tsubst_flags_t complain)3128e4b17023SJohn Marino build_vec_init (tree base, tree maxindex, tree init,
3129e4b17023SJohn Marino 		bool explicit_value_init_p,
3130e4b17023SJohn Marino 		int from_array, tsubst_flags_t complain)
3131e4b17023SJohn Marino {
3132e4b17023SJohn Marino   tree rval;
3133e4b17023SJohn Marino   tree base2 = NULL_TREE;
3134e4b17023SJohn Marino   tree itype = NULL_TREE;
3135e4b17023SJohn Marino   tree iterator;
3136e4b17023SJohn Marino   /* The type of BASE.  */
3137e4b17023SJohn Marino   tree atype = TREE_TYPE (base);
3138e4b17023SJohn Marino   /* The type of an element in the array.  */
3139e4b17023SJohn Marino   tree type = TREE_TYPE (atype);
3140e4b17023SJohn Marino   /* The element type reached after removing all outer array
3141e4b17023SJohn Marino      types.  */
3142e4b17023SJohn Marino   tree inner_elt_type;
3143e4b17023SJohn Marino   /* The type of a pointer to an element in the array.  */
3144e4b17023SJohn Marino   tree ptype;
3145e4b17023SJohn Marino   tree stmt_expr;
3146e4b17023SJohn Marino   tree compound_stmt;
3147e4b17023SJohn Marino   int destroy_temps;
3148e4b17023SJohn Marino   tree try_block = NULL_TREE;
3149e4b17023SJohn Marino   int num_initialized_elts = 0;
3150e4b17023SJohn Marino   bool is_global;
3151e4b17023SJohn Marino   tree const_init = NULL_TREE;
3152e4b17023SJohn Marino   tree obase = base;
3153e4b17023SJohn Marino   bool xvalue = false;
3154e4b17023SJohn Marino   bool errors = false;
3155e4b17023SJohn Marino 
3156e4b17023SJohn Marino   if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype))
3157e4b17023SJohn Marino     maxindex = array_type_nelts (atype);
3158e4b17023SJohn Marino 
31595ce9237cSJohn Marino   if (maxindex == NULL_TREE || maxindex == error_mark_node)
3160e4b17023SJohn Marino     return error_mark_node;
3161e4b17023SJohn Marino 
3162e4b17023SJohn Marino   if (explicit_value_init_p)
3163e4b17023SJohn Marino     gcc_assert (!init);
3164e4b17023SJohn Marino 
3165e4b17023SJohn Marino   inner_elt_type = strip_array_types (type);
3166e4b17023SJohn Marino 
3167e4b17023SJohn Marino   /* Look through the TARGET_EXPR around a compound literal.  */
3168e4b17023SJohn Marino   if (init && TREE_CODE (init) == TARGET_EXPR
3169e4b17023SJohn Marino       && TREE_CODE (TARGET_EXPR_INITIAL (init)) == CONSTRUCTOR
3170e4b17023SJohn Marino       && from_array != 2)
3171e4b17023SJohn Marino     init = TARGET_EXPR_INITIAL (init);
3172e4b17023SJohn Marino 
3173e4b17023SJohn Marino   if (init
3174e4b17023SJohn Marino       && TREE_CODE (atype) == ARRAY_TYPE
3175e4b17023SJohn Marino       && (from_array == 2
3176e4b17023SJohn Marino 	  ? (!CLASS_TYPE_P (inner_elt_type)
3177e4b17023SJohn Marino 	     || !TYPE_HAS_COMPLEX_COPY_ASSIGN (inner_elt_type))
3178e4b17023SJohn Marino 	  : !TYPE_NEEDS_CONSTRUCTING (type))
3179e4b17023SJohn Marino       && ((TREE_CODE (init) == CONSTRUCTOR
3180e4b17023SJohn Marino 	   /* Don't do this if the CONSTRUCTOR might contain something
3181e4b17023SJohn Marino 	      that might throw and require us to clean up.  */
3182e4b17023SJohn Marino 	   && (VEC_empty (constructor_elt, CONSTRUCTOR_ELTS (init))
3183e4b17023SJohn Marino 	       || ! TYPE_HAS_NONTRIVIAL_DESTRUCTOR (inner_elt_type)))
3184e4b17023SJohn Marino 	  || from_array))
3185e4b17023SJohn Marino     {
3186e4b17023SJohn Marino       /* Do non-default initialization of trivial arrays resulting from
3187e4b17023SJohn Marino 	 brace-enclosed initializers.  In this case, digest_init and
3188e4b17023SJohn Marino 	 store_constructor will handle the semantics for us.  */
3189e4b17023SJohn Marino 
3190e4b17023SJohn Marino       stmt_expr = build2 (INIT_EXPR, atype, base, init);
3191e4b17023SJohn Marino       return stmt_expr;
3192e4b17023SJohn Marino     }
3193e4b17023SJohn Marino 
3194e4b17023SJohn Marino   maxindex = cp_convert (ptrdiff_type_node, maxindex);
3195e4b17023SJohn Marino   if (TREE_CODE (atype) == ARRAY_TYPE)
3196e4b17023SJohn Marino     {
3197e4b17023SJohn Marino       ptype = build_pointer_type (type);
3198e4b17023SJohn Marino       base = cp_convert (ptype, decay_conversion (base));
3199e4b17023SJohn Marino     }
3200e4b17023SJohn Marino   else
3201e4b17023SJohn Marino     ptype = atype;
3202e4b17023SJohn Marino 
3203e4b17023SJohn Marino   /* The code we are generating looks like:
3204e4b17023SJohn Marino      ({
3205e4b17023SJohn Marino        T* t1 = (T*) base;
3206e4b17023SJohn Marino        T* rval = t1;
3207e4b17023SJohn Marino        ptrdiff_t iterator = maxindex;
3208e4b17023SJohn Marino        try {
3209e4b17023SJohn Marino 	 for (; iterator != -1; --iterator) {
3210e4b17023SJohn Marino 	   ... initialize *t1 ...
3211e4b17023SJohn Marino 	   ++t1;
3212e4b17023SJohn Marino 	 }
3213e4b17023SJohn Marino        } catch (...) {
3214e4b17023SJohn Marino 	 ... destroy elements that were constructed ...
3215e4b17023SJohn Marino        }
3216e4b17023SJohn Marino        rval;
3217e4b17023SJohn Marino      })
3218e4b17023SJohn Marino 
3219e4b17023SJohn Marino      We can omit the try and catch blocks if we know that the
3220e4b17023SJohn Marino      initialization will never throw an exception, or if the array
3221e4b17023SJohn Marino      elements do not have destructors.  We can omit the loop completely if
3222e4b17023SJohn Marino      the elements of the array do not have constructors.
3223e4b17023SJohn Marino 
3224e4b17023SJohn Marino      We actually wrap the entire body of the above in a STMT_EXPR, for
3225e4b17023SJohn Marino      tidiness.
3226e4b17023SJohn Marino 
3227e4b17023SJohn Marino      When copying from array to another, when the array elements have
3228e4b17023SJohn Marino      only trivial copy constructors, we should use __builtin_memcpy
3229e4b17023SJohn Marino      rather than generating a loop.  That way, we could take advantage
3230e4b17023SJohn Marino      of whatever cleverness the back end has for dealing with copies
3231e4b17023SJohn Marino      of blocks of memory.  */
3232e4b17023SJohn Marino 
3233e4b17023SJohn Marino   is_global = begin_init_stmts (&stmt_expr, &compound_stmt);
3234e4b17023SJohn Marino   destroy_temps = stmts_are_full_exprs_p ();
3235e4b17023SJohn Marino   current_stmt_tree ()->stmts_are_full_exprs_p = 0;
3236e4b17023SJohn Marino   rval = get_temp_regvar (ptype, base);
3237e4b17023SJohn Marino   base = get_temp_regvar (ptype, rval);
3238e4b17023SJohn Marino   iterator = get_temp_regvar (ptrdiff_type_node, maxindex);
3239e4b17023SJohn Marino 
3240e4b17023SJohn Marino   /* If initializing one array from another, initialize element by
3241e4b17023SJohn Marino      element.  We rely upon the below calls to do the argument
3242e4b17023SJohn Marino      checking.  Evaluate the initializer before entering the try block.  */
3243e4b17023SJohn Marino   if (from_array && init && TREE_CODE (init) != CONSTRUCTOR)
3244e4b17023SJohn Marino     {
3245e4b17023SJohn Marino       if (lvalue_kind (init) & clk_rvalueref)
3246e4b17023SJohn Marino 	xvalue = true;
3247e4b17023SJohn Marino       base2 = decay_conversion (init);
3248e4b17023SJohn Marino       itype = TREE_TYPE (base2);
3249e4b17023SJohn Marino       base2 = get_temp_regvar (itype, base2);
3250e4b17023SJohn Marino       itype = TREE_TYPE (itype);
3251e4b17023SJohn Marino     }
3252e4b17023SJohn Marino 
3253e4b17023SJohn Marino   /* Protect the entire array initialization so that we can destroy
3254e4b17023SJohn Marino      the partially constructed array if an exception is thrown.
3255e4b17023SJohn Marino      But don't do this if we're assigning.  */
3256e4b17023SJohn Marino   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
3257e4b17023SJohn Marino       && from_array != 2)
3258e4b17023SJohn Marino     {
3259e4b17023SJohn Marino       try_block = begin_try_block ();
3260e4b17023SJohn Marino     }
3261e4b17023SJohn Marino 
3262e4b17023SJohn Marino   /* If the initializer is {}, then all elements are initialized from {}.
3263e4b17023SJohn Marino      But for non-classes, that's the same as value-initialization.  */
3264e4b17023SJohn Marino   if (init && BRACE_ENCLOSED_INITIALIZER_P (init)
3265e4b17023SJohn Marino       && CONSTRUCTOR_NELTS (init) == 0)
3266e4b17023SJohn Marino     {
3267e4b17023SJohn Marino       if (CLASS_TYPE_P (type))
3268e4b17023SJohn Marino 	/* Leave init alone.  */;
3269e4b17023SJohn Marino       else
3270e4b17023SJohn Marino 	{
3271e4b17023SJohn Marino 	  init = NULL_TREE;
3272e4b17023SJohn Marino 	  explicit_value_init_p = true;
3273e4b17023SJohn Marino 	}
3274e4b17023SJohn Marino     }
3275e4b17023SJohn Marino 
3276e4b17023SJohn Marino   /* Maybe pull out constant value when from_array? */
3277e4b17023SJohn Marino 
3278e4b17023SJohn Marino   else if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR)
3279e4b17023SJohn Marino     {
3280e4b17023SJohn Marino       /* Do non-default initialization of non-trivial arrays resulting from
3281e4b17023SJohn Marino 	 brace-enclosed initializers.  */
3282e4b17023SJohn Marino       unsigned HOST_WIDE_INT idx;
3283e4b17023SJohn Marino       tree field, elt;
3284e4b17023SJohn Marino       /* Should we try to create a constant initializer?  */
3285e4b17023SJohn Marino       bool try_const = (TREE_CODE (atype) == ARRAY_TYPE
3286e4b17023SJohn Marino 			&& (literal_type_p (inner_elt_type)
3287e4b17023SJohn Marino 			    || TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)));
3288e4b17023SJohn Marino       /* If the constructor already has the array type, it's been through
3289e4b17023SJohn Marino 	 digest_init, so we shouldn't try to do anything more.  */
3290e4b17023SJohn Marino       bool digested = same_type_p (atype, TREE_TYPE (init));
3291e4b17023SJohn Marino       bool saw_non_const = false;
3292e4b17023SJohn Marino       bool saw_const = false;
3293e4b17023SJohn Marino       /* If we're initializing a static array, we want to do static
3294e4b17023SJohn Marino 	 initialization of any elements with constant initializers even if
3295e4b17023SJohn Marino 	 some are non-constant.  */
3296e4b17023SJohn Marino       bool do_static_init = (DECL_P (obase) && TREE_STATIC (obase));
3297e4b17023SJohn Marino       VEC(constructor_elt,gc) *new_vec;
3298e4b17023SJohn Marino       from_array = 0;
3299e4b17023SJohn Marino 
3300e4b17023SJohn Marino       if (try_const)
3301e4b17023SJohn Marino 	new_vec = VEC_alloc (constructor_elt, gc, CONSTRUCTOR_NELTS (init));
3302e4b17023SJohn Marino       else
3303e4b17023SJohn Marino 	new_vec = NULL;
3304e4b17023SJohn Marino 
3305e4b17023SJohn Marino       FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt)
3306e4b17023SJohn Marino 	{
3307e4b17023SJohn Marino 	  tree baseref = build1 (INDIRECT_REF, type, base);
3308e4b17023SJohn Marino 	  tree one_init;
3309e4b17023SJohn Marino 
3310e4b17023SJohn Marino 	  num_initialized_elts++;
3311e4b17023SJohn Marino 
3312e4b17023SJohn Marino 	  current_stmt_tree ()->stmts_are_full_exprs_p = 1;
3313e4b17023SJohn Marino 	  if (digested)
3314e4b17023SJohn Marino 	    one_init = build2 (INIT_EXPR, type, baseref, elt);
3315e4b17023SJohn Marino 	  else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
3316e4b17023SJohn Marino 	    one_init = build_aggr_init (baseref, elt, 0, complain);
3317e4b17023SJohn Marino 	  else
3318e4b17023SJohn Marino 	    one_init = cp_build_modify_expr (baseref, NOP_EXPR,
3319e4b17023SJohn Marino 					     elt, complain);
3320e4b17023SJohn Marino 	  if (one_init == error_mark_node)
3321e4b17023SJohn Marino 	    errors = true;
3322e4b17023SJohn Marino 	  if (try_const)
3323e4b17023SJohn Marino 	    {
3324e4b17023SJohn Marino 	      tree e = one_init;
3325e4b17023SJohn Marino 	      if (TREE_CODE (e) == EXPR_STMT)
3326e4b17023SJohn Marino 		e = TREE_OPERAND (e, 0);
3327e4b17023SJohn Marino 	      if (TREE_CODE (e) == CONVERT_EXPR
3328e4b17023SJohn Marino 		  && VOID_TYPE_P (TREE_TYPE (e)))
3329e4b17023SJohn Marino 		e = TREE_OPERAND (e, 0);
3330e4b17023SJohn Marino 	      e = maybe_constant_init (e);
3331e4b17023SJohn Marino 	      if (reduced_constant_expression_p (e))
3332e4b17023SJohn Marino 		{
3333e4b17023SJohn Marino 		  CONSTRUCTOR_APPEND_ELT (new_vec, field, e);
3334e4b17023SJohn Marino 		  if (do_static_init)
3335e4b17023SJohn Marino 		    one_init = NULL_TREE;
3336e4b17023SJohn Marino 		  else
3337e4b17023SJohn Marino 		    one_init = build2 (INIT_EXPR, type, baseref, e);
3338e4b17023SJohn Marino 		  saw_const = true;
3339e4b17023SJohn Marino 		}
3340e4b17023SJohn Marino 	      else
3341e4b17023SJohn Marino 		{
3342e4b17023SJohn Marino 		  if (do_static_init)
33435ce9237cSJohn Marino 		    {
33445ce9237cSJohn Marino 		      tree value = build_zero_init (TREE_TYPE (e), NULL_TREE,
33455ce9237cSJohn Marino 						    true);
33465ce9237cSJohn Marino 		      if (value)
33475ce9237cSJohn Marino 			CONSTRUCTOR_APPEND_ELT (new_vec, field, value);
33485ce9237cSJohn Marino 		    }
3349e4b17023SJohn Marino 		  saw_non_const = true;
3350e4b17023SJohn Marino 		}
3351e4b17023SJohn Marino 	    }
3352e4b17023SJohn Marino 
3353e4b17023SJohn Marino 	  if (one_init)
3354e4b17023SJohn Marino 	    finish_expr_stmt (one_init);
3355e4b17023SJohn Marino 	  current_stmt_tree ()->stmts_are_full_exprs_p = 0;
3356e4b17023SJohn Marino 
3357e4b17023SJohn Marino 	  one_init = cp_build_unary_op (PREINCREMENT_EXPR, base, 0, complain);
3358e4b17023SJohn Marino 	  if (one_init == error_mark_node)
3359e4b17023SJohn Marino 	    errors = true;
3360e4b17023SJohn Marino 	  else
3361e4b17023SJohn Marino 	    finish_expr_stmt (one_init);
3362e4b17023SJohn Marino 
3363e4b17023SJohn Marino 	  one_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
3364e4b17023SJohn Marino 					complain);
3365e4b17023SJohn Marino 	  if (one_init == error_mark_node)
3366e4b17023SJohn Marino 	    errors = true;
3367e4b17023SJohn Marino 	  else
3368e4b17023SJohn Marino 	    finish_expr_stmt (one_init);
3369e4b17023SJohn Marino 	}
3370e4b17023SJohn Marino 
3371e4b17023SJohn Marino       if (try_const)
3372e4b17023SJohn Marino 	{
3373e4b17023SJohn Marino 	  if (!saw_non_const)
3374e4b17023SJohn Marino 	    const_init = build_constructor (atype, new_vec);
3375e4b17023SJohn Marino 	  else if (do_static_init && saw_const)
3376e4b17023SJohn Marino 	    DECL_INITIAL (obase) = build_constructor (atype, new_vec);
3377e4b17023SJohn Marino 	  else
3378e4b17023SJohn Marino 	    VEC_free (constructor_elt, gc, new_vec);
3379e4b17023SJohn Marino 	}
3380e4b17023SJohn Marino 
3381e4b17023SJohn Marino       /* Clear out INIT so that we don't get confused below.  */
3382e4b17023SJohn Marino       init = NULL_TREE;
3383e4b17023SJohn Marino     }
3384e4b17023SJohn Marino   else if (from_array)
3385e4b17023SJohn Marino     {
3386e4b17023SJohn Marino       if (init)
3387e4b17023SJohn Marino 	/* OK, we set base2 above.  */;
3388e4b17023SJohn Marino       else if (CLASS_TYPE_P (type)
3389e4b17023SJohn Marino 	       && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type))
3390e4b17023SJohn Marino 	{
3391e4b17023SJohn Marino           if (complain & tf_error)
3392e4b17023SJohn Marino             error ("initializer ends prematurely");
3393e4b17023SJohn Marino 	  errors = true;
3394e4b17023SJohn Marino 	}
3395e4b17023SJohn Marino     }
3396e4b17023SJohn Marino 
3397e4b17023SJohn Marino   /* Now, default-initialize any remaining elements.  We don't need to
3398e4b17023SJohn Marino      do that if a) the type does not need constructing, or b) we've
3399e4b17023SJohn Marino      already initialized all the elements.
3400e4b17023SJohn Marino 
3401e4b17023SJohn Marino      We do need to keep going if we're copying an array.  */
3402e4b17023SJohn Marino 
3403e4b17023SJohn Marino   if (from_array
3404e4b17023SJohn Marino       || ((type_build_ctor_call (type) || init || explicit_value_init_p)
3405e4b17023SJohn Marino 	  && ! (host_integerp (maxindex, 0)
3406e4b17023SJohn Marino 		&& (num_initialized_elts
3407e4b17023SJohn Marino 		    == tree_low_cst (maxindex, 0) + 1))))
3408e4b17023SJohn Marino     {
3409e4b17023SJohn Marino       /* If the ITERATOR is equal to -1, then we don't have to loop;
3410e4b17023SJohn Marino 	 we've already initialized all the elements.  */
3411e4b17023SJohn Marino       tree for_stmt;
3412e4b17023SJohn Marino       tree elt_init;
3413e4b17023SJohn Marino       tree to;
3414e4b17023SJohn Marino 
3415e4b17023SJohn Marino       for_stmt = begin_for_stmt (NULL_TREE, NULL_TREE);
3416e4b17023SJohn Marino       finish_for_init_stmt (for_stmt);
3417e4b17023SJohn Marino       finish_for_cond (build2 (NE_EXPR, boolean_type_node, iterator,
3418e4b17023SJohn Marino 			       build_int_cst (TREE_TYPE (iterator), -1)),
3419e4b17023SJohn Marino 		       for_stmt);
3420e4b17023SJohn Marino       elt_init = cp_build_unary_op (PREDECREMENT_EXPR, iterator, 0,
3421e4b17023SJohn Marino 				    complain);
3422e4b17023SJohn Marino       if (elt_init == error_mark_node)
3423e4b17023SJohn Marino 	errors = true;
3424e4b17023SJohn Marino       finish_for_expr (elt_init, for_stmt);
3425e4b17023SJohn Marino 
3426e4b17023SJohn Marino       to = build1 (INDIRECT_REF, type, base);
3427e4b17023SJohn Marino 
3428e4b17023SJohn Marino       if (from_array)
3429e4b17023SJohn Marino 	{
3430e4b17023SJohn Marino 	  tree from;
3431e4b17023SJohn Marino 
3432e4b17023SJohn Marino 	  if (base2)
3433e4b17023SJohn Marino 	    {
3434e4b17023SJohn Marino 	      from = build1 (INDIRECT_REF, itype, base2);
3435e4b17023SJohn Marino 	      if (xvalue)
3436e4b17023SJohn Marino 		from = move (from);
3437e4b17023SJohn Marino 	    }
3438e4b17023SJohn Marino 	  else
3439e4b17023SJohn Marino 	    from = NULL_TREE;
3440e4b17023SJohn Marino 
3441e4b17023SJohn Marino 	  if (from_array == 2)
3442e4b17023SJohn Marino 	    elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
3443e4b17023SJohn Marino 					     complain);
3444e4b17023SJohn Marino 	  else if (type_build_ctor_call (type))
3445e4b17023SJohn Marino 	    elt_init = build_aggr_init (to, from, 0, complain);
3446e4b17023SJohn Marino 	  else if (from)
3447e4b17023SJohn Marino 	    elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
3448e4b17023SJohn Marino 					     complain);
3449e4b17023SJohn Marino 	  else
3450e4b17023SJohn Marino 	    gcc_unreachable ();
3451e4b17023SJohn Marino 	}
3452e4b17023SJohn Marino       else if (TREE_CODE (type) == ARRAY_TYPE)
3453e4b17023SJohn Marino 	{
3454e4b17023SJohn Marino 	  if (init != 0)
3455e4b17023SJohn Marino 	    sorry
3456e4b17023SJohn Marino 	      ("cannot initialize multi-dimensional array with initializer");
3457e4b17023SJohn Marino 	  elt_init = build_vec_init (build1 (INDIRECT_REF, type, base),
3458e4b17023SJohn Marino 				     0, 0,
3459e4b17023SJohn Marino 				     explicit_value_init_p,
3460e4b17023SJohn Marino 				     0, complain);
3461e4b17023SJohn Marino 	}
3462e4b17023SJohn Marino       else if (explicit_value_init_p)
3463e4b17023SJohn Marino 	{
3464e4b17023SJohn Marino 	  elt_init = build_value_init (type, complain);
3465e4b17023SJohn Marino 	  if (elt_init != error_mark_node)
3466e4b17023SJohn Marino 	    elt_init = build2 (INIT_EXPR, type, to, elt_init);
3467e4b17023SJohn Marino 	}
3468e4b17023SJohn Marino       else
3469e4b17023SJohn Marino 	{
3470e4b17023SJohn Marino 	  gcc_assert (type_build_ctor_call (type) || init);
3471e4b17023SJohn Marino 	  if (CLASS_TYPE_P (type))
3472e4b17023SJohn Marino 	    elt_init = build_aggr_init (to, init, 0, complain);
3473e4b17023SJohn Marino 	  else
3474e4b17023SJohn Marino 	    {
3475e4b17023SJohn Marino 	      if (TREE_CODE (init) == TREE_LIST)
3476e4b17023SJohn Marino 		init = build_x_compound_expr_from_list (init, ELK_INIT,
3477e4b17023SJohn Marino 							complain);
3478e4b17023SJohn Marino 	      elt_init = build2 (INIT_EXPR, type, to, init);
3479e4b17023SJohn Marino 	    }
3480e4b17023SJohn Marino 	}
3481e4b17023SJohn Marino 
3482e4b17023SJohn Marino       if (elt_init == error_mark_node)
3483e4b17023SJohn Marino 	errors = true;
3484e4b17023SJohn Marino 
3485e4b17023SJohn Marino       current_stmt_tree ()->stmts_are_full_exprs_p = 1;
3486e4b17023SJohn Marino       finish_expr_stmt (elt_init);
3487e4b17023SJohn Marino       current_stmt_tree ()->stmts_are_full_exprs_p = 0;
3488e4b17023SJohn Marino 
3489e4b17023SJohn Marino       finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0,
3490e4b17023SJohn Marino                                            complain));
3491e4b17023SJohn Marino       if (base2)
3492e4b17023SJohn Marino 	finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base2, 0,
3493e4b17023SJohn Marino                                              complain));
3494e4b17023SJohn Marino 
3495e4b17023SJohn Marino       finish_for_stmt (for_stmt);
3496e4b17023SJohn Marino     }
3497e4b17023SJohn Marino 
3498e4b17023SJohn Marino   /* Make sure to cleanup any partially constructed elements.  */
3499e4b17023SJohn Marino   if (flag_exceptions && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
3500e4b17023SJohn Marino       && from_array != 2)
3501e4b17023SJohn Marino     {
3502e4b17023SJohn Marino       tree e;
3503e4b17023SJohn Marino       tree m = cp_build_binary_op (input_location,
3504e4b17023SJohn Marino 				   MINUS_EXPR, maxindex, iterator,
3505e4b17023SJohn Marino 				   complain);
3506e4b17023SJohn Marino 
3507e4b17023SJohn Marino       /* Flatten multi-dimensional array since build_vec_delete only
3508e4b17023SJohn Marino 	 expects one-dimensional array.  */
3509e4b17023SJohn Marino       if (TREE_CODE (type) == ARRAY_TYPE)
3510e4b17023SJohn Marino 	m = cp_build_binary_op (input_location,
3511e4b17023SJohn Marino 				MULT_EXPR, m,
35125ce9237cSJohn Marino 				/* Force signed arithmetic.  */
35135ce9237cSJohn Marino 				convert (TREE_TYPE (m),
35145ce9237cSJohn Marino 					 array_type_nelts_total (type)),
3515e4b17023SJohn Marino 				complain);
3516e4b17023SJohn Marino 
3517e4b17023SJohn Marino       finish_cleanup_try_block (try_block);
3518e4b17023SJohn Marino       e = build_vec_delete_1 (rval, m,
3519e4b17023SJohn Marino 			      inner_elt_type, sfk_complete_destructor,
3520e4b17023SJohn Marino 			      /*use_global_delete=*/0, complain);
3521e4b17023SJohn Marino       if (e == error_mark_node)
3522e4b17023SJohn Marino 	errors = true;
3523e4b17023SJohn Marino       finish_cleanup (e, try_block);
3524e4b17023SJohn Marino     }
3525e4b17023SJohn Marino 
3526e4b17023SJohn Marino   /* The value of the array initialization is the array itself, RVAL
3527e4b17023SJohn Marino      is a pointer to the first element.  */
3528e4b17023SJohn Marino   finish_stmt_expr_expr (rval, stmt_expr);
3529e4b17023SJohn Marino 
3530e4b17023SJohn Marino   stmt_expr = finish_init_stmts (is_global, stmt_expr, compound_stmt);
3531e4b17023SJohn Marino 
3532e4b17023SJohn Marino   /* Now make the result have the correct type.  */
3533e4b17023SJohn Marino   if (TREE_CODE (atype) == ARRAY_TYPE)
3534e4b17023SJohn Marino     {
3535e4b17023SJohn Marino       atype = build_pointer_type (atype);
3536e4b17023SJohn Marino       stmt_expr = build1 (NOP_EXPR, atype, stmt_expr);
3537e4b17023SJohn Marino       stmt_expr = cp_build_indirect_ref (stmt_expr, RO_NULL, complain);
3538e4b17023SJohn Marino       TREE_NO_WARNING (stmt_expr) = 1;
3539e4b17023SJohn Marino     }
3540e4b17023SJohn Marino 
3541e4b17023SJohn Marino   current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps;
3542e4b17023SJohn Marino 
3543e4b17023SJohn Marino   if (const_init)
3544e4b17023SJohn Marino     return build2 (INIT_EXPR, atype, obase, const_init);
3545e4b17023SJohn Marino   if (errors)
3546e4b17023SJohn Marino     return error_mark_node;
3547e4b17023SJohn Marino   return stmt_expr;
3548e4b17023SJohn Marino }
3549e4b17023SJohn Marino 
3550e4b17023SJohn Marino /* Call the DTOR_KIND destructor for EXP.  FLAGS are as for
3551e4b17023SJohn Marino    build_delete.  */
3552e4b17023SJohn Marino 
3553e4b17023SJohn Marino static tree
build_dtor_call(tree exp,special_function_kind dtor_kind,int flags,tsubst_flags_t complain)3554e4b17023SJohn Marino build_dtor_call (tree exp, special_function_kind dtor_kind, int flags,
3555e4b17023SJohn Marino 		 tsubst_flags_t complain)
3556e4b17023SJohn Marino {
3557e4b17023SJohn Marino   tree name;
3558e4b17023SJohn Marino   tree fn;
3559e4b17023SJohn Marino   switch (dtor_kind)
3560e4b17023SJohn Marino     {
3561e4b17023SJohn Marino     case sfk_complete_destructor:
3562e4b17023SJohn Marino       name = complete_dtor_identifier;
3563e4b17023SJohn Marino       break;
3564e4b17023SJohn Marino 
3565e4b17023SJohn Marino     case sfk_base_destructor:
3566e4b17023SJohn Marino       name = base_dtor_identifier;
3567e4b17023SJohn Marino       break;
3568e4b17023SJohn Marino 
3569e4b17023SJohn Marino     case sfk_deleting_destructor:
3570e4b17023SJohn Marino       name = deleting_dtor_identifier;
3571e4b17023SJohn Marino       break;
3572e4b17023SJohn Marino 
3573e4b17023SJohn Marino     default:
3574e4b17023SJohn Marino       gcc_unreachable ();
3575e4b17023SJohn Marino     }
3576e4b17023SJohn Marino   fn = lookup_fnfields (TREE_TYPE (exp), name, /*protect=*/2);
3577e4b17023SJohn Marino   return build_new_method_call (exp, fn,
3578e4b17023SJohn Marino 				/*args=*/NULL,
3579e4b17023SJohn Marino 				/*conversion_path=*/NULL_TREE,
3580e4b17023SJohn Marino 				flags,
3581e4b17023SJohn Marino 				/*fn_p=*/NULL,
3582e4b17023SJohn Marino 				complain);
3583e4b17023SJohn Marino }
3584e4b17023SJohn Marino 
3585e4b17023SJohn Marino /* Generate a call to a destructor. TYPE is the type to cast ADDR to.
3586e4b17023SJohn Marino    ADDR is an expression which yields the store to be destroyed.
3587e4b17023SJohn Marino    AUTO_DELETE is the name of the destructor to call, i.e., either
3588e4b17023SJohn Marino    sfk_complete_destructor, sfk_base_destructor, or
3589e4b17023SJohn Marino    sfk_deleting_destructor.
3590e4b17023SJohn Marino 
3591e4b17023SJohn Marino    FLAGS is the logical disjunction of zero or more LOOKUP_
3592e4b17023SJohn Marino    flags.  See cp-tree.h for more info.  */
3593e4b17023SJohn Marino 
3594e4b17023SJohn Marino tree
build_delete(tree type,tree addr,special_function_kind auto_delete,int flags,int use_global_delete,tsubst_flags_t complain)3595e4b17023SJohn Marino build_delete (tree type, tree addr, special_function_kind auto_delete,
3596e4b17023SJohn Marino 	      int flags, int use_global_delete, tsubst_flags_t complain)
3597e4b17023SJohn Marino {
3598e4b17023SJohn Marino   tree expr;
3599e4b17023SJohn Marino 
3600e4b17023SJohn Marino   if (addr == error_mark_node)
3601e4b17023SJohn Marino     return error_mark_node;
3602e4b17023SJohn Marino 
3603e4b17023SJohn Marino   /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type
3604e4b17023SJohn Marino      set to `error_mark_node' before it gets properly cleaned up.  */
3605e4b17023SJohn Marino   if (type == error_mark_node)
3606e4b17023SJohn Marino     return error_mark_node;
3607e4b17023SJohn Marino 
3608e4b17023SJohn Marino   type = TYPE_MAIN_VARIANT (type);
3609e4b17023SJohn Marino 
3610e4b17023SJohn Marino   addr = mark_rvalue_use (addr);
3611e4b17023SJohn Marino 
3612e4b17023SJohn Marino   if (TREE_CODE (type) == POINTER_TYPE)
3613e4b17023SJohn Marino     {
3614e4b17023SJohn Marino       bool complete_p = true;
3615e4b17023SJohn Marino 
3616e4b17023SJohn Marino       type = TYPE_MAIN_VARIANT (TREE_TYPE (type));
3617e4b17023SJohn Marino       if (TREE_CODE (type) == ARRAY_TYPE)
3618e4b17023SJohn Marino 	goto handle_array;
3619e4b17023SJohn Marino 
3620e4b17023SJohn Marino       /* We don't want to warn about delete of void*, only other
3621e4b17023SJohn Marino 	  incomplete types.  Deleting other incomplete types
3622e4b17023SJohn Marino 	  invokes undefined behavior, but it is not ill-formed, so
3623e4b17023SJohn Marino 	  compile to something that would even do The Right Thing
3624e4b17023SJohn Marino 	  (TM) should the type have a trivial dtor and no delete
3625e4b17023SJohn Marino 	  operator.  */
3626e4b17023SJohn Marino       if (!VOID_TYPE_P (type))
3627e4b17023SJohn Marino 	{
3628e4b17023SJohn Marino 	  complete_type (type);
3629e4b17023SJohn Marino 	  if (!COMPLETE_TYPE_P (type))
3630e4b17023SJohn Marino 	    {
3631e4b17023SJohn Marino 	      if ((complain & tf_warning)
3632e4b17023SJohn Marino 		  && warning (0, "possible problem detected in invocation of "
3633e4b17023SJohn Marino 			      "delete operator:"))
3634e4b17023SJohn Marino 		{
3635e4b17023SJohn Marino 		  cxx_incomplete_type_diagnostic (addr, type, DK_WARNING);
3636e4b17023SJohn Marino 		  inform (input_location, "neither the destructor nor the class-specific "
3637e4b17023SJohn Marino 			  "operator delete will be called, even if they are "
3638e4b17023SJohn Marino 			  "declared when the class is defined");
3639e4b17023SJohn Marino 		}
3640e4b17023SJohn Marino 	      complete_p = false;
3641e4b17023SJohn Marino 	    }
3642e4b17023SJohn Marino 	  else if (auto_delete == sfk_deleting_destructor && warn_delnonvdtor
3643e4b17023SJohn Marino 	           && MAYBE_CLASS_TYPE_P (type) && !CLASSTYPE_FINAL (type)
3644e4b17023SJohn Marino 		   && TYPE_POLYMORPHIC_P (type))
3645e4b17023SJohn Marino 	    {
3646e4b17023SJohn Marino 	      tree dtor;
3647e4b17023SJohn Marino 	      dtor = CLASSTYPE_DESTRUCTORS (type);
3648e4b17023SJohn Marino 	      if (!dtor || !DECL_VINDEX (dtor))
3649e4b17023SJohn Marino 		{
3650e4b17023SJohn Marino 		  if (CLASSTYPE_PURE_VIRTUALS (type))
3651e4b17023SJohn Marino 		    warning (OPT_Wdelete_non_virtual_dtor,
3652e4b17023SJohn Marino 			     "deleting object of abstract class type %qT"
3653e4b17023SJohn Marino 			     " which has non-virtual destructor"
3654e4b17023SJohn Marino 			     " will cause undefined behaviour", type);
3655e4b17023SJohn Marino 		  else
3656e4b17023SJohn Marino 		    warning (OPT_Wdelete_non_virtual_dtor,
3657e4b17023SJohn Marino 			     "deleting object of polymorphic class type %qT"
3658e4b17023SJohn Marino 			     " which has non-virtual destructor"
3659e4b17023SJohn Marino 			     " might cause undefined behaviour", type);
3660e4b17023SJohn Marino 		}
3661e4b17023SJohn Marino 	    }
3662e4b17023SJohn Marino 	}
3663e4b17023SJohn Marino       if (VOID_TYPE_P (type) || !complete_p || !MAYBE_CLASS_TYPE_P (type))
3664e4b17023SJohn Marino 	/* Call the builtin operator delete.  */
3665e4b17023SJohn Marino 	return build_builtin_delete_call (addr);
3666e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (addr))
3667e4b17023SJohn Marino 	addr = save_expr (addr);
3668e4b17023SJohn Marino 
3669e4b17023SJohn Marino       /* Throw away const and volatile on target type of addr.  */
3670e4b17023SJohn Marino       addr = convert_force (build_pointer_type (type), addr, 0);
3671e4b17023SJohn Marino     }
3672e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE)
3673e4b17023SJohn Marino     {
3674e4b17023SJohn Marino     handle_array:
3675e4b17023SJohn Marino 
3676e4b17023SJohn Marino       if (TYPE_DOMAIN (type) == NULL_TREE)
3677e4b17023SJohn Marino 	{
3678e4b17023SJohn Marino 	  if (complain & tf_error)
3679e4b17023SJohn Marino 	    error ("unknown array size in delete");
3680e4b17023SJohn Marino 	  return error_mark_node;
3681e4b17023SJohn Marino 	}
3682e4b17023SJohn Marino       return build_vec_delete (addr, array_type_nelts (type),
3683e4b17023SJohn Marino 			       auto_delete, use_global_delete, complain);
3684e4b17023SJohn Marino     }
3685e4b17023SJohn Marino   else
3686e4b17023SJohn Marino     {
3687e4b17023SJohn Marino       /* Don't check PROTECT here; leave that decision to the
3688e4b17023SJohn Marino 	 destructor.  If the destructor is accessible, call it,
3689e4b17023SJohn Marino 	 else report error.  */
3690e4b17023SJohn Marino       addr = cp_build_addr_expr (addr, complain);
3691e4b17023SJohn Marino       if (addr == error_mark_node)
3692e4b17023SJohn Marino 	return error_mark_node;
3693e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (addr))
3694e4b17023SJohn Marino 	addr = save_expr (addr);
3695e4b17023SJohn Marino 
3696e4b17023SJohn Marino       addr = convert_force (build_pointer_type (type), addr, 0);
3697e4b17023SJohn Marino     }
3698e4b17023SJohn Marino 
3699e4b17023SJohn Marino   gcc_assert (MAYBE_CLASS_TYPE_P (type));
3700e4b17023SJohn Marino 
3701e4b17023SJohn Marino   if (TYPE_HAS_TRIVIAL_DESTRUCTOR (type))
3702e4b17023SJohn Marino     {
3703e4b17023SJohn Marino       if (auto_delete != sfk_deleting_destructor)
3704e4b17023SJohn Marino 	return void_zero_node;
3705e4b17023SJohn Marino 
3706e4b17023SJohn Marino       return build_op_delete_call (DELETE_EXPR, addr,
3707e4b17023SJohn Marino 				   cxx_sizeof_nowarn (type),
3708e4b17023SJohn Marino 				   use_global_delete,
3709e4b17023SJohn Marino 				   /*placement=*/NULL_TREE,
3710e4b17023SJohn Marino 				   /*alloc_fn=*/NULL_TREE);
3711e4b17023SJohn Marino     }
3712e4b17023SJohn Marino   else
3713e4b17023SJohn Marino     {
3714e4b17023SJohn Marino       tree head = NULL_TREE;
3715e4b17023SJohn Marino       tree do_delete = NULL_TREE;
3716e4b17023SJohn Marino       tree ifexp;
3717e4b17023SJohn Marino 
3718e4b17023SJohn Marino       if (CLASSTYPE_LAZY_DESTRUCTOR (type))
3719e4b17023SJohn Marino 	lazily_declare_fn (sfk_destructor, type);
3720e4b17023SJohn Marino 
3721e4b17023SJohn Marino       /* For `::delete x', we must not use the deleting destructor
3722e4b17023SJohn Marino 	 since then we would not be sure to get the global `operator
3723e4b17023SJohn Marino 	 delete'.  */
3724e4b17023SJohn Marino       if (use_global_delete && auto_delete == sfk_deleting_destructor)
3725e4b17023SJohn Marino 	{
3726e4b17023SJohn Marino 	  /* We will use ADDR multiple times so we must save it.  */
3727e4b17023SJohn Marino 	  addr = save_expr (addr);
3728e4b17023SJohn Marino 	  head = get_target_expr (build_headof (addr));
3729e4b17023SJohn Marino 	  /* Delete the object.  */
3730e4b17023SJohn Marino 	  do_delete = build_builtin_delete_call (head);
3731e4b17023SJohn Marino 	  /* Otherwise, treat this like a complete object destructor
3732e4b17023SJohn Marino 	     call.  */
3733e4b17023SJohn Marino 	  auto_delete = sfk_complete_destructor;
3734e4b17023SJohn Marino 	}
3735e4b17023SJohn Marino       /* If the destructor is non-virtual, there is no deleting
3736e4b17023SJohn Marino 	 variant.  Instead, we must explicitly call the appropriate
3737e4b17023SJohn Marino 	 `operator delete' here.  */
3738e4b17023SJohn Marino       else if (!DECL_VIRTUAL_P (CLASSTYPE_DESTRUCTORS (type))
3739e4b17023SJohn Marino 	       && auto_delete == sfk_deleting_destructor)
3740e4b17023SJohn Marino 	{
3741e4b17023SJohn Marino 	  /* We will use ADDR multiple times so we must save it.  */
3742e4b17023SJohn Marino 	  addr = save_expr (addr);
3743e4b17023SJohn Marino 	  /* Build the call.  */
3744e4b17023SJohn Marino 	  do_delete = build_op_delete_call (DELETE_EXPR,
3745e4b17023SJohn Marino 					    addr,
3746e4b17023SJohn Marino 					    cxx_sizeof_nowarn (type),
3747e4b17023SJohn Marino 					    /*global_p=*/false,
3748e4b17023SJohn Marino 					    /*placement=*/NULL_TREE,
3749e4b17023SJohn Marino 					    /*alloc_fn=*/NULL_TREE);
3750e4b17023SJohn Marino 	  /* Call the complete object destructor.  */
3751e4b17023SJohn Marino 	  auto_delete = sfk_complete_destructor;
3752e4b17023SJohn Marino 	}
3753e4b17023SJohn Marino       else if (auto_delete == sfk_deleting_destructor
3754e4b17023SJohn Marino 	       && TYPE_GETS_REG_DELETE (type))
3755e4b17023SJohn Marino 	{
3756e4b17023SJohn Marino 	  /* Make sure we have access to the member op delete, even though
3757e4b17023SJohn Marino 	     we'll actually be calling it from the destructor.  */
3758e4b17023SJohn Marino 	  build_op_delete_call (DELETE_EXPR, addr, cxx_sizeof_nowarn (type),
3759e4b17023SJohn Marino 				/*global_p=*/false,
3760e4b17023SJohn Marino 				/*placement=*/NULL_TREE,
3761e4b17023SJohn Marino 				/*alloc_fn=*/NULL_TREE);
3762e4b17023SJohn Marino 	}
3763e4b17023SJohn Marino 
3764e4b17023SJohn Marino       expr = build_dtor_call (cp_build_indirect_ref (addr, RO_NULL, complain),
3765e4b17023SJohn Marino 			      auto_delete, flags, complain);
3766e4b17023SJohn Marino       if (expr == error_mark_node)
3767e4b17023SJohn Marino 	return error_mark_node;
3768e4b17023SJohn Marino       if (do_delete)
3769e4b17023SJohn Marino 	expr = build2 (COMPOUND_EXPR, void_type_node, expr, do_delete);
3770e4b17023SJohn Marino 
3771e4b17023SJohn Marino       /* We need to calculate this before the dtor changes the vptr.  */
3772e4b17023SJohn Marino       if (head)
3773e4b17023SJohn Marino 	expr = build2 (COMPOUND_EXPR, void_type_node, head, expr);
3774e4b17023SJohn Marino 
3775e4b17023SJohn Marino       if (flags & LOOKUP_DESTRUCTOR)
3776e4b17023SJohn Marino 	/* Explicit destructor call; don't check for null pointer.  */
3777e4b17023SJohn Marino 	ifexp = integer_one_node;
3778e4b17023SJohn Marino       else
3779e4b17023SJohn Marino 	{
3780e4b17023SJohn Marino 	  /* Handle deleting a null pointer.  */
3781e4b17023SJohn Marino 	  ifexp = fold (cp_build_binary_op (input_location,
3782e4b17023SJohn Marino 					    NE_EXPR, addr, nullptr_node,
3783e4b17023SJohn Marino 					    complain));
3784e4b17023SJohn Marino 	  if (ifexp == error_mark_node)
3785e4b17023SJohn Marino 	    return error_mark_node;
3786e4b17023SJohn Marino 	}
3787e4b17023SJohn Marino 
3788e4b17023SJohn Marino       if (ifexp != integer_one_node)
3789e4b17023SJohn Marino 	expr = build3 (COND_EXPR, void_type_node,
3790e4b17023SJohn Marino 		       ifexp, expr, void_zero_node);
3791e4b17023SJohn Marino 
3792e4b17023SJohn Marino       return expr;
3793e4b17023SJohn Marino     }
3794e4b17023SJohn Marino }
3795e4b17023SJohn Marino 
3796e4b17023SJohn Marino /* At the beginning of a destructor, push cleanups that will call the
3797e4b17023SJohn Marino    destructors for our base classes and members.
3798e4b17023SJohn Marino 
3799e4b17023SJohn Marino    Called from begin_destructor_body.  */
3800e4b17023SJohn Marino 
3801e4b17023SJohn Marino void
push_base_cleanups(void)3802e4b17023SJohn Marino push_base_cleanups (void)
3803e4b17023SJohn Marino {
3804e4b17023SJohn Marino   tree binfo, base_binfo;
3805e4b17023SJohn Marino   int i;
3806e4b17023SJohn Marino   tree member;
3807e4b17023SJohn Marino   tree expr;
3808e4b17023SJohn Marino   VEC(tree,gc) *vbases;
3809e4b17023SJohn Marino 
3810e4b17023SJohn Marino   /* Run destructors for all virtual baseclasses.  */
3811e4b17023SJohn Marino   if (CLASSTYPE_VBASECLASSES (current_class_type))
3812e4b17023SJohn Marino     {
3813e4b17023SJohn Marino       tree cond = (condition_conversion
3814e4b17023SJohn Marino 		   (build2 (BIT_AND_EXPR, integer_type_node,
3815e4b17023SJohn Marino 			    current_in_charge_parm,
3816e4b17023SJohn Marino 			    integer_two_node)));
3817e4b17023SJohn Marino 
3818e4b17023SJohn Marino       /* The CLASSTYPE_VBASECLASSES vector is in initialization
3819e4b17023SJohn Marino 	 order, which is also the right order for pushing cleanups.  */
3820e4b17023SJohn Marino       for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0;
3821e4b17023SJohn Marino 	   VEC_iterate (tree, vbases, i, base_binfo); i++)
3822e4b17023SJohn Marino 	{
3823e4b17023SJohn Marino 	  if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo)))
3824e4b17023SJohn Marino 	    {
3825e4b17023SJohn Marino 	      expr = build_special_member_call (current_class_ref,
3826e4b17023SJohn Marino 						base_dtor_identifier,
3827e4b17023SJohn Marino 						NULL,
3828e4b17023SJohn Marino 						base_binfo,
3829e4b17023SJohn Marino 						(LOOKUP_NORMAL
3830e4b17023SJohn Marino 						 | LOOKUP_NONVIRTUAL),
3831e4b17023SJohn Marino                                                 tf_warning_or_error);
3832e4b17023SJohn Marino 	      expr = build3 (COND_EXPR, void_type_node, cond,
3833e4b17023SJohn Marino 			     expr, void_zero_node);
3834e4b17023SJohn Marino 	      finish_decl_cleanup (NULL_TREE, expr);
3835e4b17023SJohn Marino 	    }
3836e4b17023SJohn Marino 	}
3837e4b17023SJohn Marino     }
3838e4b17023SJohn Marino 
3839e4b17023SJohn Marino   /* Take care of the remaining baseclasses.  */
3840e4b17023SJohn Marino   for (binfo = TYPE_BINFO (current_class_type), i = 0;
3841e4b17023SJohn Marino        BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
3842e4b17023SJohn Marino     {
3843e4b17023SJohn Marino       if (TYPE_HAS_TRIVIAL_DESTRUCTOR (BINFO_TYPE (base_binfo))
3844e4b17023SJohn Marino 	  || BINFO_VIRTUAL_P (base_binfo))
3845e4b17023SJohn Marino 	continue;
3846e4b17023SJohn Marino 
3847e4b17023SJohn Marino       expr = build_special_member_call (current_class_ref,
3848e4b17023SJohn Marino 					base_dtor_identifier,
3849e4b17023SJohn Marino 					NULL, base_binfo,
3850e4b17023SJohn Marino 					LOOKUP_NORMAL | LOOKUP_NONVIRTUAL,
3851e4b17023SJohn Marino                                         tf_warning_or_error);
3852e4b17023SJohn Marino       finish_decl_cleanup (NULL_TREE, expr);
3853e4b17023SJohn Marino     }
3854e4b17023SJohn Marino 
3855e4b17023SJohn Marino   /* Don't automatically destroy union members.  */
3856e4b17023SJohn Marino   if (TREE_CODE (current_class_type) == UNION_TYPE)
3857e4b17023SJohn Marino     return;
3858e4b17023SJohn Marino 
3859e4b17023SJohn Marino   for (member = TYPE_FIELDS (current_class_type); member;
3860e4b17023SJohn Marino        member = DECL_CHAIN (member))
3861e4b17023SJohn Marino     {
3862e4b17023SJohn Marino       tree this_type = TREE_TYPE (member);
3863e4b17023SJohn Marino       if (this_type == error_mark_node
3864e4b17023SJohn Marino 	  || TREE_CODE (member) != FIELD_DECL
3865e4b17023SJohn Marino 	  || DECL_ARTIFICIAL (member))
3866e4b17023SJohn Marino 	continue;
3867e4b17023SJohn Marino       if (ANON_UNION_TYPE_P (this_type))
3868e4b17023SJohn Marino 	continue;
3869e4b17023SJohn Marino       if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (this_type))
3870e4b17023SJohn Marino 	{
3871e4b17023SJohn Marino 	  tree this_member = (build_class_member_access_expr
3872e4b17023SJohn Marino 			      (current_class_ref, member,
3873e4b17023SJohn Marino 			       /*access_path=*/NULL_TREE,
3874e4b17023SJohn Marino 			       /*preserve_reference=*/false,
3875e4b17023SJohn Marino 			       tf_warning_or_error));
3876e4b17023SJohn Marino 	  expr = build_delete (this_type, this_member,
3877e4b17023SJohn Marino 			       sfk_complete_destructor,
3878e4b17023SJohn Marino 			       LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL,
3879e4b17023SJohn Marino 			       0, tf_warning_or_error);
3880e4b17023SJohn Marino 	  finish_decl_cleanup (NULL_TREE, expr);
3881e4b17023SJohn Marino 	}
3882e4b17023SJohn Marino     }
3883e4b17023SJohn Marino }
3884e4b17023SJohn Marino 
3885e4b17023SJohn Marino /* Build a C++ vector delete expression.
3886e4b17023SJohn Marino    MAXINDEX is the number of elements to be deleted.
3887e4b17023SJohn Marino    ELT_SIZE is the nominal size of each element in the vector.
3888e4b17023SJohn Marino    BASE is the expression that should yield the store to be deleted.
3889e4b17023SJohn Marino    This function expands (or synthesizes) these calls itself.
3890e4b17023SJohn Marino    AUTO_DELETE_VEC says whether the container (vector) should be deallocated.
3891e4b17023SJohn Marino 
3892e4b17023SJohn Marino    This also calls delete for virtual baseclasses of elements of the vector.
3893e4b17023SJohn Marino 
3894e4b17023SJohn Marino    Update: MAXINDEX is no longer needed.  The size can be extracted from the
3895e4b17023SJohn Marino    start of the vector for pointers, and from the type for arrays.  We still
3896e4b17023SJohn Marino    use MAXINDEX for arrays because it happens to already have one of the
3897e4b17023SJohn Marino    values we'd have to extract.  (We could use MAXINDEX with pointers to
3898e4b17023SJohn Marino    confirm the size, and trap if the numbers differ; not clear that it'd
3899e4b17023SJohn Marino    be worth bothering.)  */
3900e4b17023SJohn Marino 
3901e4b17023SJohn Marino tree
build_vec_delete(tree base,tree maxindex,special_function_kind auto_delete_vec,int use_global_delete,tsubst_flags_t complain)3902e4b17023SJohn Marino build_vec_delete (tree base, tree maxindex,
3903e4b17023SJohn Marino 		  special_function_kind auto_delete_vec,
3904e4b17023SJohn Marino 		  int use_global_delete, tsubst_flags_t complain)
3905e4b17023SJohn Marino {
3906e4b17023SJohn Marino   tree type;
3907e4b17023SJohn Marino   tree rval;
3908e4b17023SJohn Marino   tree base_init = NULL_TREE;
3909e4b17023SJohn Marino 
3910e4b17023SJohn Marino   type = TREE_TYPE (base);
3911e4b17023SJohn Marino 
3912e4b17023SJohn Marino   if (TREE_CODE (type) == POINTER_TYPE)
3913e4b17023SJohn Marino     {
3914e4b17023SJohn Marino       /* Step back one from start of vector, and read dimension.  */
3915e4b17023SJohn Marino       tree cookie_addr;
3916e4b17023SJohn Marino       tree size_ptr_type = build_pointer_type (sizetype);
3917e4b17023SJohn Marino 
3918*95d28233SJohn Marino       base = mark_rvalue_use (base);
3919e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (base))
3920e4b17023SJohn Marino 	{
3921e4b17023SJohn Marino 	  base_init = get_target_expr (base);
3922e4b17023SJohn Marino 	  base = TARGET_EXPR_SLOT (base_init);
3923e4b17023SJohn Marino 	}
3924e4b17023SJohn Marino       type = strip_array_types (TREE_TYPE (type));
3925e4b17023SJohn Marino       cookie_addr = fold_build1_loc (input_location, NEGATE_EXPR,
3926e4b17023SJohn Marino 				 sizetype, TYPE_SIZE_UNIT (sizetype));
3927e4b17023SJohn Marino       cookie_addr = fold_build_pointer_plus (fold_convert (size_ptr_type, base),
3928e4b17023SJohn Marino 					     cookie_addr);
3929e4b17023SJohn Marino       maxindex = cp_build_indirect_ref (cookie_addr, RO_NULL, complain);
3930e4b17023SJohn Marino     }
3931e4b17023SJohn Marino   else if (TREE_CODE (type) == ARRAY_TYPE)
3932e4b17023SJohn Marino     {
3933e4b17023SJohn Marino       /* Get the total number of things in the array, maxindex is a
3934e4b17023SJohn Marino 	 bad name.  */
3935e4b17023SJohn Marino       maxindex = array_type_nelts_total (type);
3936e4b17023SJohn Marino       type = strip_array_types (type);
3937e4b17023SJohn Marino       base = cp_build_addr_expr (base, complain);
3938e4b17023SJohn Marino       if (base == error_mark_node)
3939e4b17023SJohn Marino 	return error_mark_node;
3940e4b17023SJohn Marino       if (TREE_SIDE_EFFECTS (base))
3941e4b17023SJohn Marino 	{
3942e4b17023SJohn Marino 	  base_init = get_target_expr (base);
3943e4b17023SJohn Marino 	  base = TARGET_EXPR_SLOT (base_init);
3944e4b17023SJohn Marino 	}
3945e4b17023SJohn Marino     }
3946e4b17023SJohn Marino   else
3947e4b17023SJohn Marino     {
3948e4b17023SJohn Marino       if (base != error_mark_node && !(complain & tf_error))
3949e4b17023SJohn Marino 	error ("type to vector delete is neither pointer or array type");
3950e4b17023SJohn Marino       return error_mark_node;
3951e4b17023SJohn Marino     }
3952e4b17023SJohn Marino 
3953e4b17023SJohn Marino   rval = build_vec_delete_1 (base, maxindex, type, auto_delete_vec,
3954e4b17023SJohn Marino 			     use_global_delete, complain);
3955e4b17023SJohn Marino   if (base_init && rval != error_mark_node)
3956e4b17023SJohn Marino     rval = build2 (COMPOUND_EXPR, TREE_TYPE (rval), base_init, rval);
3957e4b17023SJohn Marino 
3958e4b17023SJohn Marino   return rval;
3959e4b17023SJohn Marino }
3960