1 | //===----------------------------------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | // UNSUPPORTED: c++03 |
10 | |
11 | // <functional> |
12 | |
13 | // class function<R(ArgTypes...)> |
14 | |
15 | // R operator()(ArgTypes... args) const |
16 | |
17 | // This test runs in C++03, but we have deprecated using std::function in C++03. |
18 | // ADDITIONAL_COMPILE_FLAGS: -D_LIBCPP_DISABLE_DEPRECATION_WARNINGS -D_LIBCPP_ENABLE_CXX03_FUNCTION |
19 | |
20 | // Address Sanitizer doesn't instrument weak symbols on Linux. When a key |
21 | // function is defined for bad_function_call's vtable, its typeinfo and vtable |
22 | // will be defined as strong symbols in the library and weak symbols in other |
23 | // translation units. Only the strong symbol will be instrumented, increasing |
24 | // its size (due to the redzone) and leading to a serious ODR violation |
25 | // resulting in a crash. |
26 | // Some relevant bugs: |
27 | // https://github.com/google/sanitizers/issues/1017 |
28 | // https://github.com/google/sanitizers/issues/619 |
29 | // https://github.com/google/sanitizers/issues/398 |
30 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68016 |
31 | // UNSUPPORTED: asan |
32 | |
33 | #include <functional> |
34 | #include <cassert> |
35 | |
36 | #include "test_macros.h" |
37 | |
38 | |
39 | int count = 0; |
40 | |
41 | |
42 | // 0 args, return int |
43 | |
44 | int f_int_0() |
45 | { |
46 | return 3; |
47 | } |
48 | |
49 | struct A_int_0 |
50 | { |
51 | int operator()() {return 4;} |
52 | }; |
53 | |
54 | void test_int_0() |
55 | { |
56 | // function |
57 | { |
58 | std::function<int ()> r1(f_int_0); |
59 | assert(r1() == 3); |
60 | } |
61 | // function pointer |
62 | { |
63 | int (*fp)() = f_int_0; |
64 | std::function<int ()> r1(fp); |
65 | assert(r1() == 3); |
66 | } |
67 | // functor |
68 | { |
69 | A_int_0 a0; |
70 | std::function<int ()> r1(a0); |
71 | assert(r1() == 4); |
72 | } |
73 | } |
74 | |
75 | |
76 | // 0 args, return void |
77 | |
78 | void f_void_0() |
79 | { |
80 | ++count; |
81 | } |
82 | |
83 | struct A_void_0 |
84 | { |
85 | void operator()() {++count;} |
86 | }; |
87 | |
88 | void |
89 | test_void_0() |
90 | { |
91 | int save_count = count; |
92 | // function |
93 | { |
94 | std::function<void ()> r1(f_void_0); |
95 | r1(); |
96 | assert(count == save_count+1); |
97 | save_count = count; |
98 | } |
99 | // function pointer |
100 | { |
101 | void (*fp)() = f_void_0; |
102 | std::function<void ()> r1(fp); |
103 | r1(); |
104 | assert(count == save_count+1); |
105 | save_count = count; |
106 | } |
107 | // functor |
108 | { |
109 | A_void_0 a0; |
110 | std::function<void ()> r1(a0); |
111 | r1(); |
112 | assert(count == save_count+1); |
113 | save_count = count; |
114 | } |
115 | } |
116 | |
117 | // 1 arg, return void |
118 | |
119 | void f_void_1(int i) |
120 | { |
121 | count += i; |
122 | } |
123 | |
124 | struct A_void_1 |
125 | { |
126 | void operator()(int i) |
127 | { |
128 | count += i; |
129 | } |
130 | |
131 | void mem1() {++count;} |
132 | void mem2() const {++count;} |
133 | }; |
134 | |
135 | void |
136 | test_void_1() |
137 | { |
138 | int save_count = count; |
139 | // function |
140 | { |
141 | std::function<void (int)> r1(f_void_1); |
142 | int i = 2; |
143 | r1(i); |
144 | assert(count == save_count+2); |
145 | save_count = count; |
146 | } |
147 | // function pointer |
148 | { |
149 | void (*fp)(int) = f_void_1; |
150 | std::function<void (int)> r1(fp); |
151 | int i = 3; |
152 | r1(i); |
153 | assert(count == save_count+3); |
154 | save_count = count; |
155 | } |
156 | // functor |
157 | { |
158 | A_void_1 a0; |
159 | std::function<void (int)> r1(a0); |
160 | int i = 4; |
161 | r1(i); |
162 | assert(count == save_count+4); |
163 | save_count = count; |
164 | } |
165 | // member function pointer |
166 | { |
167 | void (A_void_1::*fp)() = &A_void_1::mem1; |
168 | std::function<void (A_void_1)> r1(fp); |
169 | A_void_1 a; |
170 | r1(a); |
171 | assert(count == save_count+1); |
172 | save_count = count; |
173 | A_void_1* ap = &a; |
174 | std::function<void (A_void_1*)> r2 = fp; |
175 | r2(ap); |
176 | assert(count == save_count+1); |
177 | save_count = count; |
178 | } |
179 | // const member function pointer |
180 | { |
181 | void (A_void_1::*fp)() const = &A_void_1::mem2; |
182 | std::function<void (A_void_1)> r1(fp); |
183 | A_void_1 a; |
184 | r1(a); |
185 | assert(count == save_count+1); |
186 | save_count = count; |
187 | std::function<void (A_void_1*)> r2(fp); |
188 | A_void_1* ap = &a; |
189 | r2(ap); |
190 | assert(count == save_count+1); |
191 | save_count = count; |
192 | } |
193 | } |
194 | |
195 | // 1 arg, return int |
196 | |
197 | int f_int_1(int i) |
198 | { |
199 | return i + 1; |
200 | } |
201 | |
202 | struct A_int_1 |
203 | { |
204 | A_int_1() : data_(5) {} |
205 | int operator()(int i) |
206 | { |
207 | return i - 1; |
208 | } |
209 | |
210 | int mem1() {return 3;} |
211 | int mem2() const {return 4;} |
212 | int data_; |
213 | }; |
214 | |
215 | void |
216 | test_int_1() |
217 | { |
218 | // function |
219 | { |
220 | std::function<int (int)> r1(f_int_1); |
221 | int i = 2; |
222 | assert(r1(i) == 3); |
223 | } |
224 | // function pointer |
225 | { |
226 | int (*fp)(int) = f_int_1; |
227 | std::function<int (int)> r1(fp); |
228 | int i = 3; |
229 | assert(r1(i) == 4); |
230 | } |
231 | // functor |
232 | { |
233 | A_int_1 a0; |
234 | std::function<int (int)> r1(a0); |
235 | int i = 4; |
236 | assert(r1(i) == 3); |
237 | } |
238 | // member function pointer |
239 | { |
240 | int (A_int_1::*fp)() = &A_int_1::mem1; |
241 | std::function<int (A_int_1)> r1(fp); |
242 | A_int_1 a; |
243 | assert(r1(a) == 3); |
244 | std::function<int (A_int_1*)> r2(fp); |
245 | A_int_1* ap = &a; |
246 | assert(r2(ap) == 3); |
247 | } |
248 | // const member function pointer |
249 | { |
250 | int (A_int_1::*fp)() const = &A_int_1::mem2; |
251 | std::function<int (A_int_1)> r1(fp); |
252 | A_int_1 a; |
253 | assert(r1(a) == 4); |
254 | std::function<int (A_int_1*)> r2(fp); |
255 | A_int_1* ap = &a; |
256 | assert(r2(ap) == 4); |
257 | } |
258 | // member data pointer |
259 | { |
260 | int A_int_1::*fp = &A_int_1::data_; |
261 | std::function<int& (A_int_1&)> r1(fp); |
262 | A_int_1 a; |
263 | assert(r1(a) == 5); |
264 | r1(a) = 6; |
265 | assert(r1(a) == 6); |
266 | std::function<int& (A_int_1*)> r2(fp); |
267 | A_int_1* ap = &a; |
268 | assert(r2(ap) == 6); |
269 | r2(ap) = 7; |
270 | assert(r2(ap) == 7); |
271 | } |
272 | } |
273 | |
274 | // 2 arg, return void |
275 | |
276 | void f_void_2(int i, int j) |
277 | { |
278 | count += i+j; |
279 | } |
280 | |
281 | struct A_void_2 |
282 | { |
283 | void operator()(int i, int j) |
284 | { |
285 | count += i+j; |
286 | } |
287 | |
288 | void mem1(int i) {count += i;} |
289 | void mem2(int i) const {count += i;} |
290 | }; |
291 | |
292 | void |
293 | test_void_2() |
294 | { |
295 | int save_count = count; |
296 | // function |
297 | { |
298 | std::function<void (int, int)> r1(f_void_2); |
299 | int i = 2; |
300 | int j = 3; |
301 | r1(i, j); |
302 | assert(count == save_count+5); |
303 | save_count = count; |
304 | } |
305 | // function pointer |
306 | { |
307 | void (*fp)(int, int) = f_void_2; |
308 | std::function<void (int, int)> r1(fp); |
309 | int i = 3; |
310 | int j = 4; |
311 | r1(i, j); |
312 | assert(count == save_count+7); |
313 | save_count = count; |
314 | } |
315 | // functor |
316 | { |
317 | A_void_2 a0; |
318 | std::function<void (int, int)> r1(a0); |
319 | int i = 4; |
320 | int j = 5; |
321 | r1(i, j); |
322 | assert(count == save_count+9); |
323 | save_count = count; |
324 | } |
325 | // member function pointer |
326 | { |
327 | void (A_void_2::*fp)(int) = &A_void_2::mem1; |
328 | std::function<void (A_void_2, int)> r1(fp); |
329 | A_void_2 a; |
330 | int i = 3; |
331 | r1(a, i); |
332 | assert(count == save_count+3); |
333 | save_count = count; |
334 | std::function<void (A_void_2*, int)> r2(fp); |
335 | A_void_2* ap = &a; |
336 | r2(ap, i); |
337 | assert(count == save_count+3); |
338 | save_count = count; |
339 | } |
340 | // const member function pointer |
341 | { |
342 | void (A_void_2::*fp)(int) const = &A_void_2::mem2; |
343 | std::function<void (A_void_2, int)> r1(fp); |
344 | A_void_2 a; |
345 | int i = 4; |
346 | r1(a, i); |
347 | assert(count == save_count+4); |
348 | save_count = count; |
349 | std::function<void (A_void_2*, int)> r2(fp); |
350 | A_void_2* ap = &a; |
351 | r2(ap, i); |
352 | assert(count == save_count+4); |
353 | save_count = count; |
354 | } |
355 | } |
356 | |
357 | // 2 arg, return int |
358 | |
359 | int f_int_2(int i, int j) |
360 | { |
361 | return i+j; |
362 | } |
363 | |
364 | struct A_int_2 |
365 | { |
366 | int operator()(int i, int j) |
367 | { |
368 | return i+j; |
369 | } |
370 | |
371 | int mem1(int i) {return i+1;} |
372 | int mem2(int i) const {return i+2;} |
373 | }; |
374 | |
375 | void test_int_2() |
376 | { |
377 | // function |
378 | { |
379 | std::function<int (int, int)> r1(f_int_2); |
380 | int i = 2; |
381 | int j = 3; |
382 | assert(r1(i, j) == i+j); |
383 | } |
384 | // function pointer |
385 | { |
386 | int (*fp)(int, int) = f_int_2; |
387 | std::function<int (int, int)> r1(fp); |
388 | int i = 3; |
389 | int j = 4; |
390 | assert(r1(i, j) == i+j); |
391 | } |
392 | // functor |
393 | { |
394 | A_int_2 a0; |
395 | std::function<int (int, int)> r1(a0); |
396 | int i = 4; |
397 | int j = 5; |
398 | assert(r1(i, j) == i+j); |
399 | } |
400 | // member function pointer |
401 | { |
402 | int(A_int_2::*fp)(int) = &A_int_2::mem1; |
403 | std::function<int (A_int_2, int)> r1(fp); |
404 | A_int_2 a; |
405 | int i = 3; |
406 | assert(r1(a, i) == i+1); |
407 | std::function<int (A_int_2*, int)> r2(fp); |
408 | A_int_2* ap = &a; |
409 | assert(r2(ap, i) == i+1); |
410 | } |
411 | // const member function pointer |
412 | { |
413 | int (A_int_2::*fp)(int) const = &A_int_2::mem2; |
414 | std::function<int (A_int_2, int)> r1(fp); |
415 | A_int_2 a; |
416 | int i = 4; |
417 | assert(r1(a, i) == i+2); |
418 | std::function<int (A_int_2*, int)> r2(fp); |
419 | A_int_2* ap = &a; |
420 | assert(r2(ap, i) == i+2); |
421 | } |
422 | } |
423 | |
424 | int main(int, char**) |
425 | { |
426 | test_void_0(); |
427 | test_int_0(); |
428 | test_void_1(); |
429 | test_int_1(); |
430 | test_void_2(); |
431 | test_int_2(); |
432 | |
433 | return 0; |
434 | } |
435 | |