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
This commit is contained in:
parent
20532210cd
commit
262a7d6bc0
@ -1,3 +1,12 @@
|
||||
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");
|
||||
{
|
||||
error ("non-constant array initialization");
|
||||
diagnose_non_constexpr_vec_init (t);
|
||||
}
|
||||
return false;
|
||||
|
||||
default:
|
||||
|
108
gcc/cp/tree.c
108
gcc/cp/tree.c
@ -456,6 +456,47 @@ build_cplus_new (tree type, tree init)
|
||||
return rval;
|
||||
}
|
||||
|
||||
/* 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
|
||||
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. */
|
||||
|
||||
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)
|
||||
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))));
|
||||
|
||||
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);
|
||||
}
|
||||
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. */
|
||||
@ -464,62 +505,22 @@ 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;
|
||||
tree elt_init = build_vec_init_elt (type, init);
|
||||
|
||||
/* 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)))
|
||||
if (init == void_type_node)
|
||||
{
|
||||
/* No actual initialization to do. */;
|
||||
init = NULL_TREE;
|
||||
}
|
||||
else if (init == void_type_node)
|
||||
{
|
||||
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))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
|
||||
else if (!processing_template_decl)
|
||||
require_potential_constant_expression (elt_init);
|
||||
}
|
||||
if (cxx_dialect >= cxx0x
|
||||
&& potential_constant_expression (elt_init))
|
||||
VEC_INIT_EXPR_IS_CONSTEXPR (init) = true;
|
||||
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)
|
||||
{
|
||||
|
@ -1,3 +1,7 @@
|
||||
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.
|
||||
|
19
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor9.C
Normal file
19
gcc/testsuite/g++.dg/cpp0x/constexpr-ctor9.C
Normal file
@ -0,0 +1,19 @@
|
||||
// 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user