19ca5c425SRichard Smith // RUN: %clang_cc1 -std=c++11 -fexceptions -fcxx-exceptions -fsyntax-only -verify %s 2fa453cfdSSebastian Redl 3fa453cfdSSebastian Redl // Exception specification compatibility. 4fa453cfdSSebastian Redl // We test function pointers, because functions have an extra rule in p4. 5fa453cfdSSebastian Redl 6fa453cfdSSebastian Redl // Same type is compatible 7fa453cfdSSebastian Redl extern void (*r1)() throw(int); 8fa453cfdSSebastian Redl extern void (*r1)() throw(int); 9fa453cfdSSebastian Redl 10fa453cfdSSebastian Redl // Typedefs don't matter. 11fa453cfdSSebastian Redl typedef int INT; 12fa453cfdSSebastian Redl extern void (*r2)() throw(int); 13fa453cfdSSebastian Redl extern void (*r2)() throw(INT); 14fa453cfdSSebastian Redl 15fa453cfdSSebastian Redl // Order doesn't matter. 16fa453cfdSSebastian Redl extern void (*r3)() throw(int, float); 17fa453cfdSSebastian Redl extern void (*r3)() throw(float, int); 18fa453cfdSSebastian Redl 19fa453cfdSSebastian Redl // MS throw-any spec and no spec at all are compatible 20fa453cfdSSebastian Redl extern void (*r4)(); 21fa453cfdSSebastian Redl extern void (*r4)() throw(...); 22fa453cfdSSebastian Redl 23fa453cfdSSebastian Redl // throw(X) and no spec are not compatible 24fa453cfdSSebastian Redl extern void (*r5)() throw(int); // expected-note {{previous declaration}} 25fa453cfdSSebastian Redl extern void (*r5)(); // expected-error {{exception specification in declaration does not match}} 26fa453cfdSSebastian Redl 27a91de375SRichard Smith // throw(int) and no spec are not compatible 28fa453cfdSSebastian Redl extern void f5() throw(int); // expected-note {{previous declaration}} 29a91de375SRichard Smith extern void f5(); // expected-error {{missing exception specification}} 30fa453cfdSSebastian Redl 31fa453cfdSSebastian Redl // Different types are not compatible. 32fa453cfdSSebastian Redl extern void (*r7)() throw(int); // expected-note {{previous declaration}} 33fa453cfdSSebastian Redl extern void (*r7)() throw(float); // expected-error {{exception specification in declaration does not match}} 34fa453cfdSSebastian Redl 35fa453cfdSSebastian Redl // Top-level const doesn't matter. 36fa453cfdSSebastian Redl extern void (*r8)() throw(int); 37fa453cfdSSebastian Redl extern void (*r8)() throw(const int); 38fa453cfdSSebastian Redl 39fa453cfdSSebastian Redl // Multiple appearances don't matter. 40fa453cfdSSebastian Redl extern void (*r9)() throw(int, int); 41fa453cfdSSebastian Redl extern void (*r9)() throw(int, int); 42fa453cfdSSebastian Redl 43fa453cfdSSebastian Redl 44fa453cfdSSebastian Redl // noexcept is compatible with itself 45fa453cfdSSebastian Redl extern void (*r10)() noexcept; 46fa453cfdSSebastian Redl extern void (*r10)() noexcept; 47fa453cfdSSebastian Redl 48fa453cfdSSebastian Redl // noexcept(true) is compatible with noexcept 49fa453cfdSSebastian Redl extern void (*r11)() noexcept; 50fa453cfdSSebastian Redl extern void (*r11)() noexcept(true); 51fa453cfdSSebastian Redl 52fa453cfdSSebastian Redl // noexcept(false) isn't 53fa453cfdSSebastian Redl extern void (*r12)() noexcept; // expected-note {{previous declaration}} 54fa453cfdSSebastian Redl extern void (*r12)() noexcept(false); // expected-error {{does not match}} 55fa453cfdSSebastian Redl 56fa453cfdSSebastian Redl // The form of the boolean expression doesn't matter. 57fa453cfdSSebastian Redl extern void (*r13)() noexcept(1 < 2); 58fa453cfdSSebastian Redl extern void (*r13)() noexcept(2 > 1); 59fa453cfdSSebastian Redl 60fa453cfdSSebastian Redl // noexcept(false) is incompatible with noexcept(true) 61fa453cfdSSebastian Redl extern void (*r14)() noexcept(true); // expected-note {{previous declaration}} 62fa453cfdSSebastian Redl extern void (*r14)() noexcept(false); // expected-error {{does not match}} 63fa453cfdSSebastian Redl 64fa453cfdSSebastian Redl // noexcept(false) is compatible with itself 65fa453cfdSSebastian Redl extern void (*r15)() noexcept(false); 66fa453cfdSSebastian Redl extern void (*r15)() noexcept(false); 67fa453cfdSSebastian Redl 68fa453cfdSSebastian Redl // noexcept(false) is compatible with MS throw(...) 69fa453cfdSSebastian Redl extern void (*r16)() noexcept(false); 70fa453cfdSSebastian Redl extern void (*r16)() throw(...); 71fa453cfdSSebastian Redl 72fa453cfdSSebastian Redl // noexcept(false) is *not* compatible with no spec 73fa453cfdSSebastian Redl extern void (*r17)(); // expected-note {{previous declaration}} 74fa453cfdSSebastian Redl extern void (*r17)() noexcept(false); // expected-error {{does not match}} 75fa453cfdSSebastian Redl 76fa453cfdSSebastian Redl // except for functions 77fa453cfdSSebastian Redl void f17(); 78fa453cfdSSebastian Redl void f17() noexcept(false); 79fa453cfdSSebastian Redl 80fa453cfdSSebastian Redl // noexcept(false) is compatible with dynamic specs that throw unless 81fa453cfdSSebastian Redl // CWG 1073 resolution is accepted. Clang implements it. 82fa453cfdSSebastian Redl //extern void (*r18)() throw(int); 83fa453cfdSSebastian Redl //extern void (*r18)() noexcept(false); 84fa453cfdSSebastian Redl 85fa453cfdSSebastian Redl // noexcept(true) is compatible with dynamic specs that don't throw 86fa453cfdSSebastian Redl extern void (*r19)() throw(); 87fa453cfdSSebastian Redl extern void (*r19)() noexcept(true); 88fa453cfdSSebastian Redl 89fa453cfdSSebastian Redl // The other way round doesn't work. 90fa453cfdSSebastian Redl extern void (*r20)() throw(); // expected-note {{previous declaration}} 91fa453cfdSSebastian Redl extern void (*r20)() noexcept(false); // expected-error {{does not match}} 92fa453cfdSSebastian Redl 93fa453cfdSSebastian Redl extern void (*r21)() throw(int); // expected-note {{previous declaration}} 94fa453cfdSSebastian Redl extern void (*r21)() noexcept(true); // expected-error {{does not match}} 95cb5dd007SSebastian Redl 96cb5dd007SSebastian Redl 97cb5dd007SSebastian Redl // As a very special workaround, we allow operator new to match no spec 98cb5dd007SSebastian Redl // with a throw(bad_alloc) spec, because C++0x makes an incompatible change 99cb5dd007SSebastian Redl // here. 100c34c29f6SSebastian Redl extern "C++" { namespace std { class bad_alloc {}; } } 101e8008381SSebastian Redl typedef decltype(sizeof(int)) mysize_t; 102e8008381SSebastian Redl void* operator new(mysize_t) throw(std::bad_alloc); 103e8008381SSebastian Redl void* operator new(mysize_t); 104e8008381SSebastian Redl void* operator new[](mysize_t); 105e8008381SSebastian Redl void* operator new[](mysize_t) throw(std::bad_alloc); 106cb5dd007SSebastian Redl 107*b64764a3SRichard Smith template<bool X> void equivalent() noexcept (X); 108*b64764a3SRichard Smith template<bool X> void equivalent() noexcept (X); 109*b64764a3SRichard Smith 110*b64764a3SRichard Smith template<bool X, bool Y> void not_equivalent() noexcept (X); // expected-note {{previous}} 111*b64764a3SRichard Smith template<bool X, bool Y> void not_equivalent() noexcept (Y); // expected-error {{does not match}} 112*b64764a3SRichard Smith 113*b64764a3SRichard Smith template<bool X> void missing() noexcept (X); // expected-note {{previous}} 114*b64764a3SRichard Smith // FIXME: The missing exception specification that we report here doesn't make 115*b64764a3SRichard Smith // sense in the context of this declaration. 116*b64764a3SRichard Smith template<bool P> void missing(); // expected-error {{missing exception specification 'noexcept(X)'}} 117