reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
// 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}}

// throw(int) and no spec are not compatible
extern void f5() throw(int); // expected-note {{previous declaration}}
extern void f5(); // expected-error {{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);

template<bool X> void equivalent() noexcept (X);
template<bool X> void equivalent() noexcept (X);

template<bool X, bool Y> void not_equivalent() noexcept (X); // expected-note {{previous}}
template<bool X, bool Y> void not_equivalent() noexcept (Y); // expected-error {{does not match}}

template<bool X> void missing() noexcept (X); // expected-note {{previous}}
// FIXME: The missing exception specification that we report here doesn't make
// sense in the context of this declaration.
template<bool P> void missing(); // expected-error {{missing exception specification 'noexcept(X)'}}