1 | // RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify -analyzer-config eagerly-assume=false %s |
2 | |
3 | void clang_analyzer_eval(int); |
4 | void clang_analyzer_warnIfReached(); |
5 | |
6 | #define INT_MIN 0x80000000 |
7 | #define INT_MAX 0x7fffffff |
8 | |
9 | // PR16833: Analyzer consumes memory until killed by kernel OOM killer |
10 | // while analyzing large case ranges. |
11 | void PR16833(unsigned op) { |
12 | switch (op) { |
13 | case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here. |
14 | return; |
15 | } |
16 | } |
17 | |
18 | void testAdjustment(int t) { |
19 | switch (t + 1) { |
20 | case 2: |
21 | clang_analyzer_eval(t == 1); // expected-warning{{TRUE}} |
22 | break; |
23 | case 3 ... 10: |
24 | clang_analyzer_eval(t > 1); // expected-warning{{TRUE}} |
25 | clang_analyzer_eval(t + 2 <= 11); // expected-warning{{TRUE}} |
26 | clang_analyzer_eval(t > 2); // expected-warning{{UNKNOWN}} |
27 | clang_analyzer_eval(t + 1 == 3); // expected-warning{{UNKNOWN}} |
28 | clang_analyzer_eval(t + 1 == 10); // expected-warning{{UNKNOWN}} |
29 | break; |
30 | default: |
31 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
32 | } |
33 | } |
34 | |
35 | void testUnknownVal(int value, int mask) { |
36 | // Once ConstraintManager will process '&' and this test will require some changes. |
37 | switch (value & mask) { |
38 | case 1: |
39 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
40 | break; |
41 | case 3 ... 10: |
42 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
43 | break; |
44 | default: |
45 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
46 | } |
47 | } |
48 | |
49 | void testSwitchCond(int arg) { |
50 | if (arg > 10) { |
51 | switch (arg) { |
52 | case INT_MIN ... 10: |
53 | clang_analyzer_warnIfReached(); // no-warning |
54 | break; |
55 | case 11 ... 20: |
56 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
57 | break; |
58 | default: |
59 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
60 | } |
61 | |
62 | switch (arg) { |
63 | case INT_MIN ... 9: |
64 | clang_analyzer_warnIfReached(); // no-warning |
65 | break; |
66 | case 10 ... 20: |
67 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
68 | clang_analyzer_eval(arg > 10); // expected-warning{{TRUE}} |
69 | break; |
70 | default: |
71 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
72 | } |
73 | } // arg > 10 |
74 | } |
75 | |
76 | void testDefaultUnreachable(int arg) { |
77 | if (arg > 10) { |
78 | switch (arg) { |
79 | case INT_MIN ... 9: |
80 | clang_analyzer_warnIfReached(); // no-warning |
81 | break; |
82 | case 10 ... INT_MAX: |
83 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
84 | clang_analyzer_eval(arg > 10); // expected-warning{{TRUE}} |
85 | break; |
86 | default: |
87 | clang_analyzer_warnIfReached(); // no-warning |
88 | } |
89 | } |
90 | } |
91 | |
92 | void testBranchReachability(int arg) { |
93 | if (arg > 10 && arg < 20) { |
94 | switch (arg) { |
95 | case INT_MIN ... 4: |
96 | clang_analyzer_warnIfReached(); // no-warning |
97 | break; |
98 | case 5 ... 9: |
99 | clang_analyzer_warnIfReached(); // no-warning |
100 | break; |
101 | case 10 ... 15: |
102 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
103 | clang_analyzer_eval(arg > 10 && arg <= 15); // expected-warning{{TRUE}} |
104 | break; |
105 | default: |
106 | clang_analyzer_warnIfReached(); // no-warning |
107 | break; |
108 | case 17 ... 25: |
109 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
110 | clang_analyzer_eval(arg >= 17 && arg < 20); // expected-warning{{TRUE}} |
111 | break; |
112 | case 26 ... INT_MAX: |
113 | clang_analyzer_warnIfReached(); // no-warning |
114 | break; |
115 | case 16: |
116 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
117 | clang_analyzer_eval(arg == 16); // expected-warning{{TRUE}} |
118 | break; |
119 | } |
120 | } |
121 | } |
122 | |
123 | void testDefaultBranchRange(int arg) { |
124 | switch (arg) { |
125 | case INT_MIN ... 9: |
126 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
127 | break; |
128 | case 20 ... INT_MAX: |
129 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
130 | clang_analyzer_eval(arg >= 20); // expected-warning{{TRUE}} |
131 | break; |
132 | default: |
133 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
134 | clang_analyzer_eval(arg == 16); // expected-warning{{FALSE}} |
135 | clang_analyzer_eval(arg > 9); // expected-warning{{TRUE}} |
136 | clang_analyzer_eval(arg <= 20); // expected-warning{{TRUE}} |
137 | |
138 | case 16: |
139 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
140 | } |
141 | } |
142 | |
143 | void testAllUnreachableButDefault(int arg) { |
144 | if (arg < 0) { |
145 | switch (arg) { |
146 | case 0 ... 9: |
147 | clang_analyzer_warnIfReached(); // no-warning |
148 | break; |
149 | case 20 ... INT_MAX: |
150 | clang_analyzer_warnIfReached(); // no-warning |
151 | break; |
152 | default: |
153 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
154 | break; |
155 | case 16: |
156 | clang_analyzer_warnIfReached(); // no-warning |
157 | } |
158 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
159 | } |
160 | } |
161 | |
162 | void testAllUnreachable(int arg) { |
163 | if (arg < 0) { |
164 | switch (arg) { |
165 | case 0 ... 9: |
166 | clang_analyzer_warnIfReached(); // no-warning |
167 | break; |
168 | case 20 ... INT_MAX: |
169 | clang_analyzer_warnIfReached(); // no-warning |
170 | break; |
171 | case 16: |
172 | clang_analyzer_warnIfReached(); // no-warning |
173 | } |
174 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
175 | } |
176 | } |
177 | |
178 | void testDifferentTypes(int arg) { |
179 | switch (arg) { |
180 | case -1U ... 400000000LL: |
181 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
182 | break; |
183 | default: |
184 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
185 | break; |
186 | } |
187 | } |
188 | |
189 | void testDifferentTypes2(unsigned long arg) { |
190 | switch (arg) { |
191 | case 1UL ... 400000000UL: |
192 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
193 | break; |
194 | default: |
195 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
196 | break; |
197 | } |
198 | } |
199 | |
200 | void testDifferentTypes3(int arg) { |
201 | switch (arg) { |
202 | case 1UL ... 400000000UL: |
203 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
204 | break; |
205 | default: |
206 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
207 | break; |
208 | } |
209 | } |
210 | |
211 | void testConstant() { |
212 | switch (3) { |
213 | case 1 ... 5: |
214 | clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}} |
215 | break; |
216 | default: |
217 | clang_analyzer_warnIfReached(); // no-warning |
218 | break; |
219 | } |
220 | } |
221 | |