// 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 a pointer value; should throw a non-pointer value and 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
}
