This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH, c++] Emit the diagnostic messages of convert_to_void


On 06/17/2010 05:45 PM, Shujing Zhao wrote:
On 06/17/2010 04:47 PM, Shujing Zhao wrote:
On 06/17/2010 04:19 PM, Shujing Zhao wrote:
Hi,

This patch is to fix the diagnostic issues of function convert_to_void, just like the previous one.
Tested on i686-pc-linux-gnu with no regression.
Is it ok for trunk?


Thanks
Pearly

Sorry, send the wrong patch.

Sorry, the attached patch is the right one.



I'm so sorry to send the patch again and again.



Index: typeck.c
===================================================================
--- typeck.c	(revision 160871)
+++ typeck.c	(working copy)
@@ -5589,7 +5589,7 @@
 tree
 cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain)
 {
-  lhs = convert_to_void (lhs, "left-hand operand of comma", complain);
+  lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain);
 
   if (lhs == error_mark_node || rhs == error_mark_node)
     return error_mark_node;
@@ -5856,7 +5856,7 @@
 
      Any expression can be explicitly converted to type cv void.  */
   if (TREE_CODE (type) == VOID_TYPE)
-    return convert_to_void (expr, /*implicit=*/NULL, complain);
+    return convert_to_void (expr, ICV_NULL, complain);
 
   /* [expr.static.cast]
 
Index: init.c
===================================================================
--- init.c	(revision 160871)
+++ init.c	(working copy)
@@ -1375,7 +1375,7 @@
     release_tree_vector (parms);
 
   if (TREE_SIDE_EFFECTS (rval))
-    finish_expr_stmt (convert_to_void (rval, NULL, complain));
+    finish_expr_stmt (convert_to_void (rval, ICV_NULL, complain));
 }
 
 /* This function is responsible for initializing EXP with INIT
@@ -2718,7 +2718,7 @@
     /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR.  */
     body = build2 (COMPOUND_EXPR, void_type_node, base, body);
 
-  return convert_to_void (body, /*implicit=*/NULL, tf_warning_or_error);
+  return convert_to_void (body, ICV_NULL, tf_warning_or_error);
 }
 
 /* Create an unnamed variable of the indicated TYPE.  */
Index: semantics.c
===================================================================
--- semantics.c	(revision 160871)
+++ semantics.c	(working copy)
@@ -608,10 +608,10 @@
 	{
 	  if (warn_sequence_point)
 	    verify_sequence_points (expr);
-	  expr = convert_to_void (expr, "statement", tf_warning_or_error);
+	  expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error);
 	}
       else if (!type_dependent_expression_p (expr))
-	convert_to_void (build_non_dependent_expr (expr), "statement", 
+	convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, 
                          tf_warning_or_error);
 
       if (check_for_bare_parameter_packs (expr))
@@ -869,11 +869,11 @@
     {
       if (warn_sequence_point)
 	verify_sequence_points (expr);
-      expr = convert_to_void (expr, "3rd expression in for",
+      expr = convert_to_void (expr, ICV_THIRD_IN_FOR,
                               tf_warning_or_error);
     }
   else if (!type_dependent_expression_p (expr))
-    convert_to_void (build_non_dependent_expr (expr), "3rd expression in for",
+    convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR,
                      tf_warning_or_error);
   expr = maybe_cleanup_point_expr_void (expr);
   if (check_for_bare_parameter_packs (expr))
Index: cvt.c
===================================================================
--- cvt.c	(revision 160871)
+++ cvt.c	(working copy)
@@ -651,7 +651,7 @@
 
   if (code == VOID_TYPE && (convtype & CONV_STATIC))
     {
-      e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error);
+      e = convert_to_void (e, ICV_NULL, tf_warning_or_error);
       return e;
     }
 
@@ -814,19 +814,18 @@
    make it impossible to ignore the reference return value from functions. We
    issue warnings in the confusing cases.
 
-   IMPLICIT is non-NULL iff an expression is being implicitly converted; it
-   is NULL when the user is explicitly converting an expression to void via
-   a cast.  When non-NULL, IMPLICIT is a string indicating the context of
-   the implicit conversion.  */
+   The IMPLICIT is ICV_NULL when the user is explicitly converting an expression
+   to void via a cast. If an expression is being implicitly converted, IMPLICIT
+   indicates the context of the implicit conversion.  */
 
 tree
-convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain)
+convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain)
 {
   if (expr == error_mark_node
       || TREE_TYPE (expr) == error_mark_node)
     return error_mark_node;
 
-  if (implicit == NULL)
+  if (implicit == ICV_NULL)
     mark_exp_read (expr);
   else
     {
@@ -865,12 +864,17 @@
 	tree op1 = TREE_OPERAND (expr,1);
 	tree op2 = TREE_OPERAND (expr,2);
 	bool side_effects = TREE_SIDE_EFFECTS (op1) || TREE_SIDE_EFFECTS (op2);
-	tree new_op1 = convert_to_void
-	  (op1, (implicit && !side_effects
-		 ? "second operand of conditional" : NULL), complain);
-	tree new_op2 = convert_to_void
-	  (op2, (implicit && !side_effects
-		 ? "third operand of conditional" : NULL), complain);
+	tree new_op1, new_op2;
+	if (implicit != ICV_NULL && !side_effects)
+	  {
+	    new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain);
+	    new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain);
+	  }
+	else
+	  {
+	    new_op1 = convert_to_void (op1, ICV_NULL, complain);
+	    new_op2 = convert_to_void (op2, ICV_NULL, complain);
+	  }
 
 	expr = build3 (COND_EXPR, TREE_TYPE (new_op1),
 		       TREE_OPERAND (expr, 0), new_op1, new_op2);
@@ -881,9 +885,11 @@
       {
 	/* The second part of a compound expr contains the value.  */
 	tree op1 = TREE_OPERAND (expr,1);
-	tree new_op1 = convert_to_void
-	  (op1, (implicit && !TREE_NO_WARNING (expr)
-		 ? "right-hand operand of comma" : NULL), complain);
+	tree new_op1;
+	if (implicit != ICV_NULL && !TREE_NO_WARNING (expr))
+	  new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain);
+	else
+	  new_op1 = convert_to_void (op1, ICV_NULL, complain);
 
 	if (new_op1 != op1)
 	  {
@@ -915,17 +921,88 @@
 	if (is_volatile && !is_complete)
           {
             if (complain & tf_warning)
-              warning (0, "object of incomplete type %qT will not be accessed in %s",
-                       type, implicit ? implicit : "void context");
+	      switch (implicit)
+		{
+	      	  case ICV_NULL:
+		    warning (0, "object of incomplete type %qT will not "
+			    	"be accessed in void context", type);
+		    break;
+		  case ICV_SECOND_OF_COND:
+		    warning (0, "object of incomplete type %qT will not "
+		    		"be accessed in second operand of conditional",
+			     type);
+		    break;
+		  case ICV_THIRD_OF_COND:
+		    warning (0, "object of incomplete type %qT will not "
+		  	      	"be accessed in third operand of conditional",
+			     type);
+		    break;
+		  case ICV_RIGHT_OF_COMMA:
+		    warning (0, "object of incomplete type %qT will not "
+		    		"be accessed in right-hand operand of comma",
+			     type);
+		    break;
+		  case ICV_LEFT_OF_COMMA:
+		    warning (0, "object of incomplete type %qT will not "
+		    		"be accessed in left-hand operand of comma",
+			     type);
+		    break;
+		  case ICV_STATEMENT:
+		     warning (0, "object of incomplete type %qT will not "
+		     		 "be accessed in statement",  type);
+		     break;
+		  case ICV_THIRD_IN_FOR:
+		    warning (0, "object of incomplete type %qT will not "
+		    		"be accessed in 3rd expression in for ",
+			     type);
+		    break;
+		  default:
+		    gcc_unreachable ();
+		}
           }
 	/* Don't load the value if this is an implicit dereference, or if
 	   the type needs to be handled by ctors/dtors.  */
 	else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type)))
           {
             if (complain & tf_warning)
-              warning (0, "object of type %qT will not be accessed in %s",
-                       TREE_TYPE (TREE_OPERAND (expr, 0)),
-                       implicit ? implicit : "void context");
+	      switch (implicit)
+		{
+	      	  case ICV_NULL:
+		    warning (0, "object of type %qT will not "
+			    	"be accessed in void context", type);
+		    break;
+		  case ICV_SECOND_OF_COND:
+		    warning (0, "object of type %qT will not "
+		    		"be accessed in second operand of conditional",
+			     type);
+		    break;
+		  case ICV_THIRD_OF_COND:
+		    warning (0, "object of type %qT will not "
+		  	      	"be accessed in third operand of conditional",
+			     type);
+		    break;
+		  case ICV_RIGHT_OF_COMMA:
+		    warning (0, "object of type %qT will not "
+		    		"be accessed in right-hand operand of comma",
+			     type);
+		    break;
+		  case ICV_LEFT_OF_COMMA:
+		    warning (0, "object of type %qT will not "
+		    		"be accessed in left-hand operand of comma",
+			     type);
+		    break;
+		  case ICV_STATEMENT:
+		     warning (0, "object of type %qT will not "
+		     		 "be accessed in statement",  type);
+		     break;
+		  case ICV_THIRD_IN_FOR:
+		    warning (0, "object of type %qT will not "
+		    		"be accessed in 3rd expression in for ",
+			     type);
+		    break;
+		  default:
+		    gcc_unreachable ();
+		}
           }
 	if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type))
           {
@@ -936,7 +1013,7 @@
                - automatic dereferencing of references, since the user cannot
                  control it. (See also warn_if_unused_value() in stmt.c.)  */
             if (warn_unused_value
-		&& implicit
+		&& implicit != ICV_NULL
                 && (complain & tf_warning)
                 && !TREE_NO_WARNING (expr)
                 && !is_reference)
@@ -954,8 +1031,45 @@
 	int is_complete = COMPLETE_TYPE_P (complete_type (type));
 
 	if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning))
