From 68fca5952947613ca6239242cbd498ac7ce12b7e Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 30 Jan 2014 16:15:36 +0000 Subject: [PATCH] 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 --- gcc/c-family/ChangeLog | 15 ++++++ gcc/c-family/c-common.c | 55 +++++++++++----------- gcc/c-family/c-common.h | 7 +-- gcc/c/ChangeLog | 15 ++++++ gcc/c/c-typeck.c | 103 ++++++++++++++++++++++------------------- gcc/cp/ChangeLog | 10 ++++ gcc/cp/call.c | 4 +- gcc/cp/cvt.c | 3 +- gcc/cp/typeck.c | 2 +- gcc/testsuite/ChangeLog | 6 +++ gcc/testsuite/gcc.dg/pr35635.c | 4 +- gcc/testsuite/gcc.dg/pr59940.c | 27 +++++++++++ 12 files changed, 168 insertions(+), 83 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr59940.c diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 8e3c3f8..35546ee 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,18 @@ +2014-01-30 Marek Polacek + + 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 * c-common.c (c_define_builtins): Replaced flag_enable_cilkplus with diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c index 3ea5763..e5d1075 100644 --- a/gcc/c-family/c-common.c +++ b/gcc/c-family/c-common.c @@ -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 " diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index d7077fd..e47d035 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -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 *, 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, 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 + + 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 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 *, vec *, - tree, tree); +static int convert_arguments (location_t, tree, vec *, + vec *, 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 *values, +convert_arguments (location_t loc, tree typelist, vec *values, vec *origtypes, tree function, tree fundecl) { tree typetail, val; @@ -3051,11 +3051,9 @@ convert_arguments (tree typelist, vec *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 *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 *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. */ diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f49e2e5..392fd1d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2014-01-30 Marek Polacek + + 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 PR c++/58843 diff --git a/gcc/cp/call.c b/gcc/cp/call.c index f572bc1..71f95db 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -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 " diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c index c2cdf83..e8ece0e 100644 --- a/gcc/cp/cvt.c +++ b/gcc/cp/cvt.c @@ -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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b6f4738..9249378 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5b3e071..5283614 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2014-01-30 Marek Polacek + + PR c/59940 + * gcc.dg/pr59940.c: New test. + * gcc.dg/pr35635.c (func3): Move dg-warning. + 2014-01-30 Richard Biener PR tree-optimization/59903 diff --git a/gcc/testsuite/gcc.dg/pr35635.c b/gcc/testsuite/gcc.dg/pr35635.c index 45d10a6..86612d5 100644 --- a/gcc/testsuite/gcc.dg/pr35635.c +++ b/gcc/testsuite/gcc.dg/pr35635.c @@ -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 index 0000000..63e9ce5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr59940.c @@ -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" } */ +} -- 2.7.4