blob: 4a460cfa10788491d95d24d77fb3421fc1dfa6d6 [file] [log] [blame]
Marco Antognini88559632019-07-22 09:39:13 +00001// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -std=c++17 -O0 %s -o - | FileCheck %s
2// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -std=c++17 -O0 %s -o - | FileCheck %s
3
4// Minimal reproducer for PR42665.
5
6struct Foo {
7 Foo() = default;
8 virtual ~Foo() = default;
9};
10
11template <typename Deleter>
12struct Pair {
13 Foo first;
14 Deleter second;
15};
16
17template <typename Deleter>
18Pair(Foo, Deleter) -> Pair<Deleter>;
19
20template <typename T>
21void deleter(T& t) { t.~T(); }
22
23auto make_pair() {
24 return Pair{ Foo(), deleter<Foo> };
25}
26
27void foobar() {
28 auto p = make_pair();
29 auto& f = p.first;
30 auto& d = p.second;
31 d(f); // Invoke virtual destructor of Foo through d.
32} // p's destructor is invoked.
33
34// Regexes are used to handle both kind of mangling.
35//
36// CHECK-LABEL: define linkonce_odr{{( dso_local)?}} void @{{.*deleter.*Foo.*}}(%struct.Foo* dereferenceable({{[0-9]+}})
37// CHECK-SAME: [[T:%.*]])
38// CHECK: [[T_ADDR:%.*]] = alloca %struct.Foo*
39// CHECK: store %struct.Foo* [[T]], %struct.Foo** [[T_ADDR]]
40// CHECK: [[R0:%.*]] = load %struct.Foo*, %struct.Foo** [[T_ADDR]]
41// CHECK: [[R1:%.*]] = bitcast %struct.Foo* [[R0]] to [[TYPE:.*struct\.Foo.*]]***
42// CHECK: [[VTABLE:%.*]] = load [[TYPE]]**, [[TYPE]]*** [[R1]]
43// CHECK: [[VFUN:%.*]] = getelementptr inbounds [[TYPE]]*, [[TYPE]]** [[VTABLE]], i64 0
44// CHECK: [[DTOR:%.*]] = load [[TYPE]]*, [[TYPE]]** [[VFUN]]
45// CHECK: call {{(void|i8\*)}} [[DTOR]](%struct.Foo* [[R0]]
46//
47// CHECK-LABEL: define{{( dso_local)?}} void @{{.*foobar.*}}()
48// CHECK: [[P:%.*]] = alloca %struct.Pair
49// CHECK: [[F:%.*]] = alloca %struct.Foo*
50// CHECK: [[D:%.*]] = alloca [[TYPE:void \(%struct.Foo\*\)]]**
51// CHECK: call void @{{.*make_pair.*}}(%struct.Pair* sret [[P]])
52// CHECK: [[FIRST:%.*]] = getelementptr inbounds %struct.Pair, %struct.Pair* [[P]], i32 0, i32 0
53// CHECK: store %struct.Foo* [[FIRST]], %struct.Foo** [[F]]
54// CHECK: [[SECOND:%.*]] = getelementptr inbounds %struct.Pair, %struct.Pair* [[P]], i32 0, i32 1
55// CHECK: store void (%struct.Foo*)** [[SECOND]], [[TYPE]]*** [[D]]
56// CHECK: [[R0:%.*]] = load [[TYPE]]**, [[TYPE]]*** [[D]]
57// CHECK: [[R1:%.*]] = load [[TYPE]]*, [[TYPE]]** [[R0]]
58// CHECK: [[R2:%.*]] = load %struct.Foo*, %struct.Foo** [[F]]
59// CHECK: call void [[R1]](%struct.Foo* dereferenceable({{[0-9]+}}) [[R2]])
60// CHECK: call void @{{.*Pair.*Foo.*}}(%struct.Pair* [[P]])
61