// RUN: %check_clang_tidy %s misc-throw-by-value-catch-by-reference %t -- -- -std=c++11 -fcxx-exceptions


class logic_error {
public:
  logic_error(const char *message) {}
};

typedef logic_error *logic_ptr;
typedef logic_ptr logic_double_typedef;

int lastException;

template <class T> struct remove_reference { typedef T type; };
template <class T> struct remove_reference<T &> { typedef T type; };
template <class T> struct remove_reference<T &&> { typedef T type; };

template <typename T> typename remove_reference<T>::type &&move(T &&arg) {
  return static_cast<typename remove_reference<T>::type &&>(arg);
}

logic_error CreateException() { return logic_error("created"); }

void testThrowFunc() {
  throw new logic_error("by pointer");
  // 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]
  logic_ptr tmp = new logic_error("by pointer");
  throw tmp;
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
  // 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]
  throw logic_error("by value");
  auto *literal = "test";
  throw logic_error(literal);
  throw "test string literal";
  throw L"throw wide string literal";
  const char *characters = 0;
  throw characters;
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
  // 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]
  logic_error lvalue("lvalue");
  throw lvalue;
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]

  throw move(lvalue);
  int &ex = lastException;
  throw ex;
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
  throw CreateException();
}

void throwReferenceFunc(logic_error &ref) { throw ref; }

void catchByPointer() {
  try {
    testThrowFunc();
  } catch (logic_error *e) {
    // 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]
  }
}

void catchByValue() {
  try {
    testThrowFunc();
  } catch (logic_error e) {
    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: catch handler catches by value; should catch by reference instead [misc-throw-by-value-catch-by-reference]
  }
}

void catchByReference() {
  try {
    testThrowFunc();
  } catch (logic_error &e) {
  }
}

void catchByConstReference() {
  try {
    testThrowFunc();
  } catch (const logic_error &e) {
  }
}

void catchTypedef() {
  try {
    testThrowFunc();
  } catch (logic_ptr) {
    // 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]
  }
}

void catchAll() {
  try {
    testThrowFunc();
  } catch (...) {
  }
}

void catchLiteral() {
  try {
    testThrowFunc();
  } catch (const char *) {
  } catch (const wchar_t *) {
    // disabled for now until it is clear
    // how to enable them in the test
    //} catch (const char16_t*) {
    //} catch (const char32_t*) {
  }
}

// catching fundamentals should not warn
void catchFundamental() {
  try {
    testThrowFunc();
  } catch (int) {
  } catch (double) {
  } catch (unsigned long) {
  }
}

struct TrivialType {
  double x;
  double y;
};

void catchTrivial() {
  try {
    testThrowFunc();
  } catch (TrivialType) {
  }
}

typedef logic_error &fine;
void additionalTests() {
  try {
  } catch (int i) {  // ok
    throw i;         // ok
  } catch (fine e) { // ok
    throw e;         // ok
  } catch (logic_error *e) {
    // 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]
    throw e;      // ok, despite throwing a pointer
  } catch (...) { // ok
    throw;        // ok
  }
}

struct S {};

S &returnByReference();
S returnByValue();

void f() {
  throw returnByReference(); // Should diagnose
  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: throw expression should throw anonymous temporary values instead [misc-throw-by-value-catch-by-reference]
  throw returnByValue(); // Should not diagnose
}
