1 #include <stdlib.h>
2
3 extern void foo(void *ptrA, void *ptrB, void *ptrC) /* { dg-message "argument 1 of 'foo' must be non-null" } */
4 __attribute__((nonnull (1, 3)));
5
6 extern void bar(void *ptrA, void *ptrB, void *ptrC) /* { dg-message "argument 1 of 'bar' must be non-null" } */
7 __attribute__((nonnull));
8
9 // TODO: complain about NULL and possible NULL args
10 // FIXME: ought to complain about NULL args
11
test_1(void * p,void * q,void * r)12 void test_1 (void *p, void *q, void *r)
13 {
14 foo(p, q, r);
15 foo(NULL, q, r);
16 foo(p, NULL, r);
17 foo(p, q, NULL);
18 }
19
test_1a(void * q,void * r)20 void test_1a (void *q, void *r)
21 {
22 void *p = NULL;
23 foo(p, q, r); /* { dg-warning "use of NULL 'p' where non-null expected" "warning" } */
24 /* { dg-message "argument 1 \\('p'\\) NULL where non-null expected" "note" { target *-*-* } .-1 } */
25 }
26
test_2(void * p,void * q,void * r)27 void test_2 (void *p, void *q, void *r)
28 {
29 bar(p, q, r);
30 bar(NULL, q, r);
31 bar(p, NULL, r);
32 bar(p, q, NULL);
33 }
34
test_3(void * q,void * r)35 void test_3 (void *q, void *r)
36 {
37 void *p = malloc(1024); /* { dg-message "\\(1\\) this call could return NULL" } */
38
39 foo(p, q, r); /* { dg-warning "use of possibly-NULL 'p' where non-null expected" "warning" } */
40 /* { dg-message "argument 1 \\('p'\\) from \\(1\\) could be NULL where non-null expected" "note" { target *-*-* } .-1 } */
41
42 foo(p, q, r);
43
44 free(p);
45 }
46
test_4(void * q,void * r)47 void test_4 (void *q, void *r)
48 {
49 void *p = malloc(1024); /* { dg-message "\\(1\\) this call could return NULL" } */
50
51 bar(p, q, r); /* { dg-warning "use of possibly-NULL 'p' where non-null expected" "warning" } */
52 /* { dg-message "argument 1 \\('p'\\) from \\(1\\) could be NULL where non-null expected" "note" { target *-*-* } .-1 } */
53
54 bar(p, q, r);
55
56 free(p);
57 }
58
59 /* Verify that we detect passing NULL to a __attribute__((nonnull)) function
60 when it's called via a function pointer. */
61
62 typedef void (*bar_t)(void *ptrA, void *ptrB, void *ptrC);
63
64 static bar_t __attribute__((noinline))
get_bar(void)65 get_bar (void)
66 {
67 return bar;
68 }
69
test_5(void * q,void * r)70 void test_5 (void *q, void *r)
71 {
72 void *p = malloc(1024); /* { dg-message "\\(1\\) this call could return NULL" } */
73 bar_t cb = get_bar ();
74 cb(p, q, r); /* { dg-warning "use of possibly-NULL 'p' where non-null expected" "warning" } */
75 /* { dg-message "argument 1 \\('p'\\) from \\(1\\) could be NULL where non-null expected" "note" { target *-*-* } .-1 } */
76 /* TODO: do we want an event showing where cb is assigned "bar"? */
77
78 cb(p, q, r);
79
80 free(p);
81 }
82