-	  warning (0, "object %qE of incomplete type %qT will not be accessed in %s",
-		   expr, type, implicit ? implicit : "void context");
+	  switch (implicit)
+	    {
+	      case ICV_NULL:
+		warning (0, "object %qE of incomplete type %qT will not "
+			    "be accessed in void context", expr, type);
+		break;
+	      case ICV_SECOND_OF_COND:
+	        warning (0, "object %qE of incomplete type %qT will not "
+			    "be accessed in second operand of conditional",
+			 expr, type);
+		break;
+	      case ICV_THIRD_OF_COND:
+	        warning (0, "object %qE of incomplete type %qT will not "
+			    "be accessed in third operand of conditional",
+			 expr, type);
+		break;
+	      case ICV_RIGHT_OF_COMMA:
+	        warning (0, "object %qE of incomplete type %qT will not "
+			    "be accessed in right-hand operand of comma",
+			 expr, type);
+		break;
+	      case ICV_LEFT_OF_COMMA:
+	        warning (0, "object %qE of incomplete type %qT will not "
+			    "be accessed in left-hand operand of comma",
+			 expr, type);
+		break;
+	      case ICV_STATEMENT:
+	        warning (0, "object %qE of incomplete type %qT will not "
+		            "be accessed in statement", expr, type);
+		break;
+	      case ICV_THIRD_IN_FOR:
+	        warning (0, "object %qE of incomplete type %qT will not "
+			    "be accessed in 3rd expression in for ",
+		         expr, type);
+		break;
+	      default:
+	        gcc_unreachable ();
+	    }
+
 	break;
       }
 
@@ -994,18 +1108,81 @@
 	/* [over.over] enumerates the places where we can take the address
 	   of an overloaded function, and this is not one of them.  */
 	if (complain & tf_error)
-	  error ("%s cannot resolve address of overloaded function",
-		 implicit ? implicit : "void cast");
+	  switch (implicit)
+	    {
+	      case ICV_NULL:
+		error ("void cast "
+		       "cannot resolve address of overloaded function");
+		break;
+	      case ICV_SECOND_OF_COND:
+		error ("second operand of conditional "
+		       "cannot resolve address of overloaded function");
+		break;
+	      case ICV_THIRD_OF_COND:
+		error ("third operand of conditional "
+		       "cannot resolve address of overloaded function");
+		break;
+	      case ICV_RIGHT_OF_COMMA:
+		error ("right-hand operand of comma "
+		       "cannot resolve address of overloaded function");
+		break;
+	      case ICV_LEFT_OF_COMMA:
+		error ("left-hand operand of comma "
+		       "cannot resolve address of overloaded function");
+		break;
+	      case ICV_STATEMENT:
+		error ("statement "
+		       "cannot resolve address of overloaded function");
+		break;
+	      case ICV_THIRD_IN_FOR:
+		error ("3rd expression in for "
+		       "cannot resolve address of overloaded function");
+		break;
+	    }
 	else
 	  return error_mark_node;
 	expr = void_zero_node;
       }
