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