Commit 332f1d24 by Jakub Jelinek Committed by Jakub Jelinek

re PR c++/28656 (duplicated null argument warning on memcpy())

	PR c++/28656
	* tree-vrp.c (nonnull_arg_p): Handle all nonnull attributes instead
	of just the first one.

	* c-common.c (check_function_nonnull): Handle multiple nonnull
	attributes properly.

	* c-c++-common/pr28656.c: New test.

From-SVN: r189707
parent 3c82efd9
2012-07-20 Jakub Jelinek <jakub@redhat.com>
PR c++/28656
* tree-vrp.c (nonnull_arg_p): Handle all nonnull attributes instead
of just the first one.
2012-07-20 Richard Guenther <rguenther@suse.de> 2012-07-20 Richard Guenther <rguenther@suse.de>
* builtins.c (get_object_alignment_2): Correct offset handling * builtins.c (get_object_alignment_2): Correct offset handling
......
2012-07-20 Jakub Jelinek <jakub@redhat.com>
PR c++/28656
* c-common.c (check_function_nonnull): Handle multiple nonnull
attributes properly.
2012-07-16 Steven Bosscher <steven@gcc.gnu.org> 2012-07-16 Steven Bosscher <steven@gcc.gnu.org>
* c-gimplify.c: Include dumpfile.h instead of tree-dump.h. * c-gimplify.c: Include dumpfile.h instead of tree-dump.h.
......
...@@ -8051,26 +8051,42 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name), ...@@ -8051,26 +8051,42 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
static void static void
check_function_nonnull (tree attrs, int nargs, tree *argarray) check_function_nonnull (tree attrs, int nargs, tree *argarray)
{ {
tree a, args; tree a;
int i; int i;
for (a = attrs; a; a = TREE_CHAIN (a)) attrs = lookup_attribute ("nonnull", attrs);
{ if (attrs == NULL_TREE)
if (is_attribute_p ("nonnull", TREE_PURPOSE (a))) return;
{
args = TREE_VALUE (a);
/* Walk the argument list. If we encounter an argument number we a = attrs;
should check for non-null, do it. If the attribute has no args, /* See if any of the nonnull attributes has no arguments. If so,
then every pointer argument is checked (in which case the check then every pointer argument is checked (in which case the check
for pointer type is done in check_nonnull_arg). */ for pointer type is done in check_nonnull_arg). */
if (TREE_VALUE (a) != NULL_TREE)
do
a = lookup_attribute ("nonnull", TREE_CHAIN (a));
while (a != NULL_TREE && TREE_VALUE (a) != NULL_TREE);
if (a != NULL_TREE)
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
{ check_function_arguments_recurse (check_nonnull_arg, NULL, argarray[i],
if (!args || nonnull_check_p (args, i + 1))
check_function_arguments_recurse (check_nonnull_arg, NULL,
argarray[i],
i + 1); i + 1);
else
{
/* Walk the argument list. If we encounter an argument number we
should check for non-null, do it. */
for (i = 0; i < nargs; i++)
{
for (a = attrs; ; a = TREE_CHAIN (a))
{
a = lookup_attribute ("nonnull", a);
if (a == NULL_TREE || nonnull_check_p (TREE_VALUE (a), i + 1))
break;
} }
if (a != NULL_TREE)
check_function_arguments_recurse (check_nonnull_arg, NULL,
argarray[i], i + 1);
} }
} }
} }
......
2012-07-20 Jakub Jelinek <jakub@redhat.com>
PR c++/28656
* c-c++-common/pr28656.c: New test.
2012-07-19 Jason Merrill <jason@redhat.com> 2012-07-19 Jason Merrill <jason@redhat.com>
PR c++/54026 PR c++/54026
......
/* PR c++/28656 */
/* { dg-do compile } */
/* { dg-options "-Wnonnull" } */
#ifdef __cplusplus
extern "C" {
#endif
extern void *memcpy (void *__restrict, const void *__restrict, __SIZE_TYPE__)
__attribute__((nonnull (1), nonnull (2), nonnull (1, 2), nonnull));
#ifdef __cplusplus
}
#endif
extern void bar (void *p1, void *p2, void *p3, void *p4, void *p5)
__attribute__((nonnull (1), nonnull (1, 3), nonnull (3, 5), nonnull (4)));
void
foo (void)
{
memcpy (0, 0, 0);
bar (0, 0, 0, 0, 0);
}
/* { dg-warning "null argument where non-null required\[^\n\r\]*argument 1" "" { target *-*-* } 20 } */
/* { dg-warning "null argument where non-null required\[^\n\r\]*argument 2" "" { target *-*-* } 20 } */
/* { dg-warning "null argument where non-null required\[^\n\r\]*argument 1" "" { target *-*-* } 21 } */
/* { dg-warning "null argument where non-null required\[^\n\r\]*argument 3" "" { target *-*-* } 21 } */
/* { dg-warning "null argument where non-null required\[^\n\r\]*argument 4" "" { target *-*-* } 21 } */
/* { dg-warning "null argument where non-null required\[^\n\r\]*argument 5" "" { target *-*-* } 21 } */
...@@ -353,7 +353,9 @@ nonnull_arg_p (const_tree arg) ...@@ -353,7 +353,9 @@ nonnull_arg_p (const_tree arg)
return true; return true;
fntype = TREE_TYPE (current_function_decl); fntype = TREE_TYPE (current_function_decl);
attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype)); for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs))
{
attrs = lookup_attribute ("nonnull", attrs);
/* If "nonnull" wasn't specified, we know nothing about the argument. */ /* If "nonnull" wasn't specified, we know nothing about the argument. */
if (attrs == NULL_TREE) if (attrs == NULL_TREE)
...@@ -380,6 +382,7 @@ nonnull_arg_p (const_tree arg) ...@@ -380,6 +382,7 @@ nonnull_arg_p (const_tree arg)
if (compare_tree_int (TREE_VALUE (t), arg_num) == 0) if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
return true; return true;
} }
}
return false; return false;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment