diff options
| author | Marco Antognini <marco.antognini@arm.com> | 2019-07-22 09:39:13 +0000 |
|---|---|---|
| committer | Marco Antognini <marco.antognini@arm.com> | 2019-07-22 09:39:13 +0000 |
| commit | 88559637641e993895337e1047a0bd787fecc647 (patch) | |
| tree | 639b057daba633db68b8fa4d34a957913786c64f /clang/test/CodeGenCXX | |
| parent | 6771a89fa01ffb1ea8702d7b07e259750ae62f1c (diff) | |
| download | bcm5719-llvm-88559637641e993895337e1047a0bd787fecc647.tar.gz bcm5719-llvm-88559637641e993895337e1047a0bd787fecc647.zip | |
[OpenCL] Improve destructor support in C++ for OpenCL
This re-applies r366422 with a fix for Bug PR42665 and a new regression
test.
llvm-svn: 366670
Diffstat (limited to 'clang/test/CodeGenCXX')
| -rw-r--r-- | clang/test/CodeGenCXX/PR42665.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/PR42665.cpp b/clang/test/CodeGenCXX/PR42665.cpp new file mode 100644 index 00000000000..4a460cfa107 --- /dev/null +++ b/clang/test/CodeGenCXX/PR42665.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -std=c++17 -O0 %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple %ms_abi_triple -emit-llvm -std=c++17 -O0 %s -o - | FileCheck %s + +// Minimal reproducer for PR42665. + +struct Foo { + Foo() = default; + virtual ~Foo() = default; +}; + +template <typename Deleter> +struct Pair { + Foo first; + Deleter second; +}; + +template <typename Deleter> +Pair(Foo, Deleter) -> Pair<Deleter>; + +template <typename T> +void deleter(T& t) { t.~T(); } + +auto make_pair() { + return Pair{ Foo(), deleter<Foo> }; +} + +void foobar() { + auto p = make_pair(); + auto& f = p.first; + auto& d = p.second; + d(f); // Invoke virtual destructor of Foo through d. +} // p's destructor is invoked. + +// Regexes are used to handle both kind of mangling. +// +// CHECK-LABEL: define linkonce_odr{{( dso_local)?}} void @{{.*deleter.*Foo.*}}(%struct.Foo* dereferenceable({{[0-9]+}}) +// CHECK-SAME: [[T:%.*]]) +// CHECK: [[T_ADDR:%.*]] = alloca %struct.Foo* +// CHECK: store %struct.Foo* [[T]], %struct.Foo** [[T_ADDR]] +// CHECK: [[R0:%.*]] = load %struct.Foo*, %struct.Foo** [[T_ADDR]] +// CHECK: [[R1:%.*]] = bitcast %struct.Foo* [[R0]] to [[TYPE:.*struct\.Foo.*]]*** +// CHECK: [[VTABLE:%.*]] = load [[TYPE]]**, [[TYPE]]*** [[R1]] +// CHECK: [[VFUN:%.*]] = getelementptr inbounds [[TYPE]]*, [[TYPE]]** [[VTABLE]], i64 0 +// CHECK: [[DTOR:%.*]] = load [[TYPE]]*, [[TYPE]]** [[VFUN]] +// CHECK: call {{(void|i8\*)}} [[DTOR]](%struct.Foo* [[R0]] +// +// CHECK-LABEL: define{{( dso_local)?}} void @{{.*foobar.*}}() +// CHECK: [[P:%.*]] = alloca %struct.Pair +// CHECK: [[F:%.*]] = alloca %struct.Foo* +// CHECK: [[D:%.*]] = alloca [[TYPE:void \(%struct.Foo\*\)]]** +// CHECK: call void @{{.*make_pair.*}}(%struct.Pair* sret [[P]]) +// CHECK: [[FIRST:%.*]] = getelementptr inbounds %struct.Pair, %struct.Pair* [[P]], i32 0, i32 0 +// CHECK: store %struct.Foo* [[FIRST]], %struct.Foo** [[F]] +// CHECK: [[SECOND:%.*]] = getelementptr inbounds %struct.Pair, %struct.Pair* [[P]], i32 0, i32 1 +// CHECK: store void (%struct.Foo*)** [[SECOND]], [[TYPE]]*** [[D]] +// CHECK: [[R0:%.*]] = load [[TYPE]]**, [[TYPE]]*** [[D]] +// CHECK: [[R1:%.*]] = load [[TYPE]]*, [[TYPE]]** [[R0]] +// CHECK: [[R2:%.*]] = load %struct.Foo*, %struct.Foo** [[F]] +// CHECK: call void [[R1]](%struct.Foo* dereferenceable({{[0-9]+}}) [[R2]]) +// CHECK: call void @{{.*Pair.*Foo.*}}(%struct.Pair* [[P]]) + |

