* [C++ Patch] PRs 48737 & 48744
@ 2011-05-08 22:53 Paolo Carlini
2011-05-09 9:31 ` Jason Merrill
0 siblings, 1 reply; 4+ messages in thread
From: Paolo Carlini @ 2011-05-08 22:53 UTC (permalink / raw)
To: gcc-patches; +Cc: Jason Merrill
[-- Attachment #1: Type: text/plain, Size: 606 bytes --]
Hi,
as far as I can see this is just another case where we want to pass down
more consistently the complain argument in order to avoid hard errors in
sfinae contexts. In particular, we don't want hard errors from
reshape_init itself (in order to fix 48737) and we want digest_init_r to
forward complain to convert_for_initialization (to fix 48744). This
requires some small adjustments elsewhere, not too much, in particular,
earlier, finish_compound_literal forwards its complain argument to
reshape_init and digest_init.
Tested x86_64-linux. Ok for mainline?
Thanks,
Paolo.
//////////////////
[-- Attachment #2: CL_48737_48744 --]
[-- Type: text/plain, Size: 969 bytes --]
/cp
2011-05-08 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): 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):
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-08 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/48737
PR c++/48744
* g++.dg/template/sfinae28.C: New.
* g++.dg/template/sfinae29.C: Likewise.
[-- Attachment #3: patch_48737_48744 --]
[-- Type: text/plain, Size: 11133 bytes --]
Index: testsuite/g++.dg/template/sfinae28.C
===================================================================
--- testsuite/g++.dg/template/sfinae28.C (revision 0)
+++ testsuite/g++.dg/template/sfinae28.C (revision 0)
@@ -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");
Index: testsuite/g++.dg/template/sfinae29.C
===================================================================
--- testsuite/g++.dg/template/sfinae29.C (revision 0)
+++ testsuite/g++.dg/template/sfinae29.C (revision 0)
@@ -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");
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 173549)
+++ cp/typeck.c (working copy)
@@ -6715,7 +6715,7 @@ cp_build_modify_expr (tree lhs, enum tree_code mod
}
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),
Index: cp/init.c
===================================================================
--- cp/init.c (revision 173549)
+++ cp/init.c (working copy)
@@ -1435,7 +1435,7 @@ expand_default_init (tree binfo, tree true_exp, tr
{
/* 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);
@@ -2375,7 +2375,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type,
"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)
{
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 173549)
+++ cp/decl.c (working copy)
@@ -5203,7 +5203,7 @@ reshape_init_r (tree type, reshape_iter *d, bool f
{
++d->cur;
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
- return reshape_init (type, init);
+ return reshape_init (type, init, tf_warning_or_error);
}
}
@@ -5238,7 +5238,7 @@ reshape_init_r (tree type, reshape_iter *d, bool f
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;
@@ -5264,7 +5264,12 @@ tree
/* 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 +5422,7 @@ check_initializer (tree decl, tree init, int flags
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
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 173549)
+++ cp/typeck2.c (working copy)
@@ -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);
@@ -878,7 +879,7 @@ static tree
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
@@ -932,20 +933,20 @@ static tree
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);
}
\f
/* Set of flags used within process_init_constructor to describe the
@@ -1017,7 +1018,8 @@ process_init_constructor_array (tree type, tree in
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, tf_warning_or_error);
if (ce->value != error_mark_node)
gcc_assert (same_type_ignoring_top_level_qualifiers_p
@@ -1044,7 +1046,7 @@ process_init_constructor_array (tree type, tree in
tf_warning_or_error);
else
next = build_constructor (init_list_type_node, NULL);
- next = digest_init (TREE_TYPE (type), next);
+ next = digest_init (TREE_TYPE (type), next, tf_warning_or_error);
}
else if (!zero_init_p (TREE_TYPE (type)))
next = build_zero_init (TREE_TYPE (type),
@@ -1124,7 +1126,8 @@ process_init_constructor_record (tree type, tree i
}
gcc_assert (ce->value);
- next = digest_init_r (type, ce->value, true, LOOKUP_IMPLICIT);
+ next = digest_init_r (type, ce->value, true,
+ LOOKUP_IMPLICIT, tf_warning_or_error);
++idx;
}
else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field)))
@@ -1144,7 +1147,8 @@ process_init_constructor_record (tree type, tree i
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, tf_warning_or_error);
/* Warn when some struct elements are implicitly initialized. */
warning (OPT_Wmissing_field_initializers,
@@ -1254,7 +1258,8 @@ process_init_constructor_union (tree type, tree in
}
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, tf_warning_or_error);
return picflag_from_initializer (ce->value);
}
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 173549)
+++ cp/semantics.c (working copy)
@@ -2369,7 +2369,7 @@ finish_compound_literal (tree type, tree compound_
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_
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))
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 173549)
+++ cp/decl2.c (working copy)
@@ -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))
Index: cp/call.c
===================================================================
--- cp/call.c (revision 173549)
+++ cp/call.c (working copy)
@@ -5670,7 +5670,7 @@ convert_like_real (conversion *convs, tree expr, t
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,
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);
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 173549)
+++ cp/cp-tree.h (working copy)
@@ -4875,7 +4875,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;
@@ -5641,7 +5641,7 @@ extern int abstract_virtuals_error_sfinae (tree, 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);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [C++ Patch] PRs 48737 & 48744
2011-05-08 22:53 [C++ Patch] PRs 48737 & 48744 Paolo Carlini
@ 2011-05-09 9:31 ` Jason Merrill
2011-05-09 13:05 ` Paolo Carlini
0 siblings, 1 reply; 4+ messages in thread
From: Jason Merrill @ 2011-05-09 9:31 UTC (permalink / raw)
To: Paolo Carlini; +Cc: gcc-patches
On 05/08/2011 12:51 PM, Paolo Carlini wrote:
> @@ -5203,7 +5203,7 @@ reshape_init_r (tree type, reshape_iter *d, bool f
> {
> ++d->cur;
> gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
> - return reshape_init (type, init);
> + return reshape_init (type, init, tf_warning_or_error);
Any reason not to SFINAEify reshape_init_r as well? Same question for
process_init_constructor*.
Jason
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [C++ Patch] PRs 48737 & 48744
2011-05-09 9:31 ` Jason Merrill
@ 2011-05-09 13:05 ` Paolo Carlini
2011-05-09 18:44 ` Jason Merrill
0 siblings, 1 reply; 4+ messages in thread
From: Paolo Carlini @ 2011-05-09 13:05 UTC (permalink / raw)
To: Jason Merrill; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 1112 bytes --]
Hi,
> On 05/08/2011 12:51 PM, Paolo Carlini wrote:
>> @@ -5203,7 +5203,7 @@ reshape_init_r (tree type, reshape_iter *d, bool f
>> {
>> ++d->cur;
>> gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
>> - return reshape_init (type, init);
>> + return reshape_init (type, init, tf_warning_or_error);
> Any reason not to SFINAEify reshape_init_r as well? Same question for
> process_init_constructor*.
No reason, really, in the first try I simply did the minimal set of
changes fixing the reported issues. In the second try below I'm
consistently changing all those functions too, everything seems fine,
regtests ok on x86_64-linux. The only minimally non-trivial bits are the
uses of PICFLAG_ERRONEOUS as a sort of error_mark_node in some
process_init_constructor_* functions. I didn't invent that, anyway, and
should work fine because first thing after calling those functions
process_init_constructor checks the return value for PICFLAG_ERRONEOUS
and in case transforms it to error_mark_node and bails out.
Ok?
Thanks,
Paolo.
////////////////////////
[-- Attachment #2: CL_48737_48744_2 --]
[-- Type: text/plain, Size: 1095 bytes --]
/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.
[-- Attachment #3: patch_48737_48744_2 --]
[-- Type: text/plain, Size: 24476 bytes --]
Index: testsuite/g++.dg/template/sfinae28.C
===================================================================
--- testsuite/g++.dg/template/sfinae28.C (revision 0)
+++ testsuite/g++.dg/template/sfinae28.C (revision 0)
@@ -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");
Index: testsuite/g++.dg/template/sfinae29.C
===================================================================
--- testsuite/g++.dg/template/sfinae29.C (revision 0)
+++ testsuite/g++.dg/template/sfinae29.C (revision 0)
@@ -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");
Index: cp/typeck.c
===================================================================
--- cp/typeck.c (revision 173561)
+++ cp/typeck.c (working copy)
@@ -6715,7 +6715,7 @@ cp_build_modify_expr (tree lhs, enum tree_code mod
}
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),
Index: cp/init.c
===================================================================
--- cp/init.c (revision 173561)
+++ cp/init.c (working copy)
@@ -1435,7 +1435,7 @@ expand_default_init (tree binfo, tree true_exp, tr
{
/* 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);
@@ -2375,7 +2375,7 @@ build_new_1 (VEC(tree,gc) **placement, tree type,
"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)
{
Index: cp/decl.c
===================================================================
--- cp/decl.c (revision 173561)
+++ cp/decl.c (working copy)
@@ -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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
{
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 @@ static tree
{
++d->cur;
gcc_assert (BRACE_ENCLOSED_INITIALIZER_P (init));
- return reshape_init (type, init);
+ return reshape_init (type, init, complain);
}
}
@@ -5213,11 +5226,11 @@ static tree
/* 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 @@ static tree
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 @@ tree
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
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
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c (revision 173561)
+++ cp/typeck2.c (working copy)
@@ -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 @@ static tree
{
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 @@ static tree
{
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 @@ static tree
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 @@ static tree
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 @@ static tree
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 @@ static tree
(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);
}
\f
/* 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 @@ static int
/* 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 @@ static int
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 @@ static int
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 @@ static int
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 @@ static int
}
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 @@ static int
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 @@ static int
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 @@ static int
}
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 @@ static int
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 @@ static int
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 @@ static int
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 @@ static int
{
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 @@ static int
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 @@ static int
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 ();
Index: cp/semantics.c
===================================================================
--- cp/semantics.c (revision 173561)
+++ cp/semantics.c (working copy)
@@ -2369,7 +2369,7 @@ finish_compound_literal (tree type, tree compound_
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_
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))
Index: cp/decl2.c
===================================================================
--- cp/decl2.c (revision 173561)
+++ cp/decl2.c (working copy)
@@ -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))
Index: cp/call.c
===================================================================
--- cp/call.c (revision 173561)
+++ cp/call.c (working copy)
@@ -5670,7 +5670,7 @@ convert_like_real (conversion *convs, tree expr, t
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,
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);
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h (revision 173561)
+++ cp/cp-tree.h (working copy)
@@ -4875,7 +4875,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;
@@ -5641,7 +5641,7 @@ extern int abstract_virtuals_error_sfinae (tree, 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);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [C++ Patch] PRs 48737 & 48744
2011-05-09 13:05 ` Paolo Carlini
@ 2011-05-09 18:44 ` Jason Merrill
0 siblings, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2011-05-09 18:44 UTC (permalink / raw)
To: Paolo Carlini; +Cc: gcc-patches
OK, thanks.
Jason
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2011-05-09 17:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-08 22:53 [C++ Patch] PRs 48737 & 48744 Paolo Carlini
2011-05-09 9:31 ` Jason Merrill
2011-05-09 13:05 ` Paolo Carlini
2011-05-09 18:44 ` Jason Merrill
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).