1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %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.
PR16833(unsigned op)11 void PR16833(unsigned op) {
12   switch (op) {
13   case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here.
14     return;
15   }
16 }
17 
testAdjustment(int t)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 
testUnknownVal(int value,int mask)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 
testSwitchCond(int arg)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 
testDefaultUnreachable(int arg)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 
testBranchReachability(int arg)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 
testDefaultBranchRange(int arg)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 
testAllUnreachableButDefault(int arg)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 
testAllUnreachable(int arg)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 
testDifferentTypes(int arg)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 
testDifferentTypes2(unsigned long arg)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 
testDifferentTypes3(int arg)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 
testConstant()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