re PR tree-optimization/35503 (Warning about restricted pointers?)

2016-11-13  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>

	PR c/35503
	* doc/invoke.texi: Document Wrestrict.
	* pretty-print.c (pp_format): Add case for "Z" specifier.
	(test_pp_format): Test "Z" specifier.
c-family/
	* c-common.h (warn_for_restrict): Declare.
	* c-warn.c: Include gcc-rich-location.h.
	(warn_for_restrict): New function.
	* c-format.c (gcc_tdiag_char_table): Add entry for "Z" specifier.
	(gcc_cdiag_char_table): Likewise.
	(gcc_cxxdiag_char_table): Likewise.
	* c.opt (Wrestrict): New option.
c/
	* c-parser.c (c_parser_postfix_expression_after_primary): Call
	warn_for_restrict.
cp/
	* parser.c (cp_parser_postfix_pexpression): Call warn_for_restrict.
testsuite/
	* c-c++-common/pr35503-1.c: New test.
	* c-c++-common/pr35503-2.c: Likewise.
	* c-c++-common/pr35503-3.c: Likewise.
	* gcc.dg/format/gcc_diag-1.c: Add tests for "Z" specifier.

From-SVN: r242366
This commit is contained in:
Prathamesh Kulkarni 2016-11-13 19:38:36 +00:00 committed by Prathamesh Kulkarni
parent 8d5a1b4f64
commit 975672f357
14 changed files with 212 additions and 2 deletions

View File

@ -1,3 +1,23 @@
2016-11-13 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR c/35503
* doc/invoke.texi: Document Wrestrict.
* pretty-print.c (pp_format): Add case for "Z" specifier.
(test_pp_format): Test "Z" specifier.
c-family/
* c-common.h (warn_for_restrict): Declare.
* c-warn.c: Include gcc-rich-location.h.
(warn_for_restrict): New function.
* c-format.c (gcc_tdiag_char_table): Add entry for "Z" specifier.
(gcc_cdiag_char_table): Likewise.
(gcc_cxxdiag_char_table): Likewise.
* c.opt (Wrestrict): New option.
c/
* c-parser.c (c_parser_postfix_expression_after_primary): Call
warn_for_restrict.
cp/
* parser.c (cp_parser_postfix_pexpression): Call warn_for_restrict.
2016-11-13 Eric Botcazou <ebotcazou@adacore.com>
* ipa-icf.c (sem_function::merge): Do not create a wrapper also if the

View File

@ -1492,6 +1492,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> *);
/* Places where an lvalue, or modifiable lvalue, may be required.
Used to select diagnostic messages in lvalue_error and

View File

@ -713,6 +713,7 @@ static const format_char_info gcc_tdiag_char_table[] =
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
{ "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
{ "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
@ -736,6 +737,7 @@ static const format_char_info gcc_cdiag_char_table[] =
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
{ "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
{ "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};
@ -762,6 +764,7 @@ static const format_char_info gcc_cxxdiag_char_table[] =
{ "r", 1, STD_C89, { T89_C, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "cR", NULL },
{ "<>'R",0, STD_C89, NOARGUMENTS, "", "", NULL },
{ "m", 0, STD_C89, NOARGUMENTS, "q", "", NULL },
{ "Z", 1, STD_C89, { T89_I, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "", &gcc_tdiag_char_table[0] },
{ NULL, 0, STD_C89, NOLENGTHS, NULL, NULL, NULL }
};

View File

@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "intl.h"
#include "asan.h"
#include "gcc-rich-location.h"
/* Print a warning if a constant expression had overflow in folding.
Invoke this function on every expression that the language
@ -2161,3 +2162,58 @@ maybe_warn_bool_compare (location_t loc, enum tree_code code, tree op0,
"with boolean expression is always false", cst);
}
}
/* Warn if an argument at position param_pos is passed to a
restrict-qualified param, and it aliases with another argument. */
void
warn_for_restrict (unsigned param_pos, vec<tree, va_gc> *args)
{
tree arg = (*args)[param_pos];
if (TREE_VISITED (arg) || operand_equal_p (arg, null_pointer_node, 0))
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;
FOR_EACH_VEC_ELT (*args, i, current_arg)
{
if (i == param_pos)
continue;
tree current_arg = (*args)[i];
if (operand_equal_p (arg, current_arg, 0))
{
TREE_VISITED (current_arg) = 1;
arg_positions[arg_positions_len++] = (i + 1);
}
}
if (arg_positions_len == 0)
{
free (arg_positions);
return;
}
for (unsigned i = 0; i < arg_positions_len; i++)
{
unsigned pos = arg_positions[i];
tree arg = (*args)[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,
"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);
}

View File

@ -1085,6 +1085,11 @@ Wduplicate-decl-specifier
C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall)
Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier.
Wrestrict
C ObjC C++ ObjC++ Var(warn_restrict) Warning LangEnabledBy(C ObjC C++ ObjC++)
Warn when an argument passed to a restrict-qualified parameter aliases with
another argument.
ansi
C ObjC C++ ObjC++
A synonym for -std=c89 (for C) or -std=c++98 (for C++).

View File

@ -8451,6 +8451,28 @@ 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

@ -6925,6 +6925,29 @@ 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

@ -292,7 +292,7 @@ Objective-C and Objective-C++ Dialects}.
-Wparentheses -Wno-pedantic-ms-format @gol
-Wplacement-new -Wplacement-new=@var{n} @gol
-Wpointer-arith -Wno-pointer-to-int-cast @gol
-Wno-pragmas -Wredundant-decls -Wno-return-local-addr @gol
-Wno-pragmas -Wredundant-decls -Wrestrict -Wno-return-local-addr @gol
-Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol
-Wshadow=global, -Wshadow=local, -Wshadow=compatible-local @gol
-Wshift-overflow -Wshift-overflow=@var{n} @gol
@ -6187,6 +6187,12 @@ reduce the padding and so make the structure smaller.
Warn if anything is declared more than once in the same scope, even in
cases where multiple declaration is valid and changes nothing.
@item -Wrestrict
@opindex Wrestrict
@opindex Wno-restrict
Warn when an argument passed to a restrict-qualified parameter
aliases with another argument.
@item -Wnested-externs @r{(C and Objective-C only)}
@opindex Wnested-externs
@opindex Wno-nested-externs

