summaryrefslogtreecommitdiff
path: root/clang/test/CXX/except
diff options
context:
space:
mode:
authorZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
committerZancanaro; Carlo <czan8762@plang3.cs.usyd.edu.au>2012-09-24 09:58:17 +1000
commit222e2a7620e6520ffaf4fc4e69d79c18da31542e (patch)
tree7bfbc05bfa3b41c8f9d2e56d53a0bc3e310df239 /clang/test/CXX/except
parent3d206f03985b50beacae843d880bccdc91a9f424 (diff)
Add the clang library to the repo (with some of my changes, too).
Diffstat (limited to 'clang/test/CXX/except')
-rw-r--r--clang/test/CXX/except/except.handle/p16.cpp40
-rw-r--r--clang/test/CXX/except/except.spec/canonical.cpp53
-rw-r--r--clang/test/CXX/except/except.spec/p1.cpp81
-rw-r--r--clang/test/CXX/except/except.spec/p11.cpp12
-rw-r--r--clang/test/CXX/except/except.spec/p14-ir.cpp79
-rw-r--r--clang/test/CXX/except/except.spec/p14.cpp41
-rw-r--r--clang/test/CXX/except/except.spec/p15.cpp24
-rw-r--r--clang/test/CXX/except/except.spec/p2-dynamic-types.cpp34
-rw-r--r--clang/test/CXX/except/except.spec/p2-places.cpp63
-rw-r--r--clang/test/CXX/except/except.spec/p3.cpp106
-rw-r--r--clang/test/CXX/except/except.spec/p5-pointers.cpp85
-rw-r--r--clang/test/CXX/except/except.spec/p5-virtual.cpp96
-rw-r--r--clang/test/CXX/except/except.spec/p9-dynamic.cpp12
-rw-r--r--clang/test/CXX/except/except.spec/p9-noexcept.cpp19
-rw-r--r--clang/test/CXX/except/except.spec/template.cpp12
15 files changed, 757 insertions, 0 deletions
diff --git a/clang/test/CXX/except/except.handle/p16.cpp b/clang/test/CXX/except/except.handle/p16.cpp
new file mode 100644
index 0000000..0810be1
--- /dev/null
+++ b/clang/test/CXX/except/except.handle/p16.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
+
+// The object declared in an exception-declaration or, if the
+// exception-declaration does not specify a name, a temporary (12.2)
+// is copy-initialized (8.5) from the exception object.
+//
+template<typename T>
+class X {
+ T* ptr;
+
+public:
+ X(const X<T> &) {
+ int *ip = 0;
+ ptr = ip; // expected-error{{assigning to 'float *' from incompatible type 'int *'}}
+ }
+
+ ~X() {
+ float *fp = 0;
+ ptr = fp; // expected-error{{assigning to 'int *' from incompatible type 'float *'}}
+ }
+};
+
+void f() {
+ try {
+ } catch (X<float>) { // expected-note{{instantiation}}
+ // copy constructor
+ } catch (X<int> xi) { // expected-note{{instantiation}}
+ // destructor
+ }
+}
+
+struct Abstract {
+ virtual void f() = 0; // expected-note{{pure virtual}}
+};
+
+void g() {
+ try {
+ } catch (Abstract) { // expected-error{{variable type 'Abstract' is an abstract class}}
+ }
+}
diff --git a/clang/test/CXX/except/except.spec/canonical.cpp b/clang/test/CXX/except/except.spec/canonical.cpp
new file mode 100644
index 0000000..81ca2ae
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/canonical.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// PR10087: Make sure that we don't conflate exception specifications
+// from different functions in the canonical type system.
+namespace std
+{
+
+template <class _Tp> _Tp&& declval() noexcept;
+
+template <class _Tp, class... _Args>
+struct __is_nothrow_constructible
+{
+ static const bool value = noexcept(_Tp(declval<_Args>()...));
+};
+
+template<class, class _Traits, class _Allocator>
+class basic_string
+{
+public:
+ typedef typename _Traits::char_type value_type;
+ typedef _Allocator allocator_type;
+
+ basic_string()
+ noexcept(__is_nothrow_constructible<allocator_type>::value);
+};
+
+template <class, class, class _Compare>
+struct __map_value_compare
+{
+public:
+ __map_value_compare()
+ noexcept(__is_nothrow_constructible<_Compare>::value);
+};
+
+struct less
+{
+};
+
+struct map
+{
+ typedef __map_value_compare<int, short, less> __vc;
+ __vc vc_;
+};
+
+
+template<class T, class _Traits, class _Allocator>
+basic_string<T, _Traits, _Allocator>::basic_string() noexcept(__is_nothrow_constructible<allocator_type>::value) {}
+
+template <class T, class Value, class _Compare>
+__map_value_compare<T, Value, _Compare>::__map_value_compare()
+ noexcept(__is_nothrow_constructible<_Compare>::value) {}
+
+} // std
diff --git a/clang/test/CXX/except/except.spec/p1.cpp b/clang/test/CXX/except/except.spec/p1.cpp
new file mode 100644
index 0000000..e184ec4
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p1.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Simple parser tests, dynamic specification.
+
+namespace dyn {
+
+ struct X { };
+
+ struct Y { };
+
+ void f() throw() { }
+
+ void g(int) throw(X) { }
+
+ void h() throw(X, Y) { }
+
+ class Class {
+ void foo() throw (X, Y) { }
+ };
+
+ void (*fptr)() throw();
+
+}
+
+// Simple parser tests, noexcept specification.
+
+namespace noex {
+
+ void f1() noexcept { }
+ void f2() noexcept (true) { }
+ void f3() noexcept (false) { }
+ void f4() noexcept (1 < 2) { }
+
+ class CA1 {
+ void foo() noexcept { }
+ void bar() noexcept (true) { }
+ };
+
+ void (*fptr1)() noexcept;
+ void (*fptr2)() noexcept (true);
+
+}
+
+namespace mix {
+
+ void f() throw(int) noexcept { } // expected-error {{cannot have both}}
+ void g() noexcept throw(int) { } // expected-error {{cannot have both}}
+
+}
+
+// Sema tests, noexcept specification
+
+namespace noex {
+
+ struct A {};
+
+ void g1() noexcept(A()); // expected-error {{not contextually convertible}}
+ void g2(bool b) noexcept(b); // expected-error {{argument to noexcept specifier must be a constant expression}}
+
+}
+
+namespace noexcept_unevaluated {
+ template<typename T> bool f(T) {
+ T* x = 1;
+ }
+
+ template<typename T>
+ void g(T x) noexcept((sizeof(T) == sizeof(int)) || noexcept(f(x))) { }
+
+ void h() {
+ g(1);
+ }
+}
+
+namespace PR11084 {
+ template<int X> struct A {
+ static int f() noexcept(1/X) { return 10; } // expected-error{{argument to noexcept specifier must be a constant expression}} expected-note{{division by zero}}
+ };
+
+ void g() { A<0>::f(); } // expected-note{{in instantiation of exception specification for 'f' requested here}}
+}
diff --git a/clang/test/CXX/except/except.spec/p11.cpp b/clang/test/CXX/except/except.spec/p11.cpp
new file mode 100644
index 0000000..0e4fad5
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p11.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// This is the "let the user shoot himself in the foot" clause.
+void f() noexcept {
+ throw 0; // no-error
+}
+void g() throw() {
+ throw 0; // no-error
+}
+void h() throw(int) {
+ throw 0.0; // no-error
+}
diff --git a/clang/test/CXX/except/except.spec/p14-ir.cpp b/clang/test/CXX/except/except.spec/p14-ir.cpp
new file mode 100644
index 0000000..81fbf7d
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p14-ir.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm -fexceptions -o - %s | FileCheck %s
+
+// Copy constructor
+struct X0 {
+ X0();
+ X0(const X0 &) throw();
+ X0(X0 &);
+};
+
+struct X1 {
+ X1();
+ X1(const X1 &) throw();
+};
+
+struct X2 : X1 {
+ X2();
+};
+struct X3 : X0, X1 {
+ X3();
+};
+
+struct X4 {
+ X4(X4 &) throw();
+};
+
+struct X5 : X0, X4 { };
+
+void test(X2 x2, X3 x3, X5 x5) {
+ // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X2* %this, %struct.X2*) unnamed_addr
+ // CHECK: call void @_ZN2X2C2ERKS_({{.*}}) nounwind
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+ X2 x2a(x2);
+ // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X3* %this, %struct.X3*) unnamed_addr
+ // CHECK: call void @_ZN2X3C2ERKS_({{.*}}) nounwind
+ // CHECK-NEXT: ret void
+ // CHECK-NEXT: }
+ X3 x3a(x3);
+ // CHECK: define linkonce_odr void @_ZN2X5C1ERS_({{.*}}) unnamed_addr
+ // CHECK-NOT: call void @__cxa_call_unexpected
+ // CHECK: ret void
+ X5 x5a(x5);
+}
+
+// Default constructor
+struct X6 {
+ X6() throw();
+};
+
+struct X7 {
+ X7();
+};
+
+struct X8 : X6 { };
+struct X9 : X6, X7 { };
+
+void test() {
+ // CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X8* %this) unnamed_addr
+ // CHECK: call void @_ZN2X8C2Ev({{.*}}) nounwind
+ // CHECK-NEXT: ret void
+ X8();
+
+ // CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X9* %this) unnamed_addr
+ // FIXME: check that this is the end of the line here:
+ // CHECK: call void @_ZN2X9C2Ev({{.*}})
+ // CHECK-NEXT: ret void
+ X9();
+
+ // CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X9* %this) unnamed_addr
+ // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind
+ // FIXME: and here:
+ // CHECK-NEXT: bitcast
+ // CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}})
+ // CHECK: ret void
+
+ // CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X8* %this) unnamed_addr
+ // CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind
+ // CHECK-NEXT: ret void
+}
diff --git a/clang/test/CXX/except/except.spec/p14.cpp b/clang/test/CXX/except/except.spec/p14.cpp
new file mode 100644
index 0000000..8763a70
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p14.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -verify -std=c++11 %s
+struct A { };
+struct B { };
+struct C { };
+
+// Destructor
+struct X0 {
+ virtual ~X0() throw(A); // expected-note{{overridden virtual function is here}}
+};
+struct X1 {
+ virtual ~X1() throw(B); // expected-note{{overridden virtual function is here}}
+};
+struct X2 : public X0, public X1 { }; // expected-error 2{{exception specification of overriding function is more lax than base version}}
+
+// Copy-assignment operator.
+struct CA0 {
+ CA0 &operator=(const CA0&) throw(A);
+};
+struct CA1 {
+ CA1 &operator=(const CA1&) throw(B);
+};
+struct CA2 : CA0, CA1 { };
+
+void test_CA() {
+ CA2 &(CA2::*captr1)(const CA2&) throw(A, B) = &CA2::operator=;
+ CA2 &(CA2::*captr2)(const CA2&) throw(A, B, C) = &CA2::operator=;
+ CA2 &(CA2::*captr3)(const CA2&) throw(A) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
+ CA2 &(CA2::*captr4)(const CA2&) throw(B) = &CA2::operator=; // expected-error{{target exception specification is not superset of source}}
+}
+
+// In-class member initializers.
+struct IC0 {
+ int inClassInit = 0;
+};
+struct IC1 {
+ int inClassInit = (throw B(), 0);
+};
+// FIXME: the exception specification on the default constructor is wrong:
+// we cannot currently compute the set of thrown types.
+static_assert(noexcept(IC0()), "IC0() does not throw");
+static_assert(!noexcept(IC1()), "IC1() throws");
diff --git a/clang/test/CXX/except/except.spec/p15.cpp b/clang/test/CXX/except/except.spec/p15.cpp
new file mode 100644
index 0000000..110ec3f
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p15.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Deallocation functions are implicitly noexcept.
+// Thus, explicit specs aren't allowed to conflict.
+
+void f() {
+ // Force implicit declaration of delete.
+ delete new int;
+ delete[] new int[1];
+}
+
+void operator delete(void*) noexcept;
+void operator delete[](void*) noexcept;
+
+// Same goes for explicit declarations.
+void operator delete(void*, float);
+void operator delete(void*, float) noexcept;
+
+void operator delete[](void*, float);
+void operator delete[](void*, float) noexcept;
+
+// But explicit specs stay.
+void operator delete(void*, double) throw(int); // expected-note {{previous}}
+void operator delete(void*, double) noexcept; // expected-error {{does not match}}
diff --git a/clang/test/CXX/except/except.spec/p2-dynamic-types.cpp b/clang/test/CXX/except/except.spec/p2-dynamic-types.cpp
new file mode 100644
index 0000000..57f8c32
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p2-dynamic-types.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Dynamic specifications: valid types.
+
+struct Incomplete; // expected-note 3 {{forward declaration}}
+
+// Exception spec must not have incomplete types, or pointers to them, except
+// void.
+void ic1() throw(void); // expected-error {{incomplete type 'void' is not allowed in exception specification}}
+void ic2() throw(Incomplete); // expected-error {{incomplete type 'Incomplete' is not allowed in exception specification}}
+void ic3() throw(void*);
+void ic4() throw(Incomplete*); // expected-error {{pointer to incomplete type 'Incomplete' is not allowed in exception specification}}
+void ic5() throw(Incomplete&); // expected-error {{reference to incomplete type 'Incomplete' is not allowed in exception specification}}
+
+// Don't suppress errors in template instantiation.
+template <typename T> struct TEx; // expected-note {{template is declared here}}
+
+void tf() throw(TEx<int>); // expected-error {{implicit instantiation of undefined template}}
+
+// DR 437, class throws itself.
+struct DR437 {
+ void f() throw(DR437);
+ void g() throw(DR437*);
+ void h() throw(DR437&);
+};
+
+// DR 437 within a nested class
+struct DR437_out {
+ struct DR437_in {
+ void f() throw(DR437_out);
+ void g() throw(DR437_out*);
+ void h() throw(DR437_out&);
+ };
+};
diff --git a/clang/test/CXX/except/except.spec/p2-places.cpp b/clang/test/CXX/except/except.spec/p2-places.cpp
new file mode 100644
index 0000000..67647fb
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p2-places.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Tests where specs are allowed and where they aren't.
+
+namespace dyn {
+
+ // Straight from the standard:
+
+ // Plain function with spec
+ void f() throw(int);
+
+ // Pointer to function with spec
+ void (*fp)() throw (int);
+
+ // Function taking reference to function with spec
+ void g(void pfa() throw(int));
+
+ // Typedef for pointer to function with spec
+ typedef int (*pf)() throw(int); // expected-error {{specifications are not allowed in typedefs}}
+
+ // Some more:
+
+ // Function returning function with spec
+ void (*h())() throw(int);
+
+ // Ultimate parser thrill: function with spec returning function with spec and
+ // taking pointer to function with spec.
+ // The actual function throws int, the return type double, the argument float.
+ void (*i() throw(int))(void (*)() throw(float)) throw(double);
+
+ // Pointer to pointer to function taking function with spec
+ void (**k)(void pfa() throw(int)); // no-error
+
+ // Pointer to pointer to function with spec
+ void (**j)() throw(int); // expected-error {{not allowed beyond a single}}
+
+ // Pointer to function returning pointer to pointer to function with spec
+ void (**(*h())())() throw(int); // expected-error {{not allowed beyond a single}}
+
+}
+
+namespace noex {
+
+ // These parallel those from above.
+
+ void f() noexcept(false);
+
+ void (*fp)() noexcept(false);
+
+ void g(void pfa() noexcept(false));
+
+ typedef int (*pf)() noexcept(false); // expected-error {{specifications are not allowed in typedefs}}
+
+ void (*h())() noexcept(false);
+
+ void (*i() noexcept(false))(void (*)() noexcept(true)) noexcept(false);
+
+ void (**k)(void pfa() noexcept(false)); // no-error
+
+ void (**j)() noexcept(false); // expected-error {{not allowed beyond a single}}
+
+ void (**(*h())())() noexcept(false); // expected-error {{not allowed beyond a single}}
+}
diff --git a/clang/test/CXX/except/except.spec/p3.cpp b/clang/test/CXX/except/except.spec/p3.cpp
new file mode 100644
index 0000000..d77aea4
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p3.cpp
@@ -0,0 +1,106 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Exception specification compatibility.
+// We test function pointers, because functions have an extra rule in p4.
+
+// Same type is compatible
+extern void (*r1)() throw(int);
+extern void (*r1)() throw(int);
+
+// Typedefs don't matter.
+typedef int INT;
+extern void (*r2)() throw(int);
+extern void (*r2)() throw(INT);
+
+// Order doesn't matter.
+extern void (*r3)() throw(int, float);
+extern void (*r3)() throw(float, int);
+
+// MS throw-any spec and no spec at all are compatible
+extern void (*r4)();
+extern void (*r4)() throw(...);
+
+// throw(X) and no spec are not compatible
+extern void (*r5)() throw(int); // expected-note {{previous declaration}}
+extern void (*r5)(); // expected-error {{exception specification in declaration does not match}}
+
+// For functions, we accept this with a warning.
+extern void f5() throw(int); // expected-note {{previous declaration}}
+extern void f5(); // expected-warning {{missing exception specification}}
+
+// Different types are not compatible.
+extern void (*r7)() throw(int); // expected-note {{previous declaration}}
+extern void (*r7)() throw(float); // expected-error {{exception specification in declaration does not match}}
+
+// Top-level const doesn't matter.
+extern void (*r8)() throw(int);
+extern void (*r8)() throw(const int);
+
+// Multiple appearances don't matter.
+extern void (*r9)() throw(int, int);
+extern void (*r9)() throw(int, int);
+
+
+// noexcept is compatible with itself
+extern void (*r10)() noexcept;
+extern void (*r10)() noexcept;
+
+// noexcept(true) is compatible with noexcept
+extern void (*r11)() noexcept;
+extern void (*r11)() noexcept(true);
+
+// noexcept(false) isn't
+extern void (*r12)() noexcept; // expected-note {{previous declaration}}
+extern void (*r12)() noexcept(false); // expected-error {{does not match}}
+
+// The form of the boolean expression doesn't matter.
+extern void (*r13)() noexcept(1 < 2);
+extern void (*r13)() noexcept(2 > 1);
+
+// noexcept(false) is incompatible with noexcept(true)
+extern void (*r14)() noexcept(true); // expected-note {{previous declaration}}
+extern void (*r14)() noexcept(false); // expected-error {{does not match}}
+
+// noexcept(false) is compatible with itself
+extern void (*r15)() noexcept(false);
+extern void (*r15)() noexcept(false);
+
+// noexcept(false) is compatible with MS throw(...)
+extern void (*r16)() noexcept(false);
+extern void (*r16)() throw(...);
+
+// noexcept(false) is *not* compatible with no spec
+extern void (*r17)(); // expected-note {{previous declaration}}
+extern void (*r17)() noexcept(false); // expected-error {{does not match}}
+
+// except for functions
+void f17();
+void f17() noexcept(false);
+
+// noexcept(false) is compatible with dynamic specs that throw unless
+// CWG 1073 resolution is accepted. Clang implements it.
+//extern void (*r18)() throw(int);
+//extern void (*r18)() noexcept(false);
+
+// noexcept(true) is compatible with dynamic specs that don't throw
+extern void (*r19)() throw();
+extern void (*r19)() noexcept(true);
+
+// The other way round doesn't work.
+extern void (*r20)() throw(); // expected-note {{previous declaration}}
+extern void (*r20)() noexcept(false); // expected-error {{does not match}}
+
+extern void (*r21)() throw(int); // expected-note {{previous declaration}}
+extern void (*r21)() noexcept(true); // expected-error {{does not match}}
+
+
+// As a very special workaround, we allow operator new to match no spec
+// with a throw(bad_alloc) spec, because C++0x makes an incompatible change
+// here.
+extern "C++" { namespace std { class bad_alloc {}; } }
+typedef decltype(sizeof(int)) mysize_t;
+void* operator new(mysize_t) throw(std::bad_alloc);
+void* operator new(mysize_t);
+void* operator new[](mysize_t);
+void* operator new[](mysize_t) throw(std::bad_alloc);
+
diff --git a/clang/test/CXX/except/except.spec/p5-pointers.cpp b/clang/test/CXX/except/except.spec/p5-pointers.cpp
new file mode 100644
index 0000000..dd3c060
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p5-pointers.cpp
@@ -0,0 +1,85 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Assignment of function pointers.
+
+struct A
+{
+};
+
+struct B1 : A
+{
+};
+
+struct B2 : A
+{
+};
+
+struct D : B1, B2
+{
+};
+
+struct P : private A
+{
+};
+
+// Some functions to play with below.
+void s1() throw();
+void s2() throw(int);
+void s3() throw(A);
+void s4() throw(B1);
+void s5() throw(D);
+void s6();
+void s7() throw(int, float);
+void (*s8())() throw(B1); // s8 returns a pointer to function with spec
+void s9(void (*)() throw(B1)); // s9 takes pointer to function with spec
+
+void s10() noexcept;
+void s11() noexcept(true);
+void s12() noexcept(false);
+
+void fnptrs()
+{
+ // Assignment and initialization of function pointers.
+ void (*t1)() throw() = &s1; // valid
+ t1 = &s2; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t1 = &s3; // expected-error {{not superset}} expected-error {{incompatible type}}
+ void (&t2)() throw() = s2; // expected-error {{not superset}}
+ void (*t3)() throw(int) = &s2; // valid
+ void (*t4)() throw(A) = &s1; // valid
+ t4 = &s3; // valid
+ t4 = &s4; // valid
+ t4 = &s5; // expected-error {{not superset}} expected-error {{incompatible type}}
+ void (*t5)() = &s1; // valid
+ t5 = &s2; // valid
+ t5 = &s6; // valid
+ t5 = &s7; // valid
+ t1 = t3; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t3 = t1; // valid
+ void (*t6)() throw(B1);
+ t6 = t4; // expected-error {{not superset}} expected-error {{incompatible type}}
+ t4 = t6; // valid
+ t5 = t1; // valid
+ t1 = t5; // expected-error {{not superset}} expected-error {{incompatible type}}
+
+ // return types and arguments must match exactly, no inheritance allowed
+ void (*(*t7)())() throw(B1) = &s8; // valid
+ void (*(*t8)())() throw(A) = &s8; // expected-error {{return types differ}}
+ void (*(*t9)())() throw(D) = &s8; // expected-error {{return types differ}}
+ void (*t10)(void (*)() throw(B1)) = &s9; // valid expected-warning{{disambiguated}}
+ void (*t11)(void (*)() throw(A)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}}
+ void (*t12)(void (*)() throw(D)) = &s9; // expected-error {{argument types differ}} expected-warning{{disambiguated}}
+}
+
+// Member function stuff
+
+struct Str1 { void f() throw(int); }; // expected-note {{previous declaration}}
+void Str1::f() // expected-warning {{missing exception specification}}
+{
+}
+
+void mfnptr()
+{
+ void (Str1::*pfn1)() throw(int) = &Str1::f; // valid
+ void (Str1::*pfn2)() = &Str1::f; // valid
+ void (Str1::*pfn3)() throw() = &Str1::f; // expected-error {{not superset}}
+}
diff --git a/clang/test/CXX/except/except.spec/p5-virtual.cpp b/clang/test/CXX/except/except.spec/p5-virtual.cpp
new file mode 100644
index 0000000..69daec6
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p5-virtual.cpp
@@ -0,0 +1,96 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// Compatibility of virtual functions.
+
+struct A
+{
+};
+
+struct B1 : A
+{
+};
+
+struct B2 : A
+{
+};
+
+struct D : B1, B2
+{
+};
+
+struct P : private A
+{
+};
+
+struct Base
+{
+ virtual void f1() throw();
+ virtual void f2() throw(int, float);
+
+ virtual void f3() throw(int, float);
+ virtual void f4() throw(A);
+ virtual void f5() throw(A, int, float);
+ virtual void f6();
+
+ virtual void f7() noexcept;
+ virtual void f8() noexcept;
+ virtual void f9() noexcept(false);
+ virtual void f10() noexcept(false);
+
+ virtual void f11() throw();
+ virtual void f12() noexcept;
+ virtual void f13() noexcept(false);
+ virtual void f14() throw(int);
+
+ virtual void f15();
+ virtual void f16();
+
+ virtual void g1() throw(); // expected-note {{overridden virtual function is here}}
+ virtual void g2() throw(int); // expected-note {{overridden virtual function is here}}
+ virtual void g3() throw(A); // expected-note {{overridden virtual function is here}}
+ virtual void g4() throw(B1); // expected-note {{overridden virtual function is here}}
+ virtual void g5() throw(A); // expected-note {{overridden virtual function is here}}
+
+ virtual void g6() noexcept; // expected-note {{overridden virtual function is here}}
+ virtual void g7() noexcept; // expected-note {{overridden virtual function is here}}
+
+ virtual void g8() noexcept; // expected-note {{overridden virtual function is here}}
+ virtual void g9() throw(); // expected-note {{overridden virtual function is here}}
+ virtual void g10() throw(int); // expected-note {{overridden virtual function is here}}
+};
+struct Derived : Base
+{
+ virtual void f1() throw();
+ virtual void f2() throw(float, int);
+
+ virtual void f3() throw(float);
+ virtual void f4() throw(B1);
+ virtual void f5() throw(B1, B2, int);
+ virtual void f6() throw(B2, B2, int, float, char, double, bool);
+
+ virtual void f7() noexcept;
+ virtual void f8() noexcept(true);
+ virtual void f9() noexcept(true);
+ virtual void f10() noexcept(false);
+
+ virtual void f11() noexcept;
+ virtual void f12() throw();
+ virtual void f13() throw(int);
+ virtual void f14() noexcept(true);
+
+ virtual void f15() noexcept;
+ virtual void f16() throw();
+
+ virtual void g1() throw(int); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g2(); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g3() throw(D); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g4() throw(A); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g5() throw(P); // expected-error {{exception specification of overriding function is more lax}}
+
+ virtual void g6() noexcept(false); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g7(); // expected-error {{exception specification of overriding function is more lax}}
+
+ virtual void g8() throw(int); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g9() noexcept(false); // expected-error {{exception specification of overriding function is more lax}}
+ virtual void g10() noexcept(false); // expected-error {{exception specification of overriding function is more lax}}
+};
diff --git a/clang/test/CXX/except/except.spec/p9-dynamic.cpp b/clang/test/CXX/except/except.spec/p9-dynamic.cpp
new file mode 100644
index 0000000..4559e0d
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p9-dynamic.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+
+void external();
+
+void target() throw(int)
+{
+ // CHECK: invoke void @_Z8externalv()
+ external();
+}
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-NEXT: filter [1 x i8*] [i8* bitcast (i8** @_ZTIi to i8*)]
+// CHECK: call void @__cxa_call_unexpected
diff --git a/clang/test/CXX/except/except.spec/p9-noexcept.cpp b/clang/test/CXX/except/except.spec/p9-noexcept.cpp
new file mode 100644
index 0000000..7c8d0ef
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/p9-noexcept.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 %s -std=c++11 -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s
+
+void external();
+
+void target() noexcept
+{
+ // CHECK: invoke void @_Z8externalv()
+ external();
+}
+// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*)
+// CHECK-NEXT: catch i8* null
+// CHECK-NEXT: call void @_ZSt9terminatev() noreturn nounwind
+// CHECK-NEXT: unreachable
+
+void reverse() noexcept(false)
+{
+ // CHECK: call void @_Z8externalv()
+ external();
+}
diff --git a/clang/test/CXX/except/except.spec/template.cpp b/clang/test/CXX/except/except.spec/template.cpp
new file mode 100644
index 0000000..805a604
--- /dev/null
+++ b/clang/test/CXX/except/except.spec/template.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s
+
+// We use pointer assignment compatibility to test instantiation.
+
+template <int N> void f1() throw(int);
+template <int N> void f2() noexcept(N > 1);
+
+void (*t1)() throw(int) = &f1<0>;
+void (*t2)() throw() = &f1<0>; // expected-error {{not superset}}
+
+void (*t3)() noexcept = &f2<2>; // no-error
+void (*t4)() noexcept = &f2<0>; // expected-error {{not superset}}