|  | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s | 
|  | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++98 %s | 
|  | // RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify -std=c++11 %s | 
|  |  | 
|  | struct A; // expected-note 4 {{forward declaration of 'A'}} | 
|  |  | 
|  | struct Abstract { virtual void f() = 0; }; // expected-note {{unimplemented pure virtual method 'f'}} | 
|  |  | 
|  | void trys() { | 
|  | try { | 
|  | } catch(int i) { // expected-note {{previous definition}} | 
|  | int j = i; | 
|  | int i; // expected-error {{redefinition of 'i'}} | 
|  | } catch(float i) { | 
|  | } catch(void v) { // expected-error {{cannot catch incomplete type 'void'}} | 
|  | } catch(A a) { // expected-error {{cannot catch incomplete type 'A'}} | 
|  | } catch(A *a) { // expected-error {{cannot catch pointer to incomplete type 'A'}} | 
|  | } catch(A &a) { // expected-error {{cannot catch reference to incomplete type 'A'}} | 
|  | } catch(Abstract) { // expected-error {{variable type 'Abstract' is an abstract class}} | 
|  | } catch(...) { | 
|  | int j = i; // expected-error {{use of undeclared identifier 'i'}} | 
|  | } | 
|  |  | 
|  | try { | 
|  | } catch(...) { // expected-error {{catch-all handler must come last}} | 
|  | } catch(int) { | 
|  | } | 
|  | } | 
|  |  | 
|  | void throws() { | 
|  | throw; | 
|  | throw 0; | 
|  | throw throw; // expected-error {{cannot throw object of incomplete type 'void'}} | 
|  | throw (A*)0; // expected-error {{cannot throw pointer to object of incomplete type 'A'}} | 
|  | } | 
|  |  | 
|  | void jumps() { | 
|  | l1: | 
|  | goto l5; | 
|  | goto l4; // expected-error {{cannot jump}} | 
|  | goto l3; // expected-error {{cannot jump}} | 
|  | goto l2; // expected-error {{cannot jump}} | 
|  | goto l1; | 
|  | try { // expected-note 4 {{jump bypasses initialization of try block}} | 
|  | l2: | 
|  | goto l5; | 
|  | goto l4; // expected-error {{cannot jump}} | 
|  | goto l3; // expected-error {{cannot jump}} | 
|  | goto l2; | 
|  | goto l1; | 
|  | } catch(int) { // expected-note 4 {{jump bypasses initialization of catch block}} | 
|  | l3: | 
|  | goto l5; | 
|  | goto l4; // expected-error {{cannot jump}} | 
|  | goto l3; | 
|  | goto l2; // expected-error {{cannot jump}} | 
|  | goto l1; | 
|  | } catch(...) { // expected-note 4 {{jump bypasses initialization of catch block}} | 
|  | l4: | 
|  | goto l5; | 
|  | goto l4; | 
|  | goto l3; // expected-error {{cannot jump}} | 
|  | goto l2; // expected-error {{cannot jump}} | 
|  | goto l1; | 
|  | } | 
|  | l5: | 
|  | goto l5; | 
|  | goto l4; // expected-error {{cannot jump}} | 
|  | goto l3; // expected-error {{cannot jump}} | 
|  | goto l2; // expected-error {{cannot jump}} | 
|  | goto l1; | 
|  | } | 
|  |  | 
|  | struct BadReturn { | 
|  | BadReturn() try { | 
|  | } catch(...) { | 
|  | // Try to hide | 
|  | try { | 
|  | } catch(...) { | 
|  | { | 
|  | if (0) | 
|  | return; // expected-error {{return in the catch of a function try block of a constructor is illegal}} | 
|  | } | 
|  | } | 
|  | } | 
|  | BadReturn(int); | 
|  | }; | 
|  |  | 
|  | BadReturn::BadReturn(int) try { | 
|  | } catch(...) { | 
|  | // Try to hide | 
|  | try { | 
|  | } catch(int) { | 
|  | return; // expected-error {{return in the catch of a function try block of a constructor is illegal}} | 
|  | } catch(...) { | 
|  | { | 
|  | if (0) | 
|  | return; // expected-error {{return in the catch of a function try block of a constructor is illegal}} | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | // Cannot throw an abstract type. | 
|  | class foo { | 
|  | public: | 
|  | foo() {} | 
|  | void bar () { | 
|  | throw *this; // expected-error{{cannot throw an object of abstract type 'foo'}} | 
|  | } | 
|  | virtual void test () = 0; // expected-note{{unimplemented pure virtual method 'test'}} | 
|  | }; | 
|  |  | 
|  | namespace PR6831 { | 
|  | namespace NA { struct S; } | 
|  | namespace NB { struct S; } | 
|  |  | 
|  | void f() { | 
|  | using namespace NA; | 
|  | using namespace NB; | 
|  | try { | 
|  | } catch (int S) { | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | 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); | 
|  | #if __cplusplus <= 199711L | 
|  | // expected-error@-2 {{pointer to incomplete type 'Decay::E' is not allowed in exception specification}} | 
|  | #endif | 
|  | }; | 
|  | struct D { | 
|  | C<D[10]> c; | 
|  | }; | 
|  | struct E; | 
|  | #if __cplusplus <= 199711L | 
|  | // expected-note@-2 {{forward declaration of 'Decay::E'}} | 
|  | #endif | 
|  |  | 
|  | C<E[10]> e; | 
|  | #if __cplusplus <= 199711L | 
|  | // expected-note@-2 {{in instantiation of template class 'Decay::C<Decay::E [10]>' requested here}} | 
|  | #endif | 
|  | } | 
|  |  | 
|  | void rval_ref() throw (int &&); // expected-error {{rvalue reference type 'int &&' is not allowed in exception specification}} | 
|  | #if __cplusplus <= 199711L | 
|  | // expected-warning@-2 {{rvalue references are a C++11 extension}} | 
|  | #endif | 
|  |  | 
|  | namespace HandlerInversion { | 
|  | struct B {}; | 
|  | struct D : B {}; | 
|  | struct D2 : D {}; | 
|  |  | 
|  | void f1() { | 
|  | try { | 
|  | } catch (B &b) { // expected-note {{for type 'HandlerInversion::B &'}} | 
|  | } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}} | 
|  | } | 
|  | } | 
|  |  | 
|  | void f2() { | 
|  | try { | 
|  | } catch (B *b) { // expected-note {{for type 'HandlerInversion::B *'}} | 
|  | } catch (D *d) { // expected-warning {{exception of type 'HandlerInversion::D *' will be caught by earlier handler}} | 
|  | } | 
|  | } | 
|  |  | 
|  | void f3() { | 
|  | try { | 
|  | } catch (D &d) { // Ok | 
|  | } catch (B &b) { | 
|  | } | 
|  | } | 
|  |  | 
|  | void f4() { | 
|  | try { | 
|  | } catch (B &b) { // Ok | 
|  | } | 
|  | } | 
|  |  | 
|  | void f5() { | 
|  | try { | 
|  | } catch (int) { | 
|  | } catch (float) { | 
|  | } | 
|  | } | 
|  |  | 
|  | void f6() { | 
|  | try { | 
|  | } catch (B &b) {  // expected-note {{for type 'HandlerInversion::B &'}} | 
|  | } catch (D2 &d) {  // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}} | 
|  | } | 
|  | } | 
|  |  | 
|  | void f7() { | 
|  | try { | 
|  | } catch (B *b) { // Ok | 
|  | } catch (D &d) { // Ok | 
|  | } | 
|  |  | 
|  | try { | 
|  | } catch (B b) { // Ok | 
|  | } catch (D *d) { // Ok | 
|  | } | 
|  | } | 
|  |  | 
|  | void f8() { | 
|  | try { | 
|  | } catch (const B &b) {  // expected-note {{for type 'const HandlerInversion::B &'}} | 
|  | } catch (D2 &d) {  // expected-warning {{exception of type 'HandlerInversion::D2 &' will be caught by earlier handler}} | 
|  | } | 
|  |  | 
|  | try { | 
|  | } catch (B &b) {  // expected-note {{for type 'HandlerInversion::B &'}} | 
|  | } catch (const D2 &d) {  // expected-warning {{exception of type 'const HandlerInversion::D2 &' will be caught by earlier handler}} | 
|  | } | 
|  |  | 
|  | try { | 
|  | } catch (B b) { // expected-note {{for type 'HandlerInversion::B'}} | 
|  | } catch (D &d) { // expected-warning {{exception of type 'HandlerInversion::D &' will be caught by earlier handler}} | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace ConstVolatileThrow { | 
|  | struct S { | 
|  | S() {}         // expected-note{{candidate constructor not viable}} | 
|  | S(const S &s); // expected-note{{candidate constructor not viable}} | 
|  | }; | 
|  |  | 
|  | typedef const volatile S CVS; | 
|  |  | 
|  | void f() { | 
|  | throw CVS(); // expected-error{{no matching constructor for initialization}} | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace ConstVolatileCatch { | 
|  | struct S { | 
|  | S() {} | 
|  | S(const volatile S &s); | 
|  |  | 
|  | private: | 
|  | S(const S &s); // expected-note {{declared private here}} | 
|  | }; | 
|  |  | 
|  | void f(); | 
|  |  | 
|  | void g() { | 
|  | try { | 
|  | f(); | 
|  | } catch (volatile S s) { // expected-error {{calling a private constructor}} | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace PR28047 { | 
|  | void test1(int i) { | 
|  | try { | 
|  | } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}} | 
|  | } | 
|  | } | 
|  | void test2() { | 
|  | int i; | 
|  | try { | 
|  | } catch (int(*)[i]) { // expected-error{{cannot catch variably modified type}} | 
|  | } | 
|  | } | 
|  | } |