mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-29 07:36:06 +00:00

The fix is to remove duplicate copy-initialization of the only memcpy-able struct member and to correct the address of aggregately initialized members in destructors' calls during stack unwinding (in order to obtain address of struct member by using GEP instead of 'bitcast'). Differential Revision: http://reviews.llvm.org/D10990 llvm-svn: 242127
48 lines
1.1 KiB
C++
48 lines
1.1 KiB
C++
// Check that destructors of memcpy-able struct members are called properly
|
|
// during stack unwinding after an exception.
|
|
//
|
|
// Check that destructor's argument (address of member to be destroyed) is
|
|
// obtained by taking offset from struct, not by bitcasting pointers.
|
|
//
|
|
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s
|
|
|
|
struct ImplicitCopy {
|
|
int id;
|
|
ImplicitCopy() { id = 10; }
|
|
~ImplicitCopy() { id = 20; }
|
|
};
|
|
|
|
struct ThrowCopy {
|
|
int id;
|
|
ThrowCopy() { id = 15; }
|
|
ThrowCopy(const ThrowCopy &x) {
|
|
id = 25;
|
|
throw 1;
|
|
}
|
|
~ThrowCopy() { id = 35; }
|
|
};
|
|
|
|
struct Container {
|
|
int id;
|
|
ImplicitCopy o1;
|
|
ThrowCopy o2;
|
|
|
|
Container() { id = 1000; }
|
|
~Container() { id = 2000; }
|
|
};
|
|
|
|
int main() {
|
|
try {
|
|
Container c1;
|
|
// CHECK-LABEL: main
|
|
// CHECK: %{{.+}} = getelementptr inbounds %struct.Container, %struct.Container* %{{.+}}, i32 0, i32 1
|
|
// CHECK-NOT: %{{.+}} = bitcast %struct.Container* %{{.+}} to %struct.ImplicitCopy*
|
|
Container c2(c1);
|
|
|
|
return 2;
|
|
} catch (...) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|