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