init.c (perform_member_init): Use build_vec_init_expr for value-init of arrays, too.

* init.c (perform_member_init): Use build_vec_init_expr for
	value-init of arrays, too.
	* cp-gimplify.c (cp_gimplify_expr): Use VEC_INIT_EXPR_VALUE_INIT.
	* cp-tree.h (VEC_INIT_EXPR_IS_CONSTEXPR): New macro.
	(VEC_INIT_EXPR_VALUE_INIT): New macro.
	* semantics.c (potential_constant_expression): No longer static.
	Check VEC_INIT_EXPR_IS_CONSTEXPR.
	* tree.c (build_vec_init_expr): Handle value-init.  Set
	VEC_INIT_EXPR_IS_CONSTEXPR and VEC_INIT_EXPR_VALUE_INIT.

From-SVN: r166413
This commit is contained in:
Jason Merrill 2010-11-06 20:46:45 -04:00 committed by Jason Merrill
parent acd6cc816d
commit 4de2f020aa
8 changed files with 76 additions and 28 deletions

View File

@ -1,3 +1,15 @@
2010-11-06 Jason Merrill <jason@redhat.com>
* init.c (perform_member_init): Use build_vec_init_expr for
value-init of arrays, too.
* cp-gimplify.c (cp_gimplify_expr): Use VEC_INIT_EXPR_VALUE_INIT.
* cp-tree.h (VEC_INIT_EXPR_IS_CONSTEXPR): New macro.
(VEC_INIT_EXPR_VALUE_INIT): New macro.
* semantics.c (potential_constant_expression): No longer static.
Check VEC_INIT_EXPR_IS_CONSTEXPR.
* tree.c (build_vec_init_expr): Handle value-init. Set
VEC_INIT_EXPR_IS_CONSTEXPR and VEC_INIT_EXPR_VALUE_INIT.
2010-11-06 Nathan Froyd <froydnj@codesourcery.com>
PR c++/45332

View File

@ -535,7 +535,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
gcc_assert (EXPR_HAS_LOCATION (*expr_p));
input_location = EXPR_LOCATION (*expr_p);
*expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE,
init, /*explicit_value_init_p*/false,
init, VEC_INIT_EXPR_VALUE_INIT (*expr_p),
from_array,
tf_warning_or_error);
ret = GS_OK;

View File

@ -72,6 +72,7 @@ c-common.h, not after.
CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR)
DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE)
VEC_INIT_EXPR_IS_CONSTEXPR (in VEC_INIT_EXPR)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
@ -2898,6 +2899,15 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
#define VEC_INIT_EXPR_SLOT(NODE) TREE_OPERAND (NODE, 0)
#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (NODE, 1)
/* Indicates that a VEC_INIT_EXPR is a potential constant expression.
Only set when the current function is constexpr. */
#define VEC_INIT_EXPR_IS_CONSTEXPR(NODE) \
TREE_LANG_FLAG_0 (VEC_INIT_EXPR_CHECK (NODE))
/* Indicates that a VEC_INIT_EXPR is expressing value-initialization. */
#define VEC_INIT_EXPR_VALUE_INIT(NODE) \
TREE_LANG_FLAG_1 (VEC_INIT_EXPR_CHECK (NODE))
/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a
TEMPLATE_DECL. This macro determines whether or not a given class
type is really a template type, as opposed to an instantiation or
@ -5240,6 +5250,7 @@ extern bool literal_type_p (tree);
extern tree validate_constexpr_fundecl (tree);
extern tree register_constexpr_fundef (tree, tree);
extern tree ensure_literal_type_for_constexpr_object (tree);
extern bool potential_constant_expression (tree, tsubst_flags_t);
extern tree cxx_constant_value (tree);
extern tree maybe_constant_value (tree);
extern tree maybe_constant_init (tree);

View File

