aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/init.c
diff options
context:
space:
mode:
authorJason Merrill <jason@gcc.gnu.org>2010-11-01 21:31:18 -0400
committerJason Merrill <jason@gcc.gnu.org>2010-11-01 21:31:18 -0400
commitfa2200cbb1ef5a6a7bdb9a5ba708c7400eb6b404 (patch)
tree6c2db2fc090bec484b5ef60fbe416d72e1c7b6a4 /gcc/cp/init.c
parentc41095db2f17d8e8695bfab2a582b8f99639633f (diff)
downloadgcc-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.c127
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;
}