diff options
author | Marek Polacek <polacek@redhat.com> | 2014-01-30 16:15:36 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2014-01-30 16:15:36 +0000 |
commit | 68fca5952947613ca6239242cbd498ac7ce12b7e (patch) | |
tree | 1864e86fe52740bb3329849e59bfb3edd8b05587 /gcc/c | |
parent | 2d70f6d43551f5e6344909b8f2020a92ae7e4839 (diff) | |
download | gcc-68fca5952947613ca6239242cbd498ac7ce12b7e.zip gcc-68fca5952947613ca6239242cbd498ac7ce12b7e.tar.gz gcc-68fca5952947613ca6239242cbd498ac7ce12b7e.tar.bz2 |
re PR c/59940 (Imprecise column number for -Wconversion)
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.
From-SVN: r207309
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 103 |
2 files changed, 71 insertions, 47 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index c6ca4b4..7c6ffbc 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -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 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 59bd6df..4b9f4bf 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -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. */ |