1 | /// RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s -DPOD | FileCheck %s -check-prefix=CHECK-POD |
2 | // RUN: %clang_cc1 -triple x86_64-apple-darwin12 -emit-llvm -o - -std=c++11 %s | FileCheck %s -check-prefix=CHECK-NONPOD |
3 | |
4 | // Declare the reserved placement operators. |
5 | typedef __typeof__(sizeof(0)) size_t; |
6 | void *operator new(size_t, void*) throw(); |
7 | void operator delete(void*, void*) throw(); |
8 | void *operator new[](size_t, void*) throw(); |
9 | void operator delete[](void*, void*) throw(); |
10 | template<typename T> T &&move(T&); |
11 | |
12 | struct foo { |
13 | #ifndef POD |
14 | foo() {} // non-POD |
15 | #endif |
16 | void *a, *b; |
17 | bool c; |
18 | }; |
19 | |
20 | // It is not legal to copy the tail padding in all cases, but if it is it can |
21 | // yield better codegen. |
22 | |
23 | foo *test1(void *f, const foo &x) { |
24 | return new (f) foo(x); |
25 | // CHECK-POD: test1 |
26 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
27 | |
28 | // CHECK-NONPOD: test1 |
29 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
30 | } |
31 | |
32 | foo *test2(const foo &x) { |
33 | return new foo(x); |
34 | // CHECK-POD: test2 |
35 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24 |
36 | |
37 | // CHECK-NONPOD: test2 |
38 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24 |
39 | } |
40 | |
41 | foo test3(const foo &x) { |
42 | foo f = x; |
43 | return f; |
44 | // CHECK-POD: test3 |
45 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
46 | |
47 | // CHECK-NONPOD: test3 |
48 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
49 | } |
50 | |
51 | foo *test4(foo &&x) { |
52 | return new foo(x); |
53 | // CHECK-POD: test4 |
54 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24 |
55 | |
56 | // CHECK-NONPOD: test4 |
57 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 16 {{.*}} align 8 {{.*}}i64 24 |
58 | } |
59 | |
60 | void test5(foo &f, const foo &x) { |
61 | f = x; |
62 | // CHECK-POD: test5 |
63 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
64 | |
65 | // CHECK-NONPOD: test5 |
66 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 17 |
67 | } |
68 | |
69 | extern foo globtest; |
70 | |
71 | void test6(foo &&x) { |
72 | globtest = move(x); |
73 | // CHECK-POD: test6 |
74 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
75 | |
76 | // CHECK-NONPOD: test6 |
77 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 17 |
78 | } |
79 | |
80 | void byval(foo f); |
81 | |
82 | void test7(const foo &x) { |
83 | byval(x); |
84 | // CHECK-POD: test7 |
85 | // CHECK-POD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
86 | |
87 | // CHECK-NONPOD: test7 |
88 | // CHECK-NONPOD: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}} align 8 {{.*}} align 8 {{.*}}i64 24 |
89 | } |
90 | |