diff options
author | Jason Merrill <jason@gcc.gnu.org> | 2010-11-01 21:31:18 -0400 |
---|---|---|
committer | Jason Merrill <jason@gcc.gnu.org> | 2010-11-01 21:31:18 -0400 |
commit | fa2200cbb1ef5a6a7bdb9a5ba708c7400eb6b404 (patch) | |
tree | 6c2db2fc090bec484b5ef60fbe416d72e1c7b6a4 /gcc/cp/init.c | |
parent | c41095db2f17d8e8695bfab2a582b8f99639633f (diff) | |
download | gcc-fa2200cbb1ef5a6a7bdb9a5ba708c7400eb6b404.zip gcc-fa2200cbb1ef5a6a7bdb9a5ba708c7400eb6b404.tar.gz gcc-fa2200cbb1ef5a6a7bdb9a5ba708c7400eb6b404.tar.bz2 |
call.c (null_ptr_cst_p): Use maybe_constant_value.
* call.c (null_ptr_cst_p): Use maybe_constant_value.
(set_up_extended_ref_temp): Support constant initialization.
(initialize_reference): Adjust.
* class.c (check_bitfield_decl): Use cxx_constant_value.
* cvt.c (ocp_convert): Don't use integral_constant_value when
converting to class type.
* decl.c (finish_case_label): Use maybe_constant_value.
(build_init_list_var_init): Support constant initialization.
(check_initializer): Likewise. Reorganize.
(cp_finish_decl): Likewise.
(expand_static_init): Likewise.
(compute_array_index_type): Use maybe_constant_value.
Add complain parm.
(create_array_type_for_decl, grokdeclarator): Pass it.
(build_enumerator): Use cxx_constant_value.
* decl2.c (grokfield): Use maybe_constant_init.
* except.c (check_noexcept_r): Handle constexpr.
(build_noexcept_spec): Use maybe_constant_value.
* init.c (expand_default_init): Support constant initialization.
(build_vec_init): Likewise.
(constant_value_1): Adjust.
(build_new_1): Adjust.
* parser.c (cp_parser_constant_expression): Allow non-integral
in C++0x mode.
(cp_parser_direct_declarator): Don't fold yet in C++0x mode.
(cp_parser_initializer_clause): Toss folded result if non-constant.
* pt.c (fold_decl_constant_value): Remove.
(convert_nontype_argument): Use maybe_constant_value. Give clearer
error about overflow.
(tsubst): Move array bounds handling into compute_array_index_type.
(value_dependent_expression_p): Handle constant CALL_EXPR.
* semantics.c (finish_static_assert): Use maybe_constant_value.
(ensure_literal_type_for_constexpr_object): Make sure type is complete.
(potential_constant_expression): Use maybe_constant_value.
* tree.c (cast_valid_in_integral_constant_expression_p): Any cast
is potentially valid in C++0x.
* typeck2.c (store_init_value): Handle constant init.
(check_narrowing): Use maybe_constant_value.
(build_functional_cast): Set TREE_CONSTANT on literal T().
* cp-tree.h (DECL_INTEGRAL_CONSTANT_VAR_P): Remove.
(LOOKUP_ALREADY_DIGESTED): New.
(compute_array_index_type): Adjust prototype.
From-SVN: r166167
Diffstat (limited to 'gcc/cp/init.c')
-rw-r--r-- | gcc/cp/init.c | 127 |
1 files changed, 93 insertions, 34 deletions
diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 3a6e2e7..d632816 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -1440,8 +1440,20 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags, if (parms != NULL) release_tree_vector (parms); + if (exp == true_exp && TREE_CODE (rval) == CALL_EXPR) + { + tree fn = get_callee_fndecl (rval); + if (DECL_DECLARED_CONSTEXPR_P (fn)) + { + tree e = maybe_constant_value (rval); + if (TREE_CONSTANT (e)) + rval = build2 (INIT_EXPR, type, exp, e); + } + } + + /* FIXME put back convert_to_void? */ if (TREE_SIDE_EFFECTS (rval)) - finish_expr_stmt (convert_to_void (rval, ICV_CAST, complain)); + finish_expr_stmt (rval); } /* This function is responsible for initializing EXP with INIT @@ -1708,36 +1720,18 @@ constant_value_1 (tree decl, bool integral_p) { while (TREE_CODE (decl) == CONST_DECL || (integral_p - ? DECL_INTEGRAL_CONSTANT_VAR_P (decl) + ? decl_constant_var_p (decl) : (TREE_CODE (decl) == VAR_DECL && CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (decl))))) { tree init; - /* Static data members in template classes may have - non-dependent initializers. References to such non-static - data members are not value-dependent, so we must retrieve the - initializer here. The DECL_INITIAL will have the right type, - but will not have been folded because that would prevent us - from performing all appropriate semantic checks at - instantiation time. */ - if (DECL_CLASS_SCOPE_P (decl) - && CLASSTYPE_TEMPLATE_INFO (DECL_CONTEXT (decl)) - && uses_template_parms (CLASSTYPE_TI_ARGS - (DECL_CONTEXT (decl)))) - { - ++processing_template_decl; - init = fold_non_dependent_expr (DECL_INITIAL (decl)); - --processing_template_decl; - } - else - { - /* If DECL is a static data member in a template - specialization, we must instantiate it here. The - initializer for the static data member is not processed - until needed; we need it now. */ - mark_used (decl); - init = DECL_INITIAL (decl); - } + /* If DECL is a static data member in a template + specialization, we must instantiate it here. The + initializer for the static data member is not processed + until needed; we need it now. */ + mark_used (decl); + mark_rvalue_use (decl); + init = DECL_INITIAL (decl); if (init == error_mark_node) { if (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl)) @@ -1758,8 +1752,9 @@ constant_value_1 (tree decl, bool integral_p) init = TREE_VALUE (init); if (!init || !TREE_TYPE (init) + || uses_template_parms (init) || (integral_p - ? !INTEGRAL_OR_ENUMERATION_TYPE_P (TREE_TYPE (init)) + ? false : (!TREE_CONSTANT (init) /* Do not return an aggregate constant (of which string literals are a special case), as we do not @@ -2302,7 +2297,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, tree arraytype, domain; vecinit = VEC_index (tree, *init, 0); if (TREE_CONSTANT (nelts)) - domain = compute_array_index_type (NULL_TREE, nelts); + domain = compute_array_index_type (NULL_TREE, nelts, complain); else { domain = NULL_TREE; @@ -2878,6 +2873,8 @@ build_vec_init (tree base, tree maxindex, tree init, tree try_block = NULL_TREE; int num_initialized_elts = 0; bool is_global; + tree const_init = NULL_TREE; + tree obase = base; bool xvalue = false; if (TREE_CODE (atype) == ARRAY_TYPE && TYPE_DOMAIN (atype)) @@ -2986,26 +2983,75 @@ build_vec_init (tree base, tree maxindex, tree init, try_block = begin_try_block (); } + /* Maybe pull out constant value when from_array? */ + if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR) { /* Do non-default initialization of non-trivial arrays resulting from brace-enclosed initializers. */ unsigned HOST_WIDE_INT idx; - tree elt; + tree field, elt; + /* Should we try to create a constant initializer? */ + bool try_const = (literal_type_p (inner_elt_type) + || TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type)); + bool saw_non_const = false; + bool saw_const = false; + /* If we're initializing a static array, we want to do static + initialization of any elements with constant initializers even if + some are non-constant. */ + bool do_static_init = (DECL_P (obase) && TREE_STATIC (obase)); + VEC(constructor_elt,gc) *new_vec; from_array = 0; - FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (init), idx, elt) + if (try_const) + new_vec = VEC_alloc (constructor_elt, gc, CONSTRUCTOR_NELTS (init)); + else + new_vec = NULL; + + FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (init), idx, field, elt) { tree baseref = build1 (INDIRECT_REF, type, base); + tree one_init; num_initialized_elts++; current_stmt_tree ()->stmts_are_full_exprs_p = 1; if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE) - finish_expr_stmt (build_aggr_init (baseref, elt, 0, complain)); + one_init = build_aggr_init (baseref, elt, 0, complain); else - finish_expr_stmt (cp_build_modify_expr (baseref, NOP_EXPR, - elt, complain)); + one_init = cp_build_modify_expr (baseref, NOP_EXPR, + elt, complain); + + if (try_const) + { + tree e = one_init; + if (TREE_CODE (e) == EXPR_STMT) + e = TREE_OPERAND (e, 0); + if (TREE_CODE (e) == CONVERT_EXPR + && VOID_TYPE_P (TREE_TYPE (e))) + e = TREE_OPERAND (e, 0); + e = maybe_constant_init (e); + if (reduced_constant_expression_p (e)) + { + CONSTRUCTOR_APPEND_ELT (new_vec, field, e); + if (do_static_init) + one_init = NULL_TREE; + else + one_init = build2 (INIT_EXPR, type, baseref, e); + saw_const = true; + } + else + { + if (do_static_init) + CONSTRUCTOR_APPEND_ELT (new_vec, field, + build_zero_init (TREE_TYPE (e), + NULL_TREE, true)); + saw_non_const = true; + } + } + + if (one_init) + finish_expr_stmt (one_init); current_stmt_tree ()->stmts_are_full_exprs_p = 0; finish_expr_stmt (cp_build_unary_op (PREINCREMENT_EXPR, base, 0, @@ -3014,6 +3060,16 @@ build_vec_init (tree base, tree maxindex, tree init, complain)); } + if (try_const) + { + if (!saw_non_const) + const_init = build_constructor (atype, new_vec); + else if (do_static_init && saw_const) + DECL_INITIAL (obase) = build_constructor (atype, new_vec); + else + VEC_free (constructor_elt, gc, new_vec); + } + /* Clear out INIT so that we don't get confused below. */ init = NULL_TREE; } @@ -3161,6 +3217,9 @@ build_vec_init (tree base, tree maxindex, tree init, } current_stmt_tree ()->stmts_are_full_exprs_p = destroy_temps; + + if (const_init) + return build2 (INIT_EXPR, atype, obase, const_init); return stmt_expr; } |