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