[C PATCH] Improve locinfo in the C FE (PR c/59940)

Marek Polacek polacek@redhat.com
Wed Jan 29 19:41:00 GMT 2014


Finally I managed to get this patch into regression-free shape.  It
should improve the column info for quite a lot of warnings, fixing
PR59940 on the way.  I had to add location_t to bunch of functions;
SET_EXPR_LOCATION is of no use here - we're dealing with
{VAR,PARM}_DECLs, which do not carry a locus info.  Yet the function
parameters are often called expr...
I had to use expansion_point_location_if_in_system_header to
get this working even with -ftrack-macro-expansion.

Surely there are lots of other spots to fix, but this should be
a step forward.  Interestingly, adding locs here and there sometimes
reminds me of a Whac-A-Mole game.

Regtested/bootstrapped on x86_64-linux, ok for trunk?

2014-01-29  Marek Polacek  <polacek@redhat.com>

	PR c/59940
c-family/
	* c-common.h (unsafe_conversion_p): Adjust declaration.
	(warnings_for_convert_and_check): Likewise.
	(convert_and_check): Likewise.
	* c-common.c (unsafe_conversion_p): Add location parameter.  Call
	expansion_point_location_if_in_system_header on it.
	(warnings_for_convert_and_check): Add location parameter.  Call
	expansion_point_location_if_in_system_header on it.  Use it.
	(convert_and_check): Add location parameter.  Use it.
	(conversion_warning): Likewise.
	(c_add_case_label): Adjust convert_and_check calls.
	(scalar_to_vector): Adjust unsafe_conversion_p calls.
cp/
	* typeck.c (build_ptrmemfunc1): Call convert_and_check with
	input_location.
	* cvt.c (cp_convert_and_check): Call warnings_for_convert_and_check
	with input_location.
	* call.c (build_conditional_expr_1): Call unsafe_conversion_p with
	loc parameter.
c/
	* c-typeck.c (build_function_call_vec): Use loc parameter.
	(convert_arguments): Add location parameter.  Use it.
	(ep_convert_and_check): Likewise.
	(build_atomic_assign): Adjust convert_for_assignment call.
	(build_modify_expr): Likewise.
	(digest_init): Likewise.
	(c_finish_return): Likewise.
	(build_conditional_expr): Adjust ep_convert_and_check calls.
	(convert_for_assignment): Add rhs_loc parameter.  Use it.
	(build_binary_op): Adjust convert_and_check and ep_convert_and_check
	calls.
testsuite/
	* gcc.dg/pr59940.c: New test.
	* gcc.dg/pr35635.c (func3): Move dg-warning.

--- gcc/c-family/c-common.h.mp	2014-01-29 16:32:49.169712645 +0100
+++ gcc/c-family/c-common.h	2014-01-29 16:50:21.980492697 +0100
@@ -749,7 +749,8 @@ extern tree c_common_signed_type (tree);
 extern tree c_common_signed_or_unsigned_type (int, tree);
 extern void c_common_init_ts (void);
 extern tree c_build_bitfield_integer_type (unsigned HOST_WIDE_INT, int);
-extern enum conversion_safety unsafe_conversion_p (tree, tree, bool);
+extern enum conversion_safety unsafe_conversion_p (location_t, tree, tree,
+						   bool);
 extern bool decl_with_nonnull_addr_p (const_tree);
 extern tree c_fully_fold (tree, bool, bool *);
 extern tree decl_constant_value_for_optimization (tree);
@@ -769,8 +770,8 @@ extern bool strict_aliasing_warning (tre
 extern void sizeof_pointer_memaccess_warning (location_t *, tree,
 					      vec<tree, va_gc> *, tree *,
 					      bool (*) (tree, tree));
-extern void warnings_for_convert_and_check (tree, tree, tree);
-extern tree convert_and_check (tree, tree);
+extern void warnings_for_convert_and_check (location_t, tree, tree, tree);
+extern tree convert_and_check (location_t, tree, tree);
 extern void overflow_warning (location_t, tree);
 extern bool warn_if_unused_value (const_tree, location_t);
 extern void warn_logical_operator (location_t, enum tree_code, tree,
--- gcc/c-family/c-common.c.mp	2014-01-29 16:27:45.487493021 +0100
+++ gcc/c-family/c-common.c	2014-01-29 19:04:53.176531941 +0100
@@ -2526,23 +2526,24 @@ shorten_binary_op (tree result_type, tre
   return result_type;
 }
 
-/* Checks if expression EXPR of real/integer type cannot be converted 
+/* Checks if expression EXPR of real/integer type cannot be converted
    to the real/integer type TYPE. Function returns non-zero when:
-	* EXPR is a constant which cannot be exactly converted to TYPE 
-	* EXPR is not a constant and size of EXPR's type > than size of TYPE, 
+	* EXPR is a constant which cannot be exactly converted to TYPE.
+	* EXPR is not a constant and size of EXPR's type > than size of TYPE,
 	  for EXPR type and TYPE being both integers or both real.
-	* EXPR is not a constant of real type and TYPE is an integer.  
-	* EXPR is not a constant of integer type which cannot be 
-	  exactly converted to real type.  
+	* EXPR is not a constant of real type and TYPE is an integer.
+	* EXPR is not a constant of integer type which cannot be
+	  exactly converted to real type.
    Function allows conversions between types of different signedness and
    can return SAFE_CONVERSION (zero) in that case.  Function can produce
    signedness warnings if PRODUCE_WARNS is true.  */
+
 enum conversion_safety
-unsafe_conversion_p (tree type, tree expr, bool produce_warns)
+unsafe_conversion_p (location_t loc, tree type, tree expr, bool produce_warns)
 {
   enum conversion_safety give_warning = SAFE_CONVERSION; /* is 0 or false */
   tree expr_type = TREE_TYPE (expr);
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  loc = expansion_point_location_if_in_system_header (loc);
 
   if (TREE_CODE (expr) == REAL_CST || TREE_CODE (expr) == INTEGER_CST)
     {
@@ -2705,10 +2706,9 @@ unsafe_conversion_p (tree type, tree exp
    This is a helper function for warnings_for_convert_and_check.  */
 
 static void
-conversion_warning (tree type, tree expr)
+conversion_warning (location_t loc, tree type, tree expr)
 {
   tree expr_type = TREE_TYPE (expr);
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
   enum conversion_safety conversion_kind;
 
   if (!warn_conversion && !warn_sign_conversion && !warn_float_conversion)
@@ -2738,7 +2738,7 @@ conversion_warning (tree type, tree expr
 
     case REAL_CST:
     case INTEGER_CST:
-      conversion_kind = unsafe_conversion_p (type, expr, true);
+      conversion_kind = unsafe_conversion_p (loc, type, expr, true);
       if (conversion_kind == UNSAFE_REAL)
 	warning_at (loc, OPT_Wfloat_conversion,
 		    "conversion to %qT alters %qT constant value",
@@ -2756,13 +2756,13 @@ conversion_warning (tree type, tree expr
         tree op1 = TREE_OPERAND (expr, 1);
         tree op2 = TREE_OPERAND (expr, 2);
         
-        conversion_warning (type, op1);
-        conversion_warning (type, op2);
+        conversion_warning (loc, type, op1);
+        conversion_warning (loc, type, op2);
         return;
       }
 
     default: /* 'expr' is not a constant.  */
-      conversion_kind = unsafe_conversion_p (type, expr, true);
+      conversion_kind = unsafe_conversion_p (loc, type, expr, true);
       if (conversion_kind == UNSAFE_REAL)
 	warning_at (loc, OPT_Wfloat_conversion,
 		    "conversion to %qT from %qT may alter its value",
@@ -2779,9 +2779,10 @@ conversion_warning (tree type, tree expr
    convert_and_check and cp_convert_and_check.  */
 
 void
-warnings_for_convert_and_check (tree type, tree expr, tree result)
+warnings_for_convert_and_check (location_t loc, tree type, tree expr,
+				tree result)
 {
-  location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
+  loc = expansion_point_location_if_in_system_header (loc);
 
   if (TREE_CODE (expr) == INTEGER_CST
       && (TREE_CODE (type) == INTEGER_TYPE
@@ -2801,10 +2802,10 @@ warnings_for_convert_and_check (tree typ
             warning_at (loc, OPT_Woverflow,
 			"large integer implicitly truncated to unsigned type");
           else
-            conversion_warning (type, expr);
+            conversion_warning (loc, type, expr);
         }
       else if (!int_fits_type_p (expr, c_common_unsigned_type (type)))
-	warning (OPT_Woverflow,
+	warning_at (loc, OPT_Woverflow,
 		 "overflow in implicit constant conversion");
       /* No warning for converting 0x80000000 to int.  */
       else if (pedantic
@@ -2815,14 +2816,14 @@ warnings_for_convert_and_check (tree typ
 		    "overflow in implicit constant conversion");
 
       else
-	conversion_warning (type, expr);
+	conversion_warning (loc, type, expr);
     }
   else if ((TREE_CODE (result) == INTEGER_CST
 	    || TREE_CODE (result) == FIXED_CST) && TREE_OVERFLOW (result))
     warning_at (loc, OPT_Woverflow,
 		"overflow in implicit constant conversion");
   else
-    conversion_warning (type, expr);
+    conversion_warning (loc, type, expr);
 }
 
 
@@ -2831,7 +2832,7 @@ warnings_for_convert_and_check (tree typ
    i.e. because of language rules and not because of an explicit cast.  */
 
 tree
-convert_and_check (tree type, tree expr)
+convert_and_check (location_t loc, tree type, tree expr)
 {
   tree result;
   tree expr_for_warning;
@@ -2858,7 +2859,7 @@ convert_and_check (tree type, tree expr)
   if (c_inhibit_evaluation_warnings == 0
       && !TREE_OVERFLOW_P (expr)
       && result != error_mark_node)
-    warnings_for_convert_and_check (type, expr_for_warning, result);
+    warnings_for_convert_and_check (loc, type, expr_for_warning, result);
 
   return result;
 }
@@ -5960,14 +5961,14 @@ c_add_case_label (location_t loc, splay_
   if (low_value)
     {
       low_value = check_case_value (low_value);
-      low_value = convert_and_check (type, low_value);
+      low_value = convert_and_check (loc, type, low_value);
       if (low_value == error_mark_node)
 	goto error_out;
     }
   if (high_value)
     {
       high_value = check_case_value (high_value);
-      high_value = convert_and_check (type, high_value);
+      high_value = convert_and_check (loc, type, high_value);
       if (high_value == error_mark_node)
 	goto error_out;
     }
@@ -11725,7 +11726,7 @@ scalar_to_vector (location_t loc, enum t
 	if (TREE_CODE (type0) == INTEGER_TYPE
 	    && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
 	  {
-	    if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
+	    if (unsafe_conversion_p (loc, TREE_TYPE (type1), op0, false))
 	      {
 		if (complain)
 		  error_at (loc, "conversion of scalar %qT to vector %qT "
@@ -11775,7 +11776,7 @@ scalar_to_vector (location_t loc, enum t
 	if (TREE_CODE (type0) == INTEGER_TYPE
 	    && TREE_CODE (TREE_TYPE (type1)) == INTEGER_TYPE)
 	  {
-	    if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
+	    if (unsafe_conversion_p (loc, TREE_TYPE (type1), op0, false))
 	      {
 		if (complain)
 		  error_at (loc, "conversion of scalar %qT to vector %qT "
@@ -11790,7 +11791,7 @@ scalar_to_vector (location_t loc, enum t
 		     || TREE_CODE (type0) == INTEGER_TYPE)
 		 && SCALAR_FLOAT_TYPE_P (TREE_TYPE (type1)))
 	  {
-	    if (unsafe_conversion_p (TREE_TYPE (type1), op0, false))
+	    if (unsafe_conversion_p (loc, TREE_TYPE (type1), op0, false))
 	      {
 		if (complain)
 		  error_at (loc, "conversion of scalar %qT to vector %qT "
--- gcc/cp/typeck.c.mp	2014-01-29 16:56:56.828066293 +0100
+++ gcc/cp/typeck.c	2014-01-29 16:57:13.878132301 +0100
@@ -7711,7 +7711,7 @@ build_ptrmemfunc1 (tree type, tree delta
   delta_field = DECL_CHAIN (pfn_field);
 
   /* Make sure DELTA has the type we want.  */
-  delta = convert_and_check (delta_type_node, delta);
+  delta = convert_and_check (input_location, delta_type_node, delta);
 
   /* Convert to the correct target type if necessary.  */
   pfn = fold_convert (TREE_TYPE (pfn_field), pfn);
--- gcc/cp/cvt.c.mp	2014-01-29 16:42:13.403584559 +0100
+++ gcc/cp/cvt.c	2014-01-29 16:42:46.488713199 +0100
@@ -639,7 +639,8 @@ cp_convert_and_check (tree type, tree ex
 
       if (!TREE_OVERFLOW_P (stripped)
 	  && folded_result != error_mark_node)
-	warnings_for_convert_and_check (type, folded, folded_result);
+	warnings_for_convert_and_check (input_location, type, folded,
+					folded_result);
     }
 
   return result;
--- gcc/cp/call.c.mp	2014-01-29 16:36:41.752631803 +0100
+++ gcc/cp/call.c	2014-01-29 16:37:03.374715863 +0100
@@ -4465,14 +4465,14 @@ build_conditional_expr_1 (location_t loc
 	     but the warnings (like Wsign-conversion) have already been
 	     given by the scalar build_conditional_expr_1. We still check
 	     unsafe_conversion_p to forbid truncating long long -> float.  */
-	  if (unsafe_conversion_p (stype, arg2, false))
+	  if (unsafe_conversion_p (loc, stype, arg2, false))
 	    {
 	      if (complain & tf_error)
 		error_at (loc, "conversion of scalar %qT to vector %qT "
 			       "involves truncation", arg2_type, vtype);
 	      return error_mark_node;
 	    }
-	  if (unsafe_conversion_p (stype, arg3, false))
+	  if (unsafe_conversion_p (loc, stype, arg3, false))
 	    {
 	      if (complain & tf_error)
 		error_at (loc, "conversion of scalar %qT to vector %qT "
--- gcc/c/c-typeck.c.mp	2014-01-29 16:49:46.219350367 +0100
+++ gcc/c/c-typeck.c	2014-01-29 18:16:00.975931960 +0100
@@ -89,10 +89,10 @@ static int function_types_compatible_p (
 					bool *);
 static int type_lists_compatible_p (const_tree, const_tree, bool *, bool *);
 static tree lookup_field (tree, tree);
-static int convert_arguments (tree, vec<tree, va_gc> *, vec<tree, va_gc> *,
-			      tree, tree);
+static int convert_arguments (location_t, tree, vec<tree, va_gc> *,
+			      vec<tree, va_gc> *, tree, tree);
 static tree pointer_diff (location_t, tree, tree);
-static tree convert_for_assignment (location_t, tree, tree, tree,
+static tree convert_for_assignment (location_t, location_t, tree, tree, tree,
 				    enum impl_conv, bool, tree, tree, int);
 static tree valid_compound_expr_initializer (tree, tree);
 static void push_string (const char *);
@@ -2901,7 +2901,7 @@ build_function_call_vec (location_t loc,
   /* Convert the parameters to the types declared in the
      function prototype, or apply default promotions.  */
 
-  nargs = convert_arguments (TYPE_ARG_TYPES (fntype), params, origtypes,
+  nargs = convert_arguments (loc, TYPE_ARG_TYPES (fntype), params, origtypes,
 			     function, fundecl);
   if (nargs < 0)
     return error_mark_node;
@@ -3018,7 +3018,7 @@ build_function_call_vec (location_t loc,
    failure.  */
 
 static int
-convert_arguments (tree typelist, vec<tree, va_gc> *values,
+convert_arguments (location_t loc, tree typelist, vec<tree, va_gc> *values,
 		   vec<tree, va_gc> *origtypes, tree function, tree fundecl)
 {
   tree typetail, val;
@@ -3083,11 +3083,9 @@ convert_arguments (tree typelist, vec<tr
       if (type == void_type_node)
 	{
 	  if (selector)
-	    error_at (input_location,
-		      "too many arguments to method %qE", selector);
+	    error_at (loc, "too many arguments to method %qE", selector);
 	  else
-	    error_at (input_location,
-		      "too many arguments to function %qE", function);
+	    error_at (loc, "too many arguments to function %qE", function);
 	  inform_declaration (fundecl);
 	  return parmnum;
 	}
@@ -3262,9 +3260,9 @@ convert_arguments (tree typelist, vec<tr
 	      if (excess_precision)
 		val = build1 (EXCESS_PRECISION_EXPR, valtype, val);
 	      origtype = (!origtypes) ? NULL_TREE : (*origtypes)[parmnum];
-	      parmval = convert_for_assignment (input_location, type, val,
-						origtype, ic_argpass, npc,
-						fundecl, function,
+	      parmval = convert_for_assignment (loc, UNKNOWN_LOCATION, type,
+						val, origtype, ic_argpass,
+						npc, fundecl, function,
 						parmnum + 1);
 
 	      if (targetm.calls.promote_prototypes (fundecl ? TREE_TYPE (fundecl) : 0)
@@ -3319,8 +3317,7 @@ convert_arguments (tree typelist, vec<tr
 
   if (typetail != 0 && TREE_VALUE (typetail) != void_type_node)
     {
-      error_at (input_location,
-		"too few arguments to function %qE", function);
+      error_at (loc, "too few arguments to function %qE", function);
       inform_declaration (fundecl);
       return -1;
     }
@@ -3705,8 +3702,8 @@ build_atomic_assign (location_t loc, tre
 
   /* newval = old + val;  */
   rhs = build_binary_op (loc, modifycode, old, val, 1);
-  rhs = convert_for_assignment (loc, nonatomic_lhs_type, rhs, NULL_TREE,
-				ic_assign, false, NULL_TREE,
+  rhs = convert_for_assignment (loc, UNKNOWN_LOCATION, nonatomic_lhs_type,
+				rhs, NULL_TREE, ic_assign, false, NULL_TREE,
 				NULL_TREE, 0);
   if (rhs != error_mark_node)
     {
@@ -4383,20 +4380,21 @@ c_mark_addressable (tree exp)
    the usual ones because of excess precision.  */
 
 static tree
-ep_convert_and_check (tree type, tree expr, tree semantic_type)
+ep_convert_and_check (location_t loc, tree type, tree expr,
+		      tree semantic_type)
 {
   if (TREE_TYPE (expr) == type)
     return expr;
 
   if (!semantic_type)
-    return convert_and_check (type, expr);
+    return convert_and_check (loc, type, expr);
 
   if (TREE_CODE (TREE_TYPE (expr)) == INTEGER_TYPE
       && TREE_TYPE (expr) != semantic_type)
     {
       /* For integers, we need to check the real conversion, not
 	 the conversion to the excess precision type.  */
-      expr = convert_and_check (semantic_type, expr);
+      expr = convert_and_check (loc, semantic_type, expr);
     }
   /* Result type is the excess precision type, which should be
      large enough, so do not check.  */
@@ -4680,8 +4678,10 @@ build_conditional_expr (location_t colon
 			  TYPE_READONLY (type1) || TYPE_READONLY (type2),
 			  TYPE_VOLATILE (type1) || TYPE_VOLATILE (type2));
 
-  op1 = ep_convert_and_check (result_type, op1, semantic_result_type);
-  op2 = ep_convert_and_check (result_type, op2, semantic_result_type);
+  op1 = ep_convert_and_check (colon_loc, result_type, op1,
+			      semantic_result_type);
+  op2 = ep_convert_and_check (colon_loc, result_type, op2,
+			      semantic_result_type);
 
   if (ifexp_bcp && ifexp == truthvalue_true_node)
     {
@@ -5381,9 +5381,9 @@ build_modify_expr (location_t location,
       newrhs = c_fully_fold (newrhs, false, NULL);
       if (rhs_semantic_type)
 	newrhs = build1 (EXCESS_PRECISION_EXPR, rhs_semantic_type, newrhs);
-      newrhs = convert_for_assignment (location, lhstype, newrhs, rhs_origtype,
-				       ic_assign, npc, NULL_TREE,
-				       NULL_TREE, 0);
+      newrhs = convert_for_assignment (location, rhs_loc, lhstype, newrhs,
+				       rhs_origtype, ic_assign, npc,
+				       NULL_TREE, NULL_TREE, 0);
       if (TREE_CODE (newrhs) == ERROR_MARK)
 	return error_mark_node;
     }
@@ -5418,8 +5418,9 @@ build_modify_expr (location_t location,
   if (olhstype == TREE_TYPE (result))
     goto return_result;
 
-  result = convert_for_assignment (location, olhstype, result, rhs_origtype,
-				   ic_assign, false, NULL_TREE, NULL_TREE, 0);
+  result = convert_for_assignment (location, rhs_loc, olhstype, result,
+				   rhs_origtype, ic_assign, false, NULL_TREE,
+				   NULL_TREE, 0);
   protected_set_expr_location (result, location);
 
 return_result:
@@ -5550,13 +5551,14 @@ convert_to_anonymous_field (location_t l
    ERRTYPE says whether it is argument passing, assignment,
    initialization or return.
 
-   LOCATION is the location of the RHS.
+   LOCATION is the location of the assignment, RHS_LOC is the location of
+   the RHS.
    FUNCTION is a tree for the function being called.
    PARMNUM is the number of the argument, for printing in error messages.  */
 
 static tree
-convert_for_assignment (location_t location, tree type, tree rhs,
-			tree origtype, enum impl_conv errtype,
+convert_for_assignment (location_t location, location_t rhs_loc, tree type,
+			tree rhs, tree origtype, enum impl_conv errtype,
 			bool null_pointer_constant, tree fundecl,
 			tree function, int parmnum)
 {
@@ -5728,9 +5730,11 @@ convert_for_assignment (location_t locat
       rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs);
       SET_EXPR_LOCATION (rhs, location);
 
-      rhs = convert_for_assignment (location, build_pointer_type (TREE_TYPE (type)),
-				    rhs, origtype, errtype, null_pointer_constant,
-				    fundecl, function, parmnum);
+      rhs = convert_for_assignment (location, rhs_loc,
+				    build_pointer_type (TREE_TYPE (type)),
+				    rhs, origtype, errtype,
+				    null_pointer_constant, fundecl, function,
+				    parmnum);
       if (rhs == error_mark_node)
 	return error_mark_node;
 
@@ -5756,7 +5760,8 @@ convert_for_assignment (location_t locat
       bool save = in_late_binary_op;
       if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE)
 	in_late_binary_op = true;
-      ret = convert_and_check (type, orig_rhs);
+      ret = convert_and_check (rhs_loc != UNKNOWN_LOCATION
+			       ? rhs_loc : location, type, orig_rhs);
       if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE)
 	in_late_binary_op = save;
       return ret;
@@ -5766,7 +5771,8 @@ convert_for_assignment (location_t locat
   if ((codel == RECORD_TYPE || codel == UNION_TYPE)
       && codel == coder
       && comptypes (type, rhstype))
-    return convert_and_check (type, rhs);
+    return convert_and_check (rhs_loc != UNKNOWN_LOCATION
+			      ? rhs_loc : location, type, rhs);
 
   /* Conversion to a transparent union or record from its member types.
      This applies only to function arguments.  */
@@ -6725,8 +6731,8 @@ digest_init (location_t init_loc, tree t
 
       /* Added to enable additional -Wsuggest-attribute=format warnings.  */
       if (TREE_CODE (TREE_TYPE (inside_init)) == POINTER_TYPE)
-	inside_init = convert_for_assignment (init_loc, type, inside_init,
-	    				      origtype,
+	inside_init = convert_for_assignment (init_loc, UNKNOWN_LOCATION,
+					      type, inside_init, origtype,
 					      ic_init, null_pointer_constant,
 					      NULL_TREE, NULL_TREE, 0);
       return inside_init;
@@ -6746,9 +6752,10 @@ digest_init (location_t init_loc, tree t
 	inside_init = build1 (EXCESS_PRECISION_EXPR, semantic_type,
 			      inside_init);
       inside_init
-	= convert_for_assignment (init_loc, type, inside_init, origtype,
-	    			  ic_init, null_pointer_constant,
-				  NULL_TREE, NULL_TREE, 0);
+	= convert_for_assignment (init_loc, UNKNOWN_LOCATION, type,
+				  inside_init, origtype, ic_init,
+				  null_pointer_constant, NULL_TREE, NULL_TREE,
+				  0);
 
       /* Check to see if we have already given an error message.  */
       if (inside_init == error_mark_node)
@@ -9193,8 +9200,8 @@ c_finish_return (location_t loc, tree re
     }
   else
     {
-      tree t = convert_for_assignment (loc, valtype, retval, origtype,
-	  			       ic_return,
+      tree t = convert_for_assignment (loc, UNKNOWN_LOCATION, valtype,
+				       retval, origtype, ic_return,
 				       npc, NULL_TREE, NULL_TREE, 0);
       tree res = DECL_RESULT (current_function_decl);
       tree inner;
@@ -10767,16 +10774,16 @@ build_binary_op (location_t location, en
 	  if (first_complex)
 	    {
 	      if (TREE_TYPE (op0) != result_type)
-		op0 = convert_and_check (result_type, op0);
+		op0 = convert_and_check (location, result_type, op0);
 	      if (TREE_TYPE (op1) != real_type)
-		op1 = convert_and_check (real_type, op1);
+		op1 = convert_and_check (location, real_type, op1);
 	    }
 	  else
 	    {
 	      if (TREE_TYPE (op0) != real_type)
-		op0 = convert_and_check (real_type, op0);
+		op0 = convert_and_check (location, real_type, op0);
 	      if (TREE_TYPE (op1) != result_type)
-		op1 = convert_and_check (result_type, op1);
+		op1 = convert_and_check (location, result_type, op1);
 	    }
 	  if (TREE_CODE (op0) == ERROR_MARK || TREE_CODE (op1) == ERROR_MARK)
 	    return error_mark_node;
@@ -10975,8 +10982,10 @@ build_binary_op (location_t location, en
 
   if (!converted)
     {
-      op0 = ep_convert_and_check (result_type, op0, semantic_result_type);
-      op1 = ep_convert_and_check (result_type, op1, semantic_result_type);
+      op0 = ep_convert_and_check (location, result_type, op0,
+				  semantic_result_type);
+      op1 = ep_convert_and_check (location, result_type, op1,
+				  semantic_result_type);
 
       /* This can happen if one operand has a vector type, and the other
 	 has a different type.  */
--- gcc/testsuite/gcc.dg/pr59940.c.mp	2014-01-29 18:01:41.000000000 +0100
+++ gcc/testsuite/gcc.dg/pr59940.c	2014-01-29 16:25:29.000000000 +0100
@@ -0,0 +1,27 @@
+/* PR c/59940 */
+/* { dg-do compile } */
+/* { dg-options "-Wconversion -Woverflow" } */
+
+int f (unsigned int);
+
+int
+g (void)
+{
+  int si = 12;
+  unsigned int ui = -1; /* { dg-warning "21:negative integer implicitly converted to unsigned type" } */
+  unsigned char uc;
+  ui = si; /* { dg-warning "8:conversion" } */
+  si = 0x80000000; /* { dg-warning "8:conversion of unsigned constant value to negative integer" } */
+  si = 3.2f; /* { dg-warning "8:conversion" } */
+  uc = 256; /* { dg-warning "8:large integer implicitly truncated to unsigned type" } */
+  si = 0x800000000; /* { dg-warning "8:overflow in implicit constant conversion" } */
+  return f (si) /* { dg-warning "12:conversion" } */
+         + f (si); /* { dg-warning "14:conversion" } */
+}
+
+int
+y (void)
+{
+  f (); /* { dg-error "5:too few arguments to function" } */
+  g (0xa); /* { dg-error "5:too many arguments to function" } */
+}
--- gcc/testsuite/gcc.dg/pr35635.c.mp	2014-01-29 19:09:32.067593557 +0100
+++ gcc/testsuite/gcc.dg/pr35635.c	2014-01-29 19:15:22.644920147 +0100
@@ -62,9 +62,9 @@ void func3()
   /* At least one branch of ? does not fit in the destination, thus
      warn.  */
   uchar_x = bar != 0 ? 2.1 : 10; /* { dg-warning "conversion" } */
-  uchar_x = bar != 0 
+  uchar_x = bar != 0  /* { dg-warning "negative integer implicitly converted to unsigned type" } */
     ? (unsigned char) 1024 
-    : -1; /* { dg-warning "negative integer implicitly converted to unsigned type" } */
+    : -1;
 }
 
 void func4()

	Marek



More information about the Gcc-patches mailing list