1// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2
3void clang_analyzer_eval(int);
4void 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.
11void PR16833(unsigned op) {
12  switch (op) {
13  case 0x02 << 26 ... 0x03 << 26: // Analyzer should not hang here.
14    return;
15  }
16}
17
18void 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
35void 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
49void 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
76void 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
92void 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
123void 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
143void 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
162void 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
178void 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
189void 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
200void 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
211void 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