aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2014-01-30 16:15:36 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2014-01-30 16:15:36 +0000
commit68fca5952947613ca6239242cbd498ac7ce12b7e (patch)
tree1864e86fe52740bb3329849e59bfb3edd8b05587 /gcc/c
parent2d70f6d43551f5e6344909b8f2020a92ae7e4839 (diff)
downloadgcc-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/ChangeLog15
-rw-r--r--gcc/c/c-typeck.c103
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. */