blob: 57705a646f008e8ad2cb7256c5aeedfa27ef8f5e [file] [log] [blame]
Ted Kremenekade31952011-03-12 06:14:28 +00001// RUN: %clang_cc1 -analyze -analyzer-store=region -analyzer-constraints=range -fblocks -analyzer-opt-analyze-nested-blocks -analyzer-checker=deadcode.IdempotentOperations -verify %s
2// RUN: %clang --analyze -Xclang -analyzer-disable-checker=deadcode.DeadStores -Xclang -verify %s
Tom Caredb2fa8a2010-07-06 21:43:29 +00003
4// Basic tests
5
6extern void test(int i);
Ted Kremenek45329312010-07-17 00:40:32 +00007extern void test_f(float f);
Tom Caredb2fa8a2010-07-06 21:43:29 +00008
Tom Care245adab2010-08-18 21:17:24 +00009unsigned basic() {
Tom Caredb2fa8a2010-07-06 21:43:29 +000010 int x = 10, zero = 0, one = 1;
11
12 // x op x
Ted Kremenek3e5637f2010-07-27 18:49:08 +000013 x = x; // expected-warning {{Assigned value is always the same as the existing value}}
14 test(x - x); // expected-warning {{Both operands to '-' always have the same value}}
15 x -= x; // expected-warning {{Both operands to '-=' always have the same value}}
Tom Caredb2fa8a2010-07-06 21:43:29 +000016 x = 10; // no-warning
Ted Kremenek3e5637f2010-07-27 18:49:08 +000017 test(x / x); // expected-warning {{Both operands to '/' always have the same value}}
18 x /= x; // expected-warning {{Both operands to '/=' always have the same value}}
Tom Caredb2fa8a2010-07-06 21:43:29 +000019 x = 10; // no-warning
Ted Kremenek3e5637f2010-07-27 18:49:08 +000020 test(x & x); // expected-warning {{Both operands to '&' always have the same value}}
21 x &= x; // expected-warning {{Both operands to '&=' always have the same value}}
22 test(x | x); // expected-warning {{Both operands to '|' always have the same value}}
23 x |= x; // expected-warning {{Both operands to '|=' always have the same value}}
Tom Caredb2fa8a2010-07-06 21:43:29 +000024
25 // x op 1
Ted Kremenek3e5637f2010-07-27 18:49:08 +000026 test(x * one); // expected-warning {{The right operand to '*' is always 1}}
27 x *= one; // expected-warning {{The right operand to '*=' is always 1}}
28 test(x / one); // expected-warning {{The right operand to '/' is always 1}}
29 x /= one; // expected-warning {{The right operand to '/=' is always 1}}
Tom Caredb2fa8a2010-07-06 21:43:29 +000030
31 // 1 op x
Ted Kremenek3e5637f2010-07-27 18:49:08 +000032 test(one * x); // expected-warning {{The left operand to '*' is always 1}}
Tom Caredb2fa8a2010-07-06 21:43:29 +000033
34 // x op 0
Ted Kremenek3e5637f2010-07-27 18:49:08 +000035 test(x + zero); // expected-warning {{The right operand to '+' is always 0}}
36 test(x - zero); // expected-warning {{The right operand to '-' is always 0}}
37 test(x * zero); // expected-warning {{The right operand to '*' is always 0}}
38 test(x & zero); // expected-warning {{The right operand to '&' is always 0}}
39 test(x | zero); // expected-warning {{The right operand to '|' is always 0}}
40 test(x ^ zero); // expected-warning {{The right operand to '^' is always 0}}
41 test(x << zero); // expected-warning {{The right operand to '<<' is always 0}}
42 test(x >> zero); // expected-warning {{The right operand to '>>' is always 0}}
Tom Caredb2fa8a2010-07-06 21:43:29 +000043
44 // 0 op x
Ted Kremenek3e5637f2010-07-27 18:49:08 +000045 test(zero + x); // expected-warning {{The left operand to '+' is always 0}}
46 test(zero - x); // expected-warning {{The left operand to '-' is always 0}}
47 test(zero / x); // expected-warning {{The left operand to '/' is always 0}}
48 test(zero * x); // expected-warning {{The left operand to '*' is always 0}}
49 test(zero & x); // expected-warning {{The left operand to '&' is always 0}}
50 test(zero | x); // expected-warning {{The left operand to '|' is always 0}}
51 test(zero ^ x); // expected-warning {{The left operand to '^' is always 0}}
52 test(zero << x); // expected-warning {{The left operand to '<<' is always 0}}
53 test(zero >> x); // expected-warning {{The left operand to '>>' is always 0}}
Tom Care245adab2010-08-18 21:17:24 +000054
Tom Caredb34ab72010-08-23 19:51:57 +000055 // Overwrite the values so these aren't marked as Pseudoconstants
Tom Care245adab2010-08-18 21:17:24 +000056 x = 1;
57 zero = 2;
58 one = 3;
59
60 return x + zero + one;
Tom Caredb2fa8a2010-07-06 21:43:29 +000061}
Ted Kremenek45329312010-07-17 00:40:32 +000062
63void floats(float x) {
Tom Carea7a8a452010-08-12 22:45:47 +000064 test_f(x * 1.0); // no-warning
Ted Kremenek45329312010-07-17 00:40:32 +000065 test_f(x * 1.0F); // no-warning
66}
Tom Cared85770b2010-07-30 21:42:31 +000067
Tom Carea7a8a452010-08-12 22:45:47 +000068// Ensure that we don't report false poitives in complex loops
Tom Cared85770b2010-07-30 21:42:31 +000069void bailout() {
Tom Carea7a8a452010-08-12 22:45:47 +000070 int unused = 0, result = 4;
71 result = result; // expected-warning {{Assigned value is always the same as the existing value}}
Tom Cared85770b2010-07-30 21:42:31 +000072
Tom Carea7a8a452010-08-12 22:45:47 +000073 for (unsigned bg = 0; bg < 1024; bg ++) {
74 result = bg * result; // no-warning
Tom Cared85770b2010-07-30 21:42:31 +000075
76 for (int i = 0; i < 256; i++) {
Tom Carea7a8a452010-08-12 22:45:47 +000077 unused *= i; // no-warning
Tom Cared85770b2010-07-30 21:42:31 +000078 }
79 }
80}
Tom Carea7a8a452010-08-12 22:45:47 +000081
Tom Care6d0e6ce2010-08-27 22:46:32 +000082// Relaxed liveness - check that we don't kill liveness at assignments
83typedef unsigned uintptr_t;
84void kill_at_assign() {
85 short array[2];
Ted Kremenekade31952011-03-12 06:14:28 +000086 uintptr_t x = (uintptr_t) array;
87 short *p = (short *) x;
Tom Care6d0e6ce2010-08-27 22:46:32 +000088
89 // The following branch should be infeasible.
90 if (!(p = &array[0])) { // expected-warning{{Assigned value is always the same as the existing value}}
91 p = 0;
92 *p = 1; // no-warning
93 }
94}
95
Tom Carea7a8a452010-08-12 22:45:47 +000096// False positive tests
97
98unsigned false1() {
Tom Care50e8ac22010-08-16 21:43:52 +000099 int a = 10;
100 return a * (5 - 2 - 3); // no-warning
Tom Carea7a8a452010-08-12 22:45:47 +0000101}
102
103enum testenum { enum1 = 0, enum2 };
104unsigned false2() {
Tom Care50e8ac22010-08-16 21:43:52 +0000105 int a = 1234;
106 return enum1 + a; // no-warning
Tom Carea7a8a452010-08-12 22:45:47 +0000107}
108
Tom Careef52bcb2010-08-24 21:09:07 +0000109// Self assignments of unused variables are common false positives
110unsigned false3(int param, int param2) {
Tom Care245adab2010-08-18 21:17:24 +0000111 param = param; // no-warning
112
Tom Careef52bcb2010-08-24 21:09:07 +0000113 // if a self assigned variable is used later, then it should be reported still
114 param2 = param2; // expected-warning{{Assigned value is always the same as the existing value}}
115
Tom Care245adab2010-08-18 21:17:24 +0000116 unsigned nonparam = 5;
117
118 nonparam = nonparam; // expected-warning{{Assigned value is always the same as the existing value}}
119
Tom Careef52bcb2010-08-24 21:09:07 +0000120 return param2 + nonparam;
Tom Care245adab2010-08-18 21:17:24 +0000121}
122
Tom Caredb34ab72010-08-23 19:51:57 +0000123// Pseudo-constants (vars only read) and constants should not be reported
Tom Care245adab2010-08-18 21:17:24 +0000124unsigned false4() {
125 // Trivial constant
Tom Caredb34ab72010-08-23 19:51:57 +0000126 const int height = 1;
Tom Care82389412010-08-23 19:57:25 +0000127 int c = 42;
128 test(height * c); // no-warning
Tom Caredb34ab72010-08-23 19:51:57 +0000129
Tom Care82389412010-08-23 19:57:25 +0000130 // Pseudo-constant (never changes after decl)
131 int width = height;
132
Tom Care245adab2010-08-18 21:17:24 +0000133 return width * 10; // no-warning
134}
Tom Caredb34ab72010-08-23 19:51:57 +0000135
Tom Care967fea62010-08-25 22:37:26 +0000136// Block pseudoconstants
137void false4a() {
138 // Pseudo-constant
139 __block int a = 1;
140 int b = 10;
141 __block int c = 0;
142 b *= a; // no-warning
143
144 ^{
145 // Psuedoconstant block var
146 test(b * c); // no-warning
147
148 // Non-pseudoconstant block var
149 int d = 0;
150 test(b * d); // expected-warning{{The right operand to '*' is always 0}}
151 d = 5;
152 test(d);
153 }();
154
155 test(a + b);
156}
157
Tom Caredb34ab72010-08-23 19:51:57 +0000158// Static vars are common false positives
159int false5() {
160 static int test = 0;
161 int a = 56;
162 a *= test; // no-warning
163 test++;
164 return a;
165}
166
167// Non-local storage vars are considered false positives
168int globalInt = 1;
169int false6() {
170 int localInt = 23;
171
172 localInt /= globalInt;
173
174 return localInt;
175}
Tom Care6216dc02010-08-30 19:25:43 +0000176
177// Check that assignments filter out false positives correctly
178int false7() {
179 int zero = 0; // psuedo-constant
180 int one = 1;
181
182 int a = 55;
183 a = a; // expected-warning{{Assigned value is always the same as the existing value}}
184 a = enum1 * a; // no-warning
185
186 int b = 123;
187 b = b; // no-warning
188
189 return a;
190}
Tom Care84c24ed2010-09-07 20:27:56 +0000191
192// Check truncations do not flag as self-assignments
193void false8() {
194 int a = 10000000;
195 a = (short)a; // no-warning
196 test(a);
197}
Ted Kremenek02282ac2010-09-15 03:13:30 +0000198
199// This test case previously flagged a warning at 'b == c' because the
200// analyzer previously allowed 'UnknownVal' as the index for ElementRegions.
201typedef struct RDar8431728_F {
202 int RDar8431728_A;
203 unsigned char *RDar8431728_B;
204 int RDar8431728_E[6];
205} RDar8431728_D;
206static inline int RDar8431728_C(RDar8431728_D * s, int n,
207 unsigned char **RDar8431728_B_ptr) {
208 int xy, wrap, pred, a, b, c;
209
210 xy = s->RDar8431728_E[n];
211 wrap = s->RDar8431728_A;
212
213 a = s->RDar8431728_B[xy - 1];
214 b = s->RDar8431728_B[xy - 1 - wrap];
215 c = s->RDar8431728_B[xy - wrap];
216
217 if (b == c) { // no-warning
218 pred = a;
219 } else {
220 pred = c;
221 }
222
223 *RDar8431728_B_ptr = &s->RDar8431728_B[xy];
224
225 return pred;
226}
227
Ted Kremenek74faec22010-10-29 01:06:54 +0000228// <rdar://problem/8601243> - Don't warn on pointer arithmetic. This
229// is often idiomatic.
230unsigned rdar8601243_aux(unsigned n);
231void rdar8601243() {
232 char arr[100];
233 char *start = arr;
234 start = start + rdar8601243_aux(sizeof(arr) - (arr - start)); // no-warning
235 (void) start;
236}
237