p3.cpp 3.7 KB

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