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