Commit 4de2f020 by Jason Merrill Committed by Jason Merrill

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
parent acd6cc81
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> 2010-11-06 Nathan Froyd <froydnj@codesourcery.com>
PR c++/45332 PR c++/45332
......
...@@ -535,7 +535,7 @@ cp_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) ...@@ -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)); gcc_assert (EXPR_HAS_LOCATION (*expr_p));
input_location = EXPR_LOCATION (*expr_p); input_location = EXPR_LOCATION (*expr_p);
*expr_p = build_vec_init (VEC_INIT_EXPR_SLOT (*expr_p), NULL_TREE, *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, from_array,
tf_warning_or_error); tf_warning_or_error);
ret = GS_OK; ret = GS_OK;
......
...@@ -72,6 +72,7 @@ c-common.h, not after. ...@@ -72,6 +72,7 @@ c-common.h, not after.
CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR) CONSTRUCTOR_IS_DIRECT_INIT (in CONSTRUCTOR)
LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR) LAMBDA_EXPR_CAPTURES_THIS_P (in LAMBDA_EXPR)
DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE) DECLTYPE_FOR_LAMBDA_CAPTURE (in DECLTYPE_TYPE)
VEC_INIT_EXPR_IS_CONSTEXPR (in VEC_INIT_EXPR)
1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE)
TI_PENDING_TEMPLATE_FLAG. TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE. TEMPLATE_PARMS_FOR_INLINE.
...@@ -2898,6 +2899,15 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) ...@@ -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_SLOT(NODE) TREE_OPERAND (NODE, 0)
#define VEC_INIT_EXPR_INIT(NODE) TREE_OPERAND (NODE, 1) #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 /* 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 TEMPLATE_DECL. This macro determines whether or not a given class
type is really a template type, as opposed to an instantiation or type is really a template type, as opposed to an instantiation or
...@@ -5240,6 +5250,7 @@ extern bool literal_type_p (tree); ...@@ -5240,6 +5250,7 @@ extern bool literal_type_p (tree);
extern tree validate_constexpr_fundecl (tree); extern tree validate_constexpr_fundecl (tree);
extern tree register_constexpr_fundef (tree, tree); extern tree register_constexpr_fundef (tree, tree);
extern tree ensure_literal_type_for_constexpr_object (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 cxx_constant_value (tree);
extern tree maybe_constant_value (tree); extern tree maybe_constant_value (tree);
extern tree maybe_constant_init (tree); extern tree maybe_constant_init (tree);
......
...@@ -453,10 +453,8 @@ perform_member_init (tree member, tree init) ...@@ -453,10 +453,8 @@ perform_member_init (tree member, tree init)
/* mem() means value-initialization. */ /* mem() means value-initialization. */
if (TREE_CODE (type) == ARRAY_TYPE) if (TREE_CODE (type) == ARRAY_TYPE)
{ {
init = build_vec_init (decl, NULL_TREE, NULL_TREE, init = build_vec_init_expr (type, init);
/*explicit_value_init_p=*/true, init = build2 (INIT_EXPR, type, decl, init);
/* from_array=*/0,
tf_warning_or_error);
finish_expr_stmt (init); finish_expr_stmt (init);
} }
else else
......
...@@ -5324,8 +5324,6 @@ typedef struct GTY(()) constexpr_fundef { ...@@ -5324,8 +5324,6 @@ typedef struct GTY(()) constexpr_fundef {
static GTY ((param_is (constexpr_fundef))) htab_t constexpr_fundef_table; 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. /* Utility function used for managing the constexpr function table.
Return true if the entries pointed to by P and Q are for the Return true if the entries pointed to by P and Q are for the
same constexpr function. */ same constexpr function. */
...@@ -7066,7 +7064,7 @@ morally_constexpr_builtin_function_p (tree decl) ...@@ -7066,7 +7064,7 @@ morally_constexpr_builtin_function_p (tree decl)
logical OR (5.15), and conditional (5.16) operations that are logical OR (5.15), and conditional (5.16) operations that are
not evaluated are not considered. */ not evaluated are not considered. */
static bool bool
potential_constant_expression (tree t, tsubst_flags_t flags) potential_constant_expression (tree t, tsubst_flags_t flags)
{ {
int i; int i;
...@@ -7451,11 +7449,7 @@ potential_constant_expression (tree t, tsubst_flags_t flags) ...@@ -7451,11 +7449,7 @@ potential_constant_expression (tree t, tsubst_flags_t flags)
return false; return false;
case VEC_INIT_EXPR: case VEC_INIT_EXPR:
/* We should only see this in a defaulted constructor for a class return VEC_INIT_EXPR_IS_CONSTEXPR (t);
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;
default: default:
sorry ("unexpected ast of kind %s", tree_code_name[TREE_CODE (t)]); sorry ("unexpected ast of kind %s", tree_code_name[TREE_CODE (t)]);
......
...@@ -462,34 +462,54 @@ build_vec_init_expr (tree type, tree init) ...@@ -462,34 +462,54 @@ build_vec_init_expr (tree type, tree init)
{ {
tree slot; tree slot;
tree inner_type = strip_array_types (type); tree inner_type = strip_array_types (type);
tree elt_init = integer_zero_node;
gcc_assert (init == NULL_TREE bool value_init = false;
|| (same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (init))));
/* Since we're deferring building the actual constructor calls until /* Since we're deferring building the actual constructor calls until
gimplification time, we need to build one now and throw it away so gimplification time, we need to build one now and throw it away so
that the relevant constructor gets mark_used before cgraph decides that the relevant constructor gets mark_used before cgraph decides
what functions are needed. Here we assume that init is either what functions are needed. Here we assume that init is either
NULL_TREE or another array to copy. */ NULL_TREE, void_type_node (indicating value-initialization), or
if (CLASS_TYPE_P (inner_type)) another array to copy. */
if (init == void_type_node)
{ {
VEC(tree,gc) *argvec = make_tree_vector (); elt_init = build_value_init (inner_type, tf_warning_or_error);
if (init) 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); VEC(tree,gc) *argvec = make_tree_vector ();
if (!real_lvalue_p (init)) if (init)
dummy = move (dummy); {
VEC_quick_push (tree, argvec, dummy); 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); slot = build_local_temp (type);
init = build2 (VEC_INIT_EXPR, type, slot, init); init = build2 (VEC_INIT_EXPR, type, slot, init);
SET_EXPR_LOCATION (init, input_location); 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); init = build_target_expr (slot, init);
TARGET_EXPR_IMPLICIT_P (init) = 1; TARGET_EXPR_IMPLICIT_P (init) = 1;
......
2010-11-06 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-ctor3.C: New.
2010-11-06 Simon Martin <simartin@users.sourceforge.net> 2010-11-06 Simon Martin <simartin@users.sourceforge.net>
PR c/43384 PR c/43384
......
// { dg-options -std=c++0x }
struct A
{
int arr[1];
constexpr A()
: arr() { }
};
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment