shorten_compare can produce a better locinfo if we pass location from {,cp_}build_binary_op to it; op0/op1 there don't have location. Furthermore, I see no reason why use input_location in parser_build_binary_op when we can use more accurate location.
I don't know if/how I can test the column info using dejagnu, so no testcase attached. But to give you an idea, instead of tt.c:4:3: warning: comparison is always false due to limited range of data type [-Wtype-limits] return 0UL > p; ^ we now show tt.c:4:14: warning: comparison is always false due to limited range of data type [-Wtype-limits] return 0UL > p; ^ Regtested/bootstrapped on x86_64-linux, ok for trunk? 2014-01-23 Marek Polacek <pola...@redhat.com> PR c/59846 c-family/ * c-common.c (shorten_compare): Add location_t parameter. * c-common.h (shorten_binary_op): Adjust declaration. cp/ * typeck.c (cp_build_binary_op): Pass location to shorten_compare. c/ * c-typeck.c (parser_build_binary_op): Use location instead of input_location. (build_binary_op): Pass location to shorten_compare. --- gcc/c-family/c-common.h.mp 2014-01-23 16:19:49.936114468 +0100 +++ gcc/c-family/c-common.h 2014-01-23 16:19:55.407138560 +0100 @@ -799,7 +799,8 @@ extern tree shorten_binary_op (tree resu /* Subroutine of build_binary_op, used for comparison operations. See if the operands have both been converted from subword integer types and, if so, perhaps change them both back to their original type. */ -extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *); +extern tree shorten_compare (location_t, tree *, tree *, tree *, + enum tree_code *); extern tree pointer_int_sum (location_t, enum tree_code, tree, tree, bool = true); --- gcc/c-family/c-common.c.mp 2014-01-23 16:19:49.935114463 +0100 +++ gcc/c-family/c-common.c 2014-01-23 16:19:55.407138560 +0100 @@ -3974,13 +3974,15 @@ expr_original_type (tree expr) of build_binary_op: OP0_PTR is &OP0, OP1_PTR is &OP1, RESTYPE_PTR is &RESULT_TYPE and RESCODE_PTR is &RESULTCODE. + LOC is the location of the comparison. + If this function returns nonzero, it means that the comparison has a constant value. What this function returns is an expression for that value. */ tree -shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr, - enum tree_code *rescode_ptr) +shorten_compare (location_t loc, tree *op0_ptr, tree *op1_ptr, + tree *restype_ptr, enum tree_code *rescode_ptr) { tree type; tree op0 = *op0_ptr; @@ -3989,7 +3991,6 @@ shorten_compare (tree *op0_ptr, tree *op int real1, real2; tree primop0, primop1; enum tree_code code = *rescode_ptr; - location_t loc = EXPR_LOC_OR_LOC (op0, input_location); /* Throw away any conversions to wider types already present in the operands. */ --- gcc/cp/typeck.c.mp 2014-01-23 16:19:49.939114483 +0100 +++ gcc/cp/typeck.c 2014-01-23 16:19:55.424138642 +0100 @@ -4838,7 +4838,8 @@ cp_build_binary_op (location_t location, tree xop0 = op0, xop1 = op1, xresult_type = result_type; enum tree_code xresultcode = resultcode; tree val - = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); + = shorten_compare (location, &xop0, &xop1, &xresult_type, + &xresultcode); if (val != 0) return cp_convert (boolean_type_node, val, complain); op0 = xop0, op1 = xop1; --- gcc/c/c-typeck.c.mp 2014-01-23 16:19:49.938114478 +0100 +++ gcc/c/c-typeck.c 2014-01-23 17:15:56.404366164 +0100 @@ -3388,11 +3388,11 @@ parser_build_binary_op (location_t locat /* Check for cases such as x+y<<z which users are likely to misinterpret. */ if (warn_parentheses) - warn_about_parentheses (input_location, code, - code1, arg1.value, code2, arg2.value); + warn_about_parentheses (location, code, code1, arg1.value, code2, + arg2.value); if (warn_logical_op) - warn_logical_operator (input_location, code, TREE_TYPE (result.value), + warn_logical_operator (location, code, TREE_TYPE (result.value), code1, arg1.value, code2, arg2.value); /* Warn about comparisons against string literals, with the exception @@ -10854,7 +10854,8 @@ build_binary_op (location_t location, en tree xop0 = op0, xop1 = op1, xresult_type = result_type; enum tree_code xresultcode = resultcode; tree val - = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); + = shorten_compare (location, &xop0, &xop1, &xresult_type, + &xresultcode); if (val != 0) { Marek