1 // RUN: %clang_cc1 -std=c++14 -triple i386-apple-darwin10 -analyze -analyzer-config eagerly-assume=false -analyzer-checker=core.uninitialized.Assign,core.builtin,debug.ExprInspection,core.uninitialized.UndefReturn -verify %s
2 
3 template <typename T>
4 void clang_analyzer_dump(T x);
5 void clang_analyzer_eval(int);
6 
7 struct S {
8   int a = 3;
9 };
10 S const sarr[2] = {};
11 void definit() {
12   int i = 1;
13   // FIXME: Should recognize that it is 3.
14   clang_analyzer_eval(sarr[i].a); // expected-warning{{UNKNOWN}}
15 }
16 
17 int const arr[2][2] = {};
18 void arr2init() {
19   int i = 1;
20   // FIXME: Should recognize that it is 0.
21   clang_analyzer_eval(arr[i][0]); // expected-warning{{UNKNOWN}}
22 }
23 
24 int const glob_arr1[3] = {};
25 void glob_array_index1() {
26   clang_analyzer_eval(glob_arr1[0] == 0); // expected-warning{{TRUE}}
27   clang_analyzer_eval(glob_arr1[1] == 0); // expected-warning{{TRUE}}
28   clang_analyzer_eval(glob_arr1[2] == 0); // expected-warning{{TRUE}}
29 }
30 
31 void glob_invalid_index1() {
32   const int *ptr = glob_arr1;
33   int idx = -42;
34   auto x = ptr[idx]; // expected-warning{{garbage or undefined}}
35 }
36 
37 void glob_symbolic_index1(int idx) {
38   clang_analyzer_dump(glob_arr1[idx]); // expected-warning{{Unknown}}
39 }
40 
41 int const glob_arr2[4] = {1, 2};
42 void glob_ptr_index1() {
43   int const *ptr = glob_arr2;
44   clang_analyzer_eval(ptr[0] == 1); // expected-warning{{TRUE}}
45   clang_analyzer_eval(ptr[1] == 2); // expected-warning{{TRUE}}
46   clang_analyzer_eval(ptr[2] == 0); // expected-warning{{TRUE}}
47   clang_analyzer_eval(ptr[3] == 0); // expected-warning{{TRUE}}
48   clang_analyzer_eval(ptr[4] == 0); // expected-warning{{UNDEFINED}}
49 }
50 
51 void glob_invalid_index2() {
52   const int *ptr = glob_arr2;
53   int idx = 42;
54   auto x = ptr[idx]; // expected-warning{{garbage or undefined}}
55 }
56 
57 const float glob_arr3[] = {
58     0.0000, 0.0235, 0.0470, 0.0706, 0.0941, 0.1176};
59 float no_warn_garbage_value() {
60   return glob_arr3[0]; // no-warning (garbage or undefined)
61 }
62 
63 // TODO: Support multidimensional array.
64 int const glob_arr4[4][2] = {};
65 void glob_array_index2() {
66   // FIXME: Should be TRUE.
67   clang_analyzer_eval(glob_arr4[1][0] == 0); // expected-warning{{UNKNOWN}}
68   // FIXME: Should be TRUE.
69   clang_analyzer_eval(glob_arr4[1][1] == 0); // expected-warning{{UNKNOWN}}
70 }
71 
72 // TODO: Support multidimensional array.
73 void glob_invalid_index3() {
74   int idx = -42;
75   // FIXME: Should warn {{garbage or undefined}}.
76   auto x = glob_arr4[1][idx]; // no-warning
77 }
78 
79 // TODO: Support multidimensional array.
80 void glob_invalid_index4() {
81   const int *ptr = glob_arr4[1];
82   int idx = -42;
83   // FIXME: Should warn {{garbage or undefined}}.
84   auto x = ptr[idx]; // no-warning
85 }
86 
87 // TODO: Support multidimensional array.
88 int const glob_arr5[4][2] = {{1}, 3, 4, 5};
89 void glob_array_index3() {
90   // FIXME: Should be TRUE.
91   clang_analyzer_eval(glob_arr5[0][0] == 1); // expected-warning{{UNKNOWN}}
92   // FIXME: Should be TRUE.
93   clang_analyzer_eval(glob_arr5[0][1] == 0); // expected-warning{{UNKNOWN}}
94   // FIXME: Should be TRUE.
95   clang_analyzer_eval(glob_arr5[1][0] == 3); // expected-warning{{UNKNOWN}}
96   // FIXME: Should be TRUE.
97   clang_analyzer_eval(glob_arr5[1][1] == 4); // expected-warning{{UNKNOWN}}
98   // FIXME: Should be TRUE.
99   clang_analyzer_eval(glob_arr5[2][0] == 5); // expected-warning{{UNKNOWN}}
100   // FIXME: Should be TRUE.
101   clang_analyzer_eval(glob_arr5[2][1] == 0); // expected-warning{{UNKNOWN}}
102   // FIXME: Should be TRUE.
103   clang_analyzer_eval(glob_arr5[3][0] == 0); // expected-warning{{UNKNOWN}}
104   // FIXME: Should be TRUE.
105   clang_analyzer_eval(glob_arr5[3][1] == 0); // expected-warning{{UNKNOWN}}
106 }
107 
108 // TODO: Support multidimensional array.
109 void glob_ptr_index2() {
110   int const *ptr = glob_arr5[1];
111   // FIXME: Should be TRUE.
112   clang_analyzer_eval(ptr[0] == 3); // expected-warning{{UNKNOWN}}
113   // FIXME: Should be TRUE.
114   clang_analyzer_eval(ptr[1] == 4); // expected-warning{{UNKNOWN}}
115   // FIXME: Should be UNDEFINED.
116   clang_analyzer_eval(ptr[2] == 5); // expected-warning{{UNKNOWN}}
117   // FIXME: Should be UNDEFINED.
118   clang_analyzer_eval(ptr[3] == 0); // expected-warning{{UNKNOWN}}
119   // FIXME: Should be UNDEFINED.
120   clang_analyzer_eval(ptr[4] == 0); // expected-warning{{UNKNOWN}}
121 }
122 
123 // TODO: Support multidimensional array.
124 void glob_invalid_index5() {
125   int idx = -42;
126   // FIXME: Should warn {{garbage or undefined}}.
127   auto x = glob_arr5[1][idx]; // no-warning
128 }
129 
130 // TODO: Support multidimensional array.
131 void glob_invalid_index6() {
132   int const *ptr = &glob_arr5[1][0];
133   int idx = 42;
134   // FIXME: Should warn {{garbage or undefined}}.
135   auto x = ptr[idx]; // // no-warning
136 }
137 
138 extern const int glob_arr_no_init[10];
139 void glob_array_index4() {
140   clang_analyzer_eval(glob_arr_no_init[2]); // expected-warning{{UNKNOWN}}
141 }
142 
143 struct S2 {
144   static const int arr_no_init[10];
145 };
146 void struct_arr_index1() {
147   clang_analyzer_eval(S2::arr_no_init[2]); // expected-warning{{UNKNOWN}}
148 }
149 
150 char const glob_arr6[5] = "123";
151 void glob_array_index5() {
152   clang_analyzer_eval(glob_arr6[0] == '1');  // expected-warning{{TRUE}}
153   clang_analyzer_eval(glob_arr6[1] == '2');  // expected-warning{{TRUE}}
154   clang_analyzer_eval(glob_arr6[2] == '3');  // expected-warning{{TRUE}}
155   clang_analyzer_eval(glob_arr6[3] == '\0'); // expected-warning{{TRUE}}
156   clang_analyzer_eval(glob_arr6[4] == '\0'); // expected-warning{{TRUE}}
157 }
158 
159 void glob_ptr_index3() {
160   char const *ptr = glob_arr6;
161   clang_analyzer_eval(ptr[-42] == '\0'); // expected-warning{{UNDEFINED}}
162   clang_analyzer_eval(ptr[0] == '1');    // expected-warning{{TRUE}}
163   clang_analyzer_eval(ptr[1] == '2');    // expected-warning{{TRUE}}
164   clang_analyzer_eval(ptr[2] == '3');    // expected-warning{{TRUE}}
165   clang_analyzer_eval(ptr[3] == '\0');   // expected-warning{{TRUE}}
166   clang_analyzer_eval(ptr[4] == '\0');   // expected-warning{{TRUE}}
167   clang_analyzer_eval(ptr[5] == '\0');   // expected-warning{{UNDEFINED}}
168   clang_analyzer_eval(ptr[6] == '\0');   // expected-warning{{UNDEFINED}}
169 }
170 
171 void glob_invalid_index7() {
172   int idx = -42;
173   auto x = glob_arr6[idx]; // expected-warning{{garbage or undefined}}
174 }
175 
176 void glob_invalid_index8() {
177   const char *ptr = glob_arr6;
178   int idx = 42;
179   auto x = ptr[idx]; // expected-warning{{garbage or undefined}}
180 }
181 
182 char const glob_arr7[5] = {"123"};
183 void glob_array_index6() {
184   clang_analyzer_eval(glob_arr7[0] == '1');  // expected-warning{{TRUE}}
185   clang_analyzer_eval(glob_arr7[1] == '2');  // expected-warning{{TRUE}}
186   clang_analyzer_eval(glob_arr7[2] == '3');  // expected-warning{{TRUE}}
187   clang_analyzer_eval(glob_arr7[3] == '\0'); // expected-warning{{TRUE}}
188   clang_analyzer_eval(glob_arr7[4] == '\0'); // expected-warning{{TRUE}}
189 }
190 
191 void glob_invalid_index9() {
192   int idx = -42;
193   auto x = glob_arr7[idx]; // expected-warning{{garbage or undefined}}
194 }
195 
196 void glob_invalid_index10() {
197   const char *ptr = glob_arr7;
198   int idx = 42;
199   auto x = ptr[idx]; // expected-warning{{garbage or undefined}}
200 }
201 
202 char const *const glob_ptr8 = "123";
203 void glob_ptr_index4() {
204   clang_analyzer_eval(glob_ptr8[0] == '1');  // expected-warning{{TRUE}}
205   clang_analyzer_eval(glob_ptr8[1] == '2');  // expected-warning{{TRUE}}
206   clang_analyzer_eval(glob_ptr8[2] == '3');  // expected-warning{{TRUE}}
207   clang_analyzer_eval(glob_ptr8[3] == '\0'); // expected-warning{{TRUE}}
208   // FIXME: Should be UNDEFINED.
209   // We should take into account a declaration in which the literal is used.
210   clang_analyzer_eval(glob_ptr8[4] == '\0'); // expected-warning{{TRUE}}
211 }
212 
213 void glob_invalid_index11() {
214   int idx = -42;
215   auto x = glob_ptr8[idx]; // expected-warning{{garbage or undefined}}
216 }
217 
218 void glob_invalid_index12() {
219   int idx = 42;
220   // FIXME: Should warn {{garbage or undefined}}
221   // We should take into account a declaration in which the literal is used.
222   auto x = glob_ptr8[idx]; // no-warning
223 }
224 
225 const char16_t *const glob_ptr9 = u"абв";
226 void glob_ptr_index5() {
227   clang_analyzer_eval(glob_ptr9[0] == u'а'); // expected-warning{{TRUE}}
228   clang_analyzer_eval(glob_ptr9[1] == u'б'); // expected-warning{{TRUE}}
229   clang_analyzer_eval(glob_ptr9[2] == u'в'); // expected-warning{{TRUE}}
230   clang_analyzer_eval(glob_ptr9[3] == '\0'); // expected-warning{{TRUE}}
231 }
232 
233 const char32_t *const glob_ptr10 = U"\U0001F607\U0001F608\U0001F609";
234 void glob_ptr_index6() {
235   clang_analyzer_eval(glob_ptr10[0] == U'\U0001F607'); // expected-warning{{TRUE}}
236   clang_analyzer_eval(glob_ptr10[1] == U'\U0001F608'); // expected-warning{{TRUE}}
237   clang_analyzer_eval(glob_ptr10[2] == U'\U0001F609'); // expected-warning{{TRUE}}
238   clang_analyzer_eval(glob_ptr10[3] == '\0');          // expected-warning{{TRUE}}
239 }
240 
241 const wchar_t *const glob_ptr11 = L"\123\u0041\xFF";
242 void glob_ptr_index7() {
243   clang_analyzer_eval(glob_ptr11[0] == L'\123');   // expected-warning{{TRUE}}
244   clang_analyzer_eval(glob_ptr11[1] == L'\u0041'); // expected-warning{{TRUE}}
245   clang_analyzer_eval(glob_ptr11[2] == L'\xFF');   // expected-warning{{TRUE}}
246   clang_analyzer_eval(glob_ptr11[3] == L'\0');     // expected-warning{{TRUE}}
247 }
248 
249 const char *const glob_ptr12 = u8"abc";
250 void glob_ptr_index8() {
251   clang_analyzer_eval(glob_ptr12[0] == 'a');  // expected-warning{{TRUE}}
252   clang_analyzer_eval(glob_ptr12[1] == 'b');  // expected-warning{{TRUE}}
253   clang_analyzer_eval(glob_ptr12[2] == 'c');  // expected-warning{{TRUE}}
254   clang_analyzer_eval(glob_ptr12[3] == '\0'); // expected-warning{{TRUE}}
255 }
256