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:
Jakub Jelinek 2017-02-24 21:41:54 +01:00 committed by Jakub Jelinek
parent 5713d44853
commit 4227c9adf0
14 changed files with 151 additions and 74 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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))

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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.

View 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);
}

View 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);
}