@ -453,10 +453,8 @@ perform_member_init (tree member, tree init)
/* mem() means value-initialization. */
if (TREE_CODE (type) == ARRAY_TYPE)
{
init = build_vec_init (decl, NULL_TREE, NULL_TREE,
/*explicit_value_init_p=*/true,
/* from_array=*/0,
tf_warning_or_error);
init = build_vec_init_expr (type, init);
init = build2 (INIT_EXPR, type, decl, init);
finish_expr_stmt (init);
}
else

View File

@ -5324,8 +5324,6 @@ typedef struct GTY(()) constexpr_fundef {
static GTY ((param_is (constexpr_fundef))) htab_t constexpr_fundef_table;
static bool potential_constant_expression (tree, tsubst_flags_t);
/* Utility function used for managing the constexpr function table.
Return true if the entries pointed to by P and Q are for the
same constexpr function. */
@ -7066,7 +7064,7 @@ morally_constexpr_builtin_function_p (tree decl)
logical OR (5.15), and conditional (5.16) operations that are
not evaluated are not considered. */
static bool
bool
potential_constant_expression (tree t, tsubst_flags_t flags)
{
int i;
@ -7451,11 +7449,7 @@ potential_constant_expression (tree t, tsubst_flags_t flags)
return false;
case VEC_INIT_EXPR:
/* We should only see this in a defaulted constructor for a class
with a non-static data member of array type; if we get here we
know this is a potential constant expression. */
gcc_assert (DECL_DEFAULTED_FN (current_function_decl));
return true;
return VEC_INIT_EXPR_IS_CONSTEXPR (t);
default:
sorry ("unexpected ast of kind %s", tree_code_name[TREE_CODE (t)]);

View File

@ -462,34 +462,54 @@ build_vec_init_expr (tree type, tree init)
{
tree slot;
tree inner_type = strip_array_types (type);
gcc_assert (init == NULL_TREE
|| (same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (init))));
tree elt_init = integer_zero_node;
bool value_init = false;
/* Since we're deferring building the actual constructor calls until
gimplification time, we need to build one now and throw it away so
that the relevant constructor gets mark_used before cgraph decides
what functions are needed. Here we assume that init is either
NULL_TREE or another array to copy. */
if (CLASS_TYPE_P (inner_type))
NULL_TREE, void_type_node (indicating value-initialization), or
another array to copy. */
if (init == void_type_node)
{
VEC(tree,gc) *argvec = make_tree_vector ();
if (init)
elt_init = build_value_init (inner_type, tf_warning_or_error);
value_init = true;
init = NULL_TREE;
}
else
{
gcc_assert (init == NULL_TREE
|| (same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (init))));
if (CLASS_TYPE_P (inner_type))
{
tree dummy = build_dummy_object (inner_type);
if (!real_lvalue_p (init))
dummy = move (dummy);
VEC_quick_push (tree, argvec, dummy);
VEC(tree,gc) *argvec = make_tree_vector ();
if (init)
{
tree dummy = build_dummy_object (inner_type);
if (!real_lvalue_p (init))
dummy = move (dummy);
VEC_quick_push (tree, argvec, dummy);
}
elt_init
= build_special_member_call (NULL_TREE, complete_ctor_identifier,
&argvec, inner_type, LOOKUP_NORMAL,
tf_warning_or_error);
}
build_special_member_call (NULL_TREE, complete_ctor_identifier,
&argvec, inner_type, LOOKUP_NORMAL,
tf_warning_or_error);
}
slot = build_local_temp (type);
init = build2 (VEC_INIT_EXPR, type, slot, init);
SET_EXPR_LOCATION (init, input_location);
if (current_function_decl
&& DECL_DECLARED_CONSTEXPR_P (current_function_decl)
&& potential_constant_expression (elt_init, tf_warning_or_error))
VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
init = build_target_expr (slot, init);
TARGET_EXPR_IMPLICIT_P (init) = 1;

View File

@ -1,3 +1,7 @@
2010-11-06 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-ctor3.C: New.
2010-11-06 Simon Martin <simartin@users.sourceforge.net>
PR c/43384

View File

@ -0,0 +1,9 @@
// { dg-options -std=c++0x }
struct A
{
int arr[1];
constexpr A()
: arr() { }
};