Clang Project

clang_source_code/test/CodeGenCXX/eh-aggregated-inits-unwind.cpp
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
9struct ImplicitCopy {
10  int id;
11  ImplicitCopy() { id = 10; }
12  ~ImplicitCopy() { id = 20; }
13};
14
15struct 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
25struct Container {
26  int id;
27  ImplicitCopy o1;
28  ThrowCopy o2;
29
30  Container() { id = 1000; }
31  ~Container() { id = 2000; }
32};
33
34int 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