1*67e74705SXin Li // Check that destructors of memcpy-able struct members are called properly 2*67e74705SXin Li // during stack unwinding after an exception. 3*67e74705SXin Li // 4*67e74705SXin Li // Check that destructor's argument (address of member to be destroyed) is 5*67e74705SXin Li // obtained by taking offset from struct, not by bitcasting pointers. 6*67e74705SXin Li // 7*67e74705SXin Li // RUN: %clang_cc1 -triple x86_64-unknown-unknown -fexceptions -fcxx-exceptions -O0 -fno-elide-constructors -emit-llvm %s -o - | FileCheck %s 8*67e74705SXin Li 9*67e74705SXin Li struct ImplicitCopy { 10*67e74705SXin Li int id; ImplicitCopyImplicitCopy11*67e74705SXin Li ImplicitCopy() { id = 10; } ~ImplicitCopyImplicitCopy12*67e74705SXin Li ~ImplicitCopy() { id = 20; } 13*67e74705SXin Li }; 14*67e74705SXin Li 15*67e74705SXin Li struct ThrowCopy { 16*67e74705SXin Li int id; ThrowCopyThrowCopy17*67e74705SXin Li ThrowCopy() { id = 15; } ThrowCopyThrowCopy18*67e74705SXin Li ThrowCopy(const ThrowCopy &x) { 19*67e74705SXin Li id = 25; 20*67e74705SXin Li throw 1; 21*67e74705SXin Li } ~ThrowCopyThrowCopy22*67e74705SXin Li ~ThrowCopy() { id = 35; } 23*67e74705SXin Li }; 24*67e74705SXin Li 25*67e74705SXin Li struct Container { 26*67e74705SXin Li int id; 27*67e74705SXin Li ImplicitCopy o1; 28*67e74705SXin Li ThrowCopy o2; 29*67e74705SXin Li ContainerContainer30*67e74705SXin Li Container() { id = 1000; } ~ContainerContainer31*67e74705SXin Li ~Container() { id = 2000; } 32*67e74705SXin Li }; 33*67e74705SXin Li main()34*67e74705SXin Liint main() { 35*67e74705SXin Li try { 36*67e74705SXin Li Container c1; 37*67e74705SXin Li // CHECK-LABEL: main 38*67e74705SXin Li // CHECK: %{{.+}} = getelementptr inbounds %struct.Container, %struct.Container* %{{.+}}, i32 0, i32 1 39*67e74705SXin Li // CHECK-NOT: %{{.+}} = bitcast %struct.Container* %{{.+}} to %struct.ImplicitCopy* 40*67e74705SXin Li Container c2(c1); 41*67e74705SXin Li 42*67e74705SXin Li return 2; 43*67e74705SXin Li } catch (...) { 44*67e74705SXin Li return 1; 45*67e74705SXin Li } 46*67e74705SXin Li return 0; 47*67e74705SXin Li } 48