brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.6 KiB · 269ef90 Raw
157 lines · cpp
1// RUN: %check_clang_tidy %s misc-throw-by-value-catch-by-reference %t -- -- -fcxx-exceptions2 3 4class logic_error {5public:6  logic_error(const char *message) {}7};8 9typedef logic_error *logic_ptr;10typedef logic_ptr logic_double_typedef;11 12int lastException;13 14template <class T> struct remove_reference { typedef T type; };15template <class T> struct remove_reference<T &> { typedef T type; };16template <class T> struct remove_reference<T &&> { typedef T type; };17 18template <typename T> typename remove_reference<T>::type &&move(T &&arg) {19  return static_cast<typename remove_reference<T>::type &&>(arg);20}21 22logic_error CreateException() { return logic_error("created"); }23 24void testThrowFunc() {25  throw new logic_error("by pointer");26  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression throws a pointer; it should throw a non-pointer value instead [misc-throw-by-value-catch-by-reference]27  logic_ptr tmp = new logic_error("by pointer");28  throw tmp;29  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]30  // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: throw expression throws a pointer; it should throw a non-pointer value instead [misc-throw-by-value-catch-by-reference]31  throw logic_error("by value");32  auto *literal = "test";33  throw logic_error(literal);34  throw "test string literal";35  throw L"throw wide string literal";36  const char *characters = 0;37  throw characters;38  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]39  // CHECK-MESSAGES: :[[@LINE-2]]:9: warning: throw expression throws a pointer; it should throw a non-pointer value instead [misc-throw-by-value-catch-by-reference]40  logic_error lvalue("lvalue");41  throw lvalue;42  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]43 44  throw move(lvalue);45  int &ex = lastException;46  throw ex;47  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]48  throw CreateException();49}50 51void throwReferenceFunc(logic_error &ref) { throw ref; }52 53void catchByPointer() {54  try {55    testThrowFunc();56  } catch (logic_error *e) {57    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [misc-throw-by-value-catch-by-reference]58  }59}60 61void catchByValue() {62  try {63    testThrowFunc();64  } catch (logic_error e) {65    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches by value; should catch by reference instead [misc-throw-by-value-catch-by-reference]66  }67}68 69void catchByReference() {70  try {71    testThrowFunc();72  } catch (logic_error &e) {73  }74}75 76void catchByConstReference() {77  try {78    testThrowFunc();79  } catch (const logic_error &e) {80  }81}82 83void catchTypedef() {84  try {85    testThrowFunc();86  } catch (logic_ptr) {87    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [misc-throw-by-value-catch-by-reference]88  }89}90 91void catchAll() {92  try {93    testThrowFunc();94  } catch (...) {95  }96}97 98void catchLiteral() {99  try {100    testThrowFunc();101  } catch (const char *) {102  } catch (const wchar_t *) {103    // disabled for now until it is clear104    // how to enable them in the test105    //} catch (const char16_t*) {106    //} catch (const char32_t*) {107  }108}109 110// catching fundamentals should not warn111void catchFundamental() {112  try {113    testThrowFunc();114  } catch (int) {115  } catch (double) {116  } catch (unsigned long) {117  }118}119 120struct TrivialType {121  double x;122  double y;123};124 125void catchTrivial() {126  try {127    testThrowFunc();128  } catch (TrivialType) {129  }130}131 132typedef logic_error &fine;133void additionalTests() {134  try {135  } catch (int i) {  // ok136    throw i;         // ok137  } catch (fine e) { // ok138    throw e;         // ok139  } catch (logic_error *e) {140    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches a pointer value; should throw a non-pointer value and catch by reference instead [misc-throw-by-value-catch-by-reference]141    throw e;      // ok, despite throwing a pointer142  } catch (...) { // ok143    throw;        // ok144  }145}146 147struct S {};148 149S &returnByReference();150S returnByValue();151 152void f() {153  throw returnByReference(); // Should diagnose154  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]155  throw returnByValue(); // Should not diagnose156}157