brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · 646cea4 Raw
465 lines · cpp
1// RUN: %clang_cc1 %s  -fdelayed-template-parsing -fcxx-exceptions -fsyntax-only -Wexceptions -verify -fdeclspec -std=c++172struct A_ShouldDiag {3  ~A_ShouldDiag(); // implicitly noexcept(true)4};5A_ShouldDiag::~A_ShouldDiag() { // expected-note {{destructor has a implicit non-throwing exception specification}}6  throw 1; // expected-warning {{has a non-throwing exception specification but can still throw}}7}8struct B_ShouldDiag {9  int i;10  ~B_ShouldDiag() noexcept(true) {} //no disg, no throw stmt11};12struct R_ShouldDiag : A_ShouldDiag {13  B_ShouldDiag b;14  ~R_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}15    throw 1; // expected-warning {{has a non-throwing exception specification but}}16  }17  __attribute__((nothrow)) R_ShouldDiag() {// expected-note {{function declared non-throwing here}}18    throw 1;// expected-warning {{has a non-throwing exception specification but}}19  }20  void __attribute__((nothrow)) SomeThrow() {// expected-note {{function declared non-throwing here}}21   throw 1; // expected-warning {{has a non-throwing exception specification but}}22  }23  void __declspec(nothrow) SomeDeclspecThrow() {// expected-note {{function declared non-throwing here}}24   throw 1; // expected-warning {{has a non-throwing exception specification but}}25  }26};27 28struct M_ShouldNotDiag {29  B_ShouldDiag b;30  ~M_ShouldNotDiag() noexcept(false);31};32 33M_ShouldNotDiag::~M_ShouldNotDiag() noexcept(false) {34  throw 1;35}36 37struct N_ShouldDiag {38  B_ShouldDiag b;39  ~N_ShouldDiag(); //implicitly noexcept(true)40};41 42N_ShouldDiag::~N_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}43  throw 1; // expected-warning {{has a non-throwing exception specification but}}44}45struct X_ShouldDiag {46  B_ShouldDiag b;47  ~X_ShouldDiag() noexcept { // expected-note  {{destructor has a non-throwing exception}}48    throw 1; // expected-warning {{has a non-throwing exception specification but}}49  }50};51struct Y_ShouldDiag : A_ShouldDiag {52  ~Y_ShouldDiag() noexcept(true) { // expected-note  {{destructor has a non-throwing exception specification}}53    throw 1; // expected-warning {{has a non-throwing exception specification but}}54  }55};56struct C_ShouldNotDiag {57  int i;58  ~C_ShouldNotDiag() noexcept(false) {}59};60struct D_ShouldNotDiag {61  C_ShouldNotDiag c;62  ~D_ShouldNotDiag() { //implicitly noexcept(false)63    throw 1;64  }65};66struct E_ShouldNotDiag {67  C_ShouldNotDiag c;68  ~E_ShouldNotDiag(); //implicitly noexcept(false)69};70E_ShouldNotDiag::~E_ShouldNotDiag() //implicitly noexcept(false)71{72  throw 1;73}74 75template <typename T>76class A1_ShouldDiag {77  T b;78 79public:80  ~A1_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}81    throw 1; // expected-warning {{has a non-throwing exception specification but}}82  }83};84template <typename T>85struct B1_ShouldDiag {86  T i;87  ~B1_ShouldDiag() noexcept(true) {}88};89template <typename T>90struct R1_ShouldDiag : A1_ShouldDiag<T> //expected-note {{in instantiation of member function}}91{92  B1_ShouldDiag<T> b;93  ~R1_ShouldDiag() { // expected-note  {{destructor has a implicit non-throwing exception specification}}94    throw 1; // expected-warning {{has a non-throwing exception specification but}}95  }96};97template <typename T>98struct S1_ShouldDiag : A1_ShouldDiag<T> {99  B1_ShouldDiag<T> b;100  ~S1_ShouldDiag() noexcept { // expected-note  {{destructor has a non-throwing exception specification}}101    throw 1; // expected-warning {{has a non-throwing exception specification but}}102  }103};104void operator delete(void *ptr) noexcept { // expected-note  {{deallocator has a non-throwing exception specification}}105  throw 1; // expected-warning {{has a non-throwing exception specification but}}106}107struct except_fun {108  static const bool i = false;109};110struct noexcept_fun {111  static const bool i = true;112};113template <typename T>114struct dependent_warn {115  ~dependent_warn() noexcept(T::i) {116    throw 1;117  }118};119template <typename T>120struct dependent_warn_noexcept {121  ~dependent_warn_noexcept() noexcept(T::i) { // expected-note  {{destructor has a non-throwing exception specification}}122    throw 1; // expected-warning {{has a non-throwing exception specification but}}123  }124};125template <typename T>126struct dependent_warn_both {127  ~dependent_warn_both() noexcept(T::i) { // expected-note  {{destructor has a non-throwing exception specification}}128    throw 1; // expected-warning {{has a non-throwing exception specification but}}129  }130};131void foo() noexcept { //expected-note {{function declared non-throwing here}}132  throw 1; // expected-warning {{has a non-throwing exception specification but}}133}134struct Throws {135  ~Throws() noexcept(false);136};137 138struct ShouldDiagnose {139  Throws T;140  ~ShouldDiagnose() noexcept { //expected-note {{destructor has a non-throwing exception specification}}141    throw; // expected-warning {{has a non-throwing exception specification but}}142  }143};144struct ShouldNotDiagnose {145  Throws T;146  ~ShouldNotDiagnose() {147    throw;148  }149};150 151void bar_ShouldNotDiag() noexcept {152  try {153    throw 1;154  } catch (...) {155  }156}157void f_ShouldNotDiag() noexcept {158  try {159    throw 12;160  } catch (int) {161  }162}163void g_ShouldNotDiag() noexcept {164  try {165    throw 12;166  } catch (...) {167  }168}169 170void h_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}171  try {172    throw 12; // expected-warning {{has a non-throwing exception specification but}}173  } catch (const char *) {174  }175}176 177void i_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}178  try {179    throw 12;180  } catch (int) {181    throw; // expected-warning {{has a non-throwing exception specification but}}182  }183}184void j_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}185  try {186    throw 12;187  } catch (int) {188    throw "haha"; // expected-warning {{has a non-throwing exception specification but}}189  }190}191 192void k_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}193  try {194    throw 12;195  } catch (...) {196    throw; // expected-warning {{has a non-throwing exception specification but}}197  }198}199 200void loo_ShouldDiag(int i) noexcept { //expected-note {{function declared non-throwing here}}201  if (i)202    try {203      throw 12;204    } catch (int) {205      throw "haha"; //expected-warning {{has a non-throwing exception specification but}}206    }207  i = 10;208}209 210void loo1_ShouldNotDiag() noexcept {211  if (0)212    throw 12;213}214 215void loo2_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}216  if (1)217    throw 12; // expected-warning {{has a non-throwing exception specification but}}218}219struct S {};220 221void l_ShouldDiag() noexcept { //expected-note {{function declared non-throwing here}}222  try {223    throw S{}; //expected-warning {{has a non-throwing exception specification but}}224  } catch (S *s) {225  }226}227 228void m_ShouldNotDiag() noexcept {229  try {230    const S &s = S{};231    throw s;232  } catch (S s) {233  }234}235void n_ShouldNotDiag() noexcept {236  try {237    S s = S{};238    throw s;239  } catch (const S &s) {240  }241}242// As seen in p34973, this should not throw the warning.  If there is an active243// exception, catch(...) catches everything. 244void o_ShouldNotDiag() noexcept {245  try {246    throw;247  } catch (...) {248  }249}250 251void p_ShouldNotDiag() noexcept {252  // Don't warn here: it's possible that the user arranges to only call this253  // when the active exception is of type 'int'.254  try {255    throw;256  } catch (int){257  }258}259 260void q_ShouldNotDiag() noexcept {261  try {262    throw;263  } catch (int){264  } catch (...){265  }266}267 268#define NOEXCEPT noexcept269void with_macro() NOEXCEPT { //expected-note {{function declared non-throwing here}}270  throw 1; // expected-warning {{has a non-throwing exception specification but}}271}272 273void with_try_block() try {274  throw 2;275} catch (...) {276}277 278void with_try_block1() noexcept try { //expected-note {{function declared non-throwing here}}279  throw 2; // expected-warning {{has a non-throwing exception specification but}}280} catch (char *) {281}282 283namespace derived {284struct B {};285struct D: B {};286void goodPlain() noexcept {287  try {288    throw D();289  } catch (B) {}290}291void goodReference() noexcept {292  try {293    throw D();294  } catch (B &) {}295}296void goodPointer() noexcept {297  D d;298  try {299    throw &d;300  } catch (B *) {}301}302void badPlain() noexcept { //expected-note {{function declared non-throwing here}}303  try {304    throw B(); // expected-warning {{'badPlain' has a non-throwing exception specification but can still throw}}305  } catch (D) {}306}307void badReference() noexcept { //expected-note {{function declared non-throwing here}}308  try {309    throw B(); // expected-warning {{'badReference' has a non-throwing exception specification but can still throw}}310  } catch (D &) {}311}312void badPointer() noexcept { //expected-note {{function declared non-throwing here}}313  B b;314  try {315    throw &b; // expected-warning {{'badPointer' has a non-throwing exception specification but can still throw}}316  } catch (D *) {}317}318}319 320int main() {321  R1_ShouldDiag<int> o; //expected-note {{in instantiation of member function}}322  S1_ShouldDiag<int> b; //expected-note {{in instantiation of member function}}323  dependent_warn<except_fun> f;324  dependent_warn_noexcept<noexcept_fun> f1; //expected-note {{in instantiation of member function}}325  dependent_warn_both<except_fun> f2;326  dependent_warn_both<noexcept_fun> f3; //expected-note {{in instantiation of member function}}327  ShouldDiagnose obj;328  ShouldNotDiagnose obj1;329}330 331namespace ExceptionInNamespace {332  namespace N {333    struct E {};334  }335  void run() throw() {336    try {337      throw N::E();338    } catch (const N::E &e) {339    }340  }341}342 343namespace HandlerSpecialCases {344  struct A {};345  using CA = const A;346 347  struct B : A {};348  using CB = const B;349 350  struct AmbigBase {};351  struct AmbigMiddle : AmbigBase {};352  struct AmbigDerived : AmbigBase, AmbigMiddle {}; // expected-warning {{inaccessible}}353 354  struct PrivateBase {};355  struct PrivateDerived : private PrivateBase { friend void bad3() throw(); };356 357  void good() throw() {358    try { throw CA(); } catch (volatile A&) {}359    try { throw B(); } catch (A&) {}360    try { throw B(); } catch (const volatile A&) {}361    try { throw CB(); } catch (A&) {}362    try { throw (int*)0; } catch (void* const volatile) {}363    try { throw (int*)0; } catch (void* const &) {}364    try { throw (B*)0; } catch (A*) {}365    try { throw (B*)0; } catch (A* const &) {}366    try { throw (void(*)() noexcept)0; } catch (void (*)()) {}367    try { throw (void(*)() noexcept)0; } catch (void (*const &)()) {}368    try { throw (int**)0; } catch (const int * const*) {}369    try { throw (int**)0; } catch (const int * const* const&) {}370    try { throw nullptr; } catch (int*) {}371    try { throw nullptr; } catch (int* const&) {}372  }373 374  void bad1() throw() { // expected-note {{here}}375    try { throw A(); } catch (const B&) {} // expected-warning {{still throw}}376  }377  void bad2() throw() { // expected-note {{here}}378    try { throw AmbigDerived(); } catch (const AmbigBase&) {} // expected-warning {{still throw}}379  }380  void bad3() throw() { // expected-note {{here}}381    try { throw PrivateDerived(); } catch (const PrivateBase&) {} // expected-warning {{still throw}}382  }383  void bad4() throw() { // expected-note {{here}}384    try { throw (int*)0; } catch (void* &) {} // expected-warning {{still throw}}385  }386  void bad5() throw() { // expected-note {{here}}387    try { throw (int*)0; } catch (void* const volatile &) {} // expected-warning {{still throw}}388  }389  void bad6() throw() { // expected-note {{here}}390    try { throw (int* volatile)0; } catch (void* const volatile &) {} // expected-warning {{still throw}}391  }392  void bad7() throw() { // expected-note {{here}}393    try { throw (AmbigDerived*)0; } catch (AmbigBase*) {} // expected-warning {{still throw}}394  }395  void bad8() throw() { // expected-note {{here}}396    try { throw (PrivateDerived*)0; } catch (PrivateBase*) {} // expected-warning {{still throw}}397  }398  void bad9() throw() { // expected-note {{here}}399    try { throw (B*)0; } catch (A* &) {} // expected-warning {{still throw}}400  }401  void bad10() throw() { // expected-note {{here}}402    try { throw (void(*)())0; } catch (void (*)() noexcept) {} // expected-warning {{still throw}}403  }404  void bad11() throw() { // expected-note {{here}}405    try { throw (int**)0; } catch (const int **) {} // expected-warning {{still throw}}406  }407  void bad12() throw() { // expected-note {{here}}408    try { throw nullptr; } catch (int) {} // expected-warning {{still throw}}409  }410}411 412namespace NestedTry {413  void f() noexcept {414    try {415      try {416        throw 0;417      } catch (float) {}418    } catch (int) {}419  }420 421  struct A { [[noreturn]] ~A(); };422 423  void g() noexcept { // expected-note {{here}}424    try {425      try {426        throw 0; // expected-warning {{still throw}}427      } catch (float) {}428    } catch (const char*) {}429  }430 431  void h() noexcept { // expected-note {{here}}432    try {433      try {434        throw 0;435      } catch (float) {}436    } catch (int) {437      throw; // expected-warning {{still throw}}438    }439  }440 441  // FIXME: Ideally, this should still warn; we can track which types are442  // potentially thrown by the rethrow.443  void i() noexcept {444    try {445      try {446        throw 0;447      } catch (int) {448        throw;449      }450    } catch (float) {}451  }452 453  // FIXME: Ideally, this should not warn: the second catch block is454  // unreachable.455  void j() noexcept { // expected-note {{here}}456    try {457      try {458        throw 0;459      } catch (int) {}460    } catch (float) {461      throw; // expected-warning {{still throw}}462    }463  }464}465