1// Check that delete exprs call the sized deallocation function if
2// -fsized-deallocation is passed in both C++11 and C++14.
3// RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
4// RUN: %clang_cc1 -std=c++14 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s
5
6// Check that we don't used sized deallocation without -fsized-deallocation and
7// C++14.
8// RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
9// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED
10
11// CHECK-UNSIZED-NOT: _ZdlPvm
12// CHECK-UNSIZED-NOT: _ZdaPvm
13
14typedef decltype(sizeof(0)) size_t;
15
16typedef int A;
17struct B { int n; };
18struct C { ~C() {} };
19struct D { D(); virtual ~D() {} };
20struct E {
21  void *operator new(size_t);
22  void *operator new[](size_t);
23  void operator delete(void *) noexcept;
24  void operator delete[](void *) noexcept;
25};
26struct F {
27  void *operator new(size_t);
28  void *operator new[](size_t);
29  void operator delete(void *, size_t) noexcept;
30  void operator delete[](void *, size_t) noexcept;
31};
32
33template<typename T> T get();
34
35template<typename T>
36void del() {
37  ::delete get<T*>();
38  ::delete[] get<T*>();
39  delete get<T*>();
40  delete[] get<T*>();
41}
42
43template void del<A>();
44template void del<B>();
45template void del<C>();
46template void del<D>();
47template void del<E>();
48template void del<F>();
49
50D::D() {}
51
52// CHECK-LABEL: define weak_odr void @_Z3delIiEvv()
53// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
54// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
55//
56// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
57// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
58
59// CHECK-LABEL: declare void @_ZdlPvm(i8*
60
61// CHECK-LABEL: define weak_odr void @_Z3delI1BEvv()
62// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
63// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
64//
65// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4)
66// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
67
68// CHECK-LABEL: define weak_odr void @_Z3delI1CEvv()
69// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
70// CHECK: mul i64 1, %{{[^ ]*}}
71// CHECK: add i64 %{{[^ ]*}}, 8
72// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
73//
74// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
75// CHECK: mul i64 1, %{{[^ ]*}}
76// CHECK: add i64 %{{[^ ]*}}, 8
77// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
78
79// CHECK-LABEL: declare void @_ZdaPvm(i8*
80
81// CHECK-LABEL: define weak_odr void @_Z3delI1DEvv()
82// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
83// CHECK: mul i64 8, %{{[^ ]*}}
84// CHECK: add i64 %{{[^ ]*}}, 8
85// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
86//
87// CHECK-NOT: Zdl
88// CHECK: call void %{{.*}}
89// CHECK-NOT: Zdl
90// CHECK: mul i64 8, %{{[^ ]*}}
91// CHECK: add i64 %{{[^ ]*}}, 8
92// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
93
94// CHECK-LABEL: define weak_odr void @_Z3delI1EEvv()
95// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
96// CHECK: call void @_ZdaPv(i8* %{{[^ ]*}})
97//
98// CHECK: call void @_ZN1EdlEPv(i8* %{{[^ ]*}})
99// CHECK: call void @_ZN1EdaEPv(i8* %{{[^ ]*}})
100
101// CHECK-LABEL: define weak_odr void @_Z3delI1FEvv()
102// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 1)
103// CHECK: mul i64 1, %{{[^ ]*}}
104// CHECK: add i64 %{{[^ ]*}}, 8
105// CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
106//
107// CHECK: call void @_ZN1FdlEPvm(i8* %{{[^ ]*}}, i64 1)
108// CHECK: mul i64 1, %{{[^ ]*}}
109// CHECK: add i64 %{{[^ ]*}}, 8
110// CHECK: call void @_ZN1FdaEPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}})
111
112
113// CHECK-LABEL: define linkonce_odr void @_ZN1DD0Ev(%{{[^ ]*}}* %this)
114// CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8)
115