]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/inlining/inline-defensive-checks.c
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / test / Analysis / inlining / inline-defensive-checks.c
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
2
3 // Perform inline defensive checks.
4 void idc(void *p) {
5         if (p)
6                 ;
7 }
8
9 int test01(int *p) {
10   if (p)
11     ;
12   return *p; // expected-warning {{Dereference of null pointer}}
13 }
14
15 int test02(int *p, int *x) {
16   if (p)
17     ;
18   idc(p);
19         if (x)
20                 ;
21   return *p; // expected-warning {{Dereference of null pointer}}
22 }
23
24 int test03(int *p, int *x) {
25         idc(p);
26         if (p)
27                 ;
28         return *p; // False negative
29 }
30
31 int deref04(int *p) {
32   return *p; // expected-warning {{Dereference of null pointer}}
33 }
34
35 int test04(int *p) {
36   if (p)
37     ;
38   idc(p);
39   return deref04(p);
40 }
41
42 int test11(int *q, int *x) {
43         int *p = q;
44         if (q)
45                 ;
46         if (x)
47                 ;
48         return *p; // expected-warning{{Dereference of null pointer}}
49 }
50
51 int test12(int *q) {
52         int *p = q;
53         idc(q);
54         return *p;
55 }
56
57 int test13(int *q) {
58         int *p = q;
59         idc(p);
60         return *p;
61 }
62
63 int test21(int *q, int *x) {
64         if (q)
65                 ;
66         if (x)
67                 ;
68         int *p = q;
69         return *p; // expected-warning{{Dereference of null pointer}}
70 }
71
72 int test22(int *q, int *x) {
73   idc(q);
74         if (x)
75                 ;
76         int *p = q;
77         return *p;
78 }
79
80 int test23(int *q, int *x) {
81   idc(q);
82         if (x)
83                 ;
84         int *p = q;
85   if (!p)
86     ;
87         return *p; // False negative
88 }
89
90 void use(char *p) {
91   if (!p)
92     return;
93   p[0] = 'a';
94 }
95
96 void test24(char *buffer) {
97   use(buffer);
98   buffer[1] = 'b';
99 }
100
101 // Ensure idc works on pointers with constant offset.
102 void idcchar(const char *s2) {
103   if(s2)
104     ;
105 }
106 void testConstantOffset(char *value) {
107   char *cursor = value + 5;
108   idcchar(cursor);
109   if (*cursor) {
110     cursor++;
111   }
112 }
113
114 // Ensure idc works for integer zero values (ex: suppressed div by zero).
115 void idcZero(int assume) {
116   if (assume)
117     ;
118 }
119
120 int idcTriggerZeroValue(int m) {
121   idcZero(m);
122   return 5/m; // no-warning
123 }
124
125 int idcTriggerZeroValueThroughCall(int i) {
126   return 5/i; // no-warning
127 }
128 void idcTrackZeroValueThroughCall(int x) {
129   idcZero(x);
130   idcTriggerZeroValueThroughCall(x);
131 }
132
133 int idcTriggerZeroThroughDoubleAssignemnt(int i) {
134   return 5/i; // no-warning
135 }
136 void idcTrackZeroThroughDoubleAssignemnt(int x) {
137   idcZero(x);
138   int y = x;
139   int z = y;
140   idcTriggerZeroValueThroughCall(z);
141 }
142
143 struct S {
144   int f1;
145   int f2;
146 };
147
148 void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {
149   idc(s);
150   *(&(s->f1)) = 7; // no-warning
151 }
152
153 void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {
154   idc(s);
155   int *x = &(s->f2);
156   *x = 7; // no-warning
157 }
158
159 void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {
160   idc(s);
161   int *x = &(s->f2) - 1;
162   *x = 7; // no-warning
163 }
164
165 void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
166   idc(s);
167   int *x = &(s->f1);
168   *x = 7; // no-warning
169 }
170
171 void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {
172   idc(s);
173   int *x = &*&(s->f1);
174   *x = 7; // no-warning
175 }
176
177 void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
178   idc(s);
179   int *x = &*&((++s)->f1);
180   *x = 7; // no-warning
181 }
182
183
184 struct S2 {
185   int a[1];
186 };
187
188 void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {
189   idc(s);
190   *(&(s->a[0])) = 7; // no-warning
191 }
192
193 void idcTrackConstraintThroughSymbolicRegion(int **x) {
194   idc(*x);
195   // FIXME: Should not warn.
196   **x = 7; // expected-warning{{Dereference of null pointer}}
197 }
198
199 void idcTrackConstraintThroughSymbolicRegionAndParens(int **x) {
200   idc(*x);
201   // FIXME: Should not warn.
202   *(*x) = 7; // expected-warning{{Dereference of null pointer}}
203 }
204
205 int *idcPlainNull(int coin) {
206   if (coin)
207     return 0;
208   static int X;
209   return &X;
210 }
211
212 void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {
213   *x = idcPlainNull(coin);
214   **x = 7; // no-warning
215 }
216
217 void idcTrackZeroValueThroughSymbolicRegionAndParens(int coin, int **x) {
218   *x = idcPlainNull(coin);
219   *(*x) = 7; // no-warning
220 }
221
222 struct WithInt {
223   int i;
224 };
225
226 struct WithArray {
227   struct WithInt arr[1];
228 };
229
230 struct WithArray *idcPlainNullWithArray(int coin) {
231   if (coin)
232     return 0;
233   static struct WithArray S;
234   return &S;
235 }
236
237 void idcTrackZeroValueThroughSymbolicRegionWithArray(int coin, struct WithArray **s) {
238   *s = idcPlainNullWithArray(coin);
239   (*s)->arr[0].i = 1; // no-warning
240   // Same thing.
241   (*s)->arr->i = 1; // no-warning
242 }