mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-25 01:30:44 +08:00
re PR c++/48737 ([C++0x][SFINAE] Hard errors with array list-construction with too many elements)
/cp 2011-05-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/48737 PR c++/48744 * decl.c (reshape_init): Take a complain parameter and do not call error if tf_error is not set. (check_initializer, reshape_init_r, reshape_init_array, reshape_init_array_1, reshape_init_vector, reshape_init_class): Adjust. * typeck2.c (digest_init_r): Take a complain parameter and pass it to convert_for_initialization. (digest_init, digest_init_flags, process_init_constructor_array, process_init_constructor_record, process_init_constructor_union, process_init_constructor, digest_init_r): Adjust. * init.c (expand_default_init, build_new_1): Likewise. * typeck.c (cp_build_modify_expr): Likewise. * decl2.c (grokfield): Likewise. * call.c (convert_like_real, convert_default_arg): Likewise. * semantics.c (finish_compound_literal): Pass complain to reshape_init and digest_init. * cp-tree.h: Adjust declarations. /testsuite 2011-05-09 Paolo Carlini <paolo.carlini@oracle.com> PR c++/48737 PR c++/48744 * g++.dg/template/sfinae28.C: New. * g++.dg/template/sfinae29.C: Likewise. From-SVN: r173590
This commit is contained in:
parent
e4c0337862
commit
754af126c0
@ -1,5 +1,27 @@
|
||||
2011-05-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/48737
|
||||
PR c++/48744
|
||||
* decl.c (reshape_init): Take a complain parameter and do
|
||||
not call error if tf_error is not set.
|
||||
(check_initializer, reshape_init_r, reshape_init_array,
|
||||
reshape_init_array_1, reshape_init_vector, reshape_init_class):
|
||||
Adjust.
|
||||
* typeck2.c (digest_init_r): Take a complain parameter and
|
||||
pass it to convert_for_initialization.
|
||||
(digest_init, digest_init_flags, process_init_constructor_array,
|
||||
process_init_constructor_record, process_init_constructor_union,
|
||||
process_init_constructor, digest_init_r): Adjust.
|
||||
* init.c (expand_default_init, build_new_1): Likewise.
|
||||
* typeck.c (cp_build_modify_expr): Likewise.
|
||||
* decl2.c (grokfield): Likewise.
|
||||
* call.c (convert_like_real, convert_default_arg): Likewise.
|
||||
* semantics.c (finish_compound_literal): Pass complain to
|
||||
reshape_init and digest_init.
|
||||
* cp-tree.h: Adjust declarations.
|
||||
|
||||
2011-05-07 Fabien Chêne <fabien@gcc.gnu.org>
|
||||
|
||||
|
||||
PR c++/48859
|
||||
* init.c (diagnose_uninitialized_cst_or_ref_member_1): stop the
|
||||
recursion if there is user defined constructor.
|
||||
|
@ -5670,7 +5670,7 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
|
||||
expr = build2 (COMPLEX_EXPR, totype, real, imag);
|
||||
return fold_if_not_in_template (expr);
|
||||
}
|
||||
return get_target_expr (digest_init (totype, expr));
|
||||
return get_target_expr (digest_init (totype, expr, complain));
|
||||
|
||||
default:
|
||||
break;
|
||||
@ -6032,7 +6032,7 @@ convert_default_arg (tree type, tree arg, tree fn, int parmnum)
|
||||
arg = break_out_target_exprs (arg);
|
||||
if (TREE_CODE (arg) == CONSTRUCTOR)
|
||||
{
|
||||
arg = digest_init (type, arg);
|
||||
arg = digest_init (type, arg, tf_warning_or_error);
|
||||
arg = convert_for_initialization (0, type, arg, LOOKUP_IMPLICIT,
|
||||
ICR_DEFAULT_ARGUMENT, fn, parmnum,
|
||||
tf_warning_or_error);
|
||||
|
@ -4903,7 +4903,7 @@ extern tree cxx_comdat_group (tree);
|
||||
extern bool cp_missing_noreturn_ok_p (tree);
|
||||
extern void initialize_artificial_var (tree, VEC(constructor_elt,gc) *);
|
||||
extern tree check_var_type (tree, tree);
|
||||
extern tree reshape_init (tree, tree);
|
||||
extern tree reshape_init (tree, tree, tsubst_flags_t);
|
||||
extern tree next_initializable_field (tree);
|
||||
|
||||
extern bool defer_mark_used_calls;
|
||||
@ -5669,7 +5669,7 @@ extern int abstract_virtuals_error_sfinae (tree, tree, tsubst_flags_t);
|
||||
|
||||
extern tree store_init_value (tree, tree, int);
|
||||
extern void check_narrowing (tree, tree);
|
||||
extern tree digest_init (tree, tree);
|
||||
extern tree digest_init (tree, tree, tsubst_flags_t);
|
||||
extern tree digest_init_flags (tree, tree, int);
|
||||
extern tree build_scoped_ref (tree, tree, tree *);
|
||||
extern tree build_x_arrow (tree);
|
||||
|
@ -4878,7 +4878,7 @@ typedef struct reshape_iterator_t
|
||||
constructor_elt *end;
|
||||
} reshape_iter;
|
||||
|
||||
static tree reshape_init_r (tree, reshape_iter *, bool);
|
||||
static tree reshape_init_r (tree, reshape_iter *, bool, tsubst_flags_t);
|
||||
|
||||
/* FIELD is a FIELD_DECL or NULL. In the former case, the value
|
||||
returned is the next FIELD_DECL (possibly FIELD itself) that can be
|
||||
@ -4904,7 +4904,8 @@ next_initializable_field (tree field)
|
||||
the iterator within the constructor. */
|
||||
|
||||
static tree
|
||||
reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
|
||||
reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree new_init;
|
||||
bool sized_array_p = (max_index != NULL_TREE);
|
||||
@ -4936,7 +4937,8 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
|
||||
tree elt_init;
|
||||
|
||||
check_array_designated_initializer (d->cur);
|
||||
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false);
|
||||
elt_init = reshape_init_r (elt_type, d, /*first_initializer_p=*/false,
|
||||
complain);
|
||||
if (elt_init == error_mark_node)
|
||||
return error_mark_node;
|
||||
CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (new_init),
|
||||
@ -4952,7 +4954,7 @@ reshape_init_array_1 (tree elt_type, tree max_index, reshape_iter *d)
|
||||
Parameters are the same of reshape_init_r. */
|
||||
|
||||
static tree
|
||||
reshape_init_array (tree type, reshape_iter *d)
|
||||
reshape_init_array (tree type, reshape_iter *d, tsubst_flags_t complain)
|
||||
{
|
||||
tree max_index = NULL_TREE;
|
||||
|
||||
@ -4961,14 +4963,14 @@ reshape_init_array (tree type, reshape_iter *d)
|
||||
if (TYPE_DOMAIN (type))
|
||||
max_index = array_type_nelts (type);
|
||||
|
||||
return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
|
||||
return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
|
||||
}
|
||||
|
||||
/* Subroutine of reshape_init_r, processes the initializers for vectors.
|
||||
Parameters are the same of reshape_init_r. */
|
||||
|
||||
static tree
|
||||
reshape_init_vector (tree type, reshape_iter *d)
|
||||
reshape_init_vector (tree type, reshape_iter *d, tsubst_flags_t complain)
|
||||
{
|
||||
tree max_index = NULL_TREE;
|
||||
|
||||
@ -4979,8 +4981,9 @@ reshape_init_vector (tree type, reshape_iter *d)
|
||||
tree value = d->cur->value;
|
||||
if (!same_type_p (TREE_TYPE (value), type))
|
||||
{
|
||||
error ("invalid type %qT as initializer for a vector of type %qT",
|
||||
TREE_TYPE (d->cur->value), type);
|
||||
if (complain & tf_error)
|
||||
error ("invalid type %qT as initializer for a vector of type %qT",
|
||||
TREE_TYPE (d->cur->value), type);
|
||||
value = error_mark_node;
|
||||
}
|
||||
++d->cur;
|
||||
@ -4991,14 +4994,15 @@ reshape_init_vector (tree type, reshape_iter *d)
|
||||
if (TREE_CODE (type) == VECTOR_TYPE)
|
||||
max_index = size_int (TYPE_VECTOR_SUBPARTS (type) - 1);
|
||||
|
||||
return reshape_init_array_1 (TREE_TYPE (type), max_index, d);
|
||||
return reshape_init_array_1 (TREE_TYPE (type), max_index, d, complain);
|
||||
}
|
||||
|
||||
/* Subroutine of reshape_init_r, processes the initializers for classes
|
||||
or union. Parameters are the same of reshape_init_r. */
|
||||
|
||||
static tree
|
||||
reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree field;
|
||||
tree new_init;
|
||||
@ -5018,7 +5022,8 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
initializer-list {}. */
|
||||
if (!first_initializer_p)
|
||||
{
|
||||
error ("initializer for %qT must be brace-enclosed", type);
|
||||
if (complain & tf_error)
|
||||
error ("initializer for %qT must be brace-enclosed", type);
|
||||
return error_mark_node;
|
||||
}
|
||||
return new_init;
|
||||
@ -5036,8 +5041,9 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
|
||||
if (!field || TREE_CODE (field) != FIELD_DECL)
|
||||
{
|
||||
error ("%qT has no non-static data member named %qD", type,
|
||||
d->cur->index);
|
||||
if (complain & tf_error)
|
||||
error ("%qT has no non-static data member named %qD", type,
|
||||
d->cur->index);
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
@ -5047,7 +5053,7 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
break;
|
||||
|
||||
field_init = reshape_init_r (TREE_TYPE (field), d,
|
||||
/*first_initializer_p=*/false);
|
||||
/*first_initializer_p=*/false, complain);
|
||||
if (field_init == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
@ -5074,7 +5080,8 @@ reshape_init_class (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
outermost CONSTRUCTOR node. */
|
||||
|
||||
static tree
|
||||
reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
tree init = d->cur->value;
|
||||
|
||||
@ -5089,7 +5096,12 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (init))
|
||||
{
|
||||
if (CONSTRUCTOR_NELTS (init) > 2)
|
||||
error ("too many initializers for %qT", type);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("too many initializers for %qT", type);
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
else if (first_initializer_p && d->cur != d->end)
|
||||
{
|
||||
@ -5116,7 +5128,8 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
{
|
||||
if (SCALAR_TYPE_P (type))
|
||||
{
|
||||
error ("braces around scalar initializer for type %qT", type);
|
||||
if (complain & tf_error)
|
||||
error ("braces around scalar initializer for type %qT", type);
|
||||
init = error_mark_node;
|
||||
}
|
||||
else
|
||||
@ -5203,7 +5216,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
{
|
||||
++d->cur;
|
||||
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
|
||||
return reshape_init (type, init);
|
||||
return reshape_init (type, init, complain);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5213,11 +5226,11 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
|
||||
/* Dispatch to specialized routines. */
|
||||
if (CLASS_TYPE_P (type))
|
||||
return reshape_init_class (type, d, first_initializer_p);
|
||||
return reshape_init_class (type, d, first_initializer_p, complain);
|
||||
else if (TREE_CODE (type) == ARRAY_TYPE)
|
||||
return reshape_init_array (type, d);
|
||||
return reshape_init_array (type, d, complain);
|
||||
else if (TREE_CODE (type) == VECTOR_TYPE)
|
||||
return reshape_init_vector (type, d);
|
||||
return reshape_init_vector (type, d, complain);
|
||||
else
|
||||
gcc_unreachable();
|
||||
}
|
||||
@ -5238,7 +5251,7 @@ reshape_init_r (tree type, reshape_iter *d, bool first_initializer_p)
|
||||
revised CONSTRUCTOR node is returned. */
|
||||
|
||||
tree
|
||||
reshape_init (tree type, tree init)
|
||||
reshape_init (tree type, tree init, tsubst_flags_t complain)
|
||||
{
|
||||
VEC(constructor_elt, gc) *v;
|
||||
reshape_iter d;
|
||||
@ -5257,14 +5270,19 @@ reshape_init (tree type, tree init)
|
||||
d.cur = VEC_index (constructor_elt, v, 0);
|
||||
d.end = d.cur + VEC_length (constructor_elt, v);
|
||||
|
||||
new_init = reshape_init_r (type, &d, true);
|
||||
new_init = reshape_init_r (type, &d, true, complain);
|
||||
if (new_init == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Make sure all the element of the constructor were used. Otherwise,
|
||||
issue an error about exceeding initializers. */
|
||||
if (d.cur != d.end)
|
||||
error ("too many initializers for %qT", type);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("too many initializers for %qT", type);
|
||||
else
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return new_init;
|
||||
}
|
||||
@ -5417,7 +5435,7 @@ check_initializer (tree decl, tree init, int flags, tree *cleanup)
|
||||
init = error_mark_node;
|
||||
}
|
||||
else
|
||||
init = reshape_init (type, init);
|
||||
init = reshape_init (type, init, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* If DECL has an array type without a specific bound, deduce the
|
||||
|
@ -924,7 +924,7 @@ grokfield (const cp_declarator *declarator,
|
||||
else if (!processing_template_decl)
|
||||
{
|
||||
if (TREE_CODE (init) == CONSTRUCTOR)
|
||||
init = digest_init (TREE_TYPE (value), init);
|
||||
init = digest_init (TREE_TYPE (value), init, tf_warning_or_error);
|
||||
init = maybe_constant_init (init);
|
||||
|
||||
if (init != error_mark_node && !TREE_CONSTANT (init))
|
||||
|
@ -1435,7 +1435,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags,
|
||||
{
|
||||
/* A brace-enclosed initializer for an aggregate. In C++0x this can
|
||||
happen for direct-initialization, too. */
|
||||
init = digest_init (type, init);
|
||||
init = digest_init (type, init, complain);
|
||||
init = build2 (INIT_EXPR, TREE_TYPE (exp), exp, init);
|
||||
TREE_SIDE_EFFECTS (init) = 1;
|
||||
finish_expr_stmt (init);
|
||||
@ -2378,7 +2378,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts,
|
||||
"verify length of initializer-list");
|
||||
}
|
||||
arraytype = build_cplus_array_type (type, domain);
|
||||
vecinit = digest_init (arraytype, vecinit);
|
||||
vecinit = digest_init (arraytype, vecinit, complain);
|
||||
}
|
||||
else if (*init)
|
||||
{
|
||||
|
@ -2369,7 +2369,7 @@ finish_compound_literal (tree type, tree compound_literal,
|
||||
if (TREE_CODE (type) == ARRAY_TYPE
|
||||
&& check_array_initializer (NULL_TREE, type, compound_literal))
|
||||
return error_mark_node;
|
||||
compound_literal = reshape_init (type, compound_literal);
|
||||
compound_literal = reshape_init (type, compound_literal, complain);
|
||||
if (TREE_CODE (type) == ARRAY_TYPE
|
||||
&& TYPE_DOMAIN (type) == NULL_TREE)
|
||||
{
|
||||
@ -2378,7 +2378,7 @@ finish_compound_literal (tree type, tree compound_literal,
|
||||
if (type == error_mark_node)
|
||||
return error_mark_node;
|
||||
}
|
||||
compound_literal = digest_init (type, compound_literal);
|
||||
compound_literal = digest_init (type, compound_literal, complain);
|
||||
/* Put static/constant array temporaries in static variables, but always
|
||||
represent class temporaries with TARGET_EXPR so we elide copies. */
|
||||
if ((!at_function_scope_p () || CP_TYPE_CONST_P (type))
|
||||
|
@ -6715,7 +6715,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
|
||||
}
|
||||
if (check_array_initializer (lhs, lhstype, newrhs))
|
||||
return error_mark_node;
|
||||
newrhs = digest_init (lhstype, newrhs);
|
||||
newrhs = digest_init (lhstype, newrhs, complain);
|
||||
}
|
||||
|
||||
else if (!same_or_base_type_p (TYPE_MAIN_VARIANT (lhstype),
|
||||
|
128
gcc/cp/typeck2.c
128
gcc/cp/typeck2.c
@ -39,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
|
||||
#include "diagnostic-core.h"
|
||||
|
||||
static tree
|
||||
process_init_constructor (tree type, tree init);
|
||||
process_init_constructor (tree type, tree init, tsubst_flags_t complain);
|
||||
|
||||
|
||||
/* Print an error message stemming from an attempt to use
|
||||
@ -783,8 +783,8 @@ check_narrowing (tree type, tree init)
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
permerror (input_location, "narrowing conversion of %qE from %qT to %qT inside { }",
|
||||
init, ftype, type);
|
||||
permerror (input_location, "narrowing conversion of %qE from %qT "
|
||||
"to %qT inside { }", init, ftype, type);
|
||||
}
|
||||
|
||||
/* Process the initializer INIT for a variable of type TYPE, emitting
|
||||
@ -797,7 +797,8 @@ check_narrowing (tree type, tree init)
|
||||
NESTED is true iff we are being called for an element of a CONSTRUCTOR. */
|
||||
|
||||
static tree
|
||||
digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
digest_init_r (tree type, tree init, bool nested, int flags,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
enum tree_code code = TREE_CODE (type);
|
||||
|
||||
@ -833,7 +834,8 @@ digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
{
|
||||
if (char_type != char_type_node)
|
||||
{
|
||||
error ("char-array initialized from wide string");
|
||||
if (complain & tf_error)
|
||||
error ("char-array initialized from wide string");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
@ -841,12 +843,15 @@ digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
{
|
||||
if (char_type == char_type_node)
|
||||
{
|
||||
error ("int-array initialized from non-wide string");
|
||||
if (complain & tf_error)
|
||||
error ("int-array initialized from non-wide string");
|
||||
return error_mark_node;
|
||||
}
|
||||
else if (char_type != typ1)
|
||||
{
|
||||
error ("int-array initialized from incompatible wide string");
|
||||
if (complain & tf_error)
|
||||
error ("int-array initialized from incompatible "
|
||||
"wide string");
|
||||
return error_mark_node;
|
||||
}
|
||||
}
|
||||
@ -861,7 +866,8 @@ digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
counted in the length of the constant, but in C++ this would
|
||||
be invalid. */
|
||||
if (size < TREE_STRING_LENGTH (init))
|
||||
permerror (input_location, "initializer-string for array of chars is too long");
|
||||
permerror (input_location, "initializer-string for array "
|
||||
"of chars is too long");
|
||||
}
|
||||
return init;
|
||||
}
|
||||
@ -878,7 +884,7 @@ digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
check_narrowing (type, init);
|
||||
init = convert_for_initialization (0, type, init, flags,
|
||||
ICR_INIT, NULL_TREE, 0,
|
||||
tf_warning_or_error);
|
||||
complain);
|
||||
exp = &init;
|
||||
|
||||
/* Skip any conversions since we'll be outputting the underlying
|
||||
@ -902,13 +908,14 @@ digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
|
||||
if (BRACE_ENCLOSED_INITIALIZER_P (init)
|
||||
&& !TYPE_NON_AGGREGATE_CLASS (type))
|
||||
return process_init_constructor (type, init);
|
||||
return process_init_constructor (type, init, complain);
|
||||
else
|
||||
{
|
||||
if (COMPOUND_LITERAL_P (init) && TREE_CODE (type) == ARRAY_TYPE)
|
||||
{
|
||||
error ("cannot initialize aggregate of type %qT with "
|
||||
"a compound literal", type);
|
||||
if (complain & tf_error)
|
||||
error ("cannot initialize aggregate of type %qT with "
|
||||
"a compound literal", type);
|
||||
|
||||
return error_mark_node;
|
||||
}
|
||||
@ -924,28 +931,29 @@ digest_init_r (tree type, tree init, bool nested, int flags)
|
||||
(type, TREE_TYPE (init))))
|
||||
return init;
|
||||
|
||||
error ("array must be initialized with a brace-enclosed"
|
||||
" initializer");
|
||||
if (complain & tf_error)
|
||||
error ("array must be initialized with a brace-enclosed"
|
||||
" initializer");
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
return convert_for_initialization (NULL_TREE, type, init,
|
||||
flags,
|
||||
ICR_INIT, NULL_TREE, 0,
|
||||
tf_warning_or_error);
|
||||
complain);
|
||||
}
|
||||
}
|
||||
|
||||
tree
|
||||
digest_init (tree type, tree init)
|
||||
digest_init (tree type, tree init, tsubst_flags_t complain)
|
||||
{
|
||||
return digest_init_r (type, init, false, LOOKUP_IMPLICIT);
|
||||
return digest_init_r (type, init, false, LOOKUP_IMPLICIT, complain);
|
||||
}
|
||||
|
||||
tree
|
||||
digest_init_flags (tree type, tree init, int flags)
|
||||
{
|
||||
return digest_init_r (type, init, false, flags);
|
||||
return digest_init_r (type, init, false, flags, tf_warning_or_error);
|
||||
}
|
||||
|
||||
/* Set of flags used within process_init_constructor to describe the
|
||||
@ -974,7 +982,8 @@ picflag_from_initializer (tree init)
|
||||
which describe the initializers. */
|
||||
|
||||
static int
|
||||
process_init_constructor_array (tree type, tree init)
|
||||
process_init_constructor_array (tree type, tree init,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
unsigned HOST_WIDE_INT i, len = 0;
|
||||
int flags = 0;
|
||||
@ -1001,7 +1010,12 @@ process_init_constructor_array (tree type, tree init)
|
||||
|
||||
/* There must not be more initializers than needed. */
|
||||
if (!unbounded && VEC_length (constructor_elt, v) > len)
|
||||
error ("too many initializers for %qT", type);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("too many initializers for %qT", type);
|
||||
else
|
||||
return PICFLAG_ERRONEOUS;
|
||||
}
|
||||
|
||||
FOR_EACH_VEC_ELT (constructor_elt, v, i, ce)
|
||||
{
|
||||
@ -1017,7 +1031,8 @@ process_init_constructor_array (tree type, tree init)
|
||||
else
|
||||
ce->index = size_int (i);
|
||||
gcc_assert (ce->value);
|
||||
ce->value = digest_init_r (TREE_TYPE (type), ce->value, true, LOOKUP_IMPLICIT);
|
||||
ce->value = digest_init_r (TREE_TYPE (type), ce->value, true,
|
||||
LOOKUP_IMPLICIT, complain);
|
||||
|
||||
if (ce->value != error_mark_node)
|
||||
gcc_assert (same_type_ignoring_top_level_qualifiers_p
|
||||
@ -1041,10 +1056,10 @@ process_init_constructor_array (tree type, tree init)
|
||||
one up; if it's an array, recurse. */
|
||||
if (MAYBE_CLASS_TYPE_P (TREE_TYPE (type)))
|
||||
next = build_functional_cast (TREE_TYPE (type), NULL_TREE,
|
||||
tf_warning_or_error);
|
||||
complain);
|
||||
else
|
||||
next = build_constructor (init_list_type_node, NULL);
|
||||
next = digest_init (TREE_TYPE (type), next);
|
||||
next = digest_init (TREE_TYPE (type), next, complain);
|
||||
}
|
||||
else if (!zero_init_p (TREE_TYPE (type)))
|
||||
next = build_zero_init (TREE_TYPE (type),
|
||||
@ -1068,7 +1083,8 @@ process_init_constructor_array (tree type, tree init)
|
||||
the initializers. */
|
||||
|
||||
static int
|
||||
process_init_constructor_record (tree type, tree init)
|
||||
process_init_constructor_record (tree type, tree init,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
VEC(constructor_elt,gc) *v = NULL;
|
||||
int flags = 0;
|
||||
@ -1124,7 +1140,8 @@ process_init_constructor_record (tree type, tree init)
|
||||
}
|
||||
|
||||
gcc_assert (ce->value);
|
||||
next = digest_init_r (type, ce->value, true, LOOKUP_IMPLICIT);
|
||||
next = digest_init_r (type, ce->value, true,
|
||||
LOOKUP_IMPLICIT, complain);
|
||||
++idx;
|
||||
}
|
||||
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
|
||||
@ -1137,14 +1154,15 @@ process_init_constructor_record (tree type, tree init)
|
||||
if (MAYBE_CLASS_TYPE_P (TREE_TYPE (field)))
|
||||
{
|
||||
next = finish_compound_literal (TREE_TYPE (field), next,
|
||||
tf_warning_or_error);
|
||||
complain);
|
||||
/* direct-initialize the target. No temporary is going
|
||||
to be involved. */
|
||||
if (TREE_CODE (next) == TARGET_EXPR)
|
||||
TARGET_EXPR_DIRECT_INIT_P (next) = true;
|
||||
}
|
||||
|
||||
next = digest_init_r (TREE_TYPE (field), next, true, LOOKUP_IMPLICIT);
|
||||
next = digest_init_r (TREE_TYPE (field), next, true,
|
||||
LOOKUP_IMPLICIT, complain);
|
||||
|
||||
/* Warn when some struct elements are implicitly initialized. */
|
||||
warning (OPT_Wmissing_field_initializers,
|
||||
@ -1153,11 +1171,26 @@ process_init_constructor_record (tree type, tree init)
|
||||
else
|
||||
{
|
||||
if (TREE_READONLY (field))
|
||||
error ("uninitialized const member %qD", field);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("uninitialized const member %qD", field);
|
||||
else
|
||||
return PICFLAG_ERRONEOUS;
|
||||
}
|
||||
else if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field)))
|
||||
error ("member %qD with uninitialized const fields", field);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("member %qD with uninitialized const fields", field);
|
||||
else
|
||||
return PICFLAG_ERRONEOUS;
|
||||
}
|
||||
else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
|
||||
error ("member %qD is uninitialized reference", field);
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("member %qD is uninitialized reference", field);
|
||||
else
|
||||
return PICFLAG_ERRONEOUS;
|
||||
}
|
||||
|
||||
/* Warn when some struct elements are implicitly initialized
|
||||
to zero. */
|
||||
@ -1181,8 +1214,13 @@ process_init_constructor_record (tree type, tree init)
|
||||
}
|
||||
|
||||
if (idx < VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init)))
|
||||
error ("too many initializers for %qT", type);
|
||||
|
||||
{
|
||||
if (complain & tf_error)
|
||||
error ("too many initializers for %qT", type);
|
||||
else
|
||||
return PICFLAG_ERRONEOUS;
|
||||
}
|
||||
|
||||
CONSTRUCTOR_ELTS (init) = v;
|
||||
return flags;
|
||||
}
|
||||
@ -1192,7 +1230,8 @@ process_init_constructor_record (tree type, tree init)
|
||||
which describe the initializer. */
|
||||
|
||||
static int
|
||||
process_init_constructor_union (tree type, tree init)
|
||||
process_init_constructor_union (tree type, tree init,
|
||||
tsubst_flags_t complain)
|
||||
{
|
||||
constructor_elt *ce;
|
||||
int len;
|
||||
@ -1204,6 +1243,8 @@ process_init_constructor_union (tree type, tree init)
|
||||
len = VEC_length (constructor_elt, CONSTRUCTOR_ELTS (init));
|
||||
if (len > 1)
|
||||
{
|
||||
if (!(complain & tf_error))
|
||||
return PICFLAG_ERRONEOUS;
|
||||
error ("too many initializers for %qT", type);
|
||||
VEC_block_remove (constructor_elt, CONSTRUCTOR_ELTS (init), 1, len-1);
|
||||
}
|
||||
@ -1225,7 +1266,9 @@ process_init_constructor_union (tree type, tree init)
|
||||
break;
|
||||
if (!field)
|
||||
{
|
||||
error ("no field %qD found in union being initialized", field);
|
||||
if (complain & tf_error)
|
||||
error ("no field %qD found in union being initialized",
|
||||
field);
|
||||
ce->value = error_mark_node;
|
||||
}
|
||||
ce->index = field;
|
||||
@ -1234,7 +1277,8 @@ process_init_constructor_union (tree type, tree init)
|
||||
{
|
||||
gcc_assert (TREE_CODE (ce->index) == INTEGER_CST
|
||||
|| TREE_CODE (ce->index) == RANGE_EXPR);
|
||||
error ("index value instead of field name in union initializer");
|
||||
if (complain & tf_error)
|
||||
error ("index value instead of field name in union initializer");
|
||||
ce->value = error_mark_node;
|
||||
}
|
||||
}
|
||||
@ -1247,14 +1291,16 @@ process_init_constructor_union (tree type, tree init)
|
||||
field = TREE_CHAIN (field);
|
||||
if (field == NULL_TREE)
|
||||
{
|
||||
error ("too many initializers for %qT", type);
|
||||
if (complain & tf_error)
|
||||
error ("too many initializers for %qT", type);
|
||||
ce->value = error_mark_node;
|
||||
}
|
||||
ce->index = field;
|
||||
}
|
||||
|
||||
if (ce->value && ce->value != error_mark_node)
|
||||
ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value, true, LOOKUP_IMPLICIT);
|
||||
ce->value = digest_init_r (TREE_TYPE (ce->index), ce->value,
|
||||
true, LOOKUP_IMPLICIT, complain);
|
||||
|
||||
return picflag_from_initializer (ce->value);
|
||||
}
|
||||
@ -1274,18 +1320,18 @@ process_init_constructor_union (tree type, tree init)
|
||||
of error. */
|
||||
|
||||
static tree
|
||||
process_init_constructor (tree type, tree init)
|
||||
process_init_constructor (tree type, tree init, tsubst_flags_t complain)
|
||||
{
|
||||
int flags;
|
||||
|
||||
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
|
||||
|
||||
if (TREE_CODE (type) == ARRAY_TYPE || TREE_CODE (type) == VECTOR_TYPE)
|
||||
flags = process_init_constructor_array (type, init);
|
||||
flags = process_init_constructor_array (type, init, complain);
|
||||
else if (TREE_CODE (type) == RECORD_TYPE)
|
||||
flags = process_init_constructor_record (type, init);
|
||||
flags = process_init_constructor_record (type, init, complain);
|
||||
else if (TREE_CODE (type) == UNION_TYPE)
|
||||
flags = process_init_constructor_union (type, init);
|
||||
flags = process_init_constructor_union (type, init, complain);
|
||||
else
|
||||
gcc_unreachable ();
|
||||
|
||||
|
@ -1,3 +1,10 @@
|
||||
2011-05-09 Paolo Carlini <paolo.carlini@oracle.com>
|
||||
|
||||
PR c++/48737
|
||||
PR c++/48744
|
||||
* g++.dg/template/sfinae28.C: New.
|
||||
* g++.dg/template/sfinae29.C: Likewise.
|
||||
|
||||
2011-05-09 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* g++.dg/template/nontype23.C: New.
|
||||
|
13
gcc/testsuite/g++.dg/template/sfinae28.C
Normal file
13
gcc/testsuite/g++.dg/template/sfinae28.C
Normal file
@ -0,0 +1,13 @@
|
||||
// PR c++/48737
|
||||
// { dg-options "-std=c++0x" }
|
||||
|
||||
template<class T>
|
||||
T&& create();
|
||||
|
||||
template<class T, class... Args>
|
||||
decltype(T{create<Args>()...}, char()) f(int);
|
||||
|
||||
template<class, class...>
|
||||
char (&f(...))[2];
|
||||
|
||||
static_assert(sizeof(f<int[1], int, int>(0)) != 1, "Error");
|
23
gcc/testsuite/g++.dg/template/sfinae29.C
Normal file
23
gcc/testsuite/g++.dg/template/sfinae29.C
Normal file
@ -0,0 +1,23 @@
|
||||
// PR c++/48744
|
||||
// { dg-options "-std=c++0x" }
|
||||
|
||||
template<class T>
|
||||
struct add_rval_ref {
|
||||
typedef T&& type;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct add_rval_ref<void> {
|
||||
typedef void type;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
typename add_rval_ref<T>::type create();
|
||||
|
||||
template<class T, class Arg>
|
||||
decltype(T{create<Arg>()}, char()) f(int);
|
||||
|
||||
template<class, class>
|
||||
char (&f(...))[2];
|
||||
|
||||
static_assert(sizeof(f<int, void>(0)) != 1, "Error");
|
Loading…
x
Reference in New Issue
Block a user