Implement implicit exception specifications of destructors.

llvm-svn: 131528
diff --git a/clang/test/CXX/special/class.dtor/p3-0x.cpp b/clang/test/CXX/special/class.dtor/p3-0x.cpp
new file mode 100644
index 0000000..d4a9fdd
--- /dev/null
+++ b/clang/test/CXX/special/class.dtor/p3-0x.cpp
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -std=c++0x -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+  ~A();
+};
+
+struct B {
+  ~B() throw(int);
+};
+
+struct C {
+  B b;
+  ~C() {}
+};
+
+struct D {
+  ~D() noexcept(false);
+};
+
+struct E {
+  D d;
+  ~E() {}
+};
+
+void foo() {
+  A a;
+  C c;
+  E e;
+  // CHECK: invoke void @_ZN1ED1Ev
+  // CHECK: invoke void @_ZN1CD1Ev
+  // CHECK: call void @_ZN1AD1Ev
+}
+
+struct F {
+  D d;
+  ~F();
+};
+F::~F() noexcept(false) {}
+
+struct G {
+  D d;
+  ~G();
+};
+G::~G() {}
+
+struct H {
+  B b;
+  ~H();
+};
+H::~H() throw(int) {}
+
+struct I {
+  B b;
+  ~I();
+};
+I::~I() {}
+
+// Template variants.
+
+template <typename T>
+struct TA {
+  ~TA();
+};
+
+template <typename T>
+struct TB {
+  ~TB() throw(int);
+};
+
+template <typename T>
+struct TC {
+  TB<T> b;
+  ~TC() {}
+};
+
+template <typename T>
+struct TD {
+  ~TD() noexcept(false);
+};
+
+template <typename T>
+struct TE {
+  TD<T> d;
+  ~TE() {}
+};
+
+void tfoo() {
+  TA<int> a;
+  TC<int> c;
+  TE<int> e;
+  // CHECK: invoke void @_ZN2TEIiED1Ev
+  // CHECK: invoke void @_ZN2TCIiED1Ev
+  // CHECK: call void @_ZN2TAIiED1Ev
+}
+
+template <typename T>
+struct TF {
+  TD<T> d;
+  ~TF();
+};
+template <typename T>
+TF<T>::~TF() noexcept(false) {}
+
+template <typename T>
+struct TG {
+  TD<T> d;
+  ~TG();
+};
+template <typename T>
+TG<T>::~TG() {}
+
+template <typename T>
+struct TH {
+  TB<T> b;
+  ~TH();
+};
+template <typename T>
+TH<T>::~TH() {}
+
+void tinst() {
+  TF<int> f;
+  TG<int> g;
+  TH<int> h;
+}
+// CHECK: define linkonce_odr void @_ZN2THIiED1Ev
+// CHECK: _ZTIi
+// CHECK: __cxa_call_unexpected
diff --git a/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp b/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
index f45a87c..15c8e7f 100644
--- a/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
+++ b/clang/test/CodeGenCXX/cxx0x-delegating-ctors.cpp
@@ -2,10 +2,10 @@
 
 struct non_trivial {
   non_trivial();
-  ~non_trivial();
+  ~non_trivial() noexcept(false);
 };
 non_trivial::non_trivial() {}
-non_trivial::~non_trivial() {}
+non_trivial::~non_trivial() noexcept(false) {}
 
 // We use a virtual base to ensure that the constructor
 // delegation optimization (complete->base) can't be
diff --git a/clang/test/CodeGenCXX/eh.cpp b/clang/test/CodeGenCXX/eh.cpp
index 6c44c76..88c3272 100644
--- a/clang/test/CodeGenCXX/eh.cpp
+++ b/clang/test/CodeGenCXX/eh.cpp
@@ -159,7 +159,7 @@
       // CHECK-NEXT: bitcast
       // CHECK-NEXT: invoke void @_ZN5test81AC1ERKS0_(
       // CHECK:      call i8* @__cxa_begin_catch
-      // CHECK-NEXT: invoke void @_ZN5test81AD1Ev(
+      // CHECK-NEXT: call void @_ZN5test81AD1Ev(
       // CHECK:      call void @__cxa_end_catch()
       // CHECK:      ret void
     }
@@ -272,7 +272,7 @@
 
 // PR7686
 namespace test12 {
-  struct A { ~A(); };
+  struct A { ~A() noexcept(false); };
   bool opaque(const A&);
 
   // CHECK: define void @_ZN6test124testEv()
@@ -392,8 +392,8 @@
 }
 
 namespace test16 {
-  struct A { A(); ~A(); };
-  struct B { int x; B(const A &); ~B(); };
+  struct A { A(); ~A() noexcept(false); };
+  struct B { int x; B(const A &); ~B() noexcept(false); };
   void foo();
   bool cond();