aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/typeck2.c
diff options
context:
space:
mode:
authorPaolo Carlini <paolo.carlini@oracle.com>2011-05-09 19:24:50 +0000
committerPaolo Carlini <paolo@gcc.gnu.org>2011-05-09 19:24:50 +0000
commit754af126c04251c045d99b808915d9fde11de8a5 (patch)
tree1c5d88069cb3be67ae847b2bf84b28808589d61f /gcc/cp/typeck2.c
parente4c0337862a3d76255d4ad7be49b4435910ede1e (diff)
downloadgcc-754af126c04251c045d99b808915d9fde11de8a5.zip
gcc-754af126c04251c045d99b808915d9fde11de8a5.tar.gz
gcc-754af126c04251c045d99b808915d9fde11de8a5.tar.bz2
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
Diffstat (limited to 'gcc/cp/typeck2.c')
-rw-r--r--gcc/cp/typeck2.c128
1 files changed, 87 insertions, 41 deletions
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index aec54f9..ec6b5d3 100644
--- a/gcc/cp/typeck2.c
+++ b/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 ();