-    else if (implicit && probe == expr && is_overloaded_fn (probe))
+    else if (implicit != ICV_NULL && probe == expr && is_overloaded_fn (probe))
       {
 	/* Only warn when there is no &.  */
 	if (complain & tf_warning)
-	  warning (OPT_Waddress, "%s is a reference, not call, to function %qE",
-		   implicit, expr);
+	  switch (implicit)
+	    {
+	      case ICV_SECOND_OF_COND:
+	        warning (OPT_Waddress,
+			 "second operand of conditional "
+			 "is a reference, not call, to function %qE", expr);
+		break;
+	      case ICV_THIRD_OF_COND:
+	        warning (OPT_Waddress,
+			 "third operand of conditional "
+			 "is a reference, not call, to function %qE", expr);
+		break;
+	      case ICV_RIGHT_OF_COMMA:
+	        warning (OPT_Waddress,
+			 "right-hand operand of comma "
+			 "is a reference, not call, to function %qE", expr);
+		break;
+	      case ICV_LEFT_OF_COMMA:
+	        warning (OPT_Waddress,
+			 "left-hand operand of comma "
+			 "is a reference, not call, to function %qE", expr);
+		break;
+	      case ICV_STATEMENT:
+	        warning (OPT_Waddress,
+			 "statement "
+			 "is a reference, not call, to function %qE", expr);
+		break;
+	      case ICV_THIRD_IN_FOR:
+	        warning (OPT_Waddress,
+			 "3rd expression in for "
+			 "is a reference, not call, to function %qE", expr);
+		break;
+	      default:
+	        gcc_unreachable ();
+	    }
+
 	if (TREE_CODE (expr) == COMPONENT_REF)
 	  expr = TREE_OPERAND (expr, 0);
       }
@@ -1013,7 +1190,7 @@
 
   if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
     {
-      if (implicit
+      if (implicit != ICV_NULL
 	  && warn_unused_value
 	  && !TREE_NO_WARNING (expr)
 	  && !processing_template_decl)
@@ -1022,7 +1199,35 @@
 	     been explicitly cast to void, so we must do so here.  */
 	  if (!TREE_SIDE_EFFECTS (expr)) {
             if (complain & tf_warning)
-              warning (OPT_Wunused_value, "%s has no effect", implicit);
+	      switch (implicit)
+		{
+		  case ICV_SECOND_OF_COND:
+		    warning (OPT_Wunused_value,
+			     "second operand of conditional has no effect");
+		    break;
+		  case ICV_THIRD_OF_COND:
+		    warning (OPT_Wunused_value,
+		    	     "third operand of conditional has no effect");
+		    break;
+		  case ICV_RIGHT_OF_COMMA:
+		    warning (OPT_Wunused_value,
+		    	     "right-hand operand of comma has no effect");
+		    break;
+		  case ICV_LEFT_OF_COMMA:
+		    warning (OPT_Wunused_value,
+		    	     "left-hand operand of comma has no effect");
+		    break;
+		  case ICV_STATEMENT:
+		    warning (OPT_Wunused_value,
+		    	     "statement has no effect");
+		    break;
+		  case ICV_THIRD_IN_FOR:
+		    warning (OPT_Wunused_value,
+		    	     "3rd expression in for has no effect");
+		    break;
+		  default:
+		    gcc_unreachable ();
+		}
           }
 	  else
 	    {
Index: cp-tree.h
===================================================================
--- cp-tree.h	(revision 160871)
+++ cp-tree.h	(working copy)
@@ -435,6 +435,17 @@
   ICR_ASSIGN            /* assignment */
 } impl_conv_rhs;
 
+/* Possible cases of implicit or explicit bad conversions to void. */
+typedef enum impl_conv_void {
+  ICV_NULL,		/* NULL */
+  ICV_SECOND_OF_COND,	/* second operand of conditional */
+  ICV_THIRD_OF_COND,	/* third operand of conditional */
+  ICV_RIGHT_OF_COMMA,	/* right-hand operand of comma */
+  ICV_LEFT_OF_COMMA,	/* left-hand operand of comma */
+  ICV_STATEMENT,	/* statement */
+  ICV_THIRD_IN_FOR	/* 3rd expression in for */
+} impl_conv_void;
+
 /* Macros for access to language-specific slots in an identifier.  */
 
 #define IDENTIFIER_NAMESPACE_BINDINGS(NODE)	\
@@ -4669,8 +4680,8 @@
 extern tree cp_convert				(tree, tree);
 extern tree cp_convert_and_check                (tree, tree);
 extern tree cp_fold_convert			(tree, tree);
-extern tree convert_to_void	(tree, const char */*implicit context*/,
-                                 tsubst_flags_t);
+extern tree convert_to_void			(tree, impl_conv_void,
+						 tsubst_flags_t);
 extern tree convert_force			(tree, tree, int);
 extern tree build_expr_type_conversion		(int, tree, bool);
 extern tree type_promotes_to			(tree);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]