re PR c++/79588 (ICE in warn_for_restrict with -Wrestrict)
PR c++/79588 c-family/ * c-common.c (check_function_restrict): New function. (check_function_arguments): Add FNDECL argument. Call check_function_restrict if -Wrestrict. * c-warn.c (warn_for_restrict): Remove ARGS argument, add ARGARRAY and NARGS. Use auto_vec for ARG_POSITIONS, simplify. * c-common.h (check_function_arguments): Add FNDECL argument. (warn_for_restrict): Remove ARGS argument, add ARGARRAY and NARGS. c/ * c-parser.c (c_parser_postfix_expression_after_primary): Don't handle -Wrestrict here. * c-typeck.c (build_function_call_vec): Adjust check_function_arguments caller. cp/ * call.c (build_over_call): Call check_function_arguments even for -Wrestrict, adjust check_function_arguments caller. * parser.c (cp_parser_postfix_expression): Don't handle -Wrestrict here. * typeck.c (cp_build_function_call_vec): Adjust check_function_arguments caller. testsuite/ * g++.dg/warn/Wrestrict-1.C: New test. * g++.dg/warn/Wrestrict-2.C: New test. From-SVN: r245719
This commit is contained in:
parent
5713d44853
commit
4227c9adf0
@ -1,3 +1,14 @@
|
||||
2017-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/79588
|
||||
* c-common.c (check_function_restrict): New function.
|
||||
(check_function_arguments): Add FNDECL argument. Call
|
||||
check_function_restrict if -Wrestrict.
|
||||
* c-warn.c (warn_for_restrict): Remove ARGS argument, add ARGARRAY
|
||||
and NARGS. Use auto_vec for ARG_POSITIONS, simplify.
|
||||
* c-common.h (check_function_arguments): Add FNDECL argument.
|
||||
(warn_for_restrict): Remove ARGS argument, add ARGARRAY and NARGS.
|
||||
|
||||
2017-02-24 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* c-ada-spec.c (dump_ada_function_declaration): Add comment about the
|
||||
|
@ -5364,6 +5364,49 @@ check_function_sentinel (const_tree fntype, int nargs, tree *argarray)
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the same argument isn't passed to restrict arguments
|
||||
and other arguments. */
|
||||
|
||||
static void
|
||||
check_function_restrict (const_tree fndecl, const_tree fntype,
|
||||
int nargs, tree *argarray)
|
||||
{
|
||||
int i;
|
||||
tree parms;
|
||||
|
||||
if (fndecl
|
||||
&& TREE_CODE (fndecl) == FUNCTION_DECL
|
||||
&& DECL_ARGUMENTS (fndecl))
|
||||
parms = DECL_ARGUMENTS (fndecl);
|
||||
else
|
||||
parms = TYPE_ARG_TYPES (fntype);
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
TREE_VISITED (argarray[i]) = 0;
|
||||
|
||||
for (i = 0; i < nargs && parms && parms != void_list_node; i++)
|
||||
{
|
||||
tree type;
|
||||
if (TREE_CODE (parms) == PARM_DECL)
|
||||
{
|
||||
type = TREE_TYPE (parms);
|
||||
parms = DECL_CHAIN (parms);
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TREE_VALUE (parms);
|
||||
parms = TREE_CHAIN (parms);
|
||||
}
|
||||
if (POINTER_TYPE_P (type)
|
||||
&& TYPE_RESTRICT (type)
|
||||
&& !TYPE_READONLY (TREE_TYPE (type)))
|
||||
warn_for_restrict (i, argarray, nargs);
|
||||
}
|
||||
|
||||
for (i = 0; i < nargs; i++)
|
||||
TREE_VISITED (argarray[i]) = 0;
|
||||
}
|
||||
|
||||
/* Helper for check_function_nonnull; given a list of operands which
|
||||
must be non-null in ARGS, determine if operand PARAM_NUM should be
|
||||
checked. */
|
||||
@ -5605,8 +5648,8 @@ attribute_fallthrough_p (tree attr)
|
||||
There are NARGS arguments in the array ARGARRAY. LOC should be used for
|
||||
diagnostics. Return true if -Wnonnull warning has been diagnosed. */
|
||||
bool
|
||||
check_function_arguments (location_t loc, const_tree fntype, int nargs,
|
||||
tree *argarray)
|
||||
check_function_arguments (location_t loc, const_tree fndecl, const_tree fntype,
|
||||
int nargs, tree *argarray)
|
||||
{
|
||||
bool warned_p = false;
|
||||
|
||||
@ -5624,6 +5667,9 @@ check_function_arguments (location_t loc, const_tree fntype, int nargs,
|
||||
|
||||
if (warn_format)
|
||||
check_function_sentinel (fntype, nargs, argarray);
|
||||
|
||||
if (warn_restrict)
|
||||
check_function_restrict (fndecl, fntype, nargs, argarray);
|
||||
return warned_p;
|
||||
}
|
||||
|
||||
|
@ -807,7 +807,8 @@ extern const char *fname_as_string (int);
|
||||
extern tree fname_decl (location_t, unsigned, tree);
|
||||
|
||||
extern int check_user_alignment (const_tree, bool);
|
||||
extern bool check_function_arguments (location_t loc, const_tree, int, tree *);
|
||||
extern bool check_function_arguments (location_t loc, const_tree, const_tree,
|
||||
int, tree *);
|
||||
extern void check_function_arguments_recurse (void (*)
|
||||
(void *, tree,
|
||||
unsigned HOST_WIDE_INT),
|
||||
@ -1501,7 +1502,7 @@ extern void warnings_for_convert_and_check (location_t, tree, tree, tree);
|
||||
extern void c_do_switch_warnings (splay_tree, location_t, tree, tree, bool,
|
||||
bool);
|
||||
extern void warn_for_omitted_condop (location_t, tree);
|
||||
extern void warn_for_restrict (unsigned, vec<tree, va_gc> *);
|
||||
extern void warn_for_restrict (unsigned, tree *, unsigned);
|
||||
|
||||
/* Places where an lvalue, or modifiable lvalue, may be required.
|
||||
Used to select diagnostic messages in lvalue_error and
|
||||
|
@ -2170,55 +2170,49 @@ maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0,
|
||||
restrict-qualified param, and it aliases with another argument. */
|
||||
|
||||
void
|
||||
warn_for_restrict (unsigned param_pos, vec<tree, va_gc> *args)
|
||||
warn_for_restrict (unsigned param_pos, tree *argarray, unsigned nargs)
|
||||
{
|
||||
tree arg = (*args)[param_pos];
|
||||
if (TREE_VISITED (arg) || operand_equal_p (arg, null_pointer_node, 0))
|
||||
tree arg = argarray[param_pos];
|
||||
if (TREE_VISITED (arg) || integer_zerop (arg))
|
||||
return;
|
||||
|
||||
location_t loc = EXPR_LOC_OR_LOC (arg, input_location);
|
||||
gcc_rich_location richloc (loc);
|
||||
|
||||
unsigned i;
|
||||
tree current_arg;
|
||||
int *arg_positions = XNEWVEC (int, args->length ());
|
||||
unsigned arg_positions_len = 0;
|
||||
auto_vec<int, 16> arg_positions;
|
||||
|
||||
FOR_EACH_VEC_ELT (*args, i, current_arg)
|
||||
for (i = 0; i < nargs; i++)
|
||||
{
|
||||
if (i == param_pos)
|
||||
continue;
|
||||
|
||||
tree current_arg = (*args)[i];
|
||||
tree current_arg = argarray[i];
|
||||
if (operand_equal_p (arg, current_arg, 0))
|
||||
{
|
||||
TREE_VISITED (current_arg) = 1;
|
||||
arg_positions[arg_positions_len++] = (i + 1);
|
||||
arg_positions.safe_push (i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
if (arg_positions_len == 0)
|
||||
{
|
||||
free (arg_positions);
|
||||
return;
|
||||
}
|
||||
if (arg_positions.is_empty ())
|
||||
return;
|
||||
|
||||
for (unsigned i = 0; i < arg_positions_len; i++)
|
||||
int pos;
|
||||
FOR_EACH_VEC_ELT (arg_positions, i, pos)
|
||||
{
|
||||
unsigned pos = arg_positions[i];
|
||||
tree arg = (*args)[pos - 1];
|
||||
arg = argarray[pos - 1];
|
||||
if (EXPR_HAS_LOCATION (arg))
|
||||
richloc.add_range (EXPR_LOCATION (arg), false);
|
||||
}
|
||||
|
||||
warning_at_rich_loc_n (&richloc, OPT_Wrestrict, arg_positions_len,
|
||||
warning_at_rich_loc_n (&richloc, OPT_Wrestrict, arg_positions.length (),
|
||||
"passing argument %i to restrict-qualified parameter"
|
||||
" aliases with argument %Z",
|
||||
"passing argument %i to restrict-qualified parameter"
|
||||
" aliases with arguments %Z",
|
||||
param_pos + 1, arg_positions, arg_positions_len);
|
||||
|
||||
free (arg_positions);
|
||||
param_pos + 1, arg_positions.address (),
|
||||
arg_positions.length ());
|
||||
}
|
||||
|
||||
/* Callback function to determine whether an expression TP or one of its
|
||||
|
@ -1,3 +1,11 @@
|
||||
2017-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/79588
|
||||
* c-parser.c (c_parser_postfix_expression_after_primary): Don't
|
||||
handle -Wrestrict here.
|
||||
* c-typeck.c (build_function_call_vec): Adjust
|
||||
check_function_arguments caller.
|
||||
|
||||
2017-02-23 Richard Biener <rguenther@suse.de>
|
||||
|
||||
PR c/79684
|
||||
|
@ -8418,28 +8418,6 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
|
||||
warn_for_memset (expr_loc, arg0, arg2, literal_zero_mask);
|
||||
}
|
||||
|
||||
if (TREE_CODE (expr.value) == FUNCTION_DECL && warn_restrict)
|
||||
{
|
||||
unsigned i;
|
||||
tree arg;
|
||||
FOR_EACH_VEC_SAFE_ELT (exprlist, i, arg)
|
||||
TREE_VISITED (arg) = 0;
|
||||
|
||||
unsigned param_pos = 0;
|
||||
function_args_iterator iter;
|
||||
tree t;
|
||||
FOREACH_FUNCTION_ARGS (TREE_TYPE (expr.value), t, iter)
|
||||
{
|
||||
if (POINTER_TYPE_P (t) && TYPE_RESTRICT (t)
|
||||
&& !TYPE_READONLY (TREE_TYPE (t)))
|
||||
warn_for_restrict (param_pos, exprlist);
|
||||
param_pos++;
|
||||
}
|
||||
|
||||
FOR_EACH_VEC_SAFE_ELT (exprlist, i, arg)
|
||||
TREE_VISITED (arg) = 0;
|
||||
}
|
||||
|
||||
start = expr.get_start ();
|
||||
finish = parser->tokens_buf[0].get_finish ();
|
||||
expr.value
|
||||
|
@ -3110,7 +3110,8 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
|
||||
return error_mark_node;
|
||||
|
||||
/* Check that the arguments to the function are valid. */
|
||||
bool warned_p = check_function_arguments (loc, fntype, nargs, argarray);
|
||||
bool warned_p = check_function_arguments (loc, fundecl, fntype,
|
||||
nargs, argarray);
|
||||
|
||||
if (name != NULL_TREE
|
||||
&& !strncmp (IDENTIFIER_POINTER (name), "__builtin_", 10))
|
||||
|
@ -1,3 +1,13 @@
|
||||
2017-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/79588
|
||||
* call.c (build_over_call): Call check_function_arguments even for
|
||||
-Wrestrict, adjust check_function_arguments caller.
|
||||
* parser.c (cp_parser_postfix_expression): Don't handle -Wrestrict
|
||||
here.
|
||||
* typeck.c (cp_build_function_call_vec): Adjust
|
||||
check_function_arguments caller.
|
||||
|
||||
2017-02-24 Marek Polacek <polacek@redhat.com>
|
||||
|
||||
PR translation/79705
|
||||
|
@ -7903,14 +7903,17 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain)
|
||||
the check_function_arguments function might warn about something. */
|
||||
|
||||
bool warned_p = false;
|
||||
if (warn_nonnull || warn_format || warn_suggest_attribute_format)
|
||||
if (warn_nonnull
|
||||
|| warn_format
|
||||
|| warn_suggest_attribute_format
|
||||
|| warn_restrict)
|
||||
{
|
||||
tree *fargs = (!nargs ? argarray
|
||||
: (tree *) alloca (nargs * sizeof (tree)));
|
||||
for (j = 0; j < nargs; j++)
|
||||
fargs[j] = maybe_constant_value (argarray[j]);
|
||||
|
||||
warned_p = check_function_arguments (input_location, TREE_TYPE (fn),
|
||||
warned_p = check_function_arguments (input_location, fn, TREE_TYPE (fn),
|
||||
nargs, fargs);
|
||||
}
|
||||
|
||||
|
@ -6934,29 +6934,6 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
|
||||
warn_for_memset (input_location, arg0, arg2, literal_mask);
|
||||
}
|
||||
|
||||
if (TREE_CODE (postfix_expression) == FUNCTION_DECL
|
||||
&& warn_restrict)
|
||||
{
|
||||
unsigned i;
|
||||
tree arg;
|
||||
FOR_EACH_VEC_SAFE_ELT (args, i, arg)
|
||||
TREE_VISITED (arg) = 0;
|
||||
|
||||
unsigned param_pos = 0;
|
||||
for (tree decl = DECL_ARGUMENTS (postfix_expression);
|
||||
decl != NULL_TREE;
|
||||
decl = DECL_CHAIN (decl), param_pos++)
|
||||
{
|
||||
tree type = TREE_TYPE (decl);
|
||||
if (POINTER_TYPE_P (type) && TYPE_RESTRICT (type)
|
||||
&& !TYPE_READONLY (TREE_TYPE (type)))
|
||||
warn_for_restrict (param_pos, args);
|
||||
}
|
||||
|
||||
FOR_EACH_VEC_SAFE_ELT (args, i, arg)
|
||||
TREE_VISITED (arg) = 0;
|
||||
}
|
||||
|
||||
if (TREE_CODE (postfix_expression) == COMPONENT_REF)
|
||||
{
|
||||
tree instance = TREE_OPERAND (postfix_expression, 0);
|
||||
|
@ -3667,7 +3667,7 @@ cp_build_function_call_vec (tree function, vec<tree, va_gc> **params,
|
||||
|
||||
/* Check for errors in format strings and inappropriately
|
||||
null parameters. */
|
||||
bool warned_p = check_function_arguments (input_location, fntype,
|
||||
bool warned_p = check_function_arguments (input_location, fndecl, fntype,
|
||||
nargs, argarray);
|
||||
|
||||
ret = build_cxx_call (function, nargs, argarray, complain);
|
||||
|
@ -1,3 +1,9 @@
|
||||
2017-02-24 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/79588
|
||||
* g++.dg/warn/Wrestrict-1.C: New test.
|
||||
* g++.dg/warn/Wrestrict-2.C: New test.
|
||||
|
||||
2017-02-24 David Edelsohn <dje.gcc@gmail.com>
|
||||
|
||||
* g++.dg/ext/complit15.C: Require LTO.
|
||||
|
12
gcc/testsuite/g++.dg/warn/Wrestrict-1.C
Normal file
12
gcc/testsuite/g++.dg/warn/Wrestrict-1.C
Normal file
@ -0,0 +1,12 @@
|
||||
// PR c++/79588
|
||||
// { dg-do compile }
|
||||
// { dg-options "-Wrestrict" }
|
||||
|
||||
void foo (char *__restrict, char *__restrict = __null);
|
||||
|
||||
void
|
||||
bar (char *p)
|
||||
{
|
||||
foo (p, p); // { dg-warning "to restrict-qualified parameter aliases with" }
|
||||
foo (p);
|
||||
}
|
30
gcc/testsuite/g++.dg/warn/Wrestrict-2.C
Normal file
30
gcc/testsuite/g++.dg/warn/Wrestrict-2.C
Normal file
@ -0,0 +1,30 @@
|
||||
// PR c++/79588
|
||||
// { dg-do compile }
|
||||
// { dg-options "-Wrestrict" }
|
||||
|
||||
void foo (char *__restrict, char *__restrict = __null);
|
||||
|
||||
template <int N>
|
||||
void
|
||||
bar (char **p)
|
||||
{
|
||||
foo (p[0], p[0]); // { dg-warning "to restrict-qualified parameter aliases with" }
|
||||
foo (p[0], p[N]); // { dg-warning "to restrict-qualified parameter aliases with" }
|
||||
foo (p[0]);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
void
|
||||
bar2 (char **p)
|
||||
{
|
||||
foo (p[0], p[0]); // { dg-warning "to restrict-qualified parameter aliases with" }
|
||||
foo (p[0], p[N]); // { dg-bogus "to restrict-qualified parameter aliases with" }
|
||||
foo (p[0]);
|
||||
}
|
||||
|
||||
void
|
||||
baz (char **p)
|
||||
{
|
||||
bar<0> (p);
|
||||
bar2<1> (p);
|
||||
}
|
Loading…
Reference in New Issue
Block a user