blob: 7440c77736e8fb719123970c18d35512dd6a2541 [file] [log] [blame]
Dominic Chen184c6242017-03-03 18:02:02 +00001// RUN: %clang_analyze_cc1 -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
Anna Zaks8d7c8a42013-03-02 03:20:52 +00002
3// Perform inline defensive checks.
Artem Dergachev37de8882017-04-24 19:30:33 +00004void idc(void *p) {
Anna Zaks8d7c8a42013-03-02 03:20:52 +00005 if (p)
6 ;
7}
8
9int test01(int *p) {
10 if (p)
11 ;
12 return *p; // expected-warning {{Dereference of null pointer}}
13}
14
15int 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
24int test03(int *p, int *x) {
25 idc(p);
26 if (p)
27 ;
28 return *p; // False negative
29}
30
31int deref04(int *p) {
32 return *p; // expected-warning {{Dereference of null pointer}}
33}
34
35int test04(int *p) {
36 if (p)
37 ;
38 idc(p);
39 return deref04(p);
40}
41
42int 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
51int test12(int *q) {
52 int *p = q;
53 idc(q);
54 return *p;
55}
56
57int test13(int *q) {
58 int *p = q;
59 idc(p);
60 return *p;
61}
62
63int 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
72int test22(int *q, int *x) {
73 idc(q);
74 if (x)
75 ;
76 int *p = q;
77 return *p;
78}
79
80int 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
90void use(char *p) {
91 if (!p)
92 return;
93 p[0] = 'a';
94}
95
96void test24(char *buffer) {
97 use(buffer);
98 buffer[1] = 'b';
99}
Anna Zaks6c0c47e2013-04-20 01:15:42 +0000100
101// Ensure idc works on pointers with constant offset.
102void idcchar(const char *s2) {
103 if(s2)
104 ;
105}
106void testConstantOffset(char *value) {
107 char *cursor = value + 5;
108 idcchar(cursor);
109 if (*cursor) {
110 cursor++;
111 }
112}
Anna Zaks5673b652013-07-04 02:38:06 +0000113
114// Ensure idc works for integer zero values (ex: suppressed div by zero).
115void idcZero(int assume) {
116 if (assume)
117 ;
118}
119
120int idcTriggerZeroValue(int m) {
121 idcZero(m);
122 return 5/m; // no-warning
123}
124
125int idcTriggerZeroValueThroughCall(int i) {
126 return 5/i; // no-warning
127}
128void idcTrackZeroValueThroughCall(int x) {
129 idcZero(x);
130 idcTriggerZeroValueThroughCall(x);
131}
132
133int idcTriggerZeroThroughDoubleAssignemnt(int i) {
134 return 5/i; // no-warning
135}
136void idcTrackZeroThroughDoubleAssignemnt(int x) {
137 idcZero(x);
138 int y = x;
139 int z = y;
140 idcTriggerZeroValueThroughCall(z);
141}
Artem Dergachev37de8882017-04-24 19:30:33 +0000142
143struct S {
144 int f1;
145 int f2;
146};
147
148void idcTrackZeroValueThroughUnaryPointerOperators(struct S *s) {
149 idc(s);
150 *(&(s->f1)) = 7; // no-warning
151}
152
153void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset1(struct S *s) {
154 idc(s);
155 int *x = &(s->f2);
156 *x = 7; // no-warning
157}
158
159void idcTrackZeroValueThroughUnaryPointerOperatorsWithOffset2(struct S *s) {
160 idc(s);
161 int *x = &(s->f2) - 1;
162 // FIXME: Should not warn.
163 *x = 7; // expected-warning{{Dereference of null pointer}}
164}
165
166void idcTrackZeroValueThroughUnaryPointerOperatorsWithAssignment(struct S *s) {
167 idc(s);
168 int *x = &(s->f1);
169 *x = 7; // no-warning
170}
171
Artem Dergachev8c800612017-09-27 09:50:45 +0000172void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignment(struct S *s) {
173 idc(s);
174 int *x = &*&(s->f1);
175 *x = 7; // no-warning
176}
177
178void idcTrackZeroValueThroughManyUnaryPointerOperatorsWithAssignmentAndUnaryIncrement(struct S *s) {
179 idc(s);
180 int *x = &*&((++s)->f1);
181 *x = 7; // no-warning
182}
183
Artem Dergachev37de8882017-04-24 19:30:33 +0000184
185struct S2 {
186 int a[1];
187};
188
189void idcTrackZeroValueThroughUnaryPointerOperatorsWithArrayField(struct S2 *s) {
190 idc(s);
191 *(&(s->a[0])) = 7; // no-warning
192}
Artem Dergachevfcad5742017-12-20 00:47:17 +0000193
194void idcTrackConstraintThroughSymbolicRegion(int **x) {
195 idc(*x);
196 // FIXME: Should not warn.
197 **x = 7; // expected-warning{{Dereference of null pointer}}
198}
199
200int *idcPlainNull(int coin) {
201 if (coin)
202 return 0;
203 static int X;
204 return &X;
205}
206
207void idcTrackZeroValueThroughSymbolicRegion(int coin, int **x) {
208 *x = idcPlainNull(coin);
209 **x = 7; // no-warning
210}