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 // REQUIRES: clang || apple-clang
10 // XFAIL: *
11 
12 // This tests is meant to demonstrate an existing ABI bug between the
13 // C++03 and C++11 implementations of std::function. It is not a real test.
14 
15 // RUN: %{cxx} -c %s -o %t.first.o %{flags} %{compile_flags} -std=c++03 -g
16 // RUN: %{cxx} -c %s -o %t.second.o -DWITH_MAIN %{flags} %{compile_flags} -g -std=c++11
17 // RUN: %{cxx} -o %t.exe %t.first.o %t.second.o %{flags} %{link_flags} -g
18 // RUN: %{run}
19 
20 #include <functional>
21 #include <cassert>
22 
23 typedef std::function<void(int)> Func;
24 
25 Func CreateFunc();
26 
27 #ifndef WITH_MAIN
28 // In C++03, the functions call operator, which is a part of the vtable,
29 // is defined as 'void operator()(int)', but in C++11 it's
30 // void operator()(int&&)'. So when the C++03 version is passed to C++11 code
31 // the value of the integer is interpreted as its address.
test(int x)32 void test(int x) {
33   assert(x == 42);
34 }
CreateFunc()35 Func CreateFunc() {
36   Func f(&test);
37   return f;
38 }
39 #else
main(int,char **)40 int main(int, char**) {
41   Func f = CreateFunc();
42   f(42);
43   return 0;
44 }
45 #endif
46