diff options
author | Marek Polacek <polacek@redhat.com> | 2014-01-31 08:13:50 +0000 |
---|---|---|
committer | Marek Polacek <mpolacek@gcc.gnu.org> | 2014-01-31 08:13:50 +0000 |
commit | 81e5eca87345f0eba9c9ba4a5c9afb508e701444 (patch) | |
tree | d72ad2d85070a83e828f16474ea193868efb9831 /gcc/c | |
parent | 4f50b9ff5690abc3508483ac1df2a6346fc10fe4 (diff) | |
download | gcc-81e5eca87345f0eba9c9ba4a5c9afb508e701444.zip gcc-81e5eca87345f0eba9c9ba4a5c9afb508e701444.tar.gz gcc-81e5eca87345f0eba9c9ba4a5c9afb508e701444.tar.bz2 |
re PR c/59963 (Wrong column number for warning -Woverflow)
PR c/59963
c-family/
* c-common.c (add_atomic_size_parameter): Pass vNULL to
build_function_call_vec.
(resolve_overloaded_builtin): Likewise.
* c-common.h (build_function_call_vec): Adjust declaration.
cp/
* typeck.c (build_function_call_vec): Add dummy arg_loc parameter.
c/
* c-typeck.c (convert_lvalue_to_rvalue): Pass vNULL to
build_function_call_vec.
(build_function_call): Likewise.
(build_atomic_assign): Likewise.
(build_function_call_vec): Add arg_loc parameter. Use it.
(convert_arguments): Likewise.
(convert_for_assignment): Rename rhs_loc to expr_loc.
* c-parser.c (c_parser_attributes): Pass NULL to c_parser_expr_list.
(c_parser_objc_keywordexpr): Likewise.
(c_parser_postfix_expression_after_primary): Call
build_function_call_vec with expr_loc rather than op_loc.
Call c_parser_expr_list to fill arg_loc. Pass arg_loc to
build_function_call_vec.
(c_parser_expr_list): Add locations parameter. Fill it with locations
of function arguments.
* c-decl.c (finish_decl): Pass vNULL to build_function_call_vec.
objc/
* objc-next-runtime-abi-02.c (build_throw_stmt): Pass vNULL to
build_function_call_vec.
(finish_catch): Likewise.
(next_runtime_abi_02_get_class_reference): Likewise.
* objc-next-runtime-abi-01.c (build_objc_method_call): Pass vNULL to
build_function_call_vec.
(build_throw_stmt): Likewise.
* objc-gnu-runtime-abi-01.c: (build_objc_method_call): Pass vNULL to
build_function_call_vec.
(build_throw_stmt): Likewise.
testsuite/
* gcc.dg/pr59940.c (g): Adjust dg-warning.
(y): Adjust dg-error.
* gcc.dg/cast-function-1.c (bar): Adjust dg-warnings.
* gcc.dg/pr59963-1.c: New test.
* gcc.dg/pr59963-2.c: New test.
* gcc.dg/pr59963-3.c: New test.
From-SVN: r207335
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/ChangeLog | 20 | ||||
-rw-r--r-- | gcc/c/c-decl.c | 2 | ||||
-rw-r--r-- | gcc/c/c-parser.c | 30 | ||||
-rw-r--r-- | gcc/c/c-typeck.c | 58 |
4 files changed, 74 insertions, 36 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 7c6ffbc..d9c528e 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,23 @@ +2014-01-31 Marek Polacek <polacek@redhat.com> + + PR c/59963 + * c-typeck.c (convert_lvalue_to_rvalue): Pass vNULL to + build_function_call_vec. + (build_function_call): Likewise. + (build_atomic_assign): Likewise. + (build_function_call_vec): Add arg_loc parameter. Use it. + (convert_arguments): Likewise. + (convert_for_assignment): Rename rhs_loc to expr_loc. + * c-parser.c (c_parser_attributes): Pass NULL to c_parser_expr_list. + (c_parser_objc_keywordexpr): Likewise. + (c_parser_postfix_expression_after_primary): Call + build_function_call_vec with expr_loc rather than op_loc. + Call c_parser_expr_list to fill arg_loc. Pass arg_loc to + build_function_call_vec. + (c_parser_expr_list): Add locations parameter. Fill it with locations + of function arguments. + * c-decl.c (finish_decl): Pass vNULL to build_function_call_vec. + 2014-01-30 Marek Polacek <polacek@redhat.com> PR c/59940 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 6d4e6a3..7a7d68e 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -4569,7 +4569,7 @@ finish_decl (tree decl, location_t init_loc, tree init, vec_alloc (v, 1); v->quick_push (cleanup); cleanup = build_function_call_vec (DECL_SOURCE_LOCATION (decl), - cleanup_decl, v, NULL); + vNULL, cleanup_decl, v, NULL); vec_free (v); /* Don't warn about decl unused; the cleanup uses it. */ diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index e6b7b30..8a4868b 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -1203,7 +1203,7 @@ static struct c_expr c_parser_expression (c_parser *); static struct c_expr c_parser_expression_conv (c_parser *); static vec<tree, va_gc> *c_parser_expr_list (c_parser *, bool, bool, vec<tree, va_gc> **, location_t *, - tree *); + tree *, vec<location_t> *); static void c_parser_omp_construct (c_parser *); static void c_parser_omp_threadprivate (c_parser *); static void c_parser_omp_barrier (c_parser *); @@ -3958,7 +3958,7 @@ c_parser_attributes (c_parser *parser) tree tree_list; c_parser_consume_token (parser); expr_list = c_parser_expr_list (parser, false, true, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); tree_list = build_tree_list_vec (expr_list); attr_args = tree_cons (NULL_TREE, arg1, tree_list); release_tree_vector (expr_list); @@ -3971,7 +3971,7 @@ c_parser_attributes (c_parser *parser) else { expr_list = c_parser_expr_list (parser, false, true, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); attr_args = build_tree_list_vec (expr_list); release_tree_vector (expr_list); } @@ -7637,6 +7637,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser, unsigned int i; vec<tree, va_gc> *exprlist; vec<tree, va_gc> *origtypes = NULL; + vec<location_t> arg_loc = vNULL; + while (true) { location_t op_loc = c_parser_peek_token (parser)->location; @@ -7690,7 +7692,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser, exprlist = NULL; else exprlist = c_parser_expr_list (parser, true, false, &origtypes, - sizeof_arg_loc, sizeof_arg); + sizeof_arg_loc, sizeof_arg, + &arg_loc); c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, "expected %<)%>"); orig_expr = expr; @@ -7700,10 +7703,8 @@ c_parser_postfix_expression_after_primary (c_parser *parser, expr.value, exprlist, sizeof_arg, sizeof_ptr_memacc_comptypes); - /* FIXME diagnostics: Ideally we want the FUNCNAME, not the - "(" after the FUNCNAME, which is what we have now. */ - expr.value = build_function_call_vec (op_loc, expr.value, exprlist, - origtypes); + expr.value = build_function_call_vec (expr_loc, arg_loc, expr.value, + exprlist, origtypes); expr.original_code = ERROR_MARK; if (TREE_CODE (expr.value) == INTEGER_CST && TREE_CODE (orig_expr.value) == FUNCTION_DECL @@ -7716,6 +7717,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser, release_tree_vector (exprlist); release_tree_vector (origtypes); } + arg_loc.release (); break; case CPP_DOT: /* Structure element reference. */ @@ -7869,7 +7871,8 @@ c_parser_expression_conv (c_parser *parser) /* Parse a non-empty list of expressions. If CONVERT_P, convert functions and arrays to pointers and lvalues to rvalues. If - FOLD_P, fold the expressions. + FOLD_P, fold the expressions. If LOCATIONS is non-NULL, save the + locations of function arguments into this vector. nonempty-expr-list: assignment-expression @@ -7879,7 +7882,8 @@ c_parser_expression_conv (c_parser *parser) static vec<tree, va_gc> * c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, vec<tree, va_gc> **p_orig_types, - location_t *sizeof_arg_loc, tree *sizeof_arg) + location_t *sizeof_arg_loc, tree *sizeof_arg, + vec<location_t> *locations) { vec<tree, va_gc> *ret; vec<tree, va_gc> *orig_types; @@ -7905,6 +7909,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, ret->quick_push (expr.value); if (orig_types) orig_types->quick_push (expr.original_type); + if (locations) + locations->safe_push (loc); if (sizeof_arg != NULL && cur_sizeof_arg_loc != UNKNOWN_LOCATION && expr.original_code == SIZEOF_EXPR) @@ -7929,6 +7935,8 @@ c_parser_expr_list (c_parser *parser, bool convert_p, bool fold_p, vec_safe_push (ret, expr.value); if (orig_types) vec_safe_push (orig_types, expr.original_type); + if (locations) + locations->safe_push (loc); if (++idx < 3 && sizeof_arg != NULL && cur_sizeof_arg_loc != UNKNOWN_LOCATION @@ -9026,7 +9034,7 @@ c_parser_objc_keywordexpr (c_parser *parser) { tree ret; vec<tree, va_gc> *expr_list = c_parser_expr_list (parser, true, true, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); if (vec_safe_length (expr_list) == 1) { /* Just return the expression, remove a level of diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index 4b9f4bf..da6a6fc 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -89,8 +89,9 @@ 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 (location_t, tree, vec<tree, va_gc> *, - vec<tree, va_gc> *, tree, tree); +static int convert_arguments (location_t, vec<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, location_t, tree, tree, tree, enum impl_conv, bool, tree, tree, int); @@ -2014,7 +2015,7 @@ convert_lvalue_to_rvalue (location_t loc, struct c_expr exp, params->quick_push (expr_addr); params->quick_push (tmp_addr); params->quick_push (seq_cst); - func_call = build_function_call_vec (loc, fndecl, params, NULL); + func_call = build_function_call_vec (loc, vNULL, fndecl, params, NULL); /* Return tmp which contains the value loaded. */ exp.value = build2 (COMPOUND_EXPR, nonatomic_type, func_call, tmp); @@ -2796,7 +2797,7 @@ build_function_call (location_t loc, tree function, tree params) vec_alloc (v, list_length (params)); for (; params; params = TREE_CHAIN (params)) v->quick_push (TREE_VALUE (params)); - ret = build_function_call_vec (loc, function, v, NULL); + ret = build_function_call_vec (loc, vNULL, function, v, NULL); vec_free (v); return ret; } @@ -2818,8 +2819,8 @@ static void inform_declaration (tree decl) PARAMS. */ tree -build_function_call_vec (location_t loc, tree function, - vec<tree, va_gc> *params, +build_function_call_vec (location_t loc, vec<location_t> arg_loc, + tree function, vec<tree, va_gc> *params, vec<tree, va_gc> *origtypes) { tree fntype, fundecl = 0; @@ -2901,8 +2902,8 @@ 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 (loc, TYPE_ARG_TYPES (fntype), params, origtypes, - function, fundecl); + nargs = convert_arguments (loc, arg_loc, TYPE_ARG_TYPES (fntype), params, + origtypes, function, fundecl); if (nargs < 0) return error_mark_node; @@ -2981,19 +2982,22 @@ build_function_call_vec (location_t loc, tree function, This is also where warnings about wrong number of args are generated. + ARG_LOC are locations of function arguments (if any). + Returns the actual number of arguments processed (which may be less than the length of VALUES in some error situations), or -1 on failure. */ static int -convert_arguments (location_t loc, tree typelist, vec<tree, va_gc> *values, - vec<tree, va_gc> *origtypes, tree function, tree fundecl) +convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist, + vec<tree, va_gc> *values, vec<tree, va_gc> *origtypes, + tree function, tree fundecl) { tree typetail, val; unsigned int parmnum; bool error_args = false; const bool type_generic = fundecl - && lookup_attribute ("type generic", TYPE_ATTRIBUTES(TREE_TYPE (fundecl))); + && lookup_attribute ("type generic", TYPE_ATTRIBUTES (TREE_TYPE (fundecl))); bool type_generic_remove_excess_precision = false; tree selector; @@ -3228,7 +3232,13 @@ convert_arguments (location_t loc, 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 (loc, UNKNOWN_LOCATION, type, + bool arg_loc_ok = !arg_loc.is_empty () + /* Some __atomic_* builtins have additional + hidden argument at position 0. */ + && values->length () == arg_loc.length (); + parmval = convert_for_assignment (loc, + arg_loc_ok ? arg_loc[parmnum] + : UNKNOWN_LOCATION, type, val, origtype, ic_argpass, npc, fundecl, function, parmnum + 1); @@ -3252,7 +3262,7 @@ convert_arguments (location_t loc, tree typelist, vec<tree, va_gc> *values, { /* Convert `float' to `double'. */ if (warn_double_promotion && !c_inhibit_evaluation_warnings) - warning (OPT_Wdouble_promotion, + warning_at (arg_loc[parmnum], OPT_Wdouble_promotion, "implicit conversion from %qT to %qT when passing " "argument to function", valtype, double_type_node); @@ -3619,7 +3629,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, params->quick_push (lhs_addr); params->quick_push (rhs); params->quick_push (seq_cst); - func_call = build_function_call_vec (loc, fndecl, params, NULL); + func_call = build_function_call_vec (loc, vNULL, fndecl, params, NULL); add_stmt (func_call); /* Finish the compound statement. */ @@ -3650,7 +3660,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, params->quick_push (lhs_addr); params->quick_push (old_addr); params->quick_push (seq_cst); - func_call = build_function_call_vec (loc, fndecl, params, NULL); + func_call = build_function_call_vec (loc, vNULL, fndecl, params, NULL); add_stmt (func_call); params->truncate (0); @@ -3689,7 +3699,7 @@ build_atomic_assign (location_t loc, tree lhs, enum tree_code modifycode, params->quick_push (integer_zero_node); params->quick_push (seq_cst); params->quick_push (seq_cst); - func_call = build_function_call_vec (loc, fndecl, params, NULL); + func_call = build_function_call_vec (loc, vNULL, fndecl, params, NULL); goto_stmt = build1 (GOTO_EXPR, void_type_node, done_decl); SET_EXPR_LOCATION (goto_stmt, loc); @@ -5519,13 +5529,13 @@ 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 assignment, RHS_LOC is the location of - the RHS. + LOCATION is the location of the assignment, EXPR_LOC is the location of + the RHS or, for a function, location of an argument. 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, location_t rhs_loc, tree type, +convert_for_assignment (location_t location, location_t expr_loc, tree type, tree rhs, tree origtype, enum impl_conv errtype, bool null_pointer_constant, tree fundecl, tree function, int parmnum) @@ -5698,7 +5708,7 @@ convert_for_assignment (location_t location, location_t rhs_loc, tree type, rhs = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (rhs)), rhs); SET_EXPR_LOCATION (rhs, location); - rhs = convert_for_assignment (location, rhs_loc, + rhs = convert_for_assignment (location, expr_loc, build_pointer_type (TREE_TYPE (type)), rhs, origtype, errtype, null_pointer_constant, fundecl, function, @@ -5728,8 +5738,8 @@ convert_for_assignment (location_t location, location_t rhs_loc, tree type, bool save = in_late_binary_op; if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE) in_late_binary_op = true; - ret = convert_and_check (rhs_loc != UNKNOWN_LOCATION - ? rhs_loc : location, type, orig_rhs); + ret = convert_and_check (expr_loc != UNKNOWN_LOCATION + ? expr_loc : location, type, orig_rhs); if (codel == BOOLEAN_TYPE || codel == COMPLEX_TYPE) in_late_binary_op = save; return ret; @@ -5739,8 +5749,8 @@ convert_for_assignment (location_t location, location_t rhs_loc, tree type, if ((codel == RECORD_TYPE || codel == UNION_TYPE) && codel == coder && comptypes (type, rhstype)) - return convert_and_check (rhs_loc != UNKNOWN_LOCATION - ? rhs_loc : location, type, rhs); + return convert_and_check (expr_loc != UNKNOWN_LOCATION + ? expr_loc : location, type, rhs); /* Conversion to a transparent union or record from its member types. This applies only to function arguments. */ |