PR14388: An array or function type in an exception specification should be
decayed to a pointer type. Patch by WenHan Gu, with a little tweaking and
additional testcases by me.

llvm-svn: 168822
diff --git a/clang/test/CodeGenCXX/exception-spec-decay.cpp b/clang/test/CodeGenCXX/exception-spec-decay.cpp
new file mode 100644
index 0000000..4928353
--- /dev/null
+++ b/clang/test/CodeGenCXX/exception-spec-decay.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions %s -triple=i686-unknown-linux -emit-llvm -o - | FileCheck %s
+typedef int Array[10];
+
+void foo() throw (Array) {
+  throw 0;
+  // CHECK: landingpad
+  // CHECK-NEXT: filter {{.*}} @_ZTIPi
+}
+
+struct S {
+  void foo() throw (S[10]) {
+    throw 0;
+  }
+};
+
+template <typename T>
+struct S2 {
+  void foo() throw (T) {
+    throw 0;
+  }
+};
+
+int main() {
+  S s;
+  s.foo();
+  // CHECK: landingpad
+  // CHECK-NEXT: filter {{.*}} @_ZTIP1S
+
+  S2 <int[10]> s2;
+  s2.foo();
+  // CHECK: landingpad
+  // CHECK-NEXT: filter {{.*}} @_ZTIPi
+}
diff --git a/clang/test/SemaCXX/exceptions.cpp b/clang/test/SemaCXX/exceptions.cpp
index 486d88e..8e32494 100644
--- a/clang/test/SemaCXX/exceptions.cpp
+++ b/clang/test/SemaCXX/exceptions.cpp
@@ -120,3 +120,26 @@
     }
   }
 }
+
+namespace Decay {
+  struct A {
+    void f() throw (A[10]);
+  };
+
+  template<typename T> struct B {
+    void f() throw (B[10]);
+  };
+  template struct B<int>;
+
+  void f() throw (int[10], int(*)());
+  void f() throw (int*, int());
+
+  template<typename T> struct C {
+    void f() throw (T); // expected-error {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}}
+  };
+  struct D {
+    C<D[10]> c;
+  };
+  struct E; // expected-note {{forward declaration}}
+  C<E[10]> e; // expected-note {{in instantiation of}}
+}