[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGen / temporary-lifetime.cpp
blob9f085d41d1464a32bc6c46367ea7224cb28cb933
1 // RUN: %clang_cc1 -no-enable-noundef-analysis %s -std=c++11 -O1 -DWITH_DTOR -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-DTOR %s
2 // RUN: %clang_cc1 -no-enable-noundef-analysis %s -std=c++11 -O1 -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-NO-DTOR %s
4 struct A {
5 A();
6 #ifdef WITH_DTOR
7 ~A();
8 #endif
9 char a[1024];
10 operator bool() const;
13 template <typename T>
14 void Foo(T &&);
16 template <typename T>
17 void Bar(T &&);
19 template <typename T>
20 T Baz();
22 void Test1() {
23 // CHECK-DTOR-LABEL: Test1
24 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]])
25 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])
26 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
27 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR]])
28 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]])
29 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]])
30 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])
31 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
32 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR]])
33 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]])
34 // CHECK-DTOR: }
36 // CHECK-NO-DTOR-LABEL: Test1
37 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]])
38 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])
39 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
40 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]])
41 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]])
42 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR:[^ ]+]])
43 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
44 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]])
45 // CHECK-NO-DTOR: }
47 const A &a = A{};
48 Foo(a);
51 const A &a = A{};
52 Foo(a);
56 void Test2() {
57 // CHECK-DTOR-LABEL: Test2
58 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR1:.+]])
59 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR1:[^ ]+]])
60 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
61 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR2:.+]])
62 // CHECK-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR2:[^ ]+]])
63 // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
64 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR2]])
65 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR2]])
66 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[VAR1]])
67 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR1]])
68 // CHECK-DTOR: }
70 // CHECK-NO-DTOR-LABEL: Test2
71 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR1:.+]])
72 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR1:[^ ]+]])
73 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
74 // CHECK-NO-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR2:.+]])
75 // CHECK-NO-DTOR: call void @_ZN1AC1Ev(ptr nonnull {{[^,]*}} %[[VAR2:[^ ]+]])
76 // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
77 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR2]])
78 // CHECK-NO-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR1]])
79 // CHECK-NO-DTOR: }
80 const A &a = A{};
81 Foo(a);
82 const A &b = A{};
83 Foo(b);
86 void Test3() {
87 // CHECK-DTOR-LABEL: Test3
88 // CHECK-DTOR: call void @llvm.lifetime.start
89 // CHECK-DTOR: call void @llvm.lifetime.start
91 // if.then:
92 // CHECK-DTOR: call void @llvm.lifetime.end
94 // cleanup:
95 // CHECK-DTOR: call void @llvm.lifetime.end
97 // cleanup:
98 // CHECK-DTOR: call void @llvm.lifetime.end
99 // CHECK-DTOR: }
100 const A &a = A{};
101 if (const A &b = A(a)) {
102 Foo(b);
103 return;
105 Bar(a);
108 void Test4() {
109 // CHECK-DTOR-LABEL: Test4
110 // CHECK-DTOR: call void @llvm.lifetime.start
112 // for.cond.cleanup:
113 // CHECK-DTOR: call void @llvm.lifetime.end
115 // for.body:
116 // CHECK-DTOR: }
117 for (const A &a = A{}; a;) {
118 Foo(a);
122 int Test5() {
123 // CHECK-DTOR-LABEL: Test5
124 // CHECK-DTOR: call void @llvm.lifetime.start
125 // CHECK-DTOR: call i32 @_Z3BazIiET_v()
126 // CHECK-DTOR: store
127 // CHECK-DTOR: call void @_Z3FooIRKiEvOT_
128 // CHECK-DTOR: load
129 // CHECK-DTOR: call void @llvm.lifetime.end
130 // CHECK-DTOR: }
131 const int &a = Baz<int>();
132 Foo(a);
133 return a;
136 void Test6() {
137 // CHECK-DTOR-LABEL: Test6
138 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %[[ADDR:.+]])
139 // CHECK-DTOR: call i32 @_Z3BazIiET_v()
140 // CHECK-DTOR: store
141 // CHECK-DTOR: call void @_Z3FooIiEvOT_
142 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %[[ADDR]])
143 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 {{[0-9]+}}, ptr nonnull %[[ADDR:.+]])
144 // CHECK-DTOR: call i32 @_Z3BazIiET_v()
145 // CHECK-DTOR: store
146 // CHECK-DTOR: call void @_Z3FooIiEvOT_
147 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 {{[0-9]+}}, ptr nonnull %[[ADDR]])
148 // CHECK-DTOR: }
149 Foo(Baz<int>());
150 Foo(Baz<int>());
153 void Test7() {
154 // CHECK-DTOR-LABEL: Test7
155 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]])
156 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])
157 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])
158 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[SLOT]])
159 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]])
160 // CHECK-DTOR: call void @llvm.lifetime.start.p0(i64 1024, ptr nonnull %[[ADDR:.+]])
161 // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])
162 // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])
163 // CHECK-DTOR: call void @_ZN1AD1Ev(ptr nonnull {{[^,]*}} %[[SLOT]])
164 // CHECK-DTOR: call void @llvm.lifetime.end.p0(i64 1024, ptr nonnull %[[ADDR]])
165 // CHECK-DTOR: }
166 Foo(Baz<A>());
167 Foo(Baz<A>());