1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#include <stdio.h>
struct st
{
char *str;
int i;
};
int test_1 (struct st *p)
{
fprintf (stderr, "str: %s\n", p->str); /* { dg-message "pointer 'p' is dereferenced here" } */
if (!p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
return -1;
return p->i;
}
int test_2 (int flag_a, int flag_b, struct st *p)
{
if (flag_a)
{
int j = p->i; /* { dg-message "pointer 'p' is dereferenced here" } */
if (flag_b && p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
return 1;
return j;
}
return 2;
}
int test_3 (struct st *a, struct st *b)
{
if (!a)
return b->i;
if (!b)
return a->i;
return 0;
}
int test_4 (struct st *p)
{
int *q = &p->i;
if (!p)
return -1;
return *q;
}
void test_check_after_strlen (const char *str)
{
size_t len_a = __builtin_strlen (str); /* { dg-message "pointer 'str' is dereferenced here" } */
size_t len_b = str ? __builtin_strlen (str) : 0; /* { dg-warning "check of 'str' for NULL after already dereferencing it" } */
}
void test_6 (struct st *a, struct st *b)
{
int diff = a->i - b->i; /* { dg-message "pointer 'b' is dereferenced here" } */
/* ... */
if (b) /* { dg-warning "check of 'b' for NULL after already dereferencing it" } */
fprintf (stderr, "str: %s\n", b->str);
}
void test_check_after_strcmp (const char *s1, const char *s2)
{
if (!__builtin_strcmp (s1, s2)) /* { dg-message "pointer 's1' is dereferenced here" } */
return;
/* ... */
if (s1) /* { dg-warning "check of 's1' for NULL after already dereferencing it" } */
return;
}
void test_more_than_one_deref (struct st *p)
{
char *str = p->str; /* { dg-message "pointer 'p' is dereferenced here" } */
int i = p->i;
/* ... */
if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
return;
/* ... */
}
void test_deref_under_another_name (struct st *p)
{
struct st *q = p;
int i = q->i; /* { dg-message "pointer 'p' is dereferenced here" } */
/* ... */
if (p) /* { dg-warning "check of 'p' for NULL after already dereferencing it" } */
return;
/* ... */
}
void test_check_after_memcpy_src (struct st *dst, struct st *src)
{
__builtin_memcpy (dst, src, sizeof (struct st)); /* { dg-message "pointer 'src' is dereferenced here" } */
/* ... */
if (!src) /* { dg-warning "check of 'src' for NULL after already dereferencing it" } */
return;
/* ... */
}
void test_check_after_memcpy_dst (struct st *dst, struct st *src)
{
__builtin_memcpy (dst, src, sizeof (struct st)); /* { dg-message "pointer 'dst' is dereferenced here" } */
/* ... */
if (!dst) /* { dg-warning "check of 'dst' for NULL after already dereferencing it" } */
return;
/* ... */
}
void test_merger (int *p, int flag)
{
int x = *p;
if (flag)
__builtin_free (p);
if (!flag)
__builtin_free (p); /* { dg-bogus "double-'free'" } */
}
|