]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
PR c/59940
authormpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Jan 2014 16:15:36 +0000 (16:15 +0000)
committermpolacek <mpolacek@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 30 Jan 2014 16:15:36 +0000 (16:15 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@207309 138bc75d-0d04-0410-961f-82ee72b054a4

12 files changed:
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/c-family/c-common.h
gcc/c/ChangeLog
gcc/c/c-typeck.c
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cvt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr35635.c
gcc/testsuite/gcc.dg/pr59940.c [new file with mode: 0644]

index 8e3c3f89fd9e9faa5c8c46fd015443cd71ae243a..35546ee1c8863c77c2e4e497ee0fcf2f2d645bd8 100644 (file)
@@ -1,3 +1,18 @@
+2014-01-30  Marek Polacek  <polacek@redhat.com>
+
+       PR c/59940
+       * 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.
+
 2014-01-24  Balaji V. Iyer  <balaji.v.iyer@intel.com>
 
        * c-common.c (c_define_builtins): Replaced flag_enable_cilkplus with
index 3ea5763e8da2565f28bbdbd8133e1f0d19d77131..e5d1075fc87838e1a1bdcf42b7584973bd5fe377 100644 (file)
@@ -2526,23 +2526,24 @@ shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwise)
   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 expr, bool produce_warns)
    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 type, tree expr, tree result)
             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 type, tree expr, tree result)
                    "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 type, tree expr, tree result)
    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_tree cases, tree cond, tree orig_type,
   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 tree_code code, tree op0, tree op1,
        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 tree_code code, tree op0, tree op1,
        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 tree_code code, tree op0, tree op1,
                     || 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 "
index d7077fd7f94522d987762e45aba56365c3a767fa..e47d035e63994ff23d6f0fb863b80317549e2c3d 100644 (file)
@@ -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 (tree, tree, tree);
 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,
index c6ca4b41a3387a287d94ae2e4a0305a8b6436c6b..7c6ffbc1f35423f15d33dc40df6bc69d77a7eaae 100644 (file)
@@ -1,3 +1,18 @@
+2014-01-30  Marek Polacek  <polacek@redhat.com>
+
+       PR c/59940
+       * 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.
+
 2014-01-30  Richard Biener  <rguenther@suse.de>
 
        PR c/59905
index 59bd6df21df596e17af777cf4be50a0080d0453d..4b9f4bf72aeeeadbac843f343ca8ab18dc626add 100644 (file)
@@ -89,10 +89,10 @@ static int function_types_compatible_p (const_tree, const_tree, bool *,
                                        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, tree function,
   /* 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;
@@ -2986,7 +2986,7 @@ build_function_call_vec (location_t loc, tree function,
    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;
@@ -3051,11 +3051,9 @@ convert_arguments (tree typelist, vec<tree, va_gc> *values,
       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;
        }
@@ -3230,9 +3228,9 @@ convert_arguments (tree typelist, vec<tree, va_gc> *values,
              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)
@@ -3287,8 +3285,7 @@ convert_arguments (tree typelist, vec<tree, va_gc> *values,
 
   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;
     }
@@ -3673,8 +3670,8 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode,
 
   /* 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)
     {
@@ -4351,20 +4348,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.  */
@@ -4648,8 +4646,10 @@ build_conditional_expr (location_t colon_loc, tree ifexp, bool ifexp_bcp,
                          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)
     {
@@ -5349,9 +5349,9 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
       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;
     }
@@ -5386,8 +5386,9 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
   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:
@@ -5518,13 +5519,14 @@ convert_to_anonymous_field (location_t location, tree type, tree rhs)
    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)
 {
@@ -5696,9 +5698,11 @@ convert_for_assignment (location_t location, tree type, tree rhs,
       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;
 
@@ -5724,7 +5728,8 @@ convert_for_assignment (location_t location, tree type, tree rhs,
       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;
@@ -5734,7 +5739,8 @@ convert_for_assignment (location_t location, tree type, tree rhs,
   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.  */
@@ -6693,8 +6699,8 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
 
       /* 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;
@@ -6714,9 +6720,10 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype,
        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)
@@ -9161,8 +9168,8 @@ c_finish_return (location_t loc, tree retval, tree origtype)
     }
   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;
@@ -10735,16 +10742,16 @@ build_binary_op (location_t location, enum tree_code code,
          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;
@@ -10943,8 +10950,10 @@ build_binary_op (location_t location, enum tree_code code,
 
   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.  */
index f49e2e55c4b21d9f7376df25b292b1b0c7dcf374..392fd1d766343fb709021980f9c51cbc6b7041dc 100644 (file)
@@ -1,3 +1,13 @@
+2014-01-30  Marek Polacek  <polacek@redhat.com>
+
+       PR c/59940
+       * 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.
+
 2014-01-30  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58843
index f572bc1fc88013d6952af3f021fe1b51b08bdb81..71f95dbed4a2ba088bafd55145168ed74f82a498 100644 (file)
@@ -4484,14 +4484,14 @@ build_conditional_expr_1 (location_t loc, tree arg1, tree arg2, tree arg3,
             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 "
index c2cdf833802cfb1b3ff452313b6c965d0026675e..e8ece0e0b13206057e5a9d8a545142abfd5d8318 100644 (file)
@@ -639,7 +639,8 @@ cp_convert_and_check (tree type, tree expr, tsubst_flags_t complain)
 
       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;
index b6f47384f31c58edcac746f3ce4b88b9a7891b0b..924937832f578439d8e77a6be9b432db84a6ccef 100644 (file)
@@ -7715,7 +7715,7 @@ build_ptrmemfunc1 (tree type, tree delta, tree pfn)
   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);
index 5b3e071d9c9d2857d4ca6703064d56c4595fb292..5283614f9c23992d44a2d1d8d0ce401d2164b55b 100644 (file)
@@ -1,3 +1,9 @@
+2014-01-30  Marek Polacek  <polacek@redhat.com>
+
+       PR c/59940
+       * gcc.dg/pr59940.c: New test.
+       * gcc.dg/pr35635.c (func3): Move dg-warning.
+
 2014-01-30  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/59903
index 45d10a67bd39b8991bf1cf42c944a31678358d24..86612d5283f0c88fd6d77519a8c3d82a2c139b95 100644 (file)
@@ -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()
diff --git a/gcc/testsuite/gcc.dg/pr59940.c b/gcc/testsuite/gcc.dg/pr59940.c
new file mode 100644 (file)
index 0000000..63e9ce5
--- /dev/null
@@ -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" } */
+}