Commit 262a7d6b by Jason Merrill Committed by Jason Merrill

re PR c++/47774 ([C++0x] constexpr specifier on ctor not ignored when template…

re PR c++/47774 ([C++0x] constexpr specifier on ctor not ignored when template instantiation causes ctor to not satify constexpr requirements)

	PR c++/47774
	* tree.c (build_vec_init_elt): Split out from...
	(build_vec_init_expr): ...here.
	(diagnose_non_constexpr_vec_init): New fn.
	* semantics.c (potential_constant_expression_1): Use it.
	* cp-tree.h: Declare it.

From-SVN: r170638
parent 20532210
2011-03-02 Jason Merrill <jason@redhat.com>
PR c++/47774
* tree.c (build_vec_init_elt): Split out from...
(build_vec_init_expr): ...here.
(diagnose_non_constexpr_vec_init): New fn.
* semantics.c (potential_constant_expression_1): Use it.
* cp-tree.h: Declare it.
2011-03-01 Jason Merrill <jason@redhat.com>
PR c++/46159
......
......@@ -5400,6 +5400,7 @@ extern tree build_cplus_array_type (tree, tree);
extern tree build_array_of_n_type (tree, int);
extern tree build_array_copy (tree);
extern tree build_vec_init_expr (tree, tree);
extern void diagnose_non_constexpr_vec_init (tree);
extern tree hash_tree_cons (tree, tree, tree);
extern tree hash_tree_chain (tree, tree);
extern tree build_qualified_name (tree, tree, tree, bool);
......
......@@ -7722,7 +7722,10 @@ potential_constant_expression_1 (tree t, bool want_rval, tsubst_flags_t flags)
if (VEC_INIT_EXPR_IS_CONSTEXPR (t))
return true;
if (flags & tf_error)
{
error ("non-constant array initialization");
diagnose_non_constexpr_vec_init (t);
}
return false;
default:
......
......@@ -456,44 +456,35 @@ build_cplus_new (tree type, tree init)
return rval;
}
/* Return a TARGET_EXPR which expresses the initialization of an array to
be named later, either default-initialization or copy-initialization
from another array of the same type. */
tree
build_vec_init_expr (tree type, tree init)
{
tree slot;
tree inner_type = strip_array_types (type);
tree elt_init = integer_zero_node;
bool value_init = false;
/* Subroutine of build_vec_init_expr: Build up a single element
intialization as a proxy for the full array initialization to get things
marked as used and any appropriate diagnostics.
/* 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
that the relevant constructor gets mark_used before cgraph decides
what functions are needed. Here we assume that init is either
NULL_TREE, void_type_node (indicating value-initialization), or
another array to copy. */
if (integer_zerop (array_type_nelts_total (type)))
{
/* No actual initialization to do. */;
init = NULL_TREE;
}
static tree
build_vec_init_elt (tree type, tree init)
{
tree inner_type = strip_array_types (type);
VEC(tree,gc) *argvec;
if (integer_zerop (array_type_nelts_total (type))
|| !CLASS_TYPE_P (inner_type))
/* No interesting initialization to do. */
return integer_zero_node;
else if (init == void_type_node)
{
elt_init = build_value_init (inner_type, tf_warning_or_error);
value_init = true;
init = NULL_TREE;
}
else
{
return build_value_init (inner_type, tf_warning_or_error);
gcc_assert (init == NULL_TREE
|| (same_type_ignoring_top_level_qualifiers_p
(type, TREE_TYPE (init))));
if (CLASS_TYPE_P (inner_type))
{
VEC(tree,gc) *argvec = make_tree_vector ();
argvec = make_tree_vector ();
if (init)
{
tree dummy = build_dummy_object (inner_type);
......@@ -501,25 +492,35 @@ build_vec_init_expr (tree type, tree init)
dummy = move (dummy);
VEC_quick_push (tree, argvec, dummy);
}
elt_init
= build_special_member_call (NULL_TREE, complete_ctor_identifier,
return build_special_member_call (NULL_TREE, complete_ctor_identifier,
&argvec, inner_type, LOOKUP_NORMAL,
tf_warning_or_error);
}
}
/* Return a TARGET_EXPR which expresses the initialization of an array to
be named later, either default-initialization or copy-initialization
from another array of the same type. */
tree
build_vec_init_expr (tree type, tree init)
{
tree slot;
bool value_init = false;
tree elt_init = build_vec_init_elt (type, init);
if (init == void_type_node)
{
value_init = true;
init = NULL_TREE;
}
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))
{
if (potential_constant_expression (elt_init))
if (cxx_dialect >= cxx0x
&& potential_constant_expression (elt_init))
VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
else if (!processing_template_decl)
require_potential_constant_expression (elt_init);
}
VEC_INIT_EXPR_VALUE_INIT (init) = value_init;
init = build_target_expr (slot, init);
......@@ -528,6 +529,23 @@ build_vec_init_expr (tree type, tree init)
return init;
}
/* Give a helpful diagnostic for a non-constexpr VEC_INIT_EXPR in a context
that requires a constant expression. */
void
diagnose_non_constexpr_vec_init (tree expr)
{
tree type = TREE_TYPE (VEC_INIT_EXPR_SLOT (expr));
tree init, elt_init;
if (VEC_INIT_EXPR_VALUE_INIT (expr))
init = void_zero_node;
else
init = VEC_INIT_EXPR_INIT (expr);
elt_init = build_vec_init_elt (type, init);
require_potential_constant_expression (elt_init);
}
tree
build_array_copy (tree init)
{
......
2011-03-02 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/constexpr-ctor9.C: New.
2011-03-01 Jason Merrill <jason@redhat.com>
* g++.dg/cpp0x/lambda/lambda-98.C: New.
......
// PR c++/47774
// { dg-options -std=c++0x }
struct A
{
A() {}
};
template <typename T>
struct array
{
constexpr array() : mem() {}
T mem[7];
};
int main()
{
array<A> ar;
}
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