1 // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s -o %t.report
2 // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s -o %t.report
3 
4 // We do NOT model libcxx03 implementation, but the analyzer should still
5 // not crash.
6 // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s -o %t.report
7 // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s -o %t.report
8 // RUN: rm -rf %t.report
9 
10 void clang_analyzer_eval(bool);
11 
12 // Faking std::call_once implementation.
13 namespace std {
14 
15 // Fake std::function implementation.
16 template <typename>
17 class function;
18 class function_base {
19  public:
20   long field;
21 };
22 template <typename R, typename... P>
23 class function<R(P...)> : function_base {
24  public:
operator ()(P...) const25    R operator()(P...) const {
26 
27      // Read from a super-class necessary to reproduce a crash.
28      bool a = field;
29    }
30 };
31 
32 #ifndef EMULATE_LIBSTDCPP
33 typedef struct once_flag_s {
34   unsigned long __state_ = 0;
35 } once_flag;
36 #else
37 typedef struct once_flag_s {
38   int _M_once = 0;
39 } once_flag;
40 #endif
41 
42 #ifndef EMULATE_LIBCXX03
43 template <class Callable, class... Args>
call_once(once_flag & o,Callable && func,Args &&...args)44 void call_once(once_flag &o, Callable&& func, Args&&... args) {};
45 #else
46 template <class Callable, class... Args> // libcxx03 call_once
call_once(once_flag & o,Callable func,Args &&...args)47 void call_once(once_flag &o, Callable func, Args&&... args) {};
48 #endif
49 
50 } // namespace std
51 
52 // Check with Lambdas.
test_called_warning()53 void test_called_warning() {
54   std::once_flag g_initialize;
55   int z;
56 
57   std::call_once(g_initialize, [&] {
58     int *x = nullptr;
59 #ifndef EMULATE_LIBCXX03
60     int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
61 #endif
62     z = 200;
63   });
64 }
65 
test_called_on_path_inside_no_warning()66 void test_called_on_path_inside_no_warning() {
67   std::once_flag g_initialize;
68 
69   int *x = nullptr;
70   int y = 100;
71   int z;
72 
73   std::call_once(g_initialize, [&] {
74     z = 200;
75     x = &z;
76   });
77 
78 #ifndef EMULATE_LIBCXX03
79   *x = 100; // no-warning
80   clang_analyzer_eval(z == 100); // expected-warning{{TRUE}}
81 #endif
82 }
83 
test_called_on_path_no_warning()84 void test_called_on_path_no_warning() {
85   std::once_flag g_initialize;
86 
87   int *x = nullptr;
88   int y = 100;
89 
90   std::call_once(g_initialize, [&] {
91     x = &y;
92   });
93 
94 #ifndef EMULATE_LIBCXX03
95   *x = 100; // no-warning
96 #else
97   *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
98 #endif
99 }
100 
test_called_on_path_warning()101 void test_called_on_path_warning() {
102   std::once_flag g_initialize;
103 
104   int y = 100;
105   int *x = &y;
106 
107   std::call_once(g_initialize, [&] {
108     x = nullptr;
109   });
110 
111 #ifndef EMULATE_LIBCXX03
112   *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
113 #endif
114 }
115 
test_called_once_warning()116 void test_called_once_warning() {
117   std::once_flag g_initialize;
118 
119   int *x = nullptr;
120   int y = 100;
121 
122   std::call_once(g_initialize, [&] {
123     x = nullptr;
124   });
125 
126   std::call_once(g_initialize, [&] {
127     x = &y;
128   });
129 
130 #ifndef EMULATE_LIBCXX03
131   *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
132 #endif
133 }
134 
test_called_once_no_warning()135 void test_called_once_no_warning() {
136   std::once_flag g_initialize;
137 
138   int *x = nullptr;
139   int y = 100;
140 
141   std::call_once(g_initialize, [&] {
142     x = &y;
143   });
144 
145   std::call_once(g_initialize, [&] {
146     x = nullptr;
147   });
148 
149 #ifndef EMULATE_LIBCXX03
150   *x = 100; // no-warning
151 #endif
152 }
153 
154 static int global = 0;
funcPointer()155 void funcPointer() {
156   global = 1;
157 }
158 
test_func_pointers()159 void test_func_pointers() {
160   static std::once_flag flag;
161   std::call_once(flag, &funcPointer);
162 #ifndef EMULATE_LIBCXX03
163   clang_analyzer_eval(global == 1); // expected-warning{{TRUE}}
164 #endif
165 }
166 
167 template <class _Fp>
168 class function; // undefined
169 template <class _Rp, class... _ArgTypes>
170 struct function<_Rp(_ArgTypes...)> {
operator ()function171   _Rp operator()(_ArgTypes...) const {};
172   template <class _Fp>
functionfunction173   function(_Fp) {};
174 };
175 
176 // Note: currently we do not support calls to std::function,
177 // but the analyzer should not crash either.
test_function_objects_warning()178 void test_function_objects_warning() {
179   int x = 0;
180   int *y = &x;
181 
182   std::once_flag flag;
183 
184   function<void()> func = [&]() {
185     y = nullptr;
186   };
187 
188   std::call_once(flag, func);
189 
190   func();
191   int z = *y;
192 }
193 
test_param_passing_lambda()194 void test_param_passing_lambda() {
195   std::once_flag flag;
196   int x = 120;
197   int y = 0;
198 
199   std::call_once(flag, [&](int p) {
200     y = p;
201   },
202                  x);
203 
204 #ifndef EMULATE_LIBCXX03
205   clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
206 #endif
207 }
208 
test_param_passing_lambda_false()209 void test_param_passing_lambda_false() {
210   std::once_flag flag;
211   int x = 120;
212 
213   std::call_once(flag, [&](int p) {
214     x = 0;
215   },
216                  x);
217 
218 #ifndef EMULATE_LIBCXX03
219   clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
220 #endif
221 }
222 
test_param_passing_stored_lambda()223 void test_param_passing_stored_lambda() {
224   std::once_flag flag;
225   int x = 120;
226   int y = 0;
227 
228   auto lambda = [&](int p) {
229     y = p;
230   };
231 
232   std::call_once(flag, lambda, x);
233 #ifndef EMULATE_LIBCXX03
234   clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
235 #endif
236 }
237 
test_multiparam_passing_lambda()238 void test_multiparam_passing_lambda() {
239   std::once_flag flag;
240   int x = 120;
241 
242   std::call_once(flag, [&](int a, int b, int c) {
243     x = a + b + c;
244   },
245                  1, 2, 3);
246 
247 #ifndef EMULATE_LIBCXX03
248   clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
249   clang_analyzer_eval(x == 6); // expected-warning{{TRUE}}
250 #endif
251 }
252 
253 static int global2 = 0;
test_param_passing_lambda_global()254 void test_param_passing_lambda_global() {
255   std::once_flag flag;
256   global2 = 0;
257   std::call_once(flag, [&](int a, int b, int c) {
258     global2 = a + b + c;
259   },
260                  1, 2, 3);
261 #ifndef EMULATE_LIBCXX03
262   clang_analyzer_eval(global2 == 6); // expected-warning{{TRUE}}
263 #endif
264 }
265 
266 static int global3 = 0;
funcptr(int a,int b,int c)267 void funcptr(int a, int b, int c) {
268   global3 = a + b + c;
269 }
270 
test_param_passing_funcptr()271 void test_param_passing_funcptr() {
272   std::once_flag flag;
273   global3 = 0;
274 
275   std::call_once(flag, &funcptr, 1, 2, 3);
276 
277 #ifndef EMULATE_LIBCXX03
278   clang_analyzer_eval(global3 == 6); // expected-warning{{TRUE}}
279 #endif
280 }
281 
test_blocks()282 void test_blocks() {
283   global3 = 0;
284   std::once_flag flag;
285   std::call_once(flag, ^{
286     global3 = 120;
287   });
288 #ifndef EMULATE_LIBCXX03
289   clang_analyzer_eval(global3 == 120); // expected-warning{{TRUE}}
290 #endif
291 }
292 
call_once()293 int call_once() {
294   return 5;
295 }
296 
test_non_std_call_once()297 void test_non_std_call_once() {
298   int x = call_once();
299 #ifndef EMULATE_LIBCXX03
300   clang_analyzer_eval(x == 5); // expected-warning{{TRUE}}
301 #endif
302 }
303 
304 namespace std {
305 template <typename d, typename e>
306 void call_once(d, e);
307 }
308 void g();
test_no_segfault_on_different_impl()309 void test_no_segfault_on_different_impl() {
310 #ifndef EMULATE_LIBCXX03
311   std::call_once(g, false); // no-warning
312 #endif
313 }
314 
test_lambda_refcapture()315 void test_lambda_refcapture() {
316   static std::once_flag flag;
317   int a = 6;
318   std::call_once(flag, [&](int &a) { a = 42; }, a);
319 #ifndef EMULATE_LIBCXX03
320   clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
321 #endif
322 }
323 
test_lambda_refcapture2()324 void test_lambda_refcapture2() {
325   static std::once_flag flag;
326   int a = 6;
327   std::call_once(flag, [=](int &a) { a = 42; }, a);
328 #ifndef EMULATE_LIBCXX03
329   clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
330 #endif
331 }
332 
test_lambda_fail_refcapture()333 void test_lambda_fail_refcapture() {
334   static std::once_flag flag;
335   int a = 6;
336   std::call_once(flag, [=](int a) { a = 42; }, a);
337 #ifndef EMULATE_LIBCXX03
338   clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}
339 #endif
340 }
341 
mutator(int & param)342 void mutator(int &param) {
343   param = 42;
344 }
test_reftypes_funcptr()345 void test_reftypes_funcptr() {
346   static std::once_flag flag;
347   int a = 6;
348   std::call_once(flag, &mutator, a);
349 #ifndef EMULATE_LIBCXX03
350   clang_analyzer_eval(a == 42); // expected-warning{{TRUE}}
351 #endif
352 }
353 
fail_mutator(int param)354 void fail_mutator(int param) {
355   param = 42;
356 }
test_mutator_noref()357 void test_mutator_noref() {
358   static std::once_flag flag;
359   int a = 6;
360   std::call_once(flag, &fail_mutator, a);
361 #ifndef EMULATE_LIBCXX03
362   clang_analyzer_eval(a == 42); // expected-warning{{FALSE}}
363 #endif
364 }
365 
366 // Function is implicitly treated as a function pointer
367 // even when an ampersand is not explicitly set.
callbackn(int & param)368 void callbackn(int &param) {
369   param = 42;
370 }
test_implicit_funcptr()371 void test_implicit_funcptr() {
372   int x = 0;
373   static std::once_flag flagn;
374 
375   std::call_once(flagn, callbackn, x);
376 #ifndef EMULATE_LIBCXX03
377   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
378 #endif
379 }
380 
param_passed(int * x)381 int param_passed(int *x) {
382   return *x; // no-warning, as std::function is not working yet.
383 }
384 
callback_taking_func_ok(std::function<void (int *)> & innerCallback)385 void callback_taking_func_ok(std::function<void(int*)> &innerCallback) {
386   innerCallback(nullptr);
387 }
388 
389 // The provided callback expects an std::function, but instead a pointer
390 // to a C++ function is provided.
callback_with_implicit_cast_ok()391 void callback_with_implicit_cast_ok() {
392   std::once_flag flag;
393   call_once(flag, callback_taking_func_ok, &param_passed);
394 }
395 
callback_taking_func(std::function<void ()> & innerCallback)396 void callback_taking_func(std::function<void()> &innerCallback) {
397   innerCallback();
398 }
399 
400 // The provided callback expects an std::function, but instead a C function
401 // name is provided, and C++ implicitly auto-constructs a pointer from it.
callback_with_implicit_cast()402 void callback_with_implicit_cast() {
403   std::once_flag flag;
404   call_once(flag, callback_taking_func, callback_with_implicit_cast);
405 }
406 
407 std::once_flag another_once_flag;
408 typedef void (*my_callback_t)(int *);
409 my_callback_t callback;
410 int global_int;
411 
rdar40270582()412 void rdar40270582() {
413   call_once(another_once_flag, callback, &global_int);
414 }
415