public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).