Clang Project

clang_source_code/test/CodeGenCXX/cxx1z-copy-omission.cpp
1// RUN: %clang_cc1 -std=c++1z -emit-llvm -triple x86_64-linux-gnu -o - %s | FileCheck %s
2
3struct A {
4  A(int);
5  A(A&&);
6  A(const A&);
7  ~A();
8
9  operator bool();
10
11  int arr[10];
12};
13
14A f();
15void h();
16
17// CHECK-LABEL: define {{.*}} @_Z1gv(
18void g() {
19  // CHECK: %[[A:.*]] = alloca
20  // CHECK-NOT: alloca
21  // CHECK-NOT: call
22  // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])
23  A a = A( A{ f() } );
24  // CHECK-NOT: call
25
26  // CHECK: call void @_Z1hv(
27  h();
28  // CHECK-NOT: call
29
30  // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
31  // CHECK-NOT: call
32  // CHECK-LABEL: }
33}
34
35void f(A);
36
37// CHECK-LABEL: define {{.*}} @_Z1hv(
38void h() {
39  // CHECK: %[[A:.*]] = alloca
40  // CHECK-NOT: alloca
41  // CHECK-NOT: call
42
43  // CHECK: call {{.*}} @_Z1fv({{.*}}* sret %[[A]])
44  // CHECK-NOT: call
45  // CHECK: call {{.*}} @_Z1f1A({{.*}}* %[[A]])
46  f(f());
47  // CHECK-NOT: call
48  // CHECK: call void @_ZN1AD1Ev({{.*}}* %[[A]])
49
50  // CHECK: call void @_Z1hv(
51  h();
52
53  // CHECK-NOT: call
54  // CHECK-LABEL: }
55}
56
57// We still pass classes with trivial copy/move constructors and destructors in
58// registers, even if the copy is formally omitted.
59struct B {
60  B(int);
61  int n;
62};
63
64B fB();
65void fB(B);
66
67// CHECK-LABEL: define {{.*}} @_Z1iv(
68void i() {
69  // CHECK: %[[B:.*]] = alloca
70  // CHECK-NOT: alloca
71  // CHECK-NOT: call
72
73  // CHECK: %[[B_N:.*]] = call i32 @_Z2fBv()
74  // CHECK-NOT: call
75  // CHECK: store i32 %[[B_N]],
76  // CHECK-NOT: call
77  // CHECK: %[[B_N:.*]] = load i32
78  // CHECK-NOT: call
79  // CHECK: call void @_Z2fB1B(i32 %[[B_N]])
80  fB(fB());
81
82  // CHECK-LABEL: }
83}
84
85// CHECK-LABEL: define {{.*}} @_Z1jv(
86void j() {
87  // CHECK:   alloca %{{.*}}*
88  // CHECK:   %[[OUTERTEMP:.*]] = alloca %{{.*}}
89  // CHECK:   %[[INNERTEMP:.*]] = alloca %{{.*}}
90  // CHECK:   call void @_ZN1AC1Ei(%{{.*}} %[[INNERTEMP]], i32 1)
91  // CHECK:   call zeroext i1 @_ZN1AcvbEv(%{{.*}} %[[INNERTEMP]])
92  // CHECK:   br i1
93  //
94  // CHECK:   call void @_ZN1AC1EOS_(%{{.*}} %[[OUTERTEMP]], %{{.*}} %[[INNERTEMP]])
95  // CHECK:   br label
96  //
97  // CHECK:   call void @_ZN1AC1Ei(%{{.*}} %[[OUTERTEMP]], i32 2)
98  // CHECK:   br label
99  //
100  // CHECK:   call void @_ZN1AD1Ev(%{{.*}} %[[INNERTEMP]])
101  A &&a = A(1) ?: A(2);
102
103  // CHECK:   call void @_Z1iv()
104  i();
105
106  // CHECK:   call void @_ZN1AD1Ev(%{{.*}} %[[OUTERTEMP]])
107}
108