diff options
author | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
---|---|---|
committer | Carlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au> | 2012-10-15 17:10:06 +1100 |
commit | be1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch) | |
tree | 1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/test/CXX/except | |
parent | c4626a62754862d20b41e8a46a3574264ea80e6d (diff) | |
parent | f1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff) |
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/test/CXX/except')
-rw-r--r-- | clang/test/CXX/except/except.handle/p16.cpp | 40 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/canonical.cpp | 53 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p1.cpp | 81 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p11.cpp | 12 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p14-ir.cpp | 79 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p14.cpp | 41 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p15.cpp | 24 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p2-dynamic-types.cpp | 34 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p2-places.cpp | 63 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p3.cpp | 106 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p5-pointers.cpp | 85 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p5-virtual.cpp | 96 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p9-dynamic.cpp | 12 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/p9-noexcept.cpp | 19 | ||||
-rw-r--r-- | clang/test/CXX/except/except.spec/template.cpp | 12 |
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}} |