View File

@ -294,6 +294,8 @@ pp_indent (pretty_printer *pp)
integer.
%Ns: likewise, but length specified as constant in the format string.
Flag 'q': quote formatted text (must come immediately after '%').
%Z: Requires two arguments - array of int, and len. Prints elements
of the array.
Arguments can be used sequentially, or through %N$ resp. *N$
notation Nth argument after the format string. If %N$ / *N$
@ -610,6 +612,23 @@ pp_format (pretty_printer *pp, text_info *text)
(pp, *text->args_ptr, precision, unsigned, "u");
break;
case 'Z':
{
int *v = va_arg (*text->args_ptr, int *);
unsigned len = va_arg (*text->args_ptr, unsigned);
for (unsigned i = 0; i < len; ++i)
{
pp_scalar (pp, "%i", v[i]);
if (i < len - 1)
{
pp_comma (pp);
pp_space (pp);
}
}
break;
}
case 'x':
if (wide)
pp_scalar (pp, HOST_WIDE_INT_PRINT_HEX,
@ -1424,6 +1443,13 @@ test_pp_format ()
"`\33[01m\33[Kfoo\33[m\33[K' 12345678", "%qs %x",
"foo", 0x12345678);
/* Verify %Z. */
int v[] = { 1, 2, 3 };
ASSERT_PP_FORMAT_3 ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678);
int v2[] = { 0 };
ASSERT_PP_FORMAT_3 ("0 12345678", "%Z %x", v2, 1, 0x12345678);
/* Verify that combinations work, along with unformatted text. */
assert_pp_format (SELFTEST_LOCATION,
"the quick brown fox jumps over the lazy dog",

View File

@ -1,3 +1,11 @@
2016-11-13 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
PR c/35503
* c-c++-common/pr35503-1.c: New test.
* c-c++-common/pr35503-2.c: Likewise.
* c-c++-common/pr35503-3.c: Likewise.
* gcc.dg/format/gcc_diag-1.c: Add tests for "Z" specifier.
2016-11-13 Uros Bizjak <ubizjak@gmail.com>
PR rtl-optimization/78232

View File

@ -0,0 +1,10 @@
/* { dg-do compile } */
/* { dg-options "-Wrestrict" } */
int foo (char *__restrict buf, const char *__restrict fmt, ...);
void f(void)
{
char buf[100] = "hello";
foo (buf, "%s-%s", buf, "world"); /* { dg-warning "passing argument 1 to restrict-qualified parameter aliases with argument 3" } */
}

View File

@ -0,0 +1,14 @@
/* { dg-do compile } */
/* { dg-options "-fdiagnostics-show-caret -Wrestrict" } */
void f(int *__restrict x, int *y, int *__restrict z, int *w);
void foo(int alpha, int beta)
{
f (&alpha, &beta, &alpha, &alpha); /* { dg-warning "passing argument 1 to restrict-qualified parameter aliases with arguments 3, 4" } */
/* { dg-begin-multiline-output "" }
f (&alpha, &beta, &alpha, &alpha);
^~~~~~ ~~~~~~ ~~~~~~
{ dg-end-multiline-output "" } */
}

View File

@ -0,0 +1,9 @@
/* { dg-do compile } */
/* { dg-options "-Wrestrict" } */
void f(int *x, int *__restrict y);
void foo(int a)
{
f (&a, &a); /* { dg-warning "passing argument 2 to restrict-qualified parameter aliases with argument 1" } */
}

View File

@ -32,7 +32,7 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
ullong ull, unsigned int *un, const int *cn, signed char *ss,
unsigned char *us, const signed char *css, unsigned int u1,
unsigned int u2, location_t *loc, tree t1, union tree_node *t2,
tree *t3, tree t4[])
tree *t3, tree t4[], int *v, unsigned v_len)
{
/* Acceptable C90 specifiers, flags and modifiers. */
diag ("%%");
@ -90,6 +90,10 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
cdiag ("%v%qv%#v", i, i, i);
cxxdiag ("%v%qv%#v", i, i, i);
tdiag ("%Z", v, v_len);
cdiag ("%Z", v, v_len);
cxxdiag ("%Z", v, v_len);
/* Bad stuff with extensions. */
diag ("%m", i); /* { dg-warning "format" "extra arg" } */
tdiag ("%m", i); /* { dg-warning "format" "extra arg" } */
@ -133,6 +137,9 @@ foo (int i, int i1, int i2, unsigned int u, double d, char *s, void *p,
cdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
cxxdiag ("%v", t1); /* { dg-warning "format" "wrong arg" } */
tdiag ("%Z"); /* { dg-warning "format" "missing arg" } */
tdiag ("%Z", t1); /* { dg-warning "format" "wrong arg" } */
/* Standard specifiers not accepted in the diagnostic framework. */
diag ("%X\n", u); /* { dg-warning "format" "HEX" } */
diag ("%f\n", d); /* { dg-warning "format" "float" } */