aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/cp-gimplify.c2
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/init.c6
-rw-r--r--gcc/cp/semantics.c10
-rw-r--r--gcc/cp/tree.c50
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ctor3.C9
8 files changed, 76 insertions, 28 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 784f3aa..3f3a8ee 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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
diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
index 705979d..557430d 100644
--- a/gcc/cp/cp-gimplify.c
+++ b/gcc/cp/cp-gimplify.c
@@ -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;
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8f52278..241805c 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -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);
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index ab834bf..0ecd61d 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -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
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 558be88..fd7da34 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -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)]);
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d1d306e..5440e10 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 98a866b..c5ccdb8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor3.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor3.C
new file mode 100644
index 0000000..50d4d85
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ctor3.C
@@ -0,0 +1,9 @@
+// { dg-options -std=c++0x }
+
+struct A
+{
+ int arr[1];
+
+ constexpr A()
+ : arr() { }
+};