* [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588)
@ 2017-02-20 20:38 Jakub Jelinek
2017-02-21 20:45 ` Jason Merrill
2017-02-23 22:13 ` Jeff Law
0 siblings, 2 replies; 4+ messages in thread
From: Jakub Jelinek @ 2017-02-20 20:38 UTC (permalink / raw)
To: Jason Merrill, Joseph S. Myers; +Cc: gcc-patches
Hi!
As mentioned in the PR, -Wrestrict warning is done way too early, where
e.g. default arguments aren't filled up yet (reason for ICE on first
testcase) or where arguments in templates aren't instantiated yet (reason
why we don't diagnose anything on the second testcase).
This patch moves it later where e.g. -Wformat is diagnosed and fixes
some issues I found while looking at the code.
Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
2017-02-20 Jakub Jelinek <jakub@redhat.com>
PR c++/79588
c-family/
* c-common.c (check_function_arguments): Add FNDECL argument.
Handle -Wrestrict here.
* 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.
--- gcc/c-family/c-common.c.jj 2017-01-24 23:29:05.000000000 +0100
+++ gcc/c-family/c-common.c 2017-02-20 13:17:06.601211847 +0100
@@ -5605,8 +5605,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 +5624,44 @@ check_function_arguments (location_t loc
if (warn_format)
check_function_sentinel (fntype, nargs, argarray);
+
+ if (warn_restrict)
+ {
+ 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;
+ }
return warned_p;
}
--- gcc/c-family/c-warn.c.jj 2017-02-15 18:06:19.000000000 +0100
+++ gcc/c-family/c-warn.c 2017-02-20 12:36:29.008455672 +0100
@@ -2170,55 +2170,49 @@ maybe_warn_bool_compare (location_t loc,
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
--- gcc/c-family/c-common.h.jj 2017-01-24 23:29:05.000000000 +0100
+++ gcc/c-family/c-common.h 2017-02-20 13:00:55.540080276 +0100
@@ -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_che
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
--- gcc/c/c-parser.c.jj 2017-02-16 13:01:31.000000000 +0100
+++ gcc/c/c-parser.c 2017-02-20 12:22:55.610210942 +0100
@@ -8418,28 +8418,6 @@ c_parser_postfix_expression_after_primar
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
--- gcc/c/c-typeck.c.jj 2017-01-21 02:25:57.000000000 +0100
+++ gcc/c/c-typeck.c 2017-02-20 13:01:36.829532979 +0100
@@ -3110,7 +3110,8 @@ build_function_call_vec (location_t 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))
--- gcc/cp/call.c.jj 2017-02-17 18:29:21.000000000 +0100
+++ gcc/cp/call.c 2017-02-20 13:03:21.874140599 +0100
@@ -7900,14 +7900,17 @@ build_over_call (struct z_candidate *can
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);
}
--- gcc/cp/parser.c.jj 2017-02-18 14:12:36.000000000 +0100
+++ gcc/cp/parser.c 2017-02-20 12:21:32.257313679 +0100
@@ -6933,29 +6933,6 @@ cp_parser_postfix_expression (cp_parser
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);
--- gcc/cp/typeck.c.jj 2017-02-13 20:30:33.000000000 +0100
+++ gcc/cp/typeck.c 2017-02-20 13:04:10.994489395 +0100
@@ -3661,7 +3661,7 @@ cp_build_function_call_vec (tree functio
/* 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);
--- gcc/testsuite/g++.dg/warn/Wrestrict-1.C.jj 2017-02-18 18:07:19.535116220 +0100
+++ gcc/testsuite/g++.dg/warn/Wrestrict-1.C 2017-02-18 18:05:52.000000000 +0100
@@ -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);
+}
--- gcc/testsuite/g++.dg/warn/Wrestrict-2.C.jj 2017-02-20 13:07:34.635789299 +0100
+++ gcc/testsuite/g++.dg/warn/Wrestrict-2.C 2017-02-20 12:55:12.000000000 +0100
@@ -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);
+}
Jakub
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588)
2017-02-20 20:38 [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588) Jakub Jelinek
@ 2017-02-21 20:45 ` Jason Merrill
2017-02-23 22:13 ` Jeff Law
1 sibling, 0 replies; 4+ messages in thread
From: Jason Merrill @ 2017-02-21 20:45 UTC (permalink / raw)
To: Jakub Jelinek; +Cc: Joseph S. Myers, gcc-patches List
OK if Joseph doesn't object in the next couple of days.
On Mon, Feb 20, 2017 at 12:35 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> As mentioned in the PR, -Wrestrict warning is done way too early, where
> e.g. default arguments aren't filled up yet (reason for ICE on first
> testcase) or where arguments in templates aren't instantiated yet (reason
> why we don't diagnose anything on the second testcase).
>
> This patch moves it later where e.g. -Wformat is diagnosed and fixes
> some issues I found while looking at the code.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2017-02-20 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/79588
> c-family/
> * c-common.c (check_function_arguments): Add FNDECL argument.
> Handle -Wrestrict here.
> * 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.
>
> --- gcc/c-family/c-common.c.jj 2017-01-24 23:29:05.000000000 +0100
> +++ gcc/c-family/c-common.c 2017-02-20 13:17:06.601211847 +0100
> @@ -5605,8 +5605,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 +5624,44 @@ check_function_arguments (location_t loc
>
> if (warn_format)
> check_function_sentinel (fntype, nargs, argarray);
> +
> + if (warn_restrict)
> + {
> + 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;
> + }
> return warned_p;
> }
>
> --- gcc/c-family/c-warn.c.jj 2017-02-15 18:06:19.000000000 +0100
> +++ gcc/c-family/c-warn.c 2017-02-20 12:36:29.008455672 +0100
> @@ -2170,55 +2170,49 @@ maybe_warn_bool_compare (location_t loc,
> 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
> --- gcc/c-family/c-common.h.jj 2017-01-24 23:29:05.000000000 +0100
> +++ gcc/c-family/c-common.h 2017-02-20 13:00:55.540080276 +0100
> @@ -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_che
> 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
> --- gcc/c/c-parser.c.jj 2017-02-16 13:01:31.000000000 +0100
> +++ gcc/c/c-parser.c 2017-02-20 12:22:55.610210942 +0100
> @@ -8418,28 +8418,6 @@ c_parser_postfix_expression_after_primar
> 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
> --- gcc/c/c-typeck.c.jj 2017-01-21 02:25:57.000000000 +0100
> +++ gcc/c/c-typeck.c 2017-02-20 13:01:36.829532979 +0100
> @@ -3110,7 +3110,8 @@ build_function_call_vec (location_t 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))
> --- gcc/cp/call.c.jj 2017-02-17 18:29:21.000000000 +0100
> +++ gcc/cp/call.c 2017-02-20 13:03:21.874140599 +0100
> @@ -7900,14 +7900,17 @@ build_over_call (struct z_candidate *can
> 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);
> }
>
> --- gcc/cp/parser.c.jj 2017-02-18 14:12:36.000000000 +0100
> +++ gcc/cp/parser.c 2017-02-20 12:21:32.257313679 +0100
> @@ -6933,29 +6933,6 @@ cp_parser_postfix_expression (cp_parser
> 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);
> --- gcc/cp/typeck.c.jj 2017-02-13 20:30:33.000000000 +0100
> +++ gcc/cp/typeck.c 2017-02-20 13:04:10.994489395 +0100
> @@ -3661,7 +3661,7 @@ cp_build_function_call_vec (tree functio
>
> /* 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);
> --- gcc/testsuite/g++.dg/warn/Wrestrict-1.C.jj 2017-02-18 18:07:19.535116220 +0100
> +++ gcc/testsuite/g++.dg/warn/Wrestrict-1.C 2017-02-18 18:05:52.000000000 +0100
> @@ -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);
> +}
> --- gcc/testsuite/g++.dg/warn/Wrestrict-2.C.jj 2017-02-20 13:07:34.635789299 +0100
> +++ gcc/testsuite/g++.dg/warn/Wrestrict-2.C 2017-02-20 12:55:12.000000000 +0100
> @@ -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);
> +}
>
> Jakub
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588)
2017-02-20 20:38 [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588) Jakub Jelinek
2017-02-21 20:45 ` Jason Merrill
@ 2017-02-23 22:13 ` Jeff Law
2017-02-24 20:44 ` Jakub Jelinek
1 sibling, 1 reply; 4+ messages in thread
From: Jeff Law @ 2017-02-23 22:13 UTC (permalink / raw)
To: Jakub Jelinek, Jason Merrill, Joseph S. Myers; +Cc: gcc-patches
On 02/20/2017 01:35 PM, Jakub Jelinek wrote:
> Hi!
>
> As mentioned in the PR, -Wrestrict warning is done way too early, where
> e.g. default arguments aren't filled up yet (reason for ICE on first
> testcase) or where arguments in templates aren't instantiated yet (reason
> why we don't diagnose anything on the second testcase).
>
> This patch moves it later where e.g. -Wformat is diagnosed and fixes
> some issues I found while looking at the code.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2017-02-20 Jakub Jelinek <jakub@redhat.com>
>
> PR c++/79588
> c-family/
> * c-common.c (check_function_arguments): Add FNDECL argument.
> Handle -Wrestrict here.
> * 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.
Please refactor the restrict warning bits into their own function, then
calling that from check_function_arguments. That's the style already
used there.
OK with that change.
jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588)
2017-02-23 22:13 ` Jeff Law
@ 2017-02-24 20:44 ` Jakub Jelinek
0 siblings, 0 replies; 4+ messages in thread
From: Jakub Jelinek @ 2017-02-24 20:44 UTC (permalink / raw)
To: Jeff Law; +Cc: Jason Merrill, Joseph S. Myers, gcc-patches
On Thu, Feb 23, 2017 at 03:09:47PM -0700, Jeff Law wrote:
> Please refactor the restrict warning bits into their own function, then
> calling that from check_function_arguments. That's the style already used
> there.
>
> OK with that change.
Here is what I've committed after another bootstrap/regtest:
2017-02-24 Jakub Jelinek <jakub@redhat.com>
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.
--- gcc/c-family/c-common.c.jj 2017-02-20 13:43:15.169555324 +0100
+++ gcc/c-family/c-common.c 2017-02-24 19:44:47.239427073 +0100
@@ -5364,6 +5364,49 @@ check_function_sentinel (const_tree fnty
}
}
+/* 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
if (warn_format)
check_function_sentinel (fntype, nargs, argarray);
+
+ if (warn_restrict)
+ check_function_restrict (fndecl, fntype, nargs, argarray);
return warned_p;
}
--- gcc/c-family/c-warn.c.jj 2017-02-20 13:43:15.126555893 +0100
+++ gcc/c-family/c-warn.c 2017-02-24 19:39:43.621454404 +0100
@@ -2170,55 +2170,49 @@ maybe_warn_bool_compare (location_t loc,
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
--- gcc/c-family/c-common.h.jj 2017-02-20 13:43:15.200554914 +0100
+++ gcc/c-family/c-common.h 2017-02-24 19:39:43.622454390 +0100
@@ -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_che
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
--- gcc/c/c-parser.c.jj 2017-02-20 13:43:15.041557018 +0100
+++ gcc/c/c-parser.c 2017-02-24 19:39:43.626454337 +0100
@@ -8418,28 +8418,6 @@ c_parser_postfix_expression_after_primar
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
--- gcc/c/c-typeck.c.jj 2017-02-22 22:32:35.477710734 +0100
+++ gcc/c/c-typeck.c 2017-02-24 19:39:43.629454298 +0100
@@ -3110,7 +3110,8 @@ build_function_call_vec (location_t 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))
--- gcc/cp/call.c.jj 2017-02-24 15:31:49.041955772 +0100
+++ gcc/cp/call.c 2017-02-24 19:39:43.631454271 +0100
@@ -7903,14 +7903,17 @@ build_over_call (struct z_candidate *can
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);
}
--- gcc/cp/parser.c.jj 2017-02-22 23:00:21.472093702 +0100
+++ gcc/cp/parser.c 2017-02-24 19:39:43.638454178 +0100
@@ -6934,29 +6934,6 @@ cp_parser_postfix_expression (cp_parser
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);
--- gcc/cp/typeck.c.jj 2017-02-20 13:43:21.485471769 +0100
+++ gcc/cp/typeck.c 2017-02-24 19:39:43.640454152 +0100
@@ -3667,7 +3667,7 @@ cp_build_function_call_vec (tree functio
/* 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);
--- gcc/testsuite/g++.dg/warn/Wrestrict-1.C.jj 2017-02-24 19:39:43.640454152 +0100
+++ gcc/testsuite/g++.dg/warn/Wrestrict-1.C 2017-02-24 19:39:43.640454152 +0100
@@ -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);
+}
--- gcc/testsuite/g++.dg/warn/Wrestrict-2.C.jj 2017-02-24 19:39:43.640454152 +0100
+++ gcc/testsuite/g++.dg/warn/Wrestrict-2.C 2017-02-24 19:39:43.640454152 +0100
@@ -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);
+}
Jakub
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-02-24 20:42 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-02-20 20:38 [PATCH] Move -Wrestrict warning later in the FEs and fix some issues in it (PR c++/79588) Jakub Jelinek
2017-02-21 20:45 ` Jason Merrill
2017-02-23 22:13 ` Jeff Law
2017-02-24 20:44 ` Jakub Jelinek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).