aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2014-01-31 08:13:50 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2014-01-31 08:13:50 +0000
commit81e5eca87345f0eba9c9ba4a5c9afb508e701444 (patch)
treed72ad2d85070a83e828f16474ea193868efb9831 /gcc/c
parent4f50b9ff5690abc3508483ac1df2a6346fc10fe4 (diff)
downloadgcc-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/ChangeLog20
-rw-r--r--gcc/c/c-decl.c2
-rw-r--r--gcc/c/c-parser.c30
-rw-r--r--gcc/c/c-typeck.c58
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. */