[ELF] Avoid make in elf::writeARMCmseImportLib
[llvm-project.git] / clang / test / Analysis / call_once.cpp
blob344de809078755de2ba6f7d20974a7f4e3a12a67
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
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
10 void clang_analyzer_eval(bool);
12 // Faking std::call_once implementation.
13 namespace std {
15 // Fake std::function implementation.
16 template <typename>
17 class function;
18 class function_base {
19 public:
20 long field;
22 template <typename R, typename... P>
23 class function<R(P...)> : function_base {
24 public:
25 R operator()(P...) const {
27 // Read from a super-class necessary to reproduce a crash.
28 bool a = field;
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
42 #ifndef EMULATE_LIBCXX03
43 template <class Callable, class... Args>
44 void call_once(once_flag &o, Callable&& func, Args&&... args) {};
45 #else
46 template <class Callable, class... Args> // libcxx03 call_once
47 void call_once(once_flag &o, Callable func, Args&&... args) {};
48 #endif
50 } // namespace std
52 // Check with Lambdas.
53 void test_called_warning() {
54 std::once_flag g_initialize;
55 int z;
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 });
66 void test_called_on_path_inside_no_warning() {
67 std::once_flag g_initialize;
69 int *x = nullptr;
70 int y = 100;
71 int z;
73 std::call_once(g_initialize, [&] {
74 z = 200;
75 x = &z;
76 });
78 #ifndef EMULATE_LIBCXX03
79 *x = 100; // no-warning
80 clang_analyzer_eval(z == 100); // expected-warning{{TRUE}}
81 #endif
84 void test_called_on_path_no_warning() {
85 std::once_flag g_initialize;
87 int *x = nullptr;
88 int y = 100;
90 std::call_once(g_initialize, [&] {
91 x = &y;
92 });
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
101 void test_called_on_path_warning() {
102 std::once_flag g_initialize;
104 int y = 100;
105 int *x = &y;
107 std::call_once(g_initialize, [&] {
108 x = nullptr;
111 #ifndef EMULATE_LIBCXX03
112 *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
113 #endif
116 void test_called_once_warning() {
117 std::once_flag g_initialize;
119 int *x = nullptr;
120 int y = 100;
122 std::call_once(g_initialize, [&] {
123 x = nullptr;
126 std::call_once(g_initialize, [&] {
127 x = &y;
130 #ifndef EMULATE_LIBCXX03
131 *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}}
132 #endif
135 void test_called_once_no_warning() {
136 std::once_flag g_initialize;
138 int *x = nullptr;
139 int y = 100;
141 std::call_once(g_initialize, [&] {
142 x = &y;
145 std::call_once(g_initialize, [&] {
146 x = nullptr;
149 #ifndef EMULATE_LIBCXX03
150 *x = 100; // no-warning
151 #endif
154 static int global = 0;
155 void funcPointer() {
156 global = 1;
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
167 template <class _Fp>
168 class function; // undefined
169 template <class _Rp, class... _ArgTypes>
170 struct function<_Rp(_ArgTypes...)> {
171 _Rp operator()(_ArgTypes...) const {};
172 template <class _Fp>
173 function(_Fp) {};
176 // Note: currently we do not support calls to std::function,
177 // but the analyzer should not crash either.
178 void test_function_objects_warning() {
179 int x = 0;
180 int *y = &x;
182 std::once_flag flag;
184 function<void()> func = [&]() {
185 y = nullptr;
188 std::call_once(flag, func);
190 func();
191 int z = *y;
194 void test_param_passing_lambda() {
195 std::once_flag flag;
196 int x = 120;
197 int y = 0;
199 std::call_once(flag, [&](int p) {
200 y = p;
204 #ifndef EMULATE_LIBCXX03
205 clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
206 #endif
209 void test_param_passing_lambda_false() {
210 std::once_flag flag;
211 int x = 120;
213 std::call_once(flag, [&](int p) {
214 x = 0;
218 #ifndef EMULATE_LIBCXX03
219 clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
220 #endif
223 void test_param_passing_stored_lambda() {
224 std::once_flag flag;
225 int x = 120;
226 int y = 0;
228 auto lambda = [&](int p) {
229 y = p;
232 std::call_once(flag, lambda, x);
233 #ifndef EMULATE_LIBCXX03
234 clang_analyzer_eval(y == 120); // expected-warning{{TRUE}}
235 #endif
238 void test_multiparam_passing_lambda() {
239 std::once_flag flag;
240 int x = 120;
242 std::call_once(flag, [&](int a, int b, int c) {
243 x = a + b + c;
245 1, 2, 3);
247 #ifndef EMULATE_LIBCXX03
248 clang_analyzer_eval(x == 120); // expected-warning{{FALSE}}
249 clang_analyzer_eval(x == 6); // expected-warning{{TRUE}}
250 #endif
253 static int global2 = 0;
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;
260 1, 2, 3);
261 #ifndef EMULATE_LIBCXX03
262 clang_analyzer_eval(global2 == 6); // expected-warning{{TRUE}}
263 #endif
266 static int global3 = 0;
267 void funcptr(int a, int b, int c) {
268 global3 = a + b + c;
271 void test_param_passing_funcptr() {
272 std::once_flag flag;
273 global3 = 0;
275 std::call_once(flag, &funcptr, 1, 2, 3);
277 #ifndef EMULATE_LIBCXX03
278 clang_analyzer_eval(global3 == 6); // expected-warning{{TRUE}}
279 #endif
282 void test_blocks() {
283 global3 = 0;
284 std::once_flag flag;
285 std::call_once(flag, ^{
286 global3 = 120;
288 #ifndef EMULATE_LIBCXX03
289 clang_analyzer_eval(global3 == 120); // expected-warning{{TRUE}}
290 #endif
293 int call_once() {
294 return 5;
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
304 namespace std {
305 template <typename d, typename e>
306 void call_once(d, e);
308 void g();
309 void test_no_segfault_on_different_impl() {
310 #ifndef EMULATE_LIBCXX03
311 std::call_once(g, false); // no-warning
312 #endif
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
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
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
342 void mutator(int &param) {
343 param = 42;
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
354 void fail_mutator(int param) {
355 param = 42;
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
366 // Function is implicitly treated as a function pointer
367 // even when an ampersand is not explicitly set.
368 void callbackn(int &param) {
369 param = 42;
371 void test_implicit_funcptr() {
372 int x = 0;
373 static std::once_flag flagn;
375 std::call_once(flagn, callbackn, x);
376 #ifndef EMULATE_LIBCXX03
377 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
378 #endif
381 int param_passed(int *x) {
382 return *x; // no-warning, as std::function is not working yet.
385 void callback_taking_func_ok(std::function<void(int*)> &innerCallback) {
386 innerCallback(nullptr);
389 // The provided callback expects an std::function, but instead a pointer
390 // to a C++ function is provided.
391 void callback_with_implicit_cast_ok() {
392 std::once_flag flag;
393 call_once(flag, callback_taking_func_ok, &param_passed);
396 void callback_taking_func(std::function<void()> &innerCallback) {
397 innerCallback();
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.
402 void callback_with_implicit_cast() {
403 std::once_flag flag;
404 call_once(flag, callback_taking_func, callback_with_implicit_cast);
407 std::once_flag another_once_flag;
408 typedef void (*my_callback_t)(int *);
409 my_callback_t callback;
410 int global_int;
412 void rdar40270582() {
413 call_once(another_once_flag, callback, &global_int);