Initial check in

Bug: 137197907
diff --git a/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp
new file mode 100644
index 0000000..120b07e
--- /dev/null
+++ b/src/llvm-project/clang-tools-extra/test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp
@@ -0,0 +1,156 @@
+// 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
+}