1// RUN: %clang_cc1 %s -std=c++11 -O1 -DWITH_DTOR -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-DTOR %s
2// RUN: %clang_cc1 %s -std=c++11 -O1 -triple x86_64 -emit-llvm -o - | FileCheck -check-prefix=CHECK-NO-DTOR %s
3
4struct A {
5  A();
6#ifdef WITH_DTOR
7  ~A();
8#endif
9  char a[1024];
10  operator bool() const;
11};
12
13template <typename T>
14void Foo(T &&);
15
16template <typename T>
17void Bar(T &&);
18
19template <typename T>
20T Baz();
21
22void Test1() {
23  // CHECK-DTOR-LABEL: Test1
24  // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
25  // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
26  // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
27  // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]])
28  // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
29  // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
30  // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
31  // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
32  // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR]])
33  // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
34  // CHECK-DTOR: }
35
36  // CHECK-NO-DTOR-LABEL: Test1
37  // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
38  // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
39  // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
40  // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
41  // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
42  // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR:[^ ]+]])
43  // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
44  // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
45  // CHECK-NO-DTOR: }
46  {
47    const A &a = A{};
48    Foo(a);
49  }
50  {
51    const A &a = A{};
52    Foo(a);
53  }
54}
55
56void Test2() {
57  // CHECK-DTOR-LABEL: Test2
58  // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR1:[0-9]+]])
59  // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
60  // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
61  // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR2:[0-9]+]])
62  // CHECK-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]])
63  // CHECK-DTOR: call void @_Z3FooIRK1AEvOT_
64  // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR2]])
65  // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR2]])
66  // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[VAR1]])
67  // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]])
68  // CHECK-DTOR: }
69
70  // CHECK-NO-DTOR-LABEL: Test2
71  // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR1:[0-9]+]])
72  // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR1:[^ ]+]])
73  // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
74  // CHECK-NO-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR2:[0-9]+]])
75  // CHECK-NO-DTOR: call void @_ZN1AC1Ev(%struct.A* nonnull %[[VAR2:[^ ]+]])
76  // CHECK-NO-DTOR: call void @_Z3FooIRK1AEvOT_
77  // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR2]])
78  // CHECK-NO-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR1]])
79  // CHECK-NO-DTOR: }
80  const A &a = A{};
81  Foo(a);
82  const A &b = A{};
83  Foo(b);
84}
85
86void Test3() {
87  // CHECK-DTOR-LABEL: Test3
88  // CHECK-DTOR: call void @llvm.lifetime.start
89  // CHECK-DTOR: call void @llvm.lifetime.start
90
91  // if.then:
92  // CHECK-DTOR: call void @llvm.lifetime.end
93
94  // cleanup:
95  // CHECK-DTOR: call void @llvm.lifetime.end
96
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;
104  }
105  Bar(a);
106}
107
108void Test4() {
109  // CHECK-DTOR-LABEL: Test4
110  // CHECK-DTOR: call void @llvm.lifetime.start
111
112  // for.cond.cleanup:
113  // CHECK-DTOR: call void @llvm.lifetime.end
114
115  // for.body:
116  // CHECK-DTOR: }
117  for (const A &a = A{}; a;) {
118    Foo(a);
119  }
120}
121
122int 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;
134}
135
136void Test6() {
137  // CHECK-DTOR-LABEL: Test6
138  // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]])
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(i64 {{[0-9]+}}, i8* %[[ADDR]])
143  // CHECK-DTOR: call void @llvm.lifetime.start(i64 {{[0-9]+}}, i8* %[[ADDR:[0-9]+]])
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(i64 {{[0-9]+}}, i8* %[[ADDR]])
148  // CHECK-DTOR: }
149  Foo(Baz<int>());
150  Foo(Baz<int>());
151}
152
153void Test7() {
154  // CHECK-DTOR-LABEL: Test7
155  // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
156  // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])
157  // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])
158  // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]])
159  // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
160  // CHECK-DTOR: call void @llvm.lifetime.start(i64 1024, i8* %[[ADDR:[0-9]+]])
161  // CHECK-DTOR: call void @_Z3BazI1AET_v({{.*}} %[[SLOT:[^ ]+]])
162  // CHECK-DTOR: call void @_Z3FooI1AEvOT_({{.*}} %[[SLOT]])
163  // CHECK-DTOR: call void @_ZN1AD1Ev(%struct.A* nonnull %[[SLOT]])
164  // CHECK-DTOR: call void @llvm.lifetime.end(i64 1024, i8* %[[ADDR]])
165  // CHECK-DTOR: }
166  Foo(Baz<A>());
167  Foo(Baz<A>());
168}
169