mirror of git://gcc.gnu.org/git/gcc.git
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
This commit is contained in:
parent
3c82efd91f
commit
332f1d2404
|
|
@ -1,3 +1,9 @@
|
|||
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>
|
||||
|
||||
* builtins.c (get_object_alignment_2): Correct offset handling
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
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>
|
||||
|
||||
* c-gimplify.c: Include dumpfile.h instead of tree-dump.h.
|
||||
|
|
|
|||
|
|
@ -8051,26 +8051,42 @@ handle_nonnull_attribute (tree *node, tree ARG_UNUSED (name),
|
|||
static void
|
||||
check_function_nonnull (tree attrs, int nargs, tree *argarray)
|
||||
{
|
||||
tree a, args;
|
||||
tree a;
|
||||
int i;
|
||||
|
||||
for (a = attrs; a; a = TREE_CHAIN (a))
|
||||
{
|
||||
if (is_attribute_p ("nonnull", TREE_PURPOSE (a)))
|
||||
{
|
||||
args = TREE_VALUE (a);
|
||||
attrs = lookup_attribute ("nonnull", attrs);
|
||||
if (attrs == NULL_TREE)
|
||||
return;
|
||||
|
||||
/* Walk the argument list. If we encounter an argument number we
|
||||
should check for non-null, do it. If the attribute has no args,
|
||||
then every pointer argument is checked (in which case the check
|
||||
for pointer type is done in check_nonnull_arg). */
|
||||
for (i = 0; i < nargs; i++)
|
||||
a = attrs;
|
||||
/* See if any of the nonnull attributes has no arguments. If so,
|
||||
then every pointer argument is checked (in which case the check
|
||||
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++)
|
||||
check_function_arguments_recurse (check_nonnull_arg, NULL, argarray[i],
|
||||
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))
|
||||
{
|
||||
if (!args || nonnull_check_p (args, i + 1))
|
||||
check_function_arguments_recurse (check_nonnull_arg, NULL,
|
||||
argarray[i],
|
||||
i + 1);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,8 @@
|
|||
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>
|
||||
|
||||
PR c++/54026
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
/* 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,32 +353,35 @@ nonnull_arg_p (const_tree arg)
|
|||
return true;
|
||||
|
||||
fntype = TREE_TYPE (current_function_decl);
|
||||
attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
|
||||
|
||||
/* If "nonnull" wasn't specified, we know nothing about the argument. */
|
||||
if (attrs == NULL_TREE)
|
||||
return false;
|
||||
|
||||
/* If "nonnull" applies to all the arguments, then ARG is non-null. */
|
||||
if (TREE_VALUE (attrs) == NULL_TREE)
|
||||
return true;
|
||||
|
||||
/* Get the position number for ARG in the function signature. */
|
||||
for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
|
||||
t;
|
||||
t = DECL_CHAIN (t), arg_num++)
|
||||
for (attrs = TYPE_ATTRIBUTES (fntype); attrs; attrs = TREE_CHAIN (attrs))
|
||||
{
|
||||
if (t == arg)
|
||||
break;
|
||||
}
|
||||
attrs = lookup_attribute ("nonnull", attrs);
|
||||
|
||||
gcc_assert (t == arg);
|
||||
/* If "nonnull" wasn't specified, we know nothing about the argument. */
|
||||
if (attrs == NULL_TREE)
|
||||
return false;
|
||||
|
||||
/* Now see if ARG_NUM is mentioned in the nonnull list. */
|
||||
for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
|
||||
{
|
||||
if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
|
||||
/* If "nonnull" applies to all the arguments, then ARG is non-null. */
|
||||
if (TREE_VALUE (attrs) == NULL_TREE)
|
||||
return true;
|
||||
|
||||
/* Get the position number for ARG in the function signature. */
|
||||
for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
|
||||
t;
|
||||
t = DECL_CHAIN (t), arg_num++)
|
||||
{
|
||||
if (t == arg)
|
||||
break;
|
||||
}
|
||||
|
||||
gcc_assert (t == arg);
|
||||
|
||||
/* Now see if ARG_NUM is mentioned in the nonnull list. */
|
||||
for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
|
||||
{
|
||||
if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Reference in New Issue