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  <pola...@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

Reply via email to