[clang-tools-extra] r374540 - [ClangTidy] Separate tests for infrastructure and checkers

Dmitri Gribenko via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 11 05:05:46 PDT 2019


Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-parent-virtual-call.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-parent-virtual-call.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-parent-virtual-call.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-parent-virtual-call.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,179 @@
+// RUN: %check_clang_tidy %s bugprone-parent-virtual-call %t
+
+extern int foo();
+
+class A {
+public:
+  A() = default;
+  virtual ~A() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class B : public A {
+public:
+  B() = default;
+
+  // Nothing to fix: calls to direct parent.
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+
+class C : public B {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' refers to a member overridden in subclass; did you mean 'B'? [bugprone-parent-virtual-call]
+  // CHECK-FIXES:  int virt_1() override { return B::virt_1() + B::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+  // CHECK-FIXES:  int virt_2() override { return B::virt_1() + B::virt_1(); }
+
+  // Test that non-virtual and static methods are not affected by this cherker.
+  int method_c() { return A::stat() + A::non_virt(); }
+};
+
+// Check aliased type names
+using A1 = A;
+typedef A A2;
+#define A3 A
+
+class C2 : public B {
+public:
+  int virt_1() override { return A1::virt_1() + A2::virt_1() + A3::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A1::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-2]]:49: warning: qualified name 'A2::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-3]]:64: warning: qualified name 'A3::virt_1' {{.*}}; did you mean 'B'? {{.*}}
+  // CHECK-FIXES:  int virt_1() override { return B::virt_1() + B::virt_1() + B::virt_1(); }
+};
+
+// Test that the check affects grand-grand..-parent calls too.
+class D : public C {
+public:
+  int virt_1() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: qualified name 'B::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+  // CHECK-FIXES:  int virt_1() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+  int virt_2() override { return A::virt_1() + B::virt_1() + D::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: qualified name 'B::virt_1' {{.*}}; did you mean 'C'? {{.*}}
+  // CHECK-FIXES:  int virt_2() override { return C::virt_1() + C::virt_1() + D::virt_1(); }
+};
+
+// Test classes in namespaces.
+namespace {
+class BN : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace
+
+namespace N1 {
+class A {
+public:
+  A() = default;
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+};
+} // namespace N1
+
+namespace N2 {
+class BN : public N1::A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+  int virt_2() override { return A::virt_2() + 4; }
+};
+} // namespace N2
+
+class CN : public BN {
+public:
+  int virt_1() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BN'? {{.*}}
+  // CHECK-FIXES:  int virt_1() override { return BN::virt_1() + BN::virt_1(); }
+  int virt_2() override { return A::virt_1() + BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BN'? {{.*}}
+  // CHECK-FIXES:  int virt_2() override { return BN::virt_1() + BN::virt_1(); }
+};
+
+class CNN : public N2::BN {
+public:
+  int virt_1() override { return N1::A::virt_1() + N2::BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'N1::A::virt_1' {{.*}}; did you mean 'N2::BN'? {{.*}}
+  // CHECK-FIXES:  int virt_1() override { return N2::BN::virt_1() + N2::BN::virt_1(); }
+  int virt_2() override { return N1::A::virt_1() + N2::BN::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'N1::A::virt_1' {{.*}}; did you mean 'N2::BN'? {{.*}}
+  // CHECK-FIXES:  int virt_2() override { return N2::BN::virt_1() + N2::BN::virt_1(); }
+};
+
+// Test multiple inheritance fixes
+class AA {
+public:
+  AA() = default;
+  virtual ~AA() = default;
+
+  virtual int virt_1() { return foo() + 1; }
+  virtual int virt_2() { return foo() + 2; }
+
+  int non_virt() { return foo() + 3; }
+  static int stat() { return foo() + 4; }
+};
+
+class BB_1 : virtual public AA {
+public:
+  BB_1() = default;
+
+  // Nothing to fix: calls to parent.
+  int virt_1() override { return AA::virt_1() + 3; }
+  int virt_2() override { return AA::virt_2() + 4; }
+};
+
+class BB_2 : virtual public AA {
+public:
+  BB_2() = default;
+  int virt_1() override { return AA::virt_1() + 3; }
+};
+
+class CC : public BB_1, public BB_2 {
+public:
+  int virt_1() override { return AA::virt_1() + 3; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'AA::virt_1' refers to a member overridden in subclasses; did you mean 'BB_1' or 'BB_2'? {{.*}}
+  // No fix available due to multiple choice of parent class.
+};
+
+// Test that virtual method is not diagnosed as not overridden in parent.
+class BI : public A {
+public:
+  BI() = default;
+};
+
+class CI : BI {
+  int virt_1() override { return A::virt_1(); }
+};
+
+// Test templated classes.
+template <class F> class BF : public A {
+public:
+  int virt_1() override { return A::virt_1() + 3; }
+};
+
+// Test templated parent class.
+class CF : public BF<int> {
+public:
+  int virt_1() override { return A::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BF'? {{.*}}
+};
+
+// Test both templated class and its parent class.
+template <class F> class DF : public BF<F> {
+public:
+  DF() = default;
+  int virt_1() override { return A::virt_1(); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: qualified name 'A::virt_1' {{.*}}; did you mean 'BF'? {{.*}}
+};
+
+// Just to instantiate DF<F>.
+int bar() { return (new DF<int>())->virt_1(); }

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-posix-return.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-posix-return.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-posix-return.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-posix-return.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,207 @@
+// RUN: %check_clang_tidy %s bugprone-posix-return %t
+
+#define NULL nullptr
+#define ZERO 0
+#define NEGATIVE_ONE -1
+
+typedef int pid_t;
+typedef long off_t;
+typedef decltype(sizeof(int)) size_t;
+typedef struct __posix_spawn_file_actions* posix_spawn_file_actions_t;
+typedef struct __posix_spawnattr* posix_spawnattr_t;
+# define __CPU_SETSIZE 1024
+# define __NCPUBITS (8 * sizeof (__cpu_mask))
+typedef unsigned long int __cpu_mask;
+typedef struct
+{
+  __cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
+} cpu_set_t;
+typedef struct _opaque_pthread_t *__darwin_pthread_t;
+typedef __darwin_pthread_t pthread_t;
+typedef struct pthread_attr_t_ *pthread_attr_t;
+
+extern "C" int posix_fadvise(int fd, off_t offset, off_t len, int advice);
+extern "C" int posix_fallocate(int fd, off_t offset, off_t len);
+extern "C" int posix_madvise(void *addr, size_t len, int advice);
+extern "C" int posix_memalign(void **memptr, size_t alignment, size_t size);
+extern "C" int posix_openpt(int flags);
+extern "C" int posix_spawn(pid_t *pid, const char *path,
+                const posix_spawn_file_actions_t *file_actions,
+                const posix_spawnattr_t *attrp,
+                char *const argv[], char *const envp[]);
+extern "C" int posix_spawnp(pid_t *pid, const char *file,
+                 const posix_spawn_file_actions_t *file_actions,
+                 const posix_spawnattr_t *attrp,
+                 char *const argv[], char *const envp[]);
+extern "C" int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);
+extern "C" int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);
+extern "C" int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);
+extern "C" int pthread_attr_init(pthread_attr_t *attr);
+extern "C" int pthread_yield(void);
+
+
+void warningLessThanZero() {
+  if (posix_fadvise(0, 0, 0, 0) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: the comparison always evaluates to false because posix_fadvise always returns non-negative values
+  // CHECK-FIXES: posix_fadvise(0, 0, 0, 0) > 0
+  if (posix_fallocate(0, 0, 0) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning:
+  // CHECK-FIXES: posix_fallocate(0, 0, 0) > 0
+  if (posix_madvise(NULL, 0, 0) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  // CHECK-FIXES: posix_madvise(NULL, 0, 0) > 0
+  if (posix_memalign(NULL, 0, 0) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning:
+  // CHECK-FIXES: posix_memalign(NULL, 0, 0) > 0
+  if (posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:59: warning:
+  // CHECK-FIXES: posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0
+  if (posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:60: warning:
+  // CHECK-FIXES: posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) > 0
+  if (pthread_create(NULL, NULL, NULL, NULL) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: the comparison always evaluates to false because pthread_create always returns non-negative values
+  // CHECK-FIXES: pthread_create(NULL, NULL, NULL, NULL) > 0
+  if (pthread_attr_setaffinity_np(NULL, 0, NULL) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:50: warning:
+  // CHECK-FIXES: pthread_attr_setaffinity_np(NULL, 0, NULL) > 0
+  if (pthread_attr_setschedpolicy(NULL, 0) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning:
+  // CHECK-FIXES: pthread_attr_setschedpolicy(NULL, 0) > 0)
+  if (pthread_attr_init(NULL) < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning:
+  // CHECK-FIXES: pthread_attr_init(NULL) > 0
+  if (pthread_yield() < 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
+  // CHECK-FIXES: pthread_yield() > 0
+
+}
+
+void warningAlwaysTrue() {
+  if (posix_fadvise(0, 0, 0, 0) >= 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: the comparison always evaluates to true because posix_fadvise always returns non-negative values
+  if (pthread_create(NULL, NULL, NULL, NULL) >= 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: the comparison always evaluates to true because pthread_create always returns non-negative values
+  if (pthread_attr_setaffinity_np(NULL, 0, NULL) >= 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:50: warning:
+  if (pthread_attr_setschedpolicy(NULL, 0) >= 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning:
+  if (pthread_attr_init(NULL) >= 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning:
+  if (pthread_yield() >= 0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning:
+
+}
+
+void warningEqualsNegative() {
+  if (posix_fadvise(0, 0, 0, 0) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: posix_fadvise
+  if (posix_fadvise(0, 0, 0, 0) != -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fadvise(0, 0, 0, 0) <= -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fadvise(0, 0, 0, 0) < -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fallocate(0, 0, 0) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning:
+  if (posix_madvise(NULL, 0, 0) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_memalign(NULL, 0, 0) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning:
+  if (posix_spawn(NULL, NULL, NULL, NULL, {NULL}, {NULL}) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:59: warning:
+  if (posix_spawnp(NULL, NULL, NULL, NULL, {NULL}, {NULL}) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:60: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) == -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning: pthread_create
+  if (pthread_create(NULL, NULL, NULL, NULL) != -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) <= -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) < -1) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+
+}
+
+void WarningWithMacro() {
+  if (posix_fadvise(0, 0, 0, 0) < ZERO) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  // CHECK-FIXES: posix_fadvise(0, 0, 0, 0) > ZERO
+  if (posix_fadvise(0, 0, 0, 0) >= ZERO) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fadvise(0, 0, 0, 0) == NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fadvise(0, 0, 0, 0) != NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fadvise(0, 0, 0, 0) <= NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (posix_fadvise(0, 0, 0, 0) < NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) < ZERO) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  // CHECK-FIXES: pthread_create(NULL, NULL, NULL, NULL) > ZERO
+  if (pthread_create(NULL, NULL, NULL, NULL) >= ZERO) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) == NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) != NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) <= NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+  if (pthread_create(NULL, NULL, NULL, NULL) < NEGATIVE_ONE) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:46: warning:
+
+}
+
+void noWarning() {
+  if (posix_openpt(0) < 0) {}
+  if (posix_openpt(0) <= 0) {}
+  if (posix_openpt(0) == -1) {}
+  if (posix_openpt(0) != -1) {}
+  if (posix_openpt(0) <= -1) {}
+  if (posix_openpt(0) < -1) {}
+  if (posix_fadvise(0, 0, 0, 0) <= 0) {}
+  if (posix_fadvise(0, 0, 0, 0) == 1) {}
+}
+
+namespace i {
+int posix_fadvise(int fd, off_t offset, off_t len, int advice);
+int pthread_yield(void);
+
+void noWarning() {
+  if (posix_fadvise(0, 0, 0, 0) < 0) {}
+  if (posix_fadvise(0, 0, 0, 0) >= 0) {}
+  if (posix_fadvise(0, 0, 0, 0) == -1) {}
+  if (posix_fadvise(0, 0, 0, 0) != -1) {}
+  if (posix_fadvise(0, 0, 0, 0) <= -1) {}
+  if (posix_fadvise(0, 0, 0, 0) < -1) {}
+    if (pthread_yield() < 0) {}
+    if (pthread_yield() >= 0) {}
+    if (pthread_yield() == -1) {}
+    if (pthread_yield() != -1) {}
+    if (pthread_yield() <= -1) {}
+    if (pthread_yield() < -1) {}
+}
+
+} // namespace i
+
+class G {
+ public:
+  int posix_fadvise(int fd, off_t offset, off_t len, int advice);
+  int pthread_yield(void);
+
+  void noWarning() {
+    if (posix_fadvise(0, 0, 0, 0) < 0) {}
+    if (posix_fadvise(0, 0, 0, 0) >= 0) {}
+    if (posix_fadvise(0, 0, 0, 0) == -1) {}
+    if (posix_fadvise(0, 0, 0, 0) != -1) {}
+    if (posix_fadvise(0, 0, 0, 0) <= -1) {}
+    if (posix_fadvise(0, 0, 0, 0) < -1) {}
+    if (pthread_yield() < 0) {}
+    if (pthread_yield() >= 0) {}
+    if (pthread_yield() == -1) {}
+    if (pthread_yield() != -1) {}
+    if (pthread_yield() <= -1) {}
+    if (pthread_yield() < -1) {}
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-container.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-container.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-container.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-container.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,103 @@
+// RUN: %check_clang_tidy %s bugprone-sizeof-container %t -- -- -target x86_64-unknown-unknown
+
+namespace std {
+
+typedef unsigned int size_t;
+
+template <typename T>
+struct basic_string {
+  size_t size() const;
+};
+
+template <typename T>
+basic_string<T> operator+(const basic_string<T> &, const T *);
+
+typedef basic_string<char> string;
+
+template <typename T>
+struct vector {
+  size_t size() const;
+};
+
+// std::bitset<> is not a container. sizeof() is reasonable for it.
+template <size_t N>
+struct bitset {
+  size_t size() const;
+};
+
+// std::array<> is, well, an array. sizeof() is reasonable for it.
+template <typename T, size_t N>
+struct array {
+  size_t size() const;
+};
+
+class fake_container1 {
+  size_t size() const; // non-public
+};
+
+struct fake_container2 {
+  size_t size(); // non-const
+};
+
+}
+
+using std::size_t;
+
+#define ARRAYSIZE(a) \
+  ((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))))
+
+#define ARRAYSIZE2(a) \
+  (((sizeof(a)) / (sizeof(*(a)))) / static_cast<size_t>(!((sizeof(a)) % (sizeof(*(a))))))
+
+struct string {
+  std::size_t size() const;
+};
+
+template<typename T>
+void g(T t) {
+  (void)sizeof(t);
+}
+
+void f() {
+  string s1;
+  std::string s2;
+  std::vector<int> v;
+
+  int a = 42 + sizeof(s1);
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: sizeof() doesn't return the size of the container; did you mean .size()? [bugprone-sizeof-container]
+  a = 123 * sizeof(s2);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: sizeof() doesn't return the size
+  a = 45 + sizeof(s2 + "asdf");
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: sizeof() doesn't return the size
+  a = sizeof(v);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: sizeof() doesn't return the size
+  a = sizeof(std::vector<int>{});
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: sizeof() doesn't return the size
+
+  a = sizeof(a);
+  a = sizeof(int);
+  a = sizeof(std::string);
+  a = sizeof(std::vector<int>);
+
+  g(s1);
+  g(s2);
+  g(v);
+
+  std::fake_container1 fake1;
+  std::fake_container2 fake2;
+  std::bitset<7> std_bitset;
+  std::array<int, 3> std_array;
+
+  a = sizeof(fake1);
+  a = sizeof(fake2);
+  a = sizeof(std_bitset);
+  a = sizeof(std_array);
+
+
+  std::string arr[3];
+  a = ARRAYSIZE(arr);
+  a = ARRAYSIZE2(arr);
+  a = sizeof(arr) / sizeof(arr[0]);
+
+  (void)a;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-expression.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-expression.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-expression.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-sizeof-expression.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,297 @@
+// RUN: %check_clang_tidy %s bugprone-sizeof-expression %t -- -config="{CheckOptions: [{key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression, value: 1}]}" --
+
+class C {
+  int size() { return sizeof(this); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: suspicious usage of 'sizeof(this)'
+};
+
+#define LEN 8
+
+int X;
+extern int A[10];
+extern short B[10];
+
+#pragma pack(1)
+struct  S { char a, b, c; };
+
+enum E { E_VALUE = 0 };
+enum class EC { VALUE = 0 };
+
+bool AsBool() { return false; }
+int AsInt() { return 0; }
+E AsEnum() { return E_VALUE; }
+EC AsEnumClass() { return EC::VALUE; }
+S AsStruct() { return {}; }
+
+struct M {
+  int AsInt() { return 0; }
+  E AsEnum() { return E_VALUE; }
+  S AsStruct() { return {}; }
+};
+
+int ReturnOverload(int) { return {}; }
+S ReturnOverload(S) { return {}; }
+
+template <class T>
+T ReturnTemplate(T) { return {}; }
+
+template <class T>
+bool TestTrait1() {
+  return sizeof(ReturnOverload(T{})) == sizeof(A);
+}
+
+template <class T>
+bool TestTrait2() {
+  return sizeof(ReturnTemplate(T{})) == sizeof(A);
+}
+
+template <class T>
+bool TestTrait3() {
+  return sizeof(ReturnOverload(0)) == sizeof(T{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+}
+
+template <class T>
+bool TestTrait4() {
+  return sizeof(ReturnTemplate(0)) == sizeof(T{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+}
+
+bool TestTemplates() {
+  bool b = true;
+  b &= TestTrait1<int>();
+  b &= TestTrait1<S>();
+  b &= TestTrait2<int>();
+  b &= TestTrait2<S>();
+  b &= TestTrait3<int>();
+  b &= TestTrait3<S>();
+  b &= TestTrait4<int>();
+  b &= TestTrait4<S>();
+  return b;
+}
+
+int Test1(const char* ptr) {
+  int sum = 0;
+  sum += sizeof(LEN);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
+  sum += sizeof(LEN + 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(K)'
+  sum += sizeof(sum, LEN);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(..., ...)'
+  sum += sizeof(AsBool());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+  sum += sizeof(AsInt());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+  sum += sizeof(AsEnum());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+  sum += sizeof(AsEnumClass());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+  sum += sizeof(M{}.AsInt());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+  sum += sizeof(M{}.AsEnum());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof()' on an expression that results in an integer
+  sum += sizeof(sizeof(X));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+  sum += sizeof(LEN + sizeof(X));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+  sum += sizeof(LEN + LEN + sizeof(X));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+  sum += sizeof(LEN + (LEN + sizeof(X)));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+  sum += sizeof(LEN + -sizeof(X));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+  sum += sizeof(LEN + - + -sizeof(X));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(sizeof(...))'
+  sum += sizeof(char) / sizeof(char);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+  sum += sizeof(A) / sizeof(S);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+  sum += sizeof(char) / sizeof(int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+  sum += sizeof(char) / sizeof(A);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+  sum += sizeof(B[0]) / sizeof(A);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)/sizeof(...)'; numerator is not a multiple of denominator
+  sum += sizeof(ptr) / sizeof(char);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+  sum += sizeof(ptr) / sizeof(ptr[0]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+  sum += sizeof(ptr) / sizeof(char*);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
+  sum += sizeof(ptr) / sizeof(void*);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
+  sum += sizeof(ptr) / sizeof(const void volatile*);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(P*)/sizeof(Q*)'
+  sum += sizeof(ptr) / sizeof(char);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+  sum += sizeof(ptr) / sizeof(ptr[0]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T*)/sizeof(T)'
+  sum += sizeof(int) * sizeof(char);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+  sum += sizeof(ptr) * sizeof(ptr[0]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+  sum += sizeof(int) * (2 * sizeof(char));
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+  sum += (2 * sizeof(char)) * sizeof(int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious 'sizeof' by 'sizeof' multiplication
+  if (sizeof(A) < 0x100000) sum += 42;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: suspicious comparison of 'sizeof(expr)' to a constant
+  if (sizeof(A) <= 0xFFFFFFFEU) sum += 42;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: suspicious comparison of 'sizeof(expr)' to a constant
+  return sum;
+}
+
+typedef char MyChar;
+typedef const MyChar MyConstChar;
+
+int CE0 = sizeof sizeof(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE1 = sizeof +sizeof(char);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE2 = sizeof sizeof(const char*);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE3 = sizeof sizeof(const volatile char* const*);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+int CE4 = sizeof sizeof(MyConstChar);
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: suspicious usage of 'sizeof(sizeof(...))'
+
+int Test2(MyConstChar* A) {
+  int sum = 0;
+  sum += sizeof(MyConstChar) / sizeof(char);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+  sum += sizeof(MyConstChar) / sizeof(MyChar);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+  sum += sizeof(A[0]) / sizeof(char);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+  return sum;
+}
+
+template <int T>
+int Foo() { int A[T]; return sizeof(T); }
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: suspicious usage of 'sizeof(K)'
+template <typename T>
+int Bar() { T A[5]; return sizeof(A[0]) / sizeof(T); }
+// CHECK-MESSAGES: :[[@LINE-1]]:28: warning: suspicious usage of sizeof pointer 'sizeof(T)/sizeof(T)'
+int Test3() { return Foo<42>() + Bar<char>(); }
+
+static const char* kABC = "abc";
+static const wchar_t* kDEF = L"def";
+int Test4(const char A[10]) {
+  int sum = 0;
+  sum += sizeof(kABC);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)'
+  sum += sizeof(kDEF);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(char*)'
+  return sum;
+}
+
+int Test5() {
+  typedef int Array10[10];
+
+  struct MyStruct {
+    Array10 arr;
+    Array10* ptr;
+  };
+  typedef const MyStruct TMyStruct;
+  typedef const MyStruct *PMyStruct;
+  typedef TMyStruct *PMyStruct2;
+
+  static TMyStruct kGlocalMyStruct = {};
+  static TMyStruct volatile * kGlocalMyStructPtr = &kGlocalMyStruct;
+
+  MyStruct S;
+  PMyStruct PS;
+  PMyStruct2 PS2;
+  Array10 A10;
+
+  int sum = 0;
+  sum += sizeof(&S.arr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(&kGlocalMyStruct.arr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(&kGlocalMyStructPtr->arr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(S.arr + 0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(+ S.arr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof((int*)S.arr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+
+  sum += sizeof(S.ptr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(kGlocalMyStruct.ptr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(kGlocalMyStructPtr->ptr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+
+  sum += sizeof(&kGlocalMyStruct);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(&S);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(MyStruct*);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(PMyStruct);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(PS);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(PS2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+  sum += sizeof(&A10);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(A*)'; pointer to aggregate
+
+  return sum;
+}
+
+int Test6() {
+  int sum = 0;
+
+  struct S A = AsStruct(), B = AsStruct();
+  struct S *P = &A, *Q = &B;
+  sum += sizeof(struct S) == P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(S) != P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += sizeof(S) < P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(S) <= P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(*P) >= P - Q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += Q - P > 3 * sizeof(*P);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += sizeof(S) + (P - Q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += 5 * sizeof(S) - (P - Q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += (P - Q) / sizeof(S);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+  sum += (P - Q) / sizeof(*Q);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: suspicious usage of 'sizeof(...)' in pointer arithmetic
+
+  return sum;
+}
+
+int ValidExpressions() {
+  int A[] = {1, 2, 3, 4};
+  static const char str[] = "hello";
+  static const char* ptr[] { "aaa", "bbb", "ccc" };
+  int sum = 0;
+  if (sizeof(A) < 10)
+    sum += sizeof(A);
+  sum += sizeof(int);
+  sum += sizeof(AsStruct());
+  sum += sizeof(M{}.AsStruct());
+  sum += sizeof(A[sizeof(A) / sizeof(int)]);
+  sum += sizeof(&A[sizeof(A) / sizeof(int)]);
+  sum += sizeof(sizeof(0));  // Special case: sizeof size_t.
+  sum += sizeof(void*);
+  sum += sizeof(void const *);
+  sum += sizeof(void const *) / 4;
+  sum += sizeof(str);
+  sum += sizeof(str) / sizeof(char);
+  sum += sizeof(str) / sizeof(str[0]);
+  sum += sizeof(ptr) / sizeof(ptr[0]);
+  sum += sizeof(ptr) / sizeof(*(ptr));
+  return sum;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-constructor.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-constructor.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-constructor.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,75 @@
+// RUN: %check_clang_tidy %s bugprone-string-constructor %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C> >
+struct basic_string {
+  basic_string();
+  basic_string(const C*, unsigned int size);
+  basic_string(const C *, const A &allocator = A());
+  basic_string(unsigned int size, C c);
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+}
+
+const char* kText = "";
+const char kText2[] = "";
+extern const char kText3[];
+
+void Test() {
+  std::string str('x', 4);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: string constructor parameters are probably swapped; expecting string(count, character) [bugprone-string-constructor]
+  // CHECK-FIXES: std::string str(4, 'x');
+  std::wstring wstr(L'x', 4);
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: string constructor parameters are probably swapped
+  // CHECK-FIXES: std::wstring wstr(4, L'x');
+  std::string s0(0, 'x');
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
+  std::string s1(-4, 'x');
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
+  std::string s2(0x1000000, 'x');
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
+
+  std::string q0("test", 0);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructor creating an empty string
+  std::string q1(kText, -4);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: negative value used as length parameter
+  std::string q2("test", 200);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
+  std::string q3(kText, 200);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
+  std::string q4(kText2, 200);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: length is bigger than string literal size
+  std::string q5(kText3,  0x1000000);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: suspicious large length parameter
+  std::string q6(nullptr);
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: constructing string from nullptr is undefined behaviour
+  std::string q7 = 0;
+  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: constructing string from nullptr is undefined behaviour
+}
+
+std::string StringFromZero() {
+  return 0;
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: constructing string from nullptr is undefined behaviour
+}
+
+void Valid() {
+  std::string empty();
+  std::string str(4, 'x');
+  std::wstring wstr(4, L'x');
+  std::string s1("test", 4);
+  std::string s2("test", 3);
+  std::string s3("test");
+}
+
+namespace instantiation_dependent_exprs {
+template<typename T>
+struct S {
+  bool x;
+  std::string f() { return x ? "a" : "b"; }
+};
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-integer-assignment.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,109 @@
+// RUN: %check_clang_tidy %s bugprone-string-integer-assignment %t
+
+namespace std {
+template<typename T>
+struct basic_string {
+  basic_string& operator=(T);
+  basic_string& operator=(basic_string);
+  basic_string& operator+=(T);
+  basic_string& operator+=(basic_string);
+  const T &operator[](int i) const;
+  T &operator[](int i);
+};
+
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+
+int tolower(int i);
+int toupper(int i);
+}
+
+int tolower(int i);
+int toupper(int i);
+
+typedef int MyArcaneChar;
+
+constexpr char kCharConstant = 'a';
+
+int main() {
+  std::string s;
+  std::wstring ws;
+  int x = 5;
+  const char c = 'c';
+
+  s = 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a character code when assigning {{.*}} [bugprone-string-integer-assignment]
+// CHECK-FIXES: {{^}}  s = '6';{{$}}
+  s = 66;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}}  s = "66";{{$}}
+  s = x;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}}  s = std::to_string(x);{{$}}
+  s = 'c';
+  s = static_cast<char>(6);
+
+// +=
+  ws += 6;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}}  ws += L'6';{{$}}
+  ws += 66;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}}  ws += L"66";{{$}}
+  ws += x;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: an integer is interpreted as a chara
+// CHECK-FIXES: {{^}}  ws += std::to_wstring(x);{{$}}
+  ws += L'c';
+  ws += (wchar_t)6;
+
+  std::basic_string<MyArcaneChar> as;
+  as = 6;
+  as = static_cast<MyArcaneChar>(6);
+  as = 'a';
+
+  s += toupper(x);
+  s += tolower(x);
+  s += (std::tolower(x));
+
+  s += c & s[1];
+  s += c ^ s[1];
+  s += c | s[1];
+
+  s[x] += 1;
+  s += s[x];
+  as += as[x];
+
+  // Likely character expressions.
+  s += x & 0xff;
+  s += 0xff & x;
+  s += x % 26;
+  s += 26 % x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+  // CHECK-FIXES: {{^}}  s += std::to_string(26 % x);{{$}}
+  s += c | 0x80;
+  s += c | 0x8000;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+  // CHECK-FIXES: {{^}}  s += std::to_string(c | 0x8000);{{$}}
+  as += c | 0x8000;
+
+  s += 'a' + (x % 26);
+  s += kCharConstant + (x % 26);
+  s += 'a' + (s[x] & 0xf);
+  s += (x % 10) + 'b';
+
+  s += x > 255 ? c : x;
+  s += x > 255 ? 12 : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: an integer is interpreted as a chara
+  // CHECK-FIXES: {{^}}  s += std::to_string(x > 255 ? 12 : x);{{$}}
+}
+
+namespace instantiation_dependent_exprs {
+template<typename T>
+struct S {
+  static constexpr T t = 0x8000;
+  std::string s;
+  void f(char c) { s += c | static_cast<int>(t); }
+};
+
+template S<int>;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-literal-with-embedded-nul.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-literal-with-embedded-nul.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-literal-with-embedded-nul.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-string-literal-with-embedded-nul.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy %s bugprone-string-literal-with-embedded-nul %t
+
+namespace std {
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T, typename A>
+struct basic_string {
+  typedef basic_string<C, T, A> _Type;
+  basic_string();
+  basic_string(const C *p, const A &a = A());
+
+  _Type& operator+=(const C* s);
+  _Type& operator=(const C* s);
+};
+
+typedef basic_string<char, std::char_traits<char>, std::allocator<char>> string;
+typedef basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t>> wstring;
+}
+
+bool operator==(const std::string&, const char*);
+bool operator==(const char*, const std::string&);
+
+
+const char Valid[] = "This is valid \x12.";
+const char Strange[] = "This is strange \0x12 and must be fixed";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: suspicious embedded NUL character [bugprone-string-literal-with-embedded-nul]
+
+const char textA[] = "\0x01\0x02\0x03\0x04";
+// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: suspicious embedded NUL character
+const wchar_t textW[] = L"\0x01\0x02\0x03\0x04";
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: suspicious embedded NUL character
+
+const char A[] = "\0";
+const char B[] = "\0x";
+const char C[] = "\0x1";
+const char D[] = "\0x11";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: suspicious embedded NUL character
+
+const wchar_t E[] = L"\0";
+const wchar_t F[] = L"\0x";
+const wchar_t G[] = L"\0x1";
+const wchar_t H[] = L"\0x11";
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: suspicious embedded NUL character
+
+const char I[] = "\000\000\000\000";
+const char J[] = "\0\0\0\0\0\0";
+const char K[] = "";
+
+const char L[] = "\0x12" "\0x12" "\0x12" "\0x12";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: suspicious embedded NUL character
+
+void TestA() {
+  std::string str1 = "abc\0def";
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: truncated string literal
+  std::string str2 = "\0";
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: truncated string literal
+  std::string str3("\0");
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: truncated string literal
+  std::string str4{"\x00\x01\x02\x03"};
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: truncated string literal
+
+  std::string str;
+  str += "abc\0def";
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: truncated string literal
+  str = "abc\0def";
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: truncated string literal
+
+  if (str == "abc\0def") return;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: truncated string literal
+  if ("abc\0def" == str) return;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: truncated string literal
+}
+
+void TestW() {
+  std::wstring str1 = L"abc\0def";
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: truncated string literal
+  std::wstring str2 = L"\0";
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: truncated string literal
+  std::wstring str3(L"\0");
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: truncated string literal
+  std::wstring str4{L"\x00\x01\x02\x03"};
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: truncated string literal
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage-strict.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage-strict.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage-strict.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage-strict.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,98 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-enum-usage %t -- -config="{CheckOptions: [{key: bugprone-suspicious-enum-usage.StrictMode, value: 1}]}" --
+
+enum A {
+  A = 1,
+  B = 2,
+  C = 4,
+  D = 8,
+  E = 16,
+  F = 32,
+  G = 63
+};
+
+// CHECK-NOTES: :[[@LINE+2]]:1: warning: enum type seems like a bitmask (contains mostly power-of-2 literals) but a literal is not power-of-2
+// CHECK-NOTES: :76:7: note: used here as a bitmask
+enum X {
+  X = 8,
+  Y = 16,
+  Z = 4,
+  ZZ = 3
+  // CHECK-NOTES: :[[@LINE-1]]:3: warning: enum type seems like a bitmask (contains mostly power-of-2 literals), but this literal is not a power-of-2 [bugprone-suspicious-enum-usage]
+// CHECK-NOTES: :70:13: note: used here as a bitmask
+};
+// CHECK-NOTES: :[[@LINE+2]]:1: warning: enum type seems like a bitmask (contains mostly power-of-2 literals) but some literals are not power-of-2
+// CHECK-NOTES: :73:8: note: used here as a bitmask
+enum PP {
+  P = 2,
+  Q = 3,
+  // CHECK-NOTES: :[[@LINE-1]]:3: warning: enum type seems like a bitmask (contains mostly power-of-2 literals), but this literal is not a power-of-2
+  // CHECK-NOTES: :65:11: note: used here as a bitmask
+  R = 4,
+  S = 8,
+  T = 16,
+  U = 31
+};
+
+enum {
+  H,
+  I,
+  J,
+  K,
+  L
+};
+
+enum Days {
+  Monday,
+  Tuesday,
+  Wednesday,
+  Thursday,
+  Friday,
+  Saturday,
+  Sunday
+};
+
+Days bestDay() {
+  return Friday;
+}
+
+int trigger() {
+  if (bestDay() | A)
+    return 1;
+  // CHECK-NOTES: :[[@LINE-2]]:17: warning: enum values are from different enum types
+  if (I | Y)
+    return 1;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: enum values are from different enum types
+  if (P + Q == R)
+    return 1;
+  else if ((S | R) == T)
+    return 1;
+  else
+    int k = ZZ | Z;
+  unsigned p = R;
+  PP pp = Q;
+  p |= pp;
+  
+  enum X x = Z;
+  p = x | Z;
+  return 0;
+}
+
+int dont_trigger() {
+  int a = 1, b = 5;
+  int c = a + b;
+  int d = c | H, e = b * a;
+  a = B | C;
+  b = X | Z;
+
+  unsigned bitflag;
+  enum A aa = B;
+  bitflag = aa | C;
+
+  if (Tuesday != Monday + 1 ||
+      Friday - Thursday != 1 ||
+      Sunday + Wednesday == (Sunday | Wednesday))
+    return 1;
+  if (H + I + L == 42)
+    return 1;
+  return 42;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-enum-usage.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,96 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-enum-usage %t -- -config="{CheckOptions: [{key: bugprone-suspicious-enum-usage.StrictMode, value: 0}]}" --
+
+enum Empty {
+};
+
+enum A {
+  A = 1,
+  B = 2,
+  C = 4,
+  D = 8,
+  E = 16,
+  F = 32,
+  G = 63
+};
+
+enum X {
+  X = 8,
+  Y = 16,
+  Z = 4
+};
+
+enum {
+  P = 2,
+  Q = 3,
+  R = 4,
+  S = 8,
+  T = 16
+};
+
+enum {
+  H,
+  I,
+  J,
+  K,
+  L
+};
+
+enum Days {
+  Monday,
+  Tuesday,
+  Wednesday,
+  Thursday,
+  Friday,
+  Saturday,
+  Sunday
+};
+
+Days bestDay() {
+  return Friday;
+}
+
+int trigger() {
+  Empty EmptyVal;
+  int emptytest = EmptyVal | B;
+  if (bestDay() | A)
+    return 1;
+  // CHECK-NOTES: :[[@LINE-2]]:17: warning: enum values are from different enum types
+  if (I | Y)
+    return 1;
+  // CHECK-NOTES: :[[@LINE-2]]:9: warning: enum values are from different enum types
+}
+
+int dont_trigger() {
+  unsigned p;
+  p = Q | P;
+
+  if (A + G == E)
+    return 1;
+  else if ((Q | R) == T)
+    return 1;
+  else
+    int k = T | Q;
+
+  Empty EmptyVal;
+  int emptytest = EmptyVal | B;
+
+  int a = 1, b = 5;
+  int c = a + b;
+  int d = c | H, e = b * a;
+  a = B | C;
+  b = X | Z;
+  
+  if (Tuesday != Monday + 1 ||
+      Friday - Thursday != 1 ||
+      Sunday + Wednesday == (Sunday | Wednesday))
+    return 1;
+  if (H + I + L == 42)
+    return 1;
+  return 42;
+}
+
+namespace PR34400 {
+enum { E1 = 0 };
+enum { E2 = -1 };
+enum { l = E1 | E2 };
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-memset-usage.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,77 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-memset-usage %t
+
+void *memset(void *, int, __SIZE_TYPE__);
+
+namespace std {
+  using ::memset;
+}
+
+template <typename T>
+void mtempl(int *ptr) {
+  memset(ptr, '0', sizeof(T));
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(ptr, 0, sizeof(T));
+  memset(ptr, 256, sizeof(T));
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage]
+  memset(0, sizeof(T), 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(0, 0, sizeof(T));
+  memset(0, sizeof(int), 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(0, 0, sizeof(int));
+}
+
+void foo(int xsize, int ysize) {
+  int i[5] = {1, 2, 3, 4, 5};
+  char ca[3] = {'a', 'b', 'c'};
+  int *p = i;
+  int l = 5;
+  char z = '1';
+  char *c = &z;
+  int v = 0;
+
+  memset(p, '0', l);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(p, 0, l);
+
+  memset(p, 0xabcd, l);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage]
+
+  memset(p, sizeof(int), 0);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: memset(p, 0, sizeof(int));
+  std::memset(p, sizeof(int), 0x00);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+// CHECK-FIXES: std::memset(p, 0x00, sizeof(int));
+
+#define M_CHAR_ZERO memset(p, '0', l);
+  M_CHAR_ZERO
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset fill value is char '0', potentially mistaken for int 0 [bugprone-suspicious-memset-usage]
+
+#define M_OUTSIDE_RANGE memset(p, 0xabcd, l);
+  M_OUTSIDE_RANGE
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset fill value is out of unsigned character range, gets truncated [bugprone-suspicious-memset-usage]
+
+#define M_ZERO_LENGTH memset(p, sizeof(int), 0);
+  M_ZERO_LENGTH
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped arguments [bugprone-suspicious-memset-usage]
+
+  memset(p, '2', l);
+  memset(p, 0, l);
+  memset(c, '0', 1);
+  memset(ca, '0', sizeof(ca));
+
+  memset(p, 0x00, l);
+  mtempl<int>(p);
+
+  memset(p, sizeof(int), v + 1);
+  memset(p, 0xcd, 1);
+
+  // Don't warn when the fill char and the length are both known to be
+  // zero.  No bug is possible.
+  memset(p, 0, v);
+
+  // -1 is clearly not a length by virtue of being negative, so no warning
+  // despite v == 0.
+  memset(p, -1, v);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-missing-comma.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-missing-comma.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-missing-comma.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-missing-comma.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,82 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-missing-comma %t
+
+const char* Cartoons[] = {
+  "Bugs Bunny",
+  "Homer Simpson",
+  "Mickey Mouse",
+  "Bart Simpson",
+  "Charlie Brown"  // There is a missing comma here.
+  "Fred Flintstone",
+  "Popeye",
+};
+// CHECK-MESSAGES: :[[@LINE-4]]:3: warning: suspicious string literal, probably missing a comma [bugprone-suspicious-missing-comma]
+
+const wchar_t* Colors[] = {
+  L"Red", L"Yellow", L"Blue", L"Green", L"Purple", L"Rose", L"White", L"Black"
+};
+
+// The following array should not trigger any warnings. There is more than 5
+// elements, but they are all concatenated string literals.
+const char* HttpCommands[] = {
+  "GET / HTTP/1.0\r\n"
+  "\r\n",
+
+  "GET /index.html HTTP/1.0\r\n"
+  "\r\n",
+
+  "GET /favicon.ico HTTP/1.0\r\n"
+  "header: dummy"
+  "\r\n",
+
+  "GET /index.html-en HTTP/1.0\r\n"
+  "\r\n",
+
+  "GET /index.html-fr HTTP/1.0\r\n"
+  "\r\n",
+
+  "GET /index.html-es HTTP/1.0\r\n"
+  "\r\n",
+};
+
+// This array is too small to trigger a warning.
+const char* SmallArray[] = {
+  "a" "b", "c"
+};
+
+// Parentheses should be enough to avoid warnings.
+const char* ParentheseArray[] = {
+  ("a" "b"), "c",
+  ("d"
+   "e"
+   "f"),
+  "g", "h", "i", "j", "k", "l"
+};
+
+// Indentation should be enough to avoid warnings.
+const char* CorrectlyIndentedArray[] = {
+  "This is a long message "
+      "which is spanning over multiple lines."
+      "And this should be fine.",
+  "a", "b", "c", "d", "e", "f",
+  "g", "h", "i", "j", "k", "l"
+};
+
+const char* IncorrectlyIndentedArray[] = {
+  "This is a long message "
+  "which is spanning over multiple lines."
+      "And this should be fine.",
+  "a", "b", "c", "d", "e", "f",
+  "g", "h", "i", "j", "k", "l"
+};
+// CHECK-MESSAGES: :[[@LINE-6]]:3: warning: suspicious string literal, probably missing a comma [bugprone-suspicious-missing-comma]
+
+const char* TooManyConcatenatedTokensArray[] = {
+  "Dummy line",
+  "Dummy line",
+  "a" "b" "c" "d" "e" "f",
+  "g" "h" "i" "j" "k" "l",
+  "Dummy line",
+  "Dummy line",
+  "Dummy line",
+  "Dummy line",
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon-fail.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon-fail.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon-fail.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon-fail.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,28 @@
+// RUN: not clang-tidy %s \
+// RUN:     -checks="-*,bugprone-suspicious-semicolon" -- -DERROR 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-ERROR \
+// RUN:       -implicit-check-not="{{warning|error}}:"
+// RUN: not clang-tidy %s \
+// RUN:     -checks="-*,bugprone-suspicious-semicolon,clang-diagnostic*" \
+// RUN:    -- -DWERROR -Wno-everything -Werror=unused-variable 2>&1 \
+// RUN:   | FileCheck %s -check-prefix=CHECK-WERROR \
+// RUN:       -implicit-check-not="{{warning|error}}:"
+
+// Note: This test verifies that, the checker does not emit any warning for
+//       files that do not compile.
+
+bool g();
+
+void f() {
+  if (g());
+  // CHECK-WERROR: :[[@LINE-1]]:11: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+#if ERROR
+  int a
+  // CHECK-ERROR: :[[@LINE-1]]:8: error: expected ';' at end of declaration [clang-diagnostic-error]
+#elif WERROR
+  int a;
+  // CHECK-WERROR: :[[@LINE-1]]:7: error: unused variable 'a' [clang-diagnostic-unused-variable]
+#else
+#error "One of ERROR or WERROR should be defined.
+#endif
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-semicolon.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,117 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-semicolon %t
+
+int x = 5;
+
+void nop();
+
+void correct1()
+{
+	if(x < 5) nop();
+}
+
+void correct2()
+{
+	if(x == 5)
+		nop();
+}
+
+void correct3()
+{
+	if(x > 5)
+	{
+		nop();
+	}
+}
+
+void fail1()
+{
+  if(x > 5); nop();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+  // CHECK-FIXES: if(x > 5) nop();
+}
+
+void fail2()
+{
+	if(x == 5);
+		nop();
+  // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: potentially unintended semicolon [bugprone-suspicious-semicolon]
+  // CHECK-FIXES: if(x == 5){{$}}
+}
+
+void fail3()
+{
+	if(x < 5);
+	{
+		nop();
+	}
+  // CHECK-MESSAGES: :[[@LINE-4]]:11: warning: potentially unintended semicolon
+  // CHECK-FIXES: if(x < 5){{$}}
+}
+
+void correct4()
+{
+  while(x % 5 == 1);
+  nop();
+}
+
+void correct5()
+{
+	for(int i = 0; i < x; ++i)
+		;
+}
+
+void fail4()
+{
+	for(int i = 0; i < x; ++i);
+		nop();
+  // CHECK-MESSAGES: :[[@LINE-2]]:28: warning: potentially unintended semicolon
+  // CHECK-FIXES: for(int i = 0; i < x; ++i){{$}}
+}
+
+void fail5()
+{
+	if(x % 5 == 1);
+	  nop();
+  // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: potentially unintended semicolon
+  // CHECK-FIXES: if(x % 5 == 1){{$}}
+}
+
+void fail6() {
+  int a = 0;
+  if (a != 0) {
+  } else if (a != 1);
+    a = 2;
+  // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: potentially unintended semicolon
+  // CHECK-FIXES: } else if (a != 1){{$}}
+}
+
+void fail7() {
+  if (true)
+    ;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: potentially unintended semicolon
+}
+
+void correct6()
+{
+	do; while(false);
+}
+
+int correct7()
+{
+  int t_num = 0;
+  char c = 'b';
+  char *s = "a";
+  if (s == "(" || s != "'" || c == '"') {
+    t_num += 3;
+    return (c == ')' && c == '\'');
+  }
+
+  return 0;
+}
+
+void correct8() {
+  if (true)
+    ;
+  else {
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,79 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: bugprone-suspicious-string-compare.WarnOnImplicitComparison, value: 1}, \
+// RUN:   {key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison, value: 1}]}' \
+// RUN: -- -std=c99
+
+static const char A[] = "abc";
+
+int strcmp(const char *, const char *);
+
+int test_warning_patterns() {
+  if (strcmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
+  // CHECK-FIXES: if (strcmp(A, "a") != 0)
+
+  if (strcmp(A, "a") != 0 ||
+      strcmp(A, "b"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+  // CHECK-FIXES: strcmp(A, "b") != 0)
+
+  if (strcmp(A, "a") == 1)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") == -1)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") < '0')
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") < 0.)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
+
+  if (!strcmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:8: warning: function 'strcmp' is compared using logical not operator
+  // CHECK-FIXES: if (strcmp(A, "a") == 0)
+}
+
+void test_structure_patterns() {
+  if (strcmp(A, "a")) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: function 'strcmp' is called without explicitly comparing result
+  // CHECK-FIXES: if (strcmp(A, "a") != 0) {}
+
+  while (strcmp(A, "a")) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: function 'strcmp' is called without explicitly comparing result
+  // CHECK-FIXES: while (strcmp(A, "a") != 0) {}
+
+  for (;strcmp(A, "a");) {}
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: function 'strcmp' is called without explicitly comparing result
+  // CHECK-FIXES: for (;strcmp(A, "a") != 0;) {}
+}
+
+int test_valid_patterns() {
+  // The following cases are valid.
+  if (strcmp(A, "a") < 0) return 0;
+  if (strcmp(A, "a") == 0) return 0;
+  if (strcmp(A, "a") <= 0) return 0;
+  if (strcmp(A, "a") == strcmp(A, "b")) return 0;
+  return 1;
+}
+
+int wrapper(const char* a, const char* b) {
+  return strcmp(a, b);
+}
+
+int assignment_wrapper(const char* a, const char* b) {
+  int cmp = strcmp(a, b);
+  return cmp;
+}
+
+int condexpr_wrapper(const char* a, const char* b) {
+  return (a < b) ? strcmp(a, b) : strcmp(b, a);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-suspicious-string-compare.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,337 @@
+// RUN: %check_clang_tidy %s bugprone-suspicious-string-compare %t -- \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: bugprone-suspicious-string-compare.WarnOnImplicitComparison, value: 1}, \
+// RUN:   {key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison, value: 1}]}' \
+// RUN: --
+
+typedef __SIZE_TYPE__ size;
+
+struct locale_t {
+  void* dummy;
+} locale;
+
+static const char A[] = "abc";
+static const unsigned char U[] = "abc";
+static const unsigned char V[] = "xyz";
+static const wchar_t W[] = L"abc";
+
+int strlen(const char *);
+
+int memcmp(const void *, const void *, size);
+int wmemcmp(const wchar_t *, const wchar_t *, size);
+int memicmp(const void *, const void *, size);
+int _memicmp(const void *, const void *, size);
+int _memicmp_l(const void *, const void *, size, locale_t);
+
+int strcmp(const char *, const char *);
+int strncmp(const char *, const char *, size);
+int strcasecmp(const char *, const char *);
+int strncasecmp(const char *, const char *, size);
+int stricmp(const char *, const char *);
+int strcmpi(const char *, const char *);
+int strnicmp(const char *, const char *, size);
+int _stricmp(const char *, const char * );
+int _strnicmp(const char *, const char *, size);
+int _stricmp_l(const char *, const char *, locale_t);
+int _strnicmp_l(const char *, const char *, size, locale_t);
+
+int wcscmp(const wchar_t *, const wchar_t *);
+int wcsncmp(const wchar_t *, const wchar_t *, size);
+int wcscasecmp(const wchar_t *, const wchar_t *);
+int wcsicmp(const wchar_t *, const wchar_t *);
+int wcsnicmp(const wchar_t *, const wchar_t *, size);
+int _wcsicmp(const wchar_t *, const wchar_t *);
+int _wcsnicmp(const wchar_t *, const wchar_t *, size);
+int _wcsicmp_l(const wchar_t *, const wchar_t *, locale_t);
+int _wcsnicmp_l(const wchar_t *, const wchar_t *, size, locale_t);
+
+int _mbscmp(const unsigned char *, const unsigned char *);
+int _mbsncmp(const unsigned char *, const unsigned char *, size);
+int _mbsnbcmp(const unsigned char *, const unsigned char *, size);
+int _mbsnbicmp(const unsigned char *, const unsigned char *, size);
+int _mbsicmp(const unsigned char *, const unsigned char *);
+int _mbsnicmp(const unsigned char *, const unsigned char *, size);
+int _mbscmp_l(const unsigned char *, const unsigned char *, locale_t);
+int _mbsncmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+int _mbsicmp_l(const unsigned char *, const unsigned char *, locale_t);
+int _mbsnicmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+int _mbsnbcmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+int _mbsnbicmp_l(const unsigned char *, const unsigned char *, size, locale_t);
+
+int test_warning_patterns() {
+  if (strcmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result [bugprone-suspicious-string-compare]
+  // CHECK-FIXES: if (strcmp(A, "a") != 0)
+
+  if (strcmp(A, "a") == 0 ||
+      strcmp(A, "b"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+  // CHECK-FIXES: strcmp(A, "b") != 0)
+
+  if (strcmp(A, "a") == 1)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") == -1)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") == true)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") < '0')
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (strcmp(A, "a") < 0.)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
+}
+
+int test_valid_patterns() {
+  // The following cases are valid.
+  if (strcmp(A, "a") < 0)
+    return 0;
+  if (strcmp(A, "a") == 0)
+    return 0;
+  if (strcmp(A, "a") <= 0)
+    return 0;
+
+  if (wcscmp(W, L"a") < 0)
+    return 0;
+  if (wcscmp(W, L"a") == 0)
+    return 0;
+  if (wcscmp(W, L"a") <= 0)
+    return 0;
+
+  return 1;
+}
+
+int test_implicit_compare_with_functions() {
+
+  if (memcmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memcmp' is called without explicitly comparing result
+  // CHECK-FIXES: memcmp(A, "a", 1) != 0)
+
+  if (wmemcmp(W, L"a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wmemcmp' is called without explicitly comparing result
+  // CHECK-FIXES: wmemcmp(W, L"a", 1) != 0)
+
+  if (memicmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'memicmp' is called without explicitly comparing result
+  // CHECK-FIXES: memicmp(A, "a", 1) != 0)
+
+  if (_memicmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _memicmp(A, "a", 1) != 0)
+
+  if (_memicmp_l(A, "a", 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_memicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _memicmp_l(A, "a", 1, locale) != 0)
+
+  if (strcmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+  // CHECK-FIXES: strcmp(A, "a") != 0)
+
+  if (strncmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncmp' is called without explicitly comparing result
+  // CHECK-FIXES: strncmp(A, "a", 1) != 0)
+
+  if (strcasecmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcasecmp' is called without explicitly comparing result
+  // CHECK-FIXES: strcasecmp(A, "a") != 0)
+
+  if (strncasecmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strncasecmp' is called without explicitly comparing result
+  // CHECK-FIXES: strncasecmp(A, "a", 1) != 0)
+
+  if (stricmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'stricmp' is called without explicitly comparing result
+  // CHECK-FIXES: stricmp(A, "a") != 0)
+
+  if (strcmpi(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmpi' is called without explicitly comparing result
+  // CHECK-FIXES: strcmpi(A, "a") != 0)
+
+  if (_stricmp(A, "a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp' is called without explicitly comparing result
+  // CHECK-FIXES: _stricmp(A, "a") != 0)
+
+  if (strnicmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strnicmp' is called without explicitly comparing result
+  // CHECK-FIXES: strnicmp(A, "a", 1) != 0)
+
+  if (_strnicmp(A, "a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _strnicmp(A, "a", 1) != 0)
+
+  if (_stricmp_l(A, "a", locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_stricmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _stricmp_l(A, "a", locale) != 0)
+
+  if (_strnicmp_l(A, "a", 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_strnicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _strnicmp_l(A, "a", 1, locale) != 0)
+
+  if (wcscmp(W, L"a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscmp' is called without explicitly comparing result
+  // CHECK-FIXES: wcscmp(W, L"a") != 0)
+
+  if (wcsncmp(W, L"a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsncmp' is called without explicitly comparing result
+  // CHECK-FIXES: wcsncmp(W, L"a", 1) != 0)
+
+  if (wcscasecmp(W, L"a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcscasecmp' is called without explicitly comparing result
+  // CHECK-FIXES: wcscasecmp(W, L"a") != 0)
+
+  if (wcsicmp(W, L"a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsicmp' is called without explicitly comparing result
+  // CHECK-FIXES: wcsicmp(W, L"a") != 0)
+
+  if (_wcsicmp(W, L"a"))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _wcsicmp(W, L"a") != 0)
+
+  if (_wcsicmp_l(W, L"a", locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _wcsicmp_l(W, L"a", locale) != 0)
+
+  if (wcsnicmp(W, L"a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'wcsnicmp' is called without explicitly comparing result
+  // CHECK-FIXES: wcsnicmp(W, L"a", 1) != 0)
+
+  if (_wcsnicmp(W, L"a", 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _wcsnicmp(W, L"a", 1) != 0)
+
+  if (_wcsnicmp_l(W, L"a", 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_wcsnicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _wcsnicmp_l(W, L"a", 1, locale) != 0)
+
+  if (_mbscmp(U, V))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp' is called without explicitly comparing result
+  // CHECK-FIXES: _mbscmp(U, V) != 0)
+
+  if (_mbsncmp(U, V, 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsncmp(U, V, 1) != 0)
+
+  if (_mbsnbcmp(U, V, 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsnbcmp(U, V, 1) != 0)
+
+  if (_mbsnbicmp(U, V, 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsnbicmp(U, V, 1) != 0)
+
+  if (_mbsicmp(U, V))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsicmp(U, V) != 0)
+
+  if (_mbsnicmp(U, V, 1))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsnicmp(U, V, 1) != 0)
+
+  if (_mbscmp_l(U, V, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbscmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _mbscmp_l(U, V, locale) != 0)
+
+  if (_mbsncmp_l(U, V, 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsncmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsncmp_l(U, V, 1, locale) != 0)
+
+  if (_mbsicmp_l(U, V, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsicmp_l(U, V, locale) != 0)
+
+  if (_mbsnicmp_l(U, V, 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsnicmp_l(U, V, 1, locale) != 0)
+
+  if (_mbsnbcmp_l(U, V, 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbcmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsnbcmp_l(U, V, 1, locale) != 0)
+
+  if (_mbsnbicmp_l(U, V, 1, locale))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function '_mbsnbicmp_l' is called without explicitly comparing result
+  // CHECK-FIXES: _mbsnbicmp_l(U, V, 1, locale) != 0)
+
+  return 1;
+}
+
+int strcmp_wrapper1(const char* a, const char* b) {
+  return strcmp(a, b);
+}
+
+int strcmp_wrapper2(const char* a, const char* b) {
+  return (a && b) ? strcmp(a, b) : 0;
+}
+
+#define macro_strncmp(s1, s2, n)                                              \
+  (__extension__ (__builtin_constant_p (n)                                    \
+                  && ((__builtin_constant_p (s1)                              \
+                       && strlen (s1) < ((size) (n)))                         \
+                      || (__builtin_constant_p (s2)                           \
+                          && strlen (s2) < ((size) (n))))                     \
+                  ? strcmp (s1, s2) : strncmp (s1, s2, n)))
+
+int strncmp_macro(const char* a, const char* b) {
+  if (macro_strncmp(a, b, 4))
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is called without explicitly comparing result
+
+  if (macro_strncmp(a, b, 4) == 2)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' is compared to a suspicious constant
+
+  if (macro_strncmp(a, b, 4) <= .0)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: function 'strcmp' has suspicious implicit cast
+
+  if (macro_strncmp(a, b, 4) + 0)
+    return 0;
+  // CHECK-MESSAGES: [[@LINE-2]]:7: warning: results of function 'strcmp' used by operator '+'
+
+  return 1;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-swapped-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-swapped-arguments.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-swapped-arguments.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-swapped-arguments.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy %s bugprone-swapped-arguments %t
+
+void F(int, double);
+
+int SomeFunction();
+
+template <typename T, typename U>
+void G(T a, U b) {
+  F(a, b); // no-warning
+  F(2.0, 4);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: F(4, 2.0)
+}
+
+void foo() {
+  F(1.0, 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: F(3, 1.0)
+
+#define M(x, y) x##y()
+
+  double b = 1.0;
+  F(b, M(Some, Function));
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: F(M(Some, Function), b);
+
+#define N F(b, SomeFunction())
+
+  N;
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// In macro, don't emit fixits.
+// CHECK-FIXES: #define N F(b, SomeFunction())
+
+  G(b, 3);
+  G(3, 1.0);
+  G(0, 0);
+
+  F(1.0, 1.0);    // no-warning
+  F(3, 1.0);      // no-warning
+  F(true, false); // no-warning
+  F(0, 'c');      // no-warning
+
+#define APPLY(f, x, y) f(x, y)
+  APPLY(F, 1.0, 3);
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// CHECK-FIXES: APPLY(F, 3, 1.0);
+
+#define PARAMS 1.0, 3
+#define CALL(P) F(P)
+  CALL(PARAMS);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: argument with implicit conversion from 'int' to 'double' followed by argument converted from 'double' to 'int', potentially swapped arguments.
+// In macro, don't emit fixits.
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-terminating-continue.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-terminating-continue.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-terminating-continue.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-terminating-continue.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,65 @@
+// RUN: %check_clang_tidy %s bugprone-terminating-continue %t
+
+void f() {
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(false);
+
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(0);
+
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(nullptr);
+
+  do {
+    continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+    // CHECK-FIXES: break;
+  } while(__null);
+
+
+  do {
+    int x = 1;
+    if (x > 0) continue;
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'continue' in loop with false condition is equivalent to 'break' [bugprone-terminating-continue]
+    // CHECK-FIXES: if (x > 0) break;
+  } while (false);
+}
+
+void g() {
+  do {
+    do {
+      continue;
+      int x = 1;
+    } while (1 == 1);
+  } while (false);
+
+  do {
+    for (int i = 0; i < 1; ++i) {
+      continue;
+      int x = 1;
+    }
+  } while (false);
+
+  do {
+    while (true) {
+      continue;
+      int x = 1;
+    }
+  } while (false);
+
+  int v[] = {1,2,3,34};
+  do {
+    for (int n : v) {
+      if (n>2) continue;
+    }
+  } while (false);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-throw-keyword-missing.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,167 @@
+// RUN: %check_clang_tidy %s bugprone-throw-keyword-missing %t -- -- -fexceptions
+
+namespace std {
+
+// std::string declaration (taken from test/clang-tidy/readability-redundant-string-cstr-msvc.cpp).
+template <typename T>
+class allocator {};
+template <typename T>
+class char_traits {};
+template <typename C, typename T = std::char_traits<C>, typename A = std::allocator<C>>
+struct basic_string {
+  basic_string();
+  basic_string(const basic_string &);
+  // MSVC headers define two constructors instead of using optional arguments.
+  basic_string(const C *);
+  basic_string(const C *, const A &);
+  ~basic_string();
+};
+typedef basic_string<char> string;
+typedef basic_string<wchar_t> wstring;
+
+// std::exception and std::runtime_error declaration.
+struct exception {
+  exception();
+  exception(const exception &other);
+  virtual ~exception();
+};
+
+struct runtime_error : public exception {
+  explicit runtime_error(const std::string &what_arg);
+};
+
+} // namespace std
+
+// The usage of this class should never emit a warning.
+struct RegularClass {};
+
+// Class name contains the substring "exception", in certain cases using this class should emit a warning.
+struct RegularException {
+  RegularException() {}
+
+  // Constructors with a single argument are treated differently (cxxFunctionalCastExpr).
+  RegularException(int) {}
+};
+
+// --------------
+
+void stdExceptionNotTrownTest(int i) {
+  if (i < 0)
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing]
+    std::exception();
+
+  if (i > 0)
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+    std::runtime_error("Unexpected argument");
+}
+
+void stdExceptionThrownTest(int i) {
+  if (i < 0)
+    throw std::exception();
+
+  if (i > 0)
+    throw std::runtime_error("Unexpected argument");
+}
+
+void regularClassNotThrownTest(int i) {
+  if (i < 0)
+    RegularClass();
+}
+
+void regularClassThrownTest(int i) {
+  if (i < 0)
+    throw RegularClass();
+}
+
+void nameContainsExceptionNotThrownTest(int i) {
+  if (i < 0)
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+    RegularException();
+
+  if (i > 0)
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+    RegularException(5);
+}
+
+void nameContainsExceptionThrownTest(int i) {
+  if (i < 0)
+    throw RegularException();
+
+  if (i > 0)
+    throw RegularException(5);
+}
+
+template <class Exception>
+void f(int i, Exception excToBeThrown) {}
+
+void funcCallWithTempExcTest() {
+  f(5, RegularException());
+}
+
+// Global variable initilization test.
+RegularException exc = RegularException();
+RegularException *excptr = new RegularException();
+
+void localVariableInitTest() {
+  RegularException exc = RegularException();
+  RegularException *excptr = new RegularException();
+}
+
+class CtorInitializerListTest {
+  RegularException exc;
+
+  CtorInitializerListTest() : exc(RegularException()) {}
+
+  CtorInitializerListTest(int) try : exc(RegularException()) {
+    // Constructor body
+  } catch (...) {
+    // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
+    RegularException();
+  }
+
+  CtorInitializerListTest(float);
+};
+
+CtorInitializerListTest::CtorInitializerListTest(float) try : exc(RegularException()) {
+  // Constructor body
+} catch (...) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
+  RegularException();
+}
+
+RegularException funcReturningExceptionTest(int i) {
+  return RegularException();
+}
+
+void returnedValueTest() {
+  funcReturningExceptionTest(3);
+}
+
+struct ClassBracedInitListTest {
+  ClassBracedInitListTest(RegularException exc) {}
+};
+
+void foo(RegularException, ClassBracedInitListTest) {}
+
+void bracedInitListTest() {
+  RegularException exc{};
+  ClassBracedInitListTest test = {RegularException()};
+  foo({}, {RegularException()});
+}
+
+typedef std::exception ERROR_BASE;
+class RegularError : public ERROR_BASE {};
+
+void typedefTest() {
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
+  RegularError();
+}
+
+struct ExceptionRAII {
+  ExceptionRAII() {}
+  ~ExceptionRAII() {}
+};
+
+void exceptionRAIITest() {
+  ExceptionRAII E;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable-magniute-bits-upper-limit.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- -- --target=x86_64-linux
+
+// MagnitudeBitsUpperLimit = 16 (default value)
+
+unsigned long size() { return 294967296l; }
+
+void voidFilteredOutForLoop1() {
+  for (long i = 0; i < size(); ++i) {
+    // no warning
+  }
+}
+
+void voidCaughtForLoop1() {
+  for (int i = 0; i < size(); ++i) {
+    // no warning
+  }
+}
+
+void voidCaughtForLoop2() {
+  for (short i = 0; i < size(); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'unsigned long' [bugprone-too-small-loop-variable]
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-too-small-loop-variable.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,255 @@
+// RUN: %check_clang_tidy %s bugprone-too-small-loop-variable %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:             [{key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit, \
+// RUN:               value: 1024}]}" \
+// RUN:   -- --target=x86_64-linux
+
+long size() { return 294967296l; }
+
+////////////////////////////////////////////////////////////////////////////////
+/// Test cases correctly caught by bugprone-too-small-loop-variable.
+
+void voidBadForLoop() {
+  for (int i = 0; i < size(); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidBadForLoop2() {
+  for (int i = 0; i < size() + 10; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidBadForLoop3() {
+  for (int i = 0; i <= size() - 1; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidBadForLoop4() {
+  for (int i = 0; size() > i; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidBadForLoop5() {
+  for (int i = 0; size() - 1 >= i; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidBadForLoop6() {
+  int i = 0;
+  for (; i < size(); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: loop variable has narrower type 'int' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidForLoopUnsignedBound() {
+  unsigned size = 3147483647;
+  for (int i = 0; i < size; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: loop variable has narrower type 'int' than iteration's upper bound 'unsigned int' [bugprone-too-small-loop-variable]
+  }
+}
+
+// The iteration's upper bound has a template dependent value.
+template <long size>
+void doSomething() {
+  for (short i = 0; i < size; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+// The iteration's upper bound has a template dependent type.
+template <class T>
+void doSomething() {
+  for (T i = 0; i < size(); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidForLoopInstantiation() {
+  // This line does not trigger the warning.
+  doSomething<long>();
+  // This one triggers the warning.
+  doSomething<short>();
+}
+
+// A suspicious function used in a macro.
+#define SUSPICIOUS_SIZE (size())
+void voidBadForLoopWithMacroBound() {
+  for (short i = 0; i < SUSPICIOUS_SIZE; ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'long' [bugprone-too-small-loop-variable]
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Correct loops: we should not warn here.
+
+// A simple use case when both expressions have the same type.
+void voidGoodForLoop() {
+  for (long i = 0; i < size(); ++i) { // no warning
+  }
+}
+
+// Other use case where both expressions have the same type,
+// but short expressions are converted to int by the compare operator.
+void voidGoodForLoop2() {
+  short loopCond = 10;
+  for (short i = 0; i < loopCond; ++i) { // no warning
+  }
+}
+
+// Because of the integer literal, the iteration's upper bound is int, but we suppress the warning here.
+void voidForLoopShortPlusLiteral() {
+  short size = 30000;
+  for (short i = 0; i <= (size - 1); ++i) { // no warning
+  }
+}
+
+// Addition of two short variables results in an int value, but we suppress this to avoid false positives.
+void voidForLoopShortPlusShort() {
+  short size = 256;
+  short increment = 14;
+  for (short i = 0; i < size + increment; ++i) { // no warning
+  }
+}
+
+// In this test case we have different integer types, but here the loop variable has the bigger type.
+// The iteration's bound is cast implicitly, not the loop variable.
+void voidForLoopBoundImplicitCast() {
+  short start = 256;
+  short end = 14;
+  for (int i = start; i >= end; --i) { // no warning
+  }
+}
+
+// Range based loop and other iterator based loops are ignored by this check.
+void voidRangeBasedForLoop() {
+  int array[] = {1, 2, 3, 4, 5};
+  for (const int &i : array) { // no warning
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Future possibilites to improve the check.
+
+// False positive: because of the int literal, iteration's upper bound has int type.
+void voidForLoopFalsePositive() {
+  short size = 30000;
+  bool cond = false;
+  for (short i = 0; i < (cond ? 0 : size); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]
+  }
+}
+
+void voidForLoopFalsePositive2() {
+  short size = 30000;
+  bool cond = false;
+  for (short i = 0; i < (!cond ? size : 0); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]
+  }
+}
+
+// False positive: The loop bound expression contains nested binary operators.
+void voidForLoopFalsePositive3() {
+  short number = 30000;
+  for (short i = 0; i < ((number & 0x7f) + 1); ++i) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: loop variable has narrower type 'short' than iteration's upper bound 'int' [bugprone-too-small-loop-variable]
+  }
+}
+
+// TODO: handle while loop.
+void voidBadWhileLoop() {
+  short i = 0;
+  while (i < size()) { // missing warning
+    ++i;
+  }
+}
+
+// TODO: handle do-while loop.
+void voidBadDoWhileLoop() {
+  short i = 0;
+  do {
+    ++i;
+  } while (i < size()); // missing warning
+}
+
+// TODO: handle complex loop conditions.
+void voidComplexForCond() {
+  bool additionalCond = true;
+  for (int i = 0; i < size() && additionalCond; ++i) { // missing warning
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/// Suspicious test cases ingored by this check.
+
+// Test case with a reverse iteration.
+// This is caught by -Wimplicit-int-conversion.
+void voidReverseForLoop() {
+  for (short i = size() - 1; i >= 0; --i) { // no warning
+  }
+}
+
+// Macro defined literals are used inside the loop condition.
+#define SIZE 125
+#define SIZE2 (SIZE + 1)
+void voidForLoopWithMacroBound() {
+  for (short i = 0; i < SIZE2; ++i) { // no warning
+  }
+}
+
+// A suspicious loop is not caught if the iteration's upper bound is a literal.
+void voidForLoopWithLiteralBound() {
+  for (short i = 0; i < 125; ++i) { // no warning
+  }
+}
+
+// The used literal leads to an infinite loop.
+// This is caught by -Wtautological-constant-out-of-range-compare.
+void voidForLoopWithBigLiteralBound() {
+  for (short i = 0; i < 294967296l; ++i) { // no warning
+  }
+}
+
+enum eSizeType {
+  START,
+  Y,
+  END
+};
+
+// A suspicious loop is not caught if the iteration's upper bound is an enum value.
+void voidForLoopWithEnumBound() {
+  for (short i = eSizeType::START; i < eSizeType::END; ++i) { // no warning
+  }
+}
+
+enum eSizeType2 : long {
+  START2 = 294967296l,
+  Y2,
+  END2
+};
+
+// The used enum value leads to an infinite loop.
+// This is caught by -Wtautological-constant-out-of-range-compare.
+void voidForLoopWithBigEnumBound() {
+  for (short i = eSizeType2::START2; i < eSizeType2::END2; ++i) { // no warning
+  }
+}
+
+// A suspicious loop is not caught if the iteration's upper bound is a constant variable.
+void voidForLoopWithConstBound() {
+  const long size = 252l;
+  for (short i = 0; i < size; ++i) { // no warning
+  }
+}
+
+// The used constant variable leads to an infinite loop.
+// This is caught by -Wtautological-constant-out-of-range-compare.
+void voidForLoopWithBigConstBound() {
+  const long size = 294967296l;
+  for (short i = 0; i < size; ++i) { // no warning
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undefined-memory-manipulation.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undefined-memory-manipulation.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undefined-memory-manipulation.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undefined-memory-manipulation.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,213 @@
+// RUN: %check_clang_tidy %s bugprone-undefined-memory-manipulation %t
+
+void *memset(void *, int, __SIZE_TYPE__);
+void *memcpy(void *, const void *, __SIZE_TYPE__);
+void *memmove(void *, const void *, __SIZE_TYPE__);
+
+namespace std {
+using ::memcpy;
+using ::memmove;
+using ::memset;
+}
+
+namespace types {
+// TriviallyCopyable types:
+struct Plain {
+  int n;
+};
+
+enum E {
+  X,
+  Y,
+  Z
+};
+
+struct Base {
+  float b;
+};
+
+struct Derived : Base {
+  bool d;
+};
+
+// not TriviallyCopyable types:
+struct Destruct {
+  ~Destruct() {}
+};
+
+struct Copy {
+  Copy() {}
+  Copy(const Copy &) {}
+};
+
+struct Move {
+  Move() {}
+  Move(Move &&) {}
+};
+
+struct VirtualFunc {
+  virtual void f() {}
+};
+
+struct VirtualBase : virtual Base {
+  int vb;
+};
+
+// Incomplete type, assume it is TriviallyCopyable.
+struct NoDef;
+
+} // end namespace types
+
+void f(types::NoDef *s) {
+  memset(s, 0, 5);
+}
+
+template <typename T>
+void memset_temp(T *b) {
+  memset(b, 0, sizeof(T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc' is not TriviallyCopyable [bugprone-undefined-memory-manipulation]
+}
+
+template <typename S, typename T>
+void memcpy_temp(S *a, T *b) {
+  memcpy(a, b, sizeof(T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+}
+
+template <typename S, typename T>
+void memmove_temp(S *a, T *b) {
+  memmove(a, b, sizeof(T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+}
+
+namespace aliases {
+using Copy2 = types::Copy;
+typedef types::Move Move2;
+}
+
+void notTriviallyCopyable() {
+  types::Plain p; // TriviallyCopyable for variety
+  types::Destruct d;
+  types::Copy c;
+  types::Move m;
+  types::VirtualFunc vf;
+  types::VirtualBase vb;
+
+  memset(&vf, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
+  memset(&d, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
+  memset(&c, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
+  std::memset(&m, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
+  ::memset(&vb, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
+
+  memcpy(&p, &vf, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualFunc'
+  memcpy(&p, &d, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Destruct'
+  memcpy(&c, &p, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Copy'
+  std::memcpy(&m, &p, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Move'
+  ::memcpy(&vb, &p, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualBase'
+
+  memmove(&vf, &p, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
+  memmove(&d, &p, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
+  memmove(&p, &c, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
+  std::memmove(&p, &m, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Move'
+  ::memmove(&p, &vb, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::VirtualBase'
+
+#define MEMSET memset(&vf, 0, sizeof(int));
+  MEMSET
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::VirtualFunc'
+#define MEMCPY memcpy(&d, &p, sizeof(int));
+  MEMCPY
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'types::Destruct'
+#define MEMMOVE memmove(&p, &c, sizeof(int));
+  MEMMOVE
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, source object type 'types::Copy'
+
+  memset_temp<types::VirtualFunc>(&vf);
+  memcpy_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+  memmove_temp<types::Plain, types::VirtualFunc>(&p, &vf);
+
+  aliases::Copy2 c2;
+  aliases::Move2 m2;
+  memset(&c2, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+  memset(&m2, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Move2'
+
+  typedef aliases::Copy2 Copy3;
+  typedef aliases::Copy2 *PCopy2;
+  typedef Copy3 *PCopy3;
+  Copy3 c3;
+  PCopy2 pc2;
+  PCopy3 pc3;
+  memset(&c3, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
+  memset(pc2, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'aliases::Copy2'
+  memset(pc3, 0, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: undefined behavior, destination object type 'Copy3'
+}
+
+void triviallyCopyable() {
+  types::Plain p;
+  types::Base base;
+  types::Derived derived;
+
+  int i = 5;
+  int ia[3] = {1, 2, 3};
+  float f = 3.14;
+  float fa[3] = {1.1, 2.2, 3.3};
+  bool b = false;
+  bool ba[2] = {true, false};
+  types::E e = types::X;
+  p.n = 2;
+
+  memset(&p, 0, sizeof(int));
+  memset(&base, 0, sizeof(float));
+  memset(&derived, 0, sizeof(bool));
+  memset(&i, 0, sizeof(int));
+  memset(ia, 0, sizeof(int));
+  memset(&f, 0, sizeof(float));
+  memset(fa, 0, sizeof(float));
+  memset(&b, 0, sizeof(bool));
+  memset(ba, 0, sizeof(bool));
+  memset(&e, 0, sizeof(int));
+  memset(&p.n, 0, sizeof(int));
+
+  memcpy(&p, &p, sizeof(int));
+  memcpy(&base, &base, sizeof(float));
+  memcpy(&derived, &derived, sizeof(bool));
+  memcpy(&i, &i, sizeof(int));
+  memcpy(ia, ia, sizeof(int));
+  memcpy(&f, &f, sizeof(float));
+  memcpy(fa, fa, sizeof(float));
+  memcpy(&b, &b, sizeof(bool));
+  memcpy(ba, ba, sizeof(bool));
+  memcpy(&e, &e, sizeof(int));
+  memcpy(&p.n, &p.n, sizeof(int));
+
+  memmove(&p, &p, sizeof(int));
+  memmove(&base, &base, sizeof(float));
+  memmove(&derived, &derived, sizeof(bool));
+  memmove(&i, &i, sizeof(int));
+  memmove(ia, ia, sizeof(int));
+  memmove(&f, &f, sizeof(float));
+  memmove(fa, fa, sizeof(float));
+  memmove(&b, &b, sizeof(bool));
+  memmove(ba, ba, sizeof(bool));
+  memmove(&e, &e, sizeof(int));
+  memmove(&p.n, &p.n, sizeof(int));
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor-cxx98.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor-cxx98.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor-cxx98.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor-cxx98.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,23 @@
+// RUN: clang-tidy %s -checks=-*,bugprone-undelegated-constructor -- -std=c++98 | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+struct Ctor;
+Ctor foo();
+
+struct Ctor {
+  Ctor();
+  Ctor(int);
+  Ctor(int, int);
+  Ctor(Ctor *i) {
+    Ctor();
+    Ctor(0);
+    Ctor(1, 2);
+    foo();
+  }
+};
+
+Ctor::Ctor() {
+  Ctor(1);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-undelegated-constructor.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s bugprone-undelegated-constructor %t
+
+struct Ctor;
+Ctor foo();
+
+struct Ctor {
+  Ctor();
+  Ctor(int);
+  Ctor(int, int);
+  Ctor(Ctor *i) {
+    Ctor();
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor? A temporary object is created here instead [bugprone-undelegated-constructor]
+    Ctor(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+    Ctor(1, 2);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+    foo();
+  }
+};
+
+Ctor::Ctor() {
+  Ctor(1);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: did you intend to call a delegated constructor?
+}
+
+Ctor::Ctor(int i) : Ctor(i, 1) {} // properly delegated.
+
+struct Dtor {
+  Dtor();
+  Dtor(int);
+  Dtor(int, int);
+  Dtor(Ctor *i) {
+    Dtor();
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+    Dtor(0);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+    Dtor(1, 2);
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: did you intend to call a delegated constructor?
+  }
+  ~Dtor();
+};
+
+struct Base {};
+struct Derived : public Base {
+  Derived() { Base(); }
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: did you intend to call a delegated constructor?
+};
+
+template <typename T>
+struct TDerived : public Base {
+  TDerived() { Base(); }
+};
+
+TDerived<int> t;

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment-warn-only-if-this-has-suspicious-field.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment-warn-only-if-this-has-suspicious-field.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment-warn-only-if-this-has-suspicious-field.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment-warn-only-if-this-has-suspicious-field.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s bugprone-unhandled-self-assignment %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:             [{key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField, \
+// RUN:               value: 0}]}"
+
+// Classes with pointer field are still caught.
+class PtrField {
+public:
+  PtrField &operator=(const PtrField &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:13: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// With the option, check catches classes with trivial fields.
+class TrivialFields {
+public:
+  TrivialFields &operator=(const TrivialFields &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:18: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    return *this;
+  }
+
+private:
+  int m;
+  float f;
+  double d;
+  bool b;
+};
+
+// The check warns also when there is no field at all.
+// In this case, user-defined copy assignment operator is useless anyway.
+class ClassWithoutFields {
+public:
+  ClassWithoutFields &operator=(const ClassWithoutFields &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:23: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    return *this;
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,579 @@
+// RUN: %check_clang_tidy %s bugprone-unhandled-self-assignment %t -- -- -fno-delayed-template-parsing
+
+namespace std {
+
+template <class T>
+void swap(T x, T y) {
+}
+
+template <class T>
+T &&move(T x) {
+}
+
+template <class T>
+class unique_ptr {
+};
+
+template <class T>
+class shared_ptr {
+};
+
+template <class T>
+class weak_ptr {
+};
+
+template <class T>
+class auto_ptr {
+};
+
+} // namespace std
+
+void assert(int expression){};
+
+///////////////////////////////////////////////////////////////////
+/// Test cases correctly caught by the check.
+
+class PtrField {
+public:
+  PtrField &operator=(const PtrField &object);
+
+private:
+  int *p;
+};
+
+PtrField &PtrField::operator=(const PtrField &object) {
+  // CHECK-MESSAGES: [[@LINE-1]]:21: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+  // ...
+  return *this;
+}
+
+// Class with an inline operator definition.
+class InlineDefinition {
+public:
+  InlineDefinition &operator=(const InlineDefinition &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:21: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+class UniquePtrField {
+public:
+  UniquePtrField &operator=(const UniquePtrField &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:19: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  std::unique_ptr<int> p;
+};
+
+class SharedPtrField {
+public:
+  SharedPtrField &operator=(const SharedPtrField &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:19: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  std::shared_ptr<int> p;
+};
+
+class WeakPtrField {
+public:
+  WeakPtrField &operator=(const WeakPtrField &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:17: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  std::weak_ptr<int> p;
+};
+
+class AutoPtrField {
+public:
+  AutoPtrField &operator=(const AutoPtrField &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:17: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  std::auto_ptr<int> p;
+};
+
+// Class with C array field.
+class CArrayField {
+public:
+  CArrayField &operator=(const CArrayField &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:16: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  int array[256];
+};
+
+// Make sure to not ignore cases when the operator definition calls
+// a copy constructor of another class.
+class CopyConstruct {
+public:
+  CopyConstruct &operator=(const CopyConstruct &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:18: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    WeakPtrField a;
+    WeakPtrField b(a);
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// Make sure to not ignore cases when the operator definition calls
+// a copy assignment operator of another class.
+class AssignOperator {
+public:
+  AssignOperator &operator=(const AssignOperator &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:19: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    a.operator=(object.a);
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+  WeakPtrField a;
+};
+
+class NotSelfCheck {
+public:
+  NotSelfCheck &operator=(const NotSelfCheck &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:17: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    if (&object == this->doSomething()) {
+      // ...
+    }
+    return *this;
+  }
+
+  void *doSomething() {
+    return p;
+  }
+
+private:
+  int *p;
+};
+
+template <class T>
+class TemplatePtrField {
+public:
+  TemplatePtrField<T> &operator=(const TemplatePtrField<T> &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:24: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  T *p;
+};
+
+template <class T>
+class TemplateCArrayField {
+public:
+  TemplateCArrayField<T> &operator=(const TemplateCArrayField<T> &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:27: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    // ...
+    return *this;
+  }
+
+private:
+  T p[256];
+};
+
+// Other template class's constructor is called inside a declaration.
+template <class T>
+class WrongTemplateCopyAndMove {
+public:
+  WrongTemplateCopyAndMove<T> &operator=(const WrongTemplateCopyAndMove<T> &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:32: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    TemplatePtrField<T> temp;
+    TemplatePtrField<T> temp2(temp);
+    return *this;
+  }
+
+private:
+  T *p;
+};
+
+///////////////////////////////////////////////////////////////////
+/// Test cases correctly ignored by the check.
+
+// Self-assignment is checked using the equality operator.
+class SelfCheck1 {
+public:
+  SelfCheck1 &operator=(const SelfCheck1 &object) {
+    if (this == &object)
+      return *this;
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+class SelfCheck2 {
+public:
+  SelfCheck2 &operator=(const SelfCheck2 &object) {
+    if (&object == this)
+      return *this;
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// Self-assignment is checked using the inequality operator.
+class SelfCheck3 {
+public:
+  SelfCheck3 &operator=(const SelfCheck3 &object) {
+    if (this != &object) {
+      // ...
+    }
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+class SelfCheck4 {
+public:
+  SelfCheck4 &operator=(const SelfCheck4 &object) {
+    if (&object != this) {
+      // ...
+    }
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+template <class T>
+class TemplateSelfCheck {
+public:
+  TemplateSelfCheck<T> &operator=(const TemplateSelfCheck<T> &object) {
+    if (&object != this) {
+      // ...
+    }
+    return *this;
+  }
+
+private:
+  T *p;
+};
+
+// There is no warning if the copy assignment operator gets the object by value.
+class PassedByValue {
+public:
+  PassedByValue &operator=(PassedByValue object) {
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// User-defined swap method calling std::swap inside.
+class CopyAndSwap1 {
+public:
+  CopyAndSwap1 &operator=(const CopyAndSwap1 &object) {
+    CopyAndSwap1 temp(object);
+    doSwap(temp);
+    return *this;
+  }
+
+private:
+  int *p;
+
+  void doSwap(CopyAndSwap1 &object) {
+    using std::swap;
+    swap(p, object.p);
+  }
+};
+
+// User-defined swap method used with passed-by-value parameter.
+class CopyAndSwap2 {
+public:
+  CopyAndSwap2 &operator=(CopyAndSwap2 object) {
+    doSwap(object);
+    return *this;
+  }
+
+private:
+  int *p;
+
+  void doSwap(CopyAndSwap2 &object) {
+    using std::swap;
+    swap(p, object.p);
+  }
+};
+
+// Copy-and-swap method is used but without creating a separate method for it.
+class CopyAndSwap3 {
+public:
+  CopyAndSwap3 &operator=(const CopyAndSwap3 &object) {
+    CopyAndSwap3 temp(object);
+    std::swap(p, temp.p);
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+template <class T>
+class TemplateCopyAndSwap {
+public:
+  TemplateCopyAndSwap<T> &operator=(const TemplateCopyAndSwap<T> &object) {
+    TemplateCopyAndSwap<T> temp(object);
+    std::swap(p, temp.p);
+    return *this;
+  }
+
+private:
+  T *p;
+};
+
+// Move semantics is used on a temporary copy of the object.
+class CopyAndMove1 {
+public:
+  CopyAndMove1 &operator=(const CopyAndMove1 &object) {
+    CopyAndMove1 temp(object);
+    *this = std::move(temp);
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// There is no local variable for the temporary copy.
+class CopyAndMove2 {
+public:
+  CopyAndMove2 &operator=(const CopyAndMove2 &object) {
+    *this = std::move(CopyAndMove2(object));
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+template <class T>
+class TemplateCopyAndMove {
+public:
+  TemplateCopyAndMove<T> &operator=(const TemplateCopyAndMove<T> &object) {
+    TemplateCopyAndMove<T> temp(object);
+    *this = std::move(temp);
+    return *this;
+  }
+
+private:
+  T *p;
+};
+
+// There is no local variable for the temporary copy.
+template <class T>
+class TemplateCopyAndMove2 {
+public:
+  TemplateCopyAndMove2<T> &operator=(const TemplateCopyAndMove2<T> &object) {
+    *this = std::move(TemplateCopyAndMove2<T>(object));
+    return *this;
+  }
+
+private:
+  T *p;
+};
+
+// We should not catch move assignment operators.
+class MoveAssignOperator {
+public:
+  MoveAssignOperator &operator=(MoveAssignOperator &&object) {
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// We ignore copy assignment operators without user-defined implementation.
+class DefaultOperator {
+public:
+  DefaultOperator &operator=(const DefaultOperator &object) = default;
+
+private:
+  int *p;
+};
+
+class DeletedOperator {
+public:
+  DeletedOperator &operator=(const DefaultOperator &object) = delete;
+
+private:
+  int *p;
+};
+
+class ImplicitOperator {
+private:
+  int *p;
+};
+
+// Check ignores those classes which has no any pointer or array field.
+class TrivialFields {
+public:
+  TrivialFields &operator=(const TrivialFields &object) {
+    // ...
+    return *this;
+  }
+
+private:
+  int m;
+  float f;
+  double d;
+  bool b;
+};
+
+// There is no warning when the class calls another assignment operator on 'this'
+// inside the copy assignment operator's definition.
+class AssignIsForwarded {
+public:
+  AssignIsForwarded &operator=(const AssignIsForwarded &object) {
+    operator=(object.p);
+    return *this;
+  }
+
+  AssignIsForwarded &operator=(int *pp) {
+    if (p != pp) {
+      delete p;
+      p = new int(*pp);
+    }
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// Assertion is a valid way to say that self-assignment is not expected to happen.
+class AssertGuard {
+public:
+  AssertGuard &operator=(const AssertGuard &object) {
+    assert(this != &object);
+    // ...
+    return *this;
+  }
+
+private:
+  int *p;
+};
+
+// Make sure we don't catch this operator=() as a copy assignment operator.
+// Note that RHS has swapped template arguments.
+template <typename Ty, typename Uy>
+class NotACopyAssignmentOperator {
+  Ty *Ptr1;
+  Uy *Ptr2;
+
+public:
+  NotACopyAssignmentOperator& operator=(const NotACopyAssignmentOperator<Uy, Ty> &RHS) {
+    Ptr1 = RHS.getUy();
+    Ptr2 = RHS.getTy();
+    return *this;
+  }
+
+  Ty *getTy() const { return Ptr1; }
+  Uy *getUy() const { return Ptr2; }
+};
+
+///////////////////////////////////////////////////////////////////
+/// Test cases which should be caught by the check.
+
+// TODO: handle custom pointers.
+template <class T>
+class custom_ptr {
+};
+
+class CustomPtrField {
+public:
+  CustomPtrField &operator=(const CustomPtrField &object) {
+    // ...
+    return *this;
+  }
+
+private:
+  custom_ptr<int> p;
+};
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////
+/// False positives: These are self-assignment safe, but they don't use any of the three patterns.
+
+class ArrayCopy {
+public:
+  ArrayCopy &operator=(const ArrayCopy &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:14: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    for (int i = 0; i < 256; i++)
+      array[i] = object.array[i];
+    return *this;
+  }
+
+private:
+  int array[256];
+};
+
+class GetterSetter {
+public:
+  GetterSetter &operator=(const GetterSetter &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:17: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    setValue(object.getValue());
+    return *this;
+  }
+
+  int *getValue() const { return value; }
+
+  void setValue(int *newPtr) {
+    int *pTmp(newPtr ? new int(*newPtr) : nullptr);
+    std::swap(value, pTmp);
+    delete pTmp;
+  }
+
+private:
+  int *value;
+};
+
+class CustomSelfCheck {
+public:
+  CustomSelfCheck &operator=(const CustomSelfCheck &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:20: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment]
+    if (index != object.index) {
+      // ...
+    }
+    return *this;
+  }
+
+private:
+  int *value;
+  int index;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-raii.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-raii.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-raii.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-raii.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy %s bugprone-unused-raii %t
+
+struct Foo {
+  Foo();
+  Foo(int);
+  Foo(int, int);
+  ~Foo();
+};
+
+struct Bar {
+  Bar();
+};
+
+struct FooBar {
+  FooBar();
+  Foo f;
+};
+
+template <typename T>
+void qux() {
+  T(42);
+}
+
+template <typename T>
+struct TFoo {
+  TFoo(T);
+  ~TFoo();
+};
+
+Foo f();
+
+struct Ctor {
+  Ctor(int);
+  Ctor() {
+    Ctor(0); // TODO: warn here.
+  }
+};
+
+void test() {
+  Foo(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: Foo give_me_a_name(42);
+  Foo(23, 42);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: Foo give_me_a_name(23, 42);
+  Foo();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: Foo give_me_a_name;
+  TFoo<int>(23);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: TFoo<int> give_me_a_name(23);
+
+  FooBar();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object?
+// CHECK-FIXES: FooBar give_me_a_name;
+
+  Bar();
+  f();
+  qux<Foo>();
+
+#define M Foo();
+  M
+
+  {
+    Foo();
+  }
+  Foo();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value-custom.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value-custom.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value-custom.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value-custom.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,108 @@
+// RUN: %check_clang_tidy %s bugprone-unused-return-value %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: bugprone-unused-return-value.CheckedFunctions, \
+// RUN:    value: "::fun;::ns::Outer::Inner::memFun;::ns::Type::staticFun;::ns::ClassTemplate::memFun;::ns::ClassTemplate::staticFun"}]}' \
+// RUN: --
+
+namespace std {
+
+template <typename T>
+T *launder(T *);
+
+} // namespace std
+
+namespace ns {
+
+struct Outer {
+  struct Inner {
+    bool memFun();
+  };
+};
+
+using AliasName = Outer;
+
+struct Derived : public Outer::Inner {};
+
+struct Retval {
+  int *P;
+  Retval() { P = new int; }
+  ~Retval() { delete P; }
+};
+
+struct Type {
+  Retval memFun();
+  static Retval staticFun();
+};
+
+template <typename T>
+struct ClassTemplate {
+  Retval memFun();
+  static Retval staticFun();
+};
+
+} // namespace ns
+
+int fun();
+void fun(int);
+
+void warning() {
+  fun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value returned by this function should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+
+  (fun());
+  // CHECK-NOTES: [[@LINE-1]]:4: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:4: note: cast {{.*}} this warning
+
+  ns::Outer::Inner ObjA1;
+  ObjA1.memFun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  ns::AliasName::Inner ObjA2;
+  ObjA2.memFun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  ns::Derived ObjA3;
+  ObjA3.memFun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  ns::Type::staticFun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  ns::ClassTemplate<int> ObjA4;
+  ObjA4.memFun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  ns::ClassTemplate<int>::staticFun();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+}
+
+void noWarning() {
+  auto R1 = fun();
+
+  ns::Outer::Inner ObjB1;
+  auto R2 = ObjB1.memFun();
+
+  auto R3 = ns::Type::staticFun();
+
+  ns::ClassTemplate<int> ObjB2;
+  auto R4 = ObjB2.memFun();
+
+  auto R5 = ns::ClassTemplate<int>::staticFun();
+
+  // test calling a void overload of a checked function
+  fun(5);
+
+  // test discarding return value of functions that are not configured to be checked
+  int I = 1;
+  std::launder(&I);
+
+  ns::Type ObjB3;
+  ObjB3.memFun();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-unused-return-value.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,238 @@
+// RUN: %check_clang_tidy %s bugprone-unused-return-value %t -- -- -fexceptions
+
+namespace std {
+
+struct future {};
+
+enum class launch {
+  async,
+  deferred
+};
+
+template <typename Function, typename... Args>
+future async(Function &&, Args &&...);
+
+template <typename Function, typename... Args>
+future async(launch, Function &&, Args &&...);
+
+template <typename ForwardIt, typename T>
+ForwardIt remove(ForwardIt, ForwardIt, const T &);
+
+template <typename ForwardIt, typename UnaryPredicate>
+ForwardIt remove_if(ForwardIt, ForwardIt, UnaryPredicate);
+
+template <typename ForwardIt>
+ForwardIt unique(ForwardIt, ForwardIt);
+
+template <typename T>
+struct default_delete;
+
+template <typename T, typename Deleter = std::default_delete<T>>
+struct unique_ptr {
+  T *release() noexcept;
+};
+
+template <typename T>
+struct char_traits;
+
+template <typename T>
+struct allocator;
+
+template <typename CharT,
+          typename Traits = char_traits<CharT>,
+          typename Allocator = allocator<CharT>>
+struct basic_string {
+  bool empty() const;
+};
+
+typedef basic_string<char> string;
+
+template <typename T, typename Allocator = std::allocator<T>>
+struct vector {
+  bool empty() const noexcept;
+};
+
+// the check should be able to match std lib calls even if the functions are
+// declared inside inline namespaces
+inline namespace v1 {
+
+template <typename T>
+T *launder(T *);
+
+} // namespace v1
+} // namespace std
+
+struct Foo {
+  void f();
+};
+
+int increment(int i) {
+  return i + 1;
+}
+
+void useFuture(const std::future &fut);
+
+void warning() {
+  std::async(increment, 42);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value returned by this function should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast the expression to void to silence this warning
+
+  std::async(std::launch::async, increment, 42);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  Foo F;
+  std::launder(&F);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  std::remove_if(nullptr, nullptr, nullptr);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  std::unique(nullptr, nullptr);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  std::unique_ptr<Foo> UPtr;
+  UPtr.release();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  std::string Str;
+  Str.empty();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  std::vector<Foo> Vec;
+  Vec.empty();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:3: note: cast {{.*}} this warning
+
+  // test discarding return values inside different kinds of statements
+
+  auto Lambda = [] { std::remove(nullptr, nullptr, 1); };
+  // CHECK-NOTES: [[@LINE-1]]:22: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:22: note: cast {{.*}} this warning
+
+  if (true)
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+  else if (true)
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+  else
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+  while (true)
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+  do
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+  while (true);
+
+  for (;;)
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+  for (std::remove(nullptr, nullptr, 1);;)
+    // CHECK-NOTES: [[@LINE-1]]:8: warning: the value {{.*}} should be used
+    // CHECK-NOTES: [[@LINE-2]]:8: note: cast {{.*}} this warning
+    ;
+
+  for (;; std::remove(nullptr, nullptr, 1))
+    // CHECK-NOTES: [[@LINE-1]]:11: warning: the value {{.*}} should be used
+    // CHECK-NOTES: [[@LINE-2]]:11: note: cast {{.*}} this warning
+    ;
+
+  for (auto C : "foo")
+    std::remove(nullptr, nullptr, 1);
+  // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+  // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+
+  switch (1) {
+  case 1:
+    std::remove(nullptr, nullptr, 1);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+    // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+    break;
+  default:
+    std::remove(nullptr, nullptr, 1);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+    // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+    break;
+  }
+
+  try {
+    std::remove(nullptr, nullptr, 1);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+    // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+  } catch (...) {
+    std::remove(nullptr, nullptr, 1);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: the value {{.*}} should be used
+    // CHECK-NOTES: [[@LINE-2]]:5: note: cast {{.*}} this warning
+  }
+}
+
+void noWarning() {
+  auto AsyncRetval1 = std::async(increment, 42);
+  auto AsyncRetval2 = std::async(std::launch::async, increment, 42);
+
+  Foo FNoWarning;
+  auto LaunderRetval = std::launder(&FNoWarning);
+
+  auto RemoveRetval = std::remove(nullptr, nullptr, 1);
+
+  auto RemoveIfRetval = std::remove_if(nullptr, nullptr, nullptr);
+
+  auto UniqueRetval = std::unique(nullptr, nullptr);
+
+  std::unique_ptr<Foo> UPtrNoWarning;
+  auto ReleaseRetval = UPtrNoWarning.release();
+
+  std::string StrNoWarning;
+  auto StrEmptyRetval = StrNoWarning.empty();
+
+  std::vector<Foo> VecNoWarning;
+  auto VecEmptyRetval = VecNoWarning.empty();
+
+  // test using the return value in different kinds of expressions
+  useFuture(std::async(increment, 42));
+  std::launder(&FNoWarning)->f();
+  delete std::launder(&FNoWarning);
+
+  if (std::launder(&FNoWarning))
+    ;
+  for (; std::launder(&FNoWarning);)
+    ;
+  while (std::launder(&FNoWarning))
+    ;
+  do
+    ;
+  while (std::launder(&FNoWarning));
+  switch (std::unique(1, 1))
+    ;
+
+  // cast to void should allow ignoring the return value
+  (void)std::async(increment, 42);
+
+  // test discarding return value of functions that are not configured to be checked
+  increment(1);
+
+  // test that the check is disabled inside GNU statement expressions
+  ({ std::async(increment, 42); });
+  auto StmtExprRetval = ({ std::async(increment, 42); });
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-use-after-move.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-use-after-move.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-use-after-move.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-use-after-move.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,1273 @@
+// RUN: %check_clang_tidy %s bugprone-use-after-move %t -- -- -std=c++17 -fno-delayed-template-parsing
+
+typedef decltype(nullptr) nullptr_t;
+
+namespace std {
+typedef unsigned size_t;
+
+template <typename T>
+struct unique_ptr {
+  unique_ptr();
+  T *get() const;
+  explicit operator bool() const;
+  void reset(T *ptr);
+  T &operator*() const;
+  T *operator->() const;
+  T& operator[](size_t i) const;
+};
+
+template <typename T>
+struct shared_ptr {
+  shared_ptr();
+  T *get() const;
+  explicit operator bool() const;
+  void reset(T *ptr);
+  T &operator*() const;
+  T *operator->() const;
+};
+
+template <typename T>
+struct weak_ptr {
+  weak_ptr();
+  bool expired() const;
+};
+
+#define DECLARE_STANDARD_CONTAINER(name) \
+  template <typename T>                  \
+  struct name {                          \
+    name();                              \
+    void clear();                        \
+    bool empty();                        \
+  }
+
+#define DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(name) \
+  template <typename T>                              \
+  struct name {                                      \
+    name();                                          \
+    void clear();                                    \
+    bool empty();                                    \
+    void assign(size_t, const T &);                  \
+  }
+
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(basic_string);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(vector);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(deque);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(forward_list);
+DECLARE_STANDARD_CONTAINER_WITH_ASSIGN(list);
+DECLARE_STANDARD_CONTAINER(set);
+DECLARE_STANDARD_CONTAINER(map);
+DECLARE_STANDARD_CONTAINER(multiset);
+DECLARE_STANDARD_CONTAINER(multimap);
+DECLARE_STANDARD_CONTAINER(unordered_set);
+DECLARE_STANDARD_CONTAINER(unordered_map);
+DECLARE_STANDARD_CONTAINER(unordered_multiset);
+DECLARE_STANDARD_CONTAINER(unordered_multimap);
+
+typedef basic_string<char> string;
+
+template <typename>
+struct remove_reference;
+
+template <typename _Tp>
+struct remove_reference {
+  typedef _Tp type;
+};
+
+template <typename _Tp>
+struct remove_reference<_Tp &> {
+  typedef _Tp type;
+};
+
+template <typename _Tp>
+struct remove_reference<_Tp &&> {
+  typedef _Tp type;
+};
+
+template <typename _Tp>
+constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) noexcept {
+  return static_cast<typename remove_reference<_Tp>::type &&>(__t);
+}
+
+} // namespace std
+
+class A {
+public:
+  A();
+  A(const A &);
+  A(A &&);
+
+  A &operator=(const A &);
+  A &operator=(A &&);
+
+  void foo() const;
+  int getInt() const;
+
+  operator bool() const;
+
+  int i;
+};
+
+template <class T>
+class AnnotatedContainer {
+public:
+  AnnotatedContainer();
+
+  void foo() const;
+  [[clang::reinitializes]] void clear();
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// General tests.
+
+// Simple case.
+void simple() {
+  A a;
+  a.foo();
+  A other_a = std::move(a);
+  a.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here
+}
+
+// A warning should only be emitted for one use-after-move.
+void onlyFlagOneUseAfterMove() {
+  A a;
+  a.foo();
+  A other_a = std::move(a);
+  a.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:15: note: move occurred here
+  a.foo();
+}
+
+void moveAfterMove() {
+  // Move-after-move also counts as a use.
+  {
+    A a;
+    std::move(a);
+    std::move(a);
+    // CHECK-NOTES: [[@LINE-1]]:15: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // This is also true if the move itself turns into the use on the second loop
+  // iteration.
+  {
+    A a;
+    for (int i = 0; i < 10; ++i) {
+      std::move(a);
+      // CHECK-NOTES: [[@LINE-1]]:17: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-2]]:7: note: move occurred here
+      // CHECK-NOTES: [[@LINE-3]]:17: note: the use happens in a later loop
+    }
+  }
+}
+
+// Checks also works on function parameters that have a use-after move.
+void parameters(A a) {
+  std::move(a);
+  a.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+
+void standardSmartPtr() {
+  // std::unique_ptr<>, std::shared_ptr<> and std::weak_ptr<> are guaranteed to
+  // be null after a std::move. So the check only flags accesses that would
+  // dereference the pointer.
+  {
+    std::unique_ptr<A> ptr;
+    std::move(ptr);
+    ptr.get();
+    static_cast<bool>(ptr);
+    *ptr;
+    // CHECK-NOTES: [[@LINE-1]]:6: warning: 'ptr' used after it was moved
+    // CHECK-NOTES: [[@LINE-5]]:5: note: move occurred here
+  }
+  {
+    std::unique_ptr<A> ptr;
+    std::move(ptr);
+    ptr->foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  {
+    std::unique_ptr<A> ptr;
+    std::move(ptr);
+    ptr[0];
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  {
+    std::shared_ptr<A> ptr;
+    std::move(ptr);
+    ptr.get();
+    static_cast<bool>(ptr);
+    *ptr;
+    // CHECK-NOTES: [[@LINE-1]]:6: warning: 'ptr' used after it was moved
+    // CHECK-NOTES: [[@LINE-5]]:5: note: move occurred here
+  }
+  {
+    std::shared_ptr<A> ptr;
+    std::move(ptr);
+    ptr->foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  {
+    // std::weak_ptr<> cannot be dereferenced directly, so we only check that
+    // member functions may be called on it after a move.
+    std::weak_ptr<A> ptr;
+    std::move(ptr);
+    ptr.expired();
+  }
+  // Make sure we recognize std::unique_ptr<> or std::shared_ptr<> if they're
+  // wrapped in a typedef.
+  {
+    typedef std::unique_ptr<A> PtrToA;
+    PtrToA ptr;
+    std::move(ptr);
+    ptr.get();
+  }
+  {
+    typedef std::shared_ptr<A> PtrToA;
+    PtrToA ptr;
+    std::move(ptr);
+    ptr.get();
+  }
+  // And we don't get confused if the template argument is a little more
+  // involved.
+  {
+    struct B {
+      typedef A AnotherNameForA;
+    };
+    std::unique_ptr<B::AnotherNameForA> ptr;
+    std::move(ptr);
+    ptr.get();
+  }
+  // Make sure we treat references to smart pointers correctly.
+  {
+    std::unique_ptr<A> ptr;
+    std::unique_ptr<A>& ref_to_ptr = ptr;
+    std::move(ref_to_ptr);
+    ref_to_ptr.get();
+  }
+  {
+    std::unique_ptr<A> ptr;
+    std::unique_ptr<A>&& rvalue_ref_to_ptr = std::move(ptr);
+    std::move(rvalue_ref_to_ptr);
+    rvalue_ref_to_ptr.get();
+  }
+  // We don't give any special treatment to types that are called "unique_ptr"
+  // or "shared_ptr" but are not in the "::std" namespace.
+  {
+    struct unique_ptr {
+      void get();
+    } ptr;
+    std::move(ptr);
+    ptr.get();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'ptr' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+}
+
+// The check also works in member functions.
+class Container {
+  void useAfterMoveInMemberFunction() {
+    A a;
+    std::move(a);
+    a.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+};
+
+// We see the std::move() if it's inside a declaration.
+void moveInDeclaration() {
+  A a;
+  A another_a(std::move(a));
+  a.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+}
+
+// We see the std::move if it's inside an initializer list. Initializer lists
+// are a special case because they cause ASTContext::getParents() to return
+// multiple parents for certain nodes in their subtree. This is because
+// RecursiveASTVisitor visits both the syntactic and semantic forms of
+// InitListExpr, and the parent-child relationships are different between the
+// two forms.
+void moveInInitList() {
+  struct S {
+    A a;
+  };
+  A a;
+  S s{std::move(a)};
+  a.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here
+}
+
+void lambdas() {
+  // Use-after-moves inside a lambda should be detected.
+  {
+    A a;
+    auto lambda = [a] {
+      std::move(a);
+      a.foo();
+      // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here
+    };
+  }
+  // This is just as true if the variable was declared inside the lambda.
+  {
+    auto lambda = [] {
+      A a;
+      std::move(a);
+      a.foo();
+      // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-3]]:7: note: move occurred here
+    };
+  }
+  // But don't warn if the move happened inside the lambda but the use happened
+  // outside -- because
+  // - the 'a' inside the lambda is a copy, and
+  // - we don't know when the lambda will get called anyway
+  {
+    A a;
+    auto lambda = [a] {
+      std::move(a);
+    };
+    a.foo();
+  }
+  // Warn if the use consists of a capture that happens after a move.
+  {
+    A a;
+    std::move(a);
+    auto lambda = [a]() { a.foo(); };
+    // CHECK-NOTES: [[@LINE-1]]:20: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // ...even if the capture was implicit.
+  {
+    A a;
+    std::move(a);
+    auto lambda = [=]() { a.foo(); };
+    // CHECK-NOTES: [[@LINE-1]]:20: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // Same tests but for capture by reference.
+  {
+    A a;
+    std::move(a);
+    auto lambda = [&a]() { a.foo(); };
+    // CHECK-NOTES: [[@LINE-1]]:21: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  {
+    A a;
+    std::move(a);
+    auto lambda = [&]() { a.foo(); };
+    // CHECK-NOTES: [[@LINE-1]]:20: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // But don't warn if the move happened after the capture.
+  {
+    A a;
+    auto lambda = [a]() { a.foo(); };
+    std::move(a);
+  }
+  // ...and again, same thing with an implicit move.
+  {
+    A a;
+    auto lambda = [=]() { a.foo(); };
+    std::move(a);
+  }
+  // Same tests but for capture by reference.
+  {
+    A a;
+    auto lambda = [&a]() { a.foo(); };
+    std::move(a);
+  }
+  {
+    A a;
+    auto lambda = [&]() { a.foo(); };
+    std::move(a);
+  }
+}
+
+// Use-after-moves are detected in uninstantiated templates if the moved type
+// is not a dependent type.
+template <class T>
+void movedTypeIsNotDependentType() {
+  T t;
+  A a;
+  std::move(a);
+  a.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+
+// And if the moved type is a dependent type, the use-after-move is detected if
+// the template is instantiated.
+template <class T>
+void movedTypeIsDependentType() {
+  T t;
+  std::move(t);
+  t.foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 't' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+template void movedTypeIsDependentType<A>();
+
+// We handle the case correctly where the move consists of an implicit call
+// to a conversion operator.
+void implicitConversionOperator() {
+  struct Convertible {
+    operator A() && { return A(); }
+  };
+  void takeA(A a);
+
+  Convertible convertible;
+  takeA(std::move(convertible));
+  convertible;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: 'convertible' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:9: note: move occurred here
+}
+
+// Using decltype on an expression is not a use.
+void decltypeIsNotUse() {
+  A a;
+  std::move(a);
+  decltype(a) other_a;
+}
+
+// Ignore moves or uses that occur as part of template arguments.
+template <int>
+class ClassTemplate {
+public:
+  void foo(A a);
+};
+template <int>
+void functionTemplate(A a);
+void templateArgIsNotUse() {
+  {
+    // A pattern like this occurs in the EXPECT_EQ and ASSERT_EQ macros in
+    // Google Test.
+    A a;
+    ClassTemplate<sizeof(A(std::move(a)))>().foo(std::move(a));
+  }
+  {
+    A a;
+    functionTemplate<sizeof(A(std::move(a)))>(std::move(a));
+  }
+}
+
+// Ignore moves of global variables.
+A global_a;
+void ignoreGlobalVariables() {
+  std::move(global_a);
+  global_a.foo();
+}
+
+// Ignore moves of member variables.
+class IgnoreMemberVariables {
+  A a;
+  static A static_a;
+
+  void f() {
+    std::move(a);
+    a.foo();
+
+    std::move(static_a);
+    static_a.foo();
+  }
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests involving control flow.
+
+void useAndMoveInLoop() {
+  // Warn about use-after-moves if they happen in a later loop iteration than
+  // the std::move().
+  {
+    A a;
+    for (int i = 0; i < 10; ++i) {
+      a.foo();
+      // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE+2]]:7: note: move occurred here
+      // CHECK-NOTES: [[@LINE-3]]:7: note: the use happens in a later loop
+      std::move(a);
+    }
+  }
+  // However, this case shouldn't be flagged -- the scope of the declaration of
+  // 'a' is important.
+  {
+    for (int i = 0; i < 10; ++i) {
+      A a;
+      a.foo();
+      std::move(a);
+    }
+  }
+  // Same as above, except that we have an unrelated variable being declared in
+  // the same declaration as 'a'. This case is interesting because it tests that
+  // the synthetic DeclStmts generated by the CFG are sequenced correctly
+  // relative to the other statements.
+  {
+    for (int i = 0; i < 10; ++i) {
+      A a, other;
+      a.foo();
+      std::move(a);
+    }
+  }
+  // Don't warn if we return after the move.
+  {
+    A a;
+    for (int i = 0; i < 10; ++i) {
+      a.foo();
+      if (a.getInt() > 0) {
+        std::move(a);
+        return;
+      }
+    }
+  }
+}
+
+void differentBranches(int i) {
+  // Don't warn if the use is in a different branch from the move.
+  {
+    A a;
+    if (i > 0) {
+      std::move(a);
+    } else {
+      a.foo();
+    }
+  }
+  // Same thing, but with a ternary operator.
+  {
+    A a;
+    i > 0 ? (void)std::move(a) : a.foo();
+  }
+  // A variation on the theme above.
+  {
+    A a;
+    a.getInt() > 0 ? a.getInt() : A(std::move(a)).getInt();
+  }
+  // Same thing, but with a switch statement.
+  {
+    A a;
+    switch (i) {
+    case 1:
+      std::move(a);
+      break;
+    case 2:
+      a.foo();
+      break;
+    }
+  }
+  // However, if there's a fallthrough, we do warn.
+  {
+    A a;
+    switch (i) {
+    case 1:
+      std::move(a);
+    case 2:
+      a.foo();
+      // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-4]]:7: note: move occurred here
+      break;
+    }
+  }
+}
+
+// False positive: A use-after-move is flagged even though the "if (b)" and
+// "if (!b)" are mutually exclusive.
+void mutuallyExclusiveBranchesFalsePositive(bool b) {
+  A a;
+  if (b) {
+    std::move(a);
+  }
+  if (!b) {
+    a.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-5]]:5: note: move occurred here
+  }
+}
+
+// Destructors marked [[noreturn]] are handled correctly in the control flow
+// analysis. (These are used in some styles of assertion macros.)
+class FailureLogger {
+public:
+  FailureLogger();
+  [[noreturn]] ~FailureLogger();
+  void log(const char *);
+};
+#define ASSERT(x) \
+  while (x)       \
+  FailureLogger().log(#x)
+bool operationOnA(A);
+void noreturnDestructor() {
+  A a;
+  // The while loop in the ASSERT() would ordinarily have the potential to cause
+  // a use-after-move because the second iteration of the loop would be using a
+  // variable that had been moved from in the first iteration. Check that the
+  // CFG knows that the second iteration of the loop is never reached because
+  // the FailureLogger destructor is marked [[noreturn]].
+  ASSERT(operationOnA(std::move(a)));
+}
+#undef ASSERT
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests for reinitializations
+
+template <class T>
+void swap(T &a, T &b) {
+  T tmp = std::move(a);
+  a = std::move(b);
+  b = std::move(tmp);
+}
+void assignments(int i) {
+  // Don't report a use-after-move if the variable was assigned to in the
+  // meantime.
+  {
+    A a;
+    std::move(a);
+    a = A();
+    a.foo();
+  }
+  // The assignment should also be recognized if move, assignment and use don't
+  // all happen in the same block (but the assignment is still guaranteed to
+  // prevent a use-after-move).
+  {
+    A a;
+    if (i == 1) {
+      std::move(a);
+      a = A();
+    }
+    if (i == 2) {
+      a.foo();
+    }
+  }
+  {
+    A a;
+    if (i == 1) {
+      std::move(a);
+    }
+    if (i == 2) {
+      a = A();
+      a.foo();
+    }
+  }
+  // The built-in assignment operator should also be recognized as a
+  // reinitialization. (std::move() may be called on built-in types in template
+  // code.)
+  {
+    int a1 = 1, a2 = 2;
+    swap(a1, a2);
+  }
+  // A std::move() after the assignment makes the variable invalid again.
+  {
+    A a;
+    std::move(a);
+    a = A();
+    std::move(a);
+    a.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // Report a use-after-move if we can't be sure that the variable was assigned
+  // to.
+  {
+    A a;
+    std::move(a);
+    if (i < 10) {
+      a = A();
+    }
+    if (i > 5) {
+      a.foo();
+      // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-7]]:5: note: move occurred here
+    }
+  }
+}
+
+// Passing the object to a function through a non-const pointer or reference
+// counts as a re-initialization.
+void passByNonConstPointer(A *);
+void passByNonConstReference(A &);
+void passByNonConstPointerIsReinit() {
+  {
+    A a;
+    std::move(a);
+    passByNonConstPointer(&a);
+    a.foo();
+  }
+  {
+    A a;
+    std::move(a);
+    passByNonConstReference(a);
+    a.foo();
+  }
+}
+
+// Passing the object through a const pointer or reference counts as a use --
+// since the called function cannot reinitialize the object.
+void passByConstPointer(const A *);
+void passByConstReference(const A &);
+void passByConstPointerIsUse() {
+  {
+    // Declaring 'a' as const so that no ImplicitCastExpr is inserted into the
+    // AST -- we wouldn't want the check to rely solely on that to detect a
+    // const pointer argument.
+    const A a;
+    std::move(a);
+    passByConstPointer(&a);
+    // CHECK-NOTES: [[@LINE-1]]:25: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  const A a;
+  std::move(a);
+  passByConstReference(a);
+  // CHECK-NOTES: [[@LINE-1]]:24: warning: 'a' used after it was moved
+  // CHECK-NOTES: [[@LINE-3]]:3: note: move occurred here
+}
+
+// Clearing a standard container using clear() is treated as a
+// re-initialization.
+void standardContainerClearIsReinit() {
+  {
+    std::string container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::vector<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+
+    auto container2 = container;
+    std::move(container2);
+    container2.clear();
+    container2.empty();
+  }
+  {
+    std::deque<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::forward_list<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::list<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::set<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::map<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::multiset<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::multimap<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::unordered_set<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::unordered_map<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::unordered_multiset<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  {
+    std::unordered_multimap<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  // This should also work for typedefs of standard containers.
+  {
+    typedef std::vector<int> IntVector;
+    IntVector container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  // But it shouldn't work for non-standard containers.
+  {
+    // This might be called "vector", but it's not in namespace "std".
+    struct vector {
+      void clear() {}
+    } container;
+    std::move(container);
+    container.clear();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container' used after it was
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // An intervening clear() on a different container does not reinitialize.
+  {
+    std::vector<int> container1, container2;
+    std::move(container1);
+    container2.clear();
+    container1.empty();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container1' used after it was
+    // CHECK-NOTES: [[@LINE-4]]:5: note: move occurred here
+  }
+}
+
+// Clearing a standard container using assign() is treated as a
+// re-initialization.
+void standardContainerAssignIsReinit() {
+  {
+    std::string container;
+    std::move(container);
+    container.assign(0, ' ');
+    container.empty();
+  }
+  {
+    std::vector<int> container;
+    std::move(container);
+    container.assign(0, 0);
+    container.empty();
+  }
+  {
+    std::deque<int> container;
+    std::move(container);
+    container.assign(0, 0);
+    container.empty();
+  }
+  {
+    std::forward_list<int> container;
+    std::move(container);
+    container.assign(0, 0);
+    container.empty();
+  }
+  {
+    std::list<int> container;
+    std::move(container);
+    container.clear();
+    container.empty();
+  }
+  // But it doesn't work for non-standard containers.
+  {
+    // This might be called "vector", but it's not in namespace "std".
+    struct vector {
+      void assign(std::size_t, int) {}
+    } container;
+    std::move(container);
+    container.assign(0, 0);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container' used after it was
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  // An intervening assign() on a different container does not reinitialize.
+  {
+    std::vector<int> container1, container2;
+    std::move(container1);
+    container2.assign(0, 0);
+    container1.empty();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'container1' used after it was
+    // CHECK-NOTES: [[@LINE-4]]:5: note: move occurred here
+  }
+}
+
+// Resetting the standard smart pointer types using reset() is treated as a
+// re-initialization. (We don't test std::weak_ptr<> because it can't be
+// dereferenced directly.)
+void standardSmartPointerResetIsReinit() {
+  {
+    std::unique_ptr<A> ptr;
+    std::move(ptr);
+    ptr.reset(new A);
+    *ptr;
+  }
+  {
+    std::shared_ptr<A> ptr;
+    std::move(ptr);
+    ptr.reset(new A);
+    *ptr;
+  }
+}
+
+void reinitAnnotation() {
+  {
+    AnnotatedContainer<int> obj;
+    std::move(obj);
+    obj.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'obj' used after it was
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  {
+    AnnotatedContainer<int> obj;
+    std::move(obj);
+    obj.clear();
+    obj.foo();
+  }
+  {
+    // Calling clear() on a different object to the one that was moved is not
+    // considered a reinitialization.
+    AnnotatedContainer<int> obj1, obj2;
+    std::move(obj1);
+    obj2.clear();
+    obj1.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'obj1' used after it was
+    // CHECK-NOTES: [[@LINE-4]]:5: note: move occurred here
+  }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Tests related to order of evaluation within expressions
+
+// Relative sequencing of move and use.
+void passByRvalueReference(int i, A &&a);
+void passByValue(int i, A a);
+void passByValue(A a, int i);
+A g(A, A &&);
+int intFromA(A &&);
+int intFromInt(int);
+void sequencingOfMoveAndUse() {
+  // This case is fine because the move only happens inside
+  // passByRvalueReference(). At this point, a.getInt() is guaranteed to have
+  // been evaluated.
+  {
+    A a;
+    passByRvalueReference(a.getInt(), std::move(a));
+  }
+  // However, if we pass by value, the move happens when the move constructor is
+  // called to create a temporary, and this happens before the call to
+  // passByValue(). Because the order in which arguments are evaluated isn't
+  // defined, the move may happen before the call to a.getInt().
+  //
+  // Check that we warn about a potential use-after move for both orderings of
+  // a.getInt() and std::move(a), independent of the order in which the
+  // arguments happen to get evaluated by the compiler.
+  {
+    A a;
+    passByValue(a.getInt(), std::move(a));
+    // CHECK-NOTES: [[@LINE-1]]:17: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:29: note: move occurred here
+    // CHECK-NOTES: [[@LINE-3]]:17: note: the use and move are unsequenced
+  }
+  {
+    A a;
+    passByValue(std::move(a), a.getInt());
+    // CHECK-NOTES: [[@LINE-1]]:31: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:17: note: move occurred here
+    // CHECK-NOTES: [[@LINE-3]]:31: note: the use and move are unsequenced
+  }
+  // An even more convoluted example.
+  {
+    A a;
+    g(g(a, std::move(a)), g(a, std::move(a)));
+    // CHECK-NOTES: [[@LINE-1]]:9: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:27: note: move occurred here
+    // CHECK-NOTES: [[@LINE-3]]:9: note: the use and move are unsequenced
+    // CHECK-NOTES: [[@LINE-4]]:29: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-5]]:7: note: move occurred here
+    // CHECK-NOTES: [[@LINE-6]]:29: note: the use and move are unsequenced
+  }
+  // This case is fine because the actual move only happens inside the call to
+  // operator=(). a.getInt(), by necessity, is evaluated before that call.
+  {
+    A a;
+    A vec[1];
+    vec[a.getInt()] = std::move(a);
+  }
+  // However, in the following case, the move happens before the assignment, and
+  // so the order of evaluation is not guaranteed.
+  {
+    A a;
+    int v[3];
+    v[a.getInt()] = intFromA(std::move(a));
+    // CHECK-NOTES: [[@LINE-1]]:7: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:21: note: move occurred here
+    // CHECK-NOTES: [[@LINE-3]]:7: note: the use and move are unsequenced
+  }
+  {
+    A a;
+    int v[3];
+    v[intFromA(std::move(a))] = intFromInt(a.i);
+    // CHECK-NOTES: [[@LINE-1]]:44: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:7: note: move occurred here
+    // CHECK-NOTES: [[@LINE-3]]:44: note: the use and move are unsequenced
+  }
+}
+
+// Relative sequencing of move and reinitialization. If the two are unsequenced,
+// we conservatively assume that the move happens after the reinitialization,
+// i.e. the that object does not get reinitialized after the move.
+A MutateA(A a);
+void passByValue(A a1, A a2);
+void sequencingOfMoveAndReinit() {
+  // Move and reinitialization as function arguments (which are indeterminately
+  // sequenced). Again, check that we warn for both orderings.
+  {
+    A a;
+    passByValue(std::move(a), (a = A()));
+    a.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:17: note: move occurred here
+  }
+  {
+    A a;
+    passByValue((a = A()), std::move(a));
+    a.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:28: note: move occurred here
+  }
+  // Common usage pattern: Move the object to a function that mutates it in some
+  // way, then reassign the result to the object. This pattern is fine.
+  {
+    A a;
+    a = MutateA(std::move(a));
+    a.foo();
+  }
+}
+
+// Relative sequencing of reinitialization and use. If the two are unsequenced,
+// we conservatively assume that the reinitialization happens after the use,
+// i.e. that the object is not reinitialized at the point in time when it is
+// used.
+void sequencingOfReinitAndUse() {
+  // Reinitialization and use in function arguments. Again, check both possible
+  // orderings.
+  {
+    A a;
+    std::move(a);
+    passByValue(a.getInt(), (a = A()));
+    // CHECK-NOTES: [[@LINE-1]]:17: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+  {
+    A a;
+    std::move(a);
+    passByValue((a = A()), a.getInt());
+    // CHECK-NOTES: [[@LINE-1]]:28: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:5: note: move occurred here
+  }
+}
+
+// The comma operator sequences its operands.
+void commaOperatorSequences() {
+  {
+    A a;
+    A(std::move(a))
+    , (a = A());
+    a.foo();
+  }
+  {
+    A a;
+    (a = A()), A(std::move(a));
+    a.foo();
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-3]]:16: note: move occurred here
+  }
+}
+
+// An initializer list sequences its initialization clauses.
+void initializerListSequences() {
+  {
+    struct S1 {
+      int i;
+      A a;
+    };
+    A a;
+    S1 s1{a.getInt(), std::move(a)};
+  }
+  {
+    struct S2 {
+      A a;
+      int i;
+    };
+    A a;
+    S2 s2{std::move(a), a.getInt()};
+    // CHECK-NOTES: [[@LINE-1]]:25: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:11: note: move occurred here
+  }
+}
+
+// A declaration statement containing multiple declarations sequences the
+// initializer expressions.
+void declarationSequences() {
+  {
+    A a;
+    A a1 = a, a2 = std::move(a);
+  }
+  {
+    A a;
+    A a1 = std::move(a), a2 = a;
+    // CHECK-NOTES: [[@LINE-1]]:31: warning: 'a' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:12: note: move occurred here
+  }
+}
+
+// The logical operators && and || sequence their operands.
+void logicalOperatorsSequence() {
+  {
+    A a;
+    if (a.getInt() > 0 && A(std::move(a)).getInt() > 0) {
+      A().foo();
+    }
+  }
+  // A variation: Negate the result of the && (which pushes the && further down
+  // into the AST).
+  {
+    A a;
+    if (!(a.getInt() > 0 && A(std::move(a)).getInt() > 0)) {
+      A().foo();
+    }
+  }
+  {
+    A a;
+    if (A(std::move(a)).getInt() > 0 && a.getInt() > 0) {
+      // CHECK-NOTES: [[@LINE-1]]:41: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-2]]:9: note: move occurred here
+      A().foo();
+    }
+  }
+  {
+    A a;
+    if (a.getInt() > 0 || A(std::move(a)).getInt() > 0) {
+      A().foo();
+    }
+  }
+  {
+    A a;
+    if (A(std::move(a)).getInt() > 0 || a.getInt() > 0) {
+      // CHECK-NOTES: [[@LINE-1]]:41: warning: 'a' used after it was moved
+      // CHECK-NOTES: [[@LINE-2]]:9: note: move occurred here
+      A().foo();
+    }
+  }
+}
+
+// A range-based for sequences the loop variable declaration before the body.
+void forRangeSequences() {
+  A v[2] = {A(), A()};
+  for (A &a : v) {
+    std::move(a);
+  }
+}
+
+// If a variable is declared in an if, while or switch statement, the init
+// statement (for if and switch) is sequenced before the variable declaration,
+// which in turn is sequenced before the evaluation of the condition. We place
+// all tests inside a for loop to ensure that the checker understands the
+// sequencing. If it didn't, then the loop would trigger the "moved twice"
+// logic.
+void ifWhileAndSwitchSequenceInitDeclAndCondition() {
+  for (int i = 0; i < 10; ++i) {
+    A a1;
+    if (A a2 = std::move(a1)) {
+      std::move(a2);
+    }
+  }
+  for (int i = 0; i < 10; ++i) {
+    A a1;
+    if (A a2 = std::move(a1); a2) {
+      std::move(a2);
+    }
+  }
+  for (int i = 0; i < 10; ++i) {
+    A a1;
+    if (A a2 = std::move(a1); A a3 = std::move(a2)) {
+      std::move(a3);
+    }
+  }
+  for (int i = 0; i < 10; ++i) {
+    // init followed by condition with move, but without variable declaration.
+    if (A a1; A(std::move(a1)).getInt() > 0) {}
+  }
+  for (int i = 0; i < 10; ++i) {
+    if (A a1; A(std::move(a1)).getInt() > a1.getInt()) {}
+    // CHECK-NOTES: [[@LINE-1]]:43: warning: 'a1' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:15: note: move occurred here
+    // CHECK-NOTES: [[@LINE-3]]:43: note: the use and move are unsequenced
+  }
+  for (int i = 0; i < 10; ++i) {
+    A a1;
+    if (A a2 = std::move(a1); A(a1) > 0) {}
+    // CHECK-NOTES: [[@LINE-1]]:33: warning: 'a1' used after it was moved
+    // CHECK-NOTES: [[@LINE-2]]:16: note: move occurred here
+  }
+  while (A a = A()) {
+    std::move(a);
+  }
+  for (int i = 0; i < 10; ++i) {
+    A a1;
+    switch (A a2 = std::move(a1); a2) {
+      case true:
+        std::move(a2);
+    }
+  }
+  for (int i = 0; i < 10; ++i) {
+    A a1;
+    switch (A a2 = a1; A a3 = std::move(a2)) {
+      case true:
+        std::move(a3);
+    }
+  }
+}
+
+// Some statements in templates (e.g. null, break and continue statements) may
+// be shared between the uninstantiated and instantiated versions of the
+// template and therefore have multiple parents. Make sure the sequencing code
+// handles this correctly.
+template <class> void nullStatementSequencesInTemplate() {
+  int c = 0;
+  (void)c;
+  ;
+  std::move(c);
+}
+template void nullStatementSequencesInTemplate<int>();
+
+namespace PR33020 {
+class D {
+  ~D();
+};
+struct A {
+  D d;
+};
+class B {
+  A a;
+};
+template <typename T>
+class C : T, B {
+  void m_fn1() {
+    int a;
+    std::move(a);
+    C c;
+  }
+};
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/bugprone-virtual-near-miss.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,133 @@
+// RUN: %check_clang_tidy %s bugprone-virtual-near-miss %t
+
+class NoDefinedClass1;
+class NoDefinedClass2;
+
+struct Base {
+  virtual void func();
+  virtual void gunk();
+  virtual ~Base();
+  virtual Base &operator=(const Base &);
+  virtual NoDefinedClass1 *f();
+};
+
+struct Derived : Base {
+  // Should not warn "do you want to override 'gunk'?", because gunk is already
+  // overriden by this class.
+  virtual void funk();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::funk' has a similar name and the same signature as virtual method 'Base::func'; did you mean to override it? [bugprone-virtual-near-miss]
+  // CHECK-FIXES: virtual void func();
+
+  void func2();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::func2' has {{.*}} 'Base::func'
+  // CHECK-FIXES: void func();
+
+  void func22(); // Should not warn.
+
+  void gunk(); // Should not warn: gunk is override.
+
+  void fun();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Derived::fun' has {{.*}} 'Base::func'
+  // CHECK-FIXES: void func();
+
+  Derived &operator==(const Base &); // Should not warn: operators are ignored.
+
+  virtual NoDefinedClass2 *f1(); // Should not crash: non-defined class return type is ignored.
+};
+
+template <typename T>
+struct TBase {
+  virtual void tfunc(T t);
+};
+
+template <typename T>
+struct TDerived : TBase<T> {
+  virtual void tfunk(T t);
+  // Should not apply fix for template.
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: method 'TDerived<double>::tfunk' has {{.*}} 'TBase<double>::tfunc'
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: method 'TDerived<int>::tfunk' has {{.*}} 'TBase<int>::tfunc'
+  // CHECK-FIXES: virtual void tfunk(T t);
+};
+
+TDerived<int> T1;
+TDerived<double> T2;
+
+// Should not fix macro definition
+#define MACRO1 void funcM()
+// CHECK-FIXES: #define MACRO1 void funcM()
+#define MACRO2(m) void m()
+// CHECK-FIXES: #define MACRO2(m) void m()
+
+struct DerivedMacro : Base {
+  MACRO1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::funcM' has {{.*}} 'Base::func'
+  // CHECK-FIXES: MACRO1;
+
+  MACRO2(func3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'DerivedMacro::func3' has {{.*}} 'Base::func'
+  // CHECK-FIXES: MACRO2(func);
+};
+
+typedef Derived derived_type;
+
+class Father {
+public:
+  Father();
+  virtual void func();
+  virtual Father *create(int i);
+  virtual Base &&generate();
+  virtual Base *canonical(Derived D);
+};
+
+class Mother {
+public:
+  Mother();
+  static void method();
+  virtual int method(int argc, const char **argv);
+  virtual int method(int argc) const;
+  virtual int decay(const char *str);
+};
+
+class Child : private Father, private Mother {
+public:
+  Child();
+
+  virtual void func2();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::func2' has {{.*}} 'Father::func'
+  // CHECK-FIXES: virtual void func();
+
+  int methoe(int x, char **strs); // Should not warn: parameter types don't match.
+
+  int methoe(int x);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoe' has {{.*}} 'Mother::method'
+  // CHECK-FIXES: int method(int x);
+
+  void methof(int x, const char **strs); // Should not warn: return types don't match.
+
+  int methoh(int x, const char **strs);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::methoh' has {{.*}} 'Mother::method'
+  // CHECK-FIXES: int method(int x, const char **strs);
+
+  virtual Child *creat(int i);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::creat' has {{.*}} 'Father::create'
+  // CHECK-FIXES: virtual Child *create(int i);
+
+  virtual Derived &&generat();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::generat' has {{.*}} 'Father::generate'
+  // CHECK-FIXES: virtual Derived &&generate();
+
+  int decaz(const char str[]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::decaz' has {{.*}} 'Mother::decay'
+  // CHECK-FIXES: int decay(const char str[]);
+
+  operator bool();
+
+  derived_type *canonica(derived_type D);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::canonica' has {{.*}} 'Father::canonical'
+  // CHECK-FIXES: derived_type *canonical(derived_type D);
+
+private:
+  void funk();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: method 'Child::funk' has {{.*}} 'Father::func'
+  // CHECK-FIXES: void func();
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl21-cpp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl21-cpp.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl21-cpp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl21-cpp.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,134 @@
+// RUN: %check_clang_tidy %s cert-dcl21-cpp %t
+
+class A {};
+
+A operator++(A &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a non-constant object instead of a constant object type [cert-dcl21-cpp]
+// CHECK-FIXES: {{^}}const A operator++(A &, int);
+
+A operator--(A &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a no
+// CHECK-FIXES: {{^}}const A operator--(A &, int);
+
+class B {};
+
+B &operator++(B &);
+const B operator++(B &, int);
+
+B &operator--(B &);
+const B operator--(B &, int);
+
+
+class D {
+D &operator++();
+const D operator++(int);
+
+D &operator--();
+const D operator--(int);
+};
+
+class C {
+C operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a no
+// CHECK-FIXES: {{^}}const C operator++(int);
+
+C operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a no
+// CHECK-FIXES: {{^}}const C operator--(int);
+};
+
+class E {};
+
+E &operator++(E &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a reference instead of a constant object type [cert-dcl21-cpp]
+// CHECK-FIXES: {{^}}const E operator++(E &, int);
+
+E &operator--(E &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const E operator--(E &, int);
+
+class G {
+G &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const G operator++(int);
+
+G &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const G operator--(int);
+};
+
+class F {};
+
+const F &operator++(F &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const F operator++(F &, int);
+
+const F &operator--(F &, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const F operator--(F &, int);
+
+class H {
+const H &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const H operator++(int);
+
+const H &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const H operator--(int);
+};
+
+
+#define FROM_MACRO P&
+class P {
+const FROM_MACRO operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const FROM_MACRO operator++(int);
+};
+
+
+template<typename T>
+class Q {
+const Q &operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}const Q<T> operator++(int);
+
+const Q &operator--(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: overloaded 'operator--' returns a re
+// CHECK-FIXES: {{^}}const Q<T> operator--(int);
+};
+
+void foobar() {
+  Q<int> a;
+  Q<float> b;
+  (void)a;
+  (void)b;
+}
+
+struct S {};
+typedef S& SRef;
+
+SRef operator++(SRef, int);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}SRef operator++(SRef, int);
+
+struct T {
+  typedef T& TRef;
+  
+  TRef operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}  TRef operator++(int);
+};
+
+struct U {
+  typedef const U& ConstURef;
+  
+  ConstURef& operator++(int);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: overloaded 'operator++' returns a re
+// CHECK-FIXES: {{^}}  ConstURef& operator++(int);
+};
+
+struct V {
+  V *operator++(int);
+  V *const operator--(int);
+};
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl58-cpp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl58-cpp.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl58-cpp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-dcl58-cpp.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,67 @@
+// RUN: %check_clang_tidy %s cert-dcl58-cpp %t -- -- -std=c++1z -I %S/Inputs/Headers
+
+#include "system-header-simulation.h"
+
+namespace A {
+  namespace B {
+    int b;
+  }
+}
+
+namespace A {
+  namespace B {
+    int c;
+  }
+}
+
+namespace posix {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'posix' namespace can result in undefined behavior [cert-dcl58-cpp]
+  namespace vmi {
+  }
+}
+
+namespace std {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'std' namespace can
+  int stdInt;
+}
+
+namespace foobar {
+  namespace std {
+    int bar;
+  }
+}
+
+namespace posix::a {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'posix' namespace 
+}
+
+enum class MyError {
+  ErrorA,
+  ErrorB
+};
+
+namespace std {
+template <>
+struct is_error_code_enum<MyError> : std::true_type {};
+
+template<>
+void swap<MyError>(MyError &a, MyError &b);
+}
+
+enum class MyError2 {
+  Error2A,
+  Error2B
+};
+
+namespace std {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: modification of 'std' namespace 
+template <>
+struct is_error_code_enum<MyError2> : std::true_type {};
+
+int foobar;
+}
+
+using namespace std;
+
+int x;
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-env33-c.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-env33-c.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-env33-c.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-env33-c.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s cert-env33-c %t
+
+typedef struct FILE {} FILE;
+
+extern int system(const char *);
+extern FILE *popen(const char *, const char *);
+extern FILE *_popen(const char *, const char *);
+
+void f(void) {
+  // It is permissible to check for the presence of a command processor.
+  system(0);
+
+  system("test");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'system' uses a command processor [cert-env33-c]
+
+  popen("test", "test");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling 'popen' uses a command processor
+  _popen("test", "test");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling '_popen' uses a command processor
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,103 @@
+// RUN: %check_clang_tidy %s cert-err34-c %t -- -- -std=c11
+
+typedef __SIZE_TYPE__      size_t;
+typedef signed             ptrdiff_t;
+typedef long long          intmax_t;
+typedef unsigned long long uintmax_t;
+typedef void *             FILE;
+
+extern FILE *stdin;
+
+extern int fscanf(FILE * restrict stream, const char * restrict format, ...);
+extern int scanf(const char * restrict format, ...);
+extern int sscanf(const char * restrict s, const char * restrict format, ...);
+
+extern double atof(const char *nptr);
+extern int atoi(const char *nptr);
+extern long int atol(const char *nptr);
+extern long long int atoll(const char *nptr);
+
+void f1(const char *in) {
+  int i;
+  long long ll;
+  unsigned int ui;
+  unsigned long long ull;
+  intmax_t im;
+  uintmax_t uim;
+  float f;
+  double d;
+  long double ld;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+  sscanf(in, "%d", &i);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+  fscanf(stdin, "%lld", &ll);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoul' instead [cert-err34-c]
+  sscanf(in, "%u", &ui);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoull' instead [cert-err34-c]
+  fscanf(stdin, "%llu", &ull);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoimax' instead [cert-err34-c]
+  scanf("%jd", &im);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an unsigned integer value, but function will not report conversion errors; consider using 'strtoumax' instead [cert-err34-c]
+  fscanf(stdin, "%ju", &uim);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtof' instead [cert-err34-c]
+  sscanf(in, "%f", &f); // to float
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
+  fscanf(stdin, "%lg", &d);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtold' instead [cert-err34-c]
+  sscanf(in, "%Le", &ld);
+
+  // These are conversions with other modifiers
+  short s;
+  char c;
+  size_t st;
+  ptrdiff_t pt;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%hhd", &c);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%hd", &s);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%zu", &st);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%td", &pt);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%o", ui);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%X", ui);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%x", ui);
+}
+
+void f2(const char *in) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+  int i = atoi(in); // to int
+  // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+  long l = atol(in); // to long
+  // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+  long long ll = atoll(in); // to long long
+  // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
+  double d = atof(in); // to double
+}
+
+void f3(void) {
+  int i;
+  unsigned int u;
+  float f;
+  char str[32];
+
+  // Test that we don't report multiple infractions for a single call.
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%d%u%f", &i, &u, &f);
+
+  // Test that we still catch infractions that are not the first specifier.
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'scanf' used to convert
+  scanf("%s%d", str, &i);
+}
+
+void do_not_diagnose(void) {
+  char str[32];
+
+  scanf("%s", str); // Not a numerical conversion
+  scanf("%*d"); // Assignment suppressed
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-err34-c.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,43 @@
+// RUN: %check_clang_tidy %s cert-err34-c %t
+
+typedef void *             FILE;
+
+extern FILE *stdin;
+
+extern int fscanf(FILE * stream, const char * format, ...);
+extern int sscanf(const char * s, const char * format, ...);
+
+extern double atof(const char *nptr);
+extern int atoi(const char *nptr);
+extern long int atol(const char *nptr);
+extern long long int atoll(const char *nptr);
+
+namespace std {
+using ::FILE; using ::stdin;
+using ::fscanf; using ::sscanf;
+using ::atof; using ::atoi; using ::atol; using ::atoll;
+}
+
+void f1(const char *in) {
+  int i;
+  long long ll;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'sscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+  std::sscanf(in, "%d", &i);
+  // CHECK-MESSAGES: :[[@LINE+1]]:3: warning: 'fscanf' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+  std::fscanf(std::stdin, "%lld", &ll);
+}
+
+void f2(const char *in) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:11: warning: 'atoi' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+  int i = std::atoi(in); // to int
+  // CHECK-MESSAGES: :[[@LINE+1]]:12: warning: 'atol' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtol' instead [cert-err34-c]
+  long l = std::atol(in); // to long
+
+  using namespace std;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'atoll' used to convert a string to an integer value, but function will not report conversion errors; consider using 'strtoll' instead [cert-err34-c]
+  long long ll = atoll(in); // to long long
+  // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: 'atof' used to convert a string to a floating-point value, but function will not report conversion errors; consider using 'strtod' instead [cert-err34-c]
+  double d = atof(in); // to double
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-flp30-c.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-flp30-c.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-flp30-c.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-flp30-c.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy %s cert-flp30-c %t
+
+float g(void);
+
+void func(void) {
+  for (float x = 0.1f; x <= 1.0f; x += 0.1f) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:37: warning: loop induction expression should not have floating-point type [cert-flp30-c]
+
+  float f = 1.0f;
+  for (; f > 0; --f) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: loop induction expression
+
+  for (;;g()) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: loop induction expression
+
+  for (int i = 0; i < 10; i += 1.0f) {}
+
+  for (int i = 0; i < 10; ++i) {}
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s cert-msc30-c %t
+
+extern int rand(void);
+int nonrand();
+
+int cTest() {
+  int i = rand();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness [cert-msc30-c]
+
+  int k = nonrand();
+
+  return 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-limited-randomness.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s cert-msc50-cpp %t
+
+int rand();
+int rand(int);
+
+namespace std {
+using ::rand;
+}
+
+namespace nonstd {
+  int rand();
+}
+
+void testFunction1() {
+  int i = std::rand();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness; use C++11 random library instead [cert-msc50-cpp]
+
+  int j = ::rand();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness; use C++11 random library instead [cert-msc50-cpp]
+
+  int k = rand(i);
+
+  int l = nonstd::rand();
+
+  int m = rand();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: rand() has limited randomness; use C++11 random library instead [cert-msc50-cpp]
+}
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc32-c.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc32-c.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc32-c.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc32-c.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,27 @@
+// RUN: %check_clang_tidy %s cert-msc32-c %t -- -config="{CheckOptions: [{key: cert-msc32-c.DisallowedSeedTypes, value: 'some_type,time_t'}]}" -- -std=c99
+
+void srand(int seed);
+typedef int time_t;
+time_t time(time_t *t);
+
+void f() {
+  srand(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc32-c]
+
+  const int a = 1;
+  srand(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc32-c]
+
+  time_t t;
+  srand(time(&t)); // Disallowed seed type
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc32-c]
+}
+
+void g() {
+  typedef int user_t;
+  user_t a = 1;
+  srand(a);
+
+  int b = 1;
+  srand(b); // Can not evaluate as int
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc51-cpp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc51-cpp.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc51-cpp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-msc51-cpp.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,211 @@
+// RUN: %check_clang_tidy %s cert-msc51-cpp %t -- \
+// RUN:     -config="{CheckOptions: [{key: cert-msc51-cpp.DisallowedSeedTypes, value: 'some_type,time_t'}]}"
+
+namespace std {
+
+void srand(int seed);
+
+template <class UIntType, UIntType a, UIntType c, UIntType m>
+struct linear_congruential_engine {
+  linear_congruential_engine(int _ = 0);
+  void seed(int _ = 0);
+};
+using default_random_engine = linear_congruential_engine<unsigned int, 1, 2, 3>;
+
+using size_t = int;
+template <class UIntType, size_t w, size_t n, size_t m, size_t r,
+          UIntType a, size_t u, UIntType d, size_t s,
+          UIntType b, size_t t,
+          UIntType c, size_t l, UIntType f>
+struct mersenne_twister_engine {
+  mersenne_twister_engine(int _ = 0);
+  void seed(int _ = 0);
+};
+using mt19937 = mersenne_twister_engine<unsigned int, 32, 624, 397, 21, 0x9908b0df, 11, 0xffffffff, 7, 0x9d2c5680, 15, 0xefc60000, 18, 1812433253>;
+
+template <class UIntType, size_t w, size_t s, size_t r>
+struct subtract_with_carry_engine {
+  subtract_with_carry_engine(int _ = 0);
+  void seed(int _ = 0);
+};
+using ranlux24_base = subtract_with_carry_engine<unsigned int, 24, 10, 24>;
+
+template <class Engine, size_t p, size_t r>
+struct discard_block_engine {
+  discard_block_engine();
+  discard_block_engine(int _);
+  void seed();
+  void seed(int _);
+};
+using ranlux24 = discard_block_engine<ranlux24_base, 223, 23>;
+
+template <class Engine, size_t w, class UIntType>
+struct independent_bits_engine {
+  independent_bits_engine();
+  independent_bits_engine(int _);
+  void seed();
+  void seed(int _);
+};
+using independent_bits = independent_bits_engine<ranlux24_base, 223, int>;
+
+template <class Engine, size_t k>
+struct shuffle_order_engine {
+  shuffle_order_engine();
+  shuffle_order_engine(int _);
+  void seed();
+  void seed(int _);
+};
+using shuffle_order = shuffle_order_engine<ranlux24_base, 223>;
+
+struct random_device {
+  random_device();
+  int operator()();
+};
+} // namespace std
+
+using time_t = unsigned int;
+time_t time(time_t *t);
+
+void f() {
+  const int seed = 2;
+  time_t t;
+
+  std::srand(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::srand(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::srand(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  // One instantiation for every engine
+  std::default_random_engine engine1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::default_random_engine engine2(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::default_random_engine engine3(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::default_random_engine engine4(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine1.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  std::mt19937 engine5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::mt19937 engine6(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::mt19937 engine7(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::mt19937 engine8(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine5.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine5.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine5.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine5.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  std::ranlux24_base engine9;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::ranlux24_base engine10(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::ranlux24_base engine11(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::ranlux24_base engine12(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine9.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine9.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine9.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine9.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  std::ranlux24 engine13;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::ranlux24 engine14(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::ranlux24 engine15(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::ranlux24 engine16(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine13.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine13.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine13.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine13.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  std::independent_bits engine17;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::independent_bits engine18(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::independent_bits engine19(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::independent_bits engine20(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine17.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine17.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine17.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine17.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+
+  std::shuffle_order engine21;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  std::shuffle_order engine22(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::shuffle_order engine23(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  std::shuffle_order engine24(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine21.seed();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a default argument will generate a predictable sequence of values [cert-msc51-cpp]
+  engine21.seed(1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine21.seed(seed);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a constant value will generate a predictable sequence of values [cert-msc51-cpp]
+  engine21.seed(time(&t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: random number generator seeded with a disallowed source of seed value will generate a predictable sequence of values [cert-msc51-cpp]
+}
+
+struct A {
+  A(int _ = 0);
+  void seed(int _ = 0);
+};
+
+void g() {
+  int n = 1;
+  std::default_random_engine engine1(n);
+  std::mt19937 engine2(n);
+  std::ranlux24_base engine3(n);
+  std::ranlux24 engine4(n);
+  std::independent_bits engine5(n);
+  std::shuffle_order engine6(n);
+
+  std::random_device dev;
+  std::default_random_engine engine7(dev());
+  std::mt19937 engine8(dev());
+  std::ranlux24_base engine9(dev());
+  std::ranlux24 engine10(dev());
+  std::independent_bits engine11(dev());
+  std::shuffle_order engine12(dev());
+
+  A a1;
+  A a2(1);
+  a1.seed();
+  a1.seed(1);
+  a1.seed(n);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop11-cpp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop11-cpp.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop11-cpp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop11-cpp.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,21 @@
+// RUN: %check_clang_tidy %s cert-oop11-cpp %t
+
+struct B {
+  B(B&&) noexcept = default;
+
+  B(const B &) = default;
+  B& operator=(const B&) = default;
+  ~B() {}
+};
+
+struct D {
+  B b;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:14: warning: move constructor initializes class member by calling a copy constructor [cert-oop11-cpp]
+  D(D &&d) : b(d.b) {}
+
+  // This should not produce a diagnostic because it is not covered under
+  // the CERT guideline for OOP11-CPP. However, this will produce a diagnostic
+  // under performance-move-constructor-init.
+  D(B b) : b(b) {}
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop54-cpp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop54-cpp.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop54-cpp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-oop54-cpp.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,16 @@
+// RUN: %check_clang_tidy %s cert-oop54-cpp %t
+
+// Test whether bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField option is set correctly.
+class TrivialFields {
+public:
+  TrivialFields &operator=(const TrivialFields &object) {
+    // CHECK-MESSAGES: [[@LINE-1]]:18: warning: operator=() does not handle self-assignment properly [cert-oop54-cpp]
+    return *this;
+  }
+
+private:
+  int m;
+  float f;
+  double d;
+  bool b;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-setlongjmp.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-setlongjmp.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-setlongjmp.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-setlongjmp.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s cert-err52-cpp %t
+
+typedef void *jmp_buf;
+extern int __setjmpimpl(jmp_buf);
+#define setjmp(x) __setjmpimpl(x)
+[[noreturn]] extern void longjmp(jmp_buf, int);
+
+namespace std {
+using ::jmp_buf;
+using ::longjmp;
+}
+
+static jmp_buf env;
+void g() {
+  std::longjmp(env, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead [cert-err52-cpp]
+  ::longjmp(env, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
+  longjmp(env, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call 'longjmp'; consider using exception handling instead
+}
+
+void f() {
+  (void)setjmp(env);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not call 'setjmp'; consider using exception handling instead
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-static-object-exception.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-static-object-exception.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-static-object-exception.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-static-object-exception.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,275 @@
+// RUN: clang-tidy %s -checks="-*,cert-err58-cpp" -- -std=c++17 -target x86_64-pc-linux-gnu \
+// RUN:   | FileCheck %s -check-prefix=CHECK-EXCEPTIONS \
+// RUN:   -implicit-check-not="{{warning|error}}:"
+// RUN: clang-tidy %s -checks="-*,cert-err58-cpp" -- -DNONEXCEPTIONS -fno-exceptions -std=c++17 -target x86_64-pc-linux-gnu \
+// RUN:   | FileCheck %s -allow-empty -check-prefix=CHECK-NONEXCEPTIONS \
+// RUN:   -implicit-check-not="{{warning|error}}:"
+
+struct S {
+  S() noexcept(false);
+};
+
+struct T {
+  T() noexcept;
+};
+
+struct U {
+  U() {}
+};
+
+struct V {
+  explicit V(const char *) {} // Can throw
+};
+
+struct Cleanup {
+  ~Cleanup() {}
+};
+
+struct W {
+  W(Cleanup c = {}) noexcept(false);
+};
+
+struct X {
+  X(S = {}) noexcept;
+};
+
+struct Y {
+  S s;
+};
+
+struct Z {
+  T t;
+};
+
+int f();
+int g() noexcept(false);
+int h() noexcept(true);
+
+struct UserConv_Bad {
+  operator int() noexcept(false);
+};
+
+struct UserConv_Good {
+  operator int() noexcept;
+};
+
+UserConv_Bad some_bad_func() noexcept;
+UserConv_Good some_good_func() noexcept;
+
+S s;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+T t; // ok
+U u;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+V v("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+W w;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+X x1(S{});
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'x1' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+X x2;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'x2' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+Y y;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'y' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 36:8: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+Z z;
+
+int i = f();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'i' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 44:5: note: possibly throwing function declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+int j = g();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'j' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 45:5: note: possibly throwing function declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+int k = h();
+int l = some_bad_func();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'l' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 49:3: note: possibly throwing function declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+int m = some_good_func();
+
+typedef decltype(sizeof(int)) size_t;
+inline void *operator new(size_t sz, void *here) noexcept { return here; }
+char n[sizeof(int)];
+int *o = new (n) int();
+int *p = new int();
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'p' with static storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+thread_local S s3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 's3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local T t3; // ok
+thread_local U u3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'u3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local V v3("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'v3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local W w3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'w3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+void f(S s1, T t1, U u1, V v1, W w1) { // ok, ok, ok, ok, ok
+  S s2; // ok
+  T t2; // ok
+  U u2; // ok
+  V v2("v"); // ok
+  W w2; // ok
+
+  thread_local S s3; // ok
+  thread_local T t3; // ok
+  thread_local U u3; // ok
+  thread_local V v3("v"); // ok
+  thread_local W w3; // ok
+
+  static S s4; // ok
+  static T t4; // ok
+  static U u4; // ok
+  static V v4("v"); // ok
+  static W w4; // ok
+}
+
+namespace {
+S s;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+T t; // ok
+U u;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+V v("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+W w;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:3: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+thread_local S s3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 's3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local T t3; // ok
+thread_local U u3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'u3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local V v3("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'v3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+thread_local W w3;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:16: warning: initialization of 'w3' with thread_local storage duration may throw an exception that cannot be caught
+// CHECK-NONEXCEPTIONS-NOT: warning:
+}; // namespace
+
+class Statics {
+  static S s; // warn when initialized
+  static T t; // ok
+  static U u; // warn when initialized
+  static V v; // warn when initialized
+  static W w; // warn when initialized
+
+  void f(S s, T t, U u, V v) {
+    S s2;      // ok
+    T t2;      // ok
+    U u2;      // ok
+    V v2("v"); // ok
+    W w2;      // ok
+
+    thread_local S s3;      // ok
+    thread_local T t3;      // ok
+    thread_local U u3;      // ok
+    thread_local V v3("v"); // ok
+    thread_local W w3;      // ok
+
+    static S s4;      // ok
+    static T t4;      // ok
+    static U u4;      // ok
+    static V v4("v"); // ok
+    static W w4;      // ok
+  }
+};
+
+S Statics::s;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 's' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: 9:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+T Statics::t;
+U Statics::u;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'u' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 17:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+V Statics::v("v");
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'v' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 21:12: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+W Statics::w;
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:12: warning: initialization of 'w' with static storage duration may throw an exception that cannot be caught
+// CHECK-EXCEPTIONS: 29:3: note: possibly throwing constructor declared here
+// CHECK-NONEXCEPTIONS-NOT: warning:
+
+#ifndef NONEXCEPTIONS
+namespace pr35457 {
+constexpr int foo(int x) { if (x <= 0) throw 12; return x; }
+
+constexpr int bar = foo(1); // OK
+// CHECK-EXCEPTIONS-NOT: warning: initialization of 'bar' with static storage
+int baz = foo(0); // Not OK; throws at runtime when exceptions are enabled.
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:5: warning: initialization of 'baz' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-6]]:15: note: possibly throwing function declared here
+} // namespace pr35457
+#endif // NONEXCEPTIONS
+
+namespace pr39777 {
+struct S { S(); };
+struct T { T() noexcept; };
+
+auto Okay1 = []{ S s; };
+auto Okay2 = []{ (void)new int; };
+auto NotOkay1 = []{ S s; return 12; }(); // Because the lambda call is not noexcept
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay1' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-7]]:12: note: possibly throwing constructor declared here
+auto NotOkay2 = []() noexcept { S s; return 12; }(); // Because S::S() is not noexcept
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay2' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-10]]:12: note: possibly throwing constructor declared here
+auto Okay3 = []() noexcept { T t; return t; }();
+
+struct U {
+  U() noexcept;
+  auto getBadLambda() const noexcept {
+    return []{ S s; return s; };
+  }
+};
+auto Okay4 = []{ U u; return u.getBadLambda(); }();
+auto NotOkay3 = []() noexcept { U u; return u.getBadLambda(); }()(); // Because the lambda returned and called is not noexcept
+// CHECK-EXCEPTIONS: :[[@LINE-1]]:6: warning: initialization of 'NotOkay3' with static storage duration may throw an exception that cannot be caught [cert-err58-cpp]
+// CHECK-EXCEPTIONS: :[[@LINE-6]]:12: note: possibly throwing function declared here
+
+#ifndef NONEXCEPTIONS
+struct Bad {
+  Bad() {
+    throw 12;
+  }
+};
+
+static auto NotOkay4 = [bad = Bad{}](){};
+// FIXME: the above should be diagnosed because the capture init can trigger
+// an exception when constructing the Bad object.
+#endif // NONEXCEPTIONS
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-throw-exception-type.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-throw-exception-type.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-throw-exception-type.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-throw-exception-type.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,129 @@
+// RUN: %check_clang_tidy -std=c++11,c++14 %s cert-err60-cpp %t -- -- -fcxx-exceptions
+// FIXME: Split off parts of this test that rely on dynamic exeption
+// specifications, and run this test in all language modes.
+
+struct S {};
+struct T : S {};
+struct U {
+  U() = default;
+  U(const U&) = default;
+};
+
+struct V {
+  V() = default;
+  V(const V&) noexcept;
+};
+
+struct W {
+  W() = default;
+  W(const W&) noexcept(false);
+};
+
+struct X {
+  X() = default;
+  X(const X&) {}
+};
+
+struct Y {
+  Y() = default;
+  Y(const Y&) throw();
+};
+
+struct Z {
+  Z() = default;
+  Z(const Z&) throw(int);
+};
+
+void g() noexcept(false);
+
+struct A {
+  A() = default;
+  A(const A&) noexcept(noexcept(g()));
+};
+
+struct B {
+  B() = default;
+  B(const B&) = default;
+  B(const A&) noexcept(false);
+};
+
+class C {
+  W M; // W is not no-throw copy constructible
+public:
+  C() = default;
+  C(const C&) = default;
+};
+
+struct D {
+  D() = default;
+  D(const D&) noexcept(false);
+  D(D&) noexcept(true);
+};
+
+struct E {
+  E() = default;
+  E(E&) noexcept(true);
+  E(const E&) noexcept(false);
+};
+
+struct Allocates {
+  int *x;
+  Allocates() : x(new int(0)) {}
+  Allocates(const Allocates &other) : x(new int(*other.x)) {}
+};
+
+struct OptionallyAllocates {
+  int *x;
+  OptionallyAllocates() : x(new int(0)) {}
+  OptionallyAllocates(const Allocates &other) noexcept(true) {
+    try {
+      x = new int(*other.x);
+    } catch (...) {
+      x = nullptr;
+    }
+  }
+};
+
+void f() {
+  throw 12; // ok
+  throw "test"; // ok
+  throw S(); // ok
+  throw T(); // ok
+  throw U(); // ok
+  throw V(); // ok
+  throw W(); // match, noexcept(false)
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible [cert-err60-cpp]
+  throw X(); // match, no noexcept clause, nontrivial
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw Y(); // ok
+  throw Z(); // match, throw(int)
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw A(); // match, noexcept(false)
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw B(); // ok
+  throw C(); // match, C has a member variable that makes it throwing on copy
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw D(); // match, has throwing copy constructor
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw E(); // match, has throwing copy constructor
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw Allocates(); // match, copy constructor throws
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
+  throw OptionallyAllocates(); // ok
+}
+
+namespace PR25574 {
+struct B {
+  B(const B&) noexcept;
+};
+
+struct D : B {
+  D();
+  virtual ~D() noexcept;
+};
+
+template <typename T>
+void f() {
+  throw D();
+}
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-uppercase-literal-suffix-integer.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-uppercase-literal-suffix-integer.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-uppercase-literal-suffix-integer.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-uppercase-literal-suffix-integer.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,159 @@
+// RUN: %check_clang_tidy %s cert-dcl16-c %t -- -- -I %S
+// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -fix -- -I %S
+// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -warnings-as-errors='-*,cert-dcl16-c' -- -I %S
+
+#include "readability-uppercase-literal-suffix.h"
+
+void integer_suffix() {
+  static constexpr auto v0 = __LINE__; // synthetic
+  static_assert(v0 == 9 || v0 == 5, "");
+
+  static constexpr auto v1 = __cplusplus; // synthetic, long
+
+  static constexpr auto v2 = 1; // no literal
+  static_assert(is_same<decltype(v2), const int>::value, "");
+  static_assert(v2 == 1, "");
+
+  // Unsigned
+
+  static constexpr auto v3 = 1u;
+  static_assert(is_same<decltype(v3), const unsigned int>::value, "");
+  static_assert(v3 == 1, "");
+
+  static constexpr auto v4 = 1U; // OK.
+  static_assert(is_same<decltype(v4), const unsigned int>::value, "");
+  static_assert(v4 == 1, "");
+
+  // Long
+
+  static constexpr auto v5 = 1l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
+  // CHECK-MESSAGES-NEXT: ^~
+  // CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
+  // CHECK-FIXES: static constexpr auto v5 = 1L;
+  static_assert(is_same<decltype(v5), const long>::value, "");
+  static_assert(v5 == 1, "");
+
+  static constexpr auto v6 = 1L; // OK.
+  static_assert(is_same<decltype(v6), const long>::value, "");
+  static_assert(v6 == 1, "");
+
+  // Long Long
+
+  static constexpr auto v7 = 1ll;
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll;
+  // CHECK-MESSAGES-NEXT: ^~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}}
+  // CHECK-FIXES: static constexpr auto v7 = 1LL;
+  static_assert(is_same<decltype(v7), const long long>::value, "");
+  static_assert(v7 == 1, "");
+
+  static constexpr auto v8 = 1LL; // OK.
+  static_assert(is_same<decltype(v8), const long long>::value, "");
+  static_assert(v8 == 1, "");
+
+  // Unsigned Long
+
+  static constexpr auto v9 = 1ul;
+  static_assert(is_same<decltype(v9), const unsigned long>::value, "");
+  static_assert(v9 == 1, "");
+
+  static constexpr auto v10 = 1uL;
+  static_assert(is_same<decltype(v10), const unsigned long>::value, "");
+  static_assert(v10 == 1, "");
+
+  static constexpr auto v11 = 1Ul;
+  static_assert(is_same<decltype(v11), const unsigned long>::value, "");
+  static_assert(v11 == 1, "");
+
+  static constexpr auto v12 = 1UL; // OK.
+  static_assert(is_same<decltype(v12), const unsigned long>::value, "");
+  static_assert(v12 == 1, "");
+
+  // Long Unsigned
+
+  static constexpr auto v13 = 1lu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu;
+  // CHECK-MESSAGES-NEXT: ^~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+  // CHECK-FIXES: static constexpr auto v13 = 1LU;
+  static_assert(is_same<decltype(v13), const unsigned long>::value, "");
+  static_assert(v13 == 1, "");
+
+  static constexpr auto v14 = 1Lu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu;
+  // CHECK-MESSAGES-NEXT: ^~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+  // CHECK-FIXES: static constexpr auto v14 = 1LU;
+  static_assert(is_same<decltype(v14), const unsigned long>::value, "");
+  static_assert(v14 == 1, "");
+
+  static constexpr auto v15 = 1lU;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lU', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1lU;
+  // CHECK-MESSAGES-NEXT: ^~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
+  // CHECK-FIXES: static constexpr auto v15 = 1LU;
+  static_assert(is_same<decltype(v15), const unsigned long>::value, "");
+  static_assert(v15 == 1, "");
+
+  static constexpr auto v16 = 1LU; // OK.
+  static_assert(is_same<decltype(v16), const unsigned long>::value, "");
+  static_assert(v16 == 1, "");
+
+  // Unsigned Long Long
+
+  static constexpr auto v17 = 1ull;
+  static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
+  static_assert(v17 == 1, "");
+
+  static constexpr auto v18 = 1uLL;
+  static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
+  static_assert(v18 == 1, "");
+
+  static constexpr auto v19 = 1Ull;
+  static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
+  static_assert(v19 == 1, "");
+
+  static constexpr auto v20 = 1ULL; // OK.
+  static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
+  static_assert(v20 == 1, "");
+
+  // Long Long Unsigned
+
+  static constexpr auto v21 = 1llu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llu', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v21 = 1llu;
+  // CHECK-MESSAGES-NEXT: ^~~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+  // CHECK-FIXES: static constexpr auto v21 = 1LLU;
+  static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
+  static_assert(v21 == 1, "");
+
+  static constexpr auto v22 = 1LLu;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'LLu', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v22 = 1LLu;
+  // CHECK-MESSAGES-NEXT: ^~~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+  // CHECK-FIXES: static constexpr auto v22 = 1LLU;
+  static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
+  static_assert(v22 == 1, "");
+
+  static constexpr auto v23 = 1llU;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llU', which is not uppercase
+  // CHECK-MESSAGES-NEXT: static constexpr auto v23 = 1llU;
+  // CHECK-MESSAGES-NEXT: ^~~~
+  // CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
+  // CHECK-FIXES: static constexpr auto v23 = 1LLU;
+  static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
+  static_assert(v23 == 1, "");
+
+  static constexpr auto v24 = 1LLU; // OK.
+  static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
+  static_assert(v24 == 1, "");
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cert-variadic-function-def.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cert-variadic-function-def.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cert-variadic-function-def.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cert-variadic-function-def.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s cert-dcl50-cpp %t
+
+// Variadic function definitions are diagnosed.
+void f1(int, ...) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: do not define a C-style variadic function; consider using a function parameter pack or currying instead [cert-dcl50-cpp]
+
+// Variadic function *declarations* are not diagnosed.
+void f2(int, ...); // ok
+
+// Function parameter packs are good, however.
+template <typename Arg, typename... Ts>
+void f3(Arg F, Ts... Rest) {}
+
+struct S {
+  void f(int, ...); // ok
+  void f1(int, ...) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: do not define a C-style variadic function; consider using a function parameter pack or currying instead
+};
+
+// Function definitions that are extern "C" are good.
+extern "C" void f4(int, ...) {} // ok
+extern "C" {
+  void f5(int, ...) {} // ok
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-avoid-goto.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-avoid-goto.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-avoid-goto.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-avoid-goto.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,139 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-avoid-goto %t
+
+void noop() {}
+
+int main() {
+  noop();
+  goto jump_to_me;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
+  // CHECK-NOTES: [[@LINE+3]]:1: note: label defined here
+  noop();
+
+jump_to_me:;
+
+jump_backwards:;
+  noop();
+  goto jump_backwards;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: avoid using 'goto' for flow control
+  // CHECK-NOTES: [[@LINE-4]]:1: note: label defined here
+
+  goto jump_in_line;
+  ;
+jump_in_line:;
+  // CHECK-NOTES: [[@LINE-3]]:3: warning: avoid using 'goto' for flow control
+  // CHECK-NOTES: [[@LINE-2]]:1: note: label defined here
+
+  // Test the GNU extension https://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
+some_label:;
+  void *dynamic_label = &&some_label;
+
+  // FIXME: `IndirectGotoStmt` is not detected.
+  goto *dynamic_label;
+}
+
+void forward_jump_out_nested_loop() {
+  int array[] = {1, 2, 3, 4, 5};
+  for (int i = 0; i < 10; ++i) {
+    noop();
+    for (int j = 0; j < 10; ++j) {
+      noop();
+      if (i + j > 10)
+        goto early_exit1;
+    }
+    noop();
+  }
+
+  for (int i = 0; i < 10; ++i) {
+    noop();
+    while (true) {
+      noop();
+      if (i > 5)
+        goto early_exit1;
+    }
+    noop();
+  }
+
+  for (auto value : array) {
+    noop();
+    for (auto number : array) {
+      noop();
+      if (number == 5)
+        goto early_exit1;
+    }
+  }
+
+  do {
+    noop();
+    do {
+      noop();
+      goto early_exit1;
+    } while (true);
+  } while (true);
+
+  do {
+    for (auto number : array) {
+      noop();
+      if (number == 2)
+        goto early_exit1;
+    }
+  } while (true);
+
+  // Jumping further results in error, because the variable declaration would
+  // be skipped.
+early_exit1:;
+
+  int i = 0;
+  while (true) {
+    noop();
+    while (true) {
+      noop();
+      if (i > 5)
+        goto early_exit2;
+      i++;
+    }
+    noop();
+  }
+
+  while (true) {
+    noop();
+    for (int j = 0; j < 10; ++j) {
+      noop();
+      if (j > 5)
+        goto early_exit2;
+    }
+    noop();
+  }
+
+  while (true) {
+    noop();
+    for (auto number : array) {
+      if (number == 1)
+        goto early_exit2;
+      noop();
+    }
+  }
+
+  while (true) {
+    noop();
+    do {
+      noop();
+      goto early_exit2;
+    } while (true);
+  }
+early_exit2:;
+}
+
+void jump_out_backwards() {
+
+before_the_loop:
+  noop();
+
+  for (int i = 0; i < 10; ++i) {
+    for (int j = 0; j < 10; ++j) {
+      if (i * j > 80)
+        goto before_the_loop;
+      // CHECK-NOTES: [[@LINE-1]]:9: warning: avoid using 'goto' for flow control
+      // CHECK-NOTES: [[@LINE-8]]:1: note: label defined here
+    }
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-init-variables.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,80 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-init-variables %t -- -- -fno-delayed-template-parsing
+
+// Ensure that function declarations are not changed.
+void some_func(int x, double d, bool b, const char *p);
+
+// Ensure that function arguments are not changed
+int identity_function(int x) {
+  return x;
+}
+
+int do_not_modify_me;
+
+static int should_not_be_initialized;
+extern int should_not_be_initialized2;
+
+typedef struct {
+  int unaltered1;
+  int unaltered2;
+} UnusedStruct;
+
+typedef int my_int_type;
+#define MACRO_INT int
+#define FULL_DECLARATION() int macrodecl;
+
+template <typename T>
+void template_test_function() {
+  T t;
+  int uninitialized;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'uninitialized' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  int uninitialized = 0;{{$}}
+}
+
+void init_unit_tests() {
+  int x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'x' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  int x = 0;{{$}}
+  my_int_type myint;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: variable 'myint' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  my_int_type myint = 0;{{$}}
+
+  MACRO_INT macroint;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'macroint' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  MACRO_INT macroint = 0;{{$}}
+  FULL_DECLARATION();
+
+  int x0 = 1, x1, x2 = 2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: variable 'x1' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  int x0 = 1, x1 = 0, x2 = 2;{{$}}
+  int y0, y1 = 1, y2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'y0' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: variable 'y2' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  int y0 = 0, y1 = 1, y2 = 0;{{$}}
+  int hasval = 42;
+
+  float f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: variable 'f' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  float f = NAN;{{$}}
+  float fval = 85.0;
+  double d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: variable 'd' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  double d = NAN;{{$}}
+  double dval = 99.0;
+
+  bool b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: variable 'b' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  bool b = 0;{{$}}
+  bool bval = true;
+
+  const char *ptr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: variable 'ptr' is not initialized [cppcoreguidelines-init-variables]
+  // CHECK-FIXES: {{^}}  const char *ptr = nullptr;{{$}}
+  const char *ptrval = "a string";
+
+  UnusedStruct u;
+
+  static int does_not_need_an_initializer;
+  extern int does_not_need_an_initializer2;
+  int parens(42);
+  int braces{42};
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-interfaces-global-init.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,84 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-interfaces-global-init %t
+
+constexpr int makesInt() { return 3; }
+constexpr int takesInt(int i) { return i + 1; }
+constexpr int takesIntPtr(int *i) { return *i; }
+
+extern int ExternGlobal;
+static int GlobalScopeBadInit1 = ExternGlobal;
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+static int GlobalScopeBadInit2 = takesInt(ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+static int GlobalScopeBadInit3 = takesIntPtr(&ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+static int GlobalScopeBadInit4 = 3 * (ExternGlobal + 2);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+
+namespace ns {
+static int NamespaceScope = makesInt();
+static int NamespaceScopeBadInit = takesInt(ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+
+struct A {
+  static int ClassScope;
+  static int ClassScopeBadInit;
+};
+
+int A::ClassScopeBadInit = takesInt(ExternGlobal);
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ExternGlobal'
+
+static int FromClassBadInit = takesInt(A::ClassScope);
+// CHECK-MESSAGES: [[@LINE-1]]:12: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'ClassScope'
+} // namespace ns
+
+// "const int B::I;" is fine, it just ODR-defines B::I. See [9.4.3] Static
+// members [class.static]. However the ODR-definitions are not in the right
+// order (C::I after C::J, see [3.6.2.3]).
+class B1 {
+  static const int I = 0;
+  static const int J = I;
+};
+const int B1::J;
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: initializing non-local variable with non-const expression depending on uninitialized non-local variable 'I'
+const int B1::I;
+
+void f() {
+  // This is fine, it's executed after dynamic initialization occurs.
+  static int G = takesInt(ExternGlobal);
+}
+
+// Declaration then definition then usage is fine.
+extern int ExternGlobal2;
+extern int ExternGlobal2;
+int ExternGlobal2 = 123;
+static int GlobalScopeGoodInit1 = ExternGlobal2;
+
+
+// Defined global variables are fine:
+static int GlobalScope = makesInt();
+static int GlobalScopeGoodInit2 = takesInt(GlobalScope);
+static int GlobalScope2 = takesInt(ns::NamespaceScope);
+// Enums are fine.
+enum Enum { kEnumValue = 1 };
+static int GlobalScopeFromEnum = takesInt(kEnumValue);
+
+// Leave constexprs alone.
+extern constexpr int GlobalScopeConstexpr = makesInt();
+static constexpr int GlobalScopeConstexprOk =
+    takesInt(GlobalScopeConstexpr);
+
+// This is a pretty common instance: People are usually not using constexpr, but
+// this is what they should write:
+static constexpr const char kValue[] = "value";
+constexpr int Fingerprint(const char *value) { return 0; }
+static int kFingerprint = Fingerprint(kValue);
+
+// This is fine because the ODR-definitions are in the right order (C::J after
+// C::I).
+class B2 {
+  static const int I = 0;
+  static const int J = I;
+};
+const int B2::I;
+const int B2::J;
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-caps-only.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-caps-only.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-caps-only.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-caps-only.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: cppcoreguidelines-macro-usage.CheckCapsOnly, value: 1}]}' --
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define problematic_constant 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_constant' using all uppercase characters
+
+#define problematic_function(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_function' using all uppercase characters
+
+#define problematic_variadic(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_variadic' using all uppercase characters
+//
+#define problematic_variadic2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro definition does not define the macro name 'problematic_variadic2' using all uppercase characters
+
+#define OKISH_CONSTANT 42
+#define OKISH_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define OKISH_VARIADIC(...) (__VA_ARGS__)
+
+#endif

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-command-line-macros.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-command-line-macros.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-command-line-macros.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-command-line-macros.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,8 @@
+// RUN: %check_clang_tidy -check-suffixes=NORMAL %s cppcoreguidelines-macro-usage %t -- -- -D_ZZZ_IM_A_MACRO
+// RUN: %check_clang_tidy -check-suffixes=NORMAL %s cppcoreguidelines-macro-usage %t -- -config='{CheckOptions: [{key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros, value: 1}]}' -- -D_ZZZ_IM_A_MACRO
+// RUN: %check_clang_tidy -check-suffixes=NORMAL,CL %s cppcoreguidelines-macro-usage %t -- -config='{CheckOptions: [{key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros, value: 0}]}' -- -D_ZZZ_IM_A_MACRO
+
+// CHECK-MESSAGES-CL: warning: macro '_ZZZ_IM_A_MACRO' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_CONSTANT 0
+// CHECK-MESSAGES-NORMAL: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-custom.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-custom.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-custom.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage-custom.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: cppcoreguidelines-macro-usage.AllowedRegexp, value: "DEBUG_*|TEST_*"}]}' --
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define PROBLEMATIC_CONSTANT 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: function-like macro 'PROBLEMATIC_FUNCTION' used; consider a 'constexpr' template function
+
+#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC' used; consider using a 'constexpr' variadic template function
+
+#define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC2' used; consider using a 'constexpr' variadic template function
+
+#define DEBUG_CONSTANT 0
+#define DEBUG_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define DEBUG_VARIADIC(...) (__VA_ARGS__)
+#define TEST_CONSTANT 0
+#define TEST_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+#define TEST_VARIADIC(...) (__VA_ARGS__)
+#define TEST_VARIADIC2(x, ...) (__VA_ARGS__)
+
+#endif

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-macro-usage.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-macro-usage %t -- -header-filter=.* -system-headers --
+
+#ifndef INCLUDE_GUARD
+#define INCLUDE_GUARD
+
+#define PROBLEMATIC_CONSTANT 0
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: macro 'PROBLEMATIC_CONSTANT' used to declare a constant; consider using a 'constexpr' constant
+
+#define PROBLEMATIC_FUNCTION(x, y) ((a) > (b) ? (a) : (b))
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: function-like macro 'PROBLEMATIC_FUNCTION' used; consider a 'constexpr' template function
+
+#define PROBLEMATIC_VARIADIC(...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC' used; consider using a 'constexpr' variadic template function
+
+#define PROBLEMATIC_VARIADIC2(x, ...) (__VA_ARGS__)
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: variadic macro 'PROBLEMATIC_VARIADIC2' used; consider using a 'constexpr' variadic template function
+
+#endif

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-long-is-32bits.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -- -- -target x86_64-unknown-linux -m32
+
+static_assert(sizeof(int) * 8 == 32, "int is 32-bits");
+static_assert(sizeof(long) * 8 == 32, "long is 32-bits");
+static_assert(sizeof(long long) * 8 == 64, "long long is 64-bits");
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+  int i;        // i.e. int32_t
+  long l;       // i.e. int32_t
+  long long ll; // i.e. int64_t
+
+  unsigned int ui;        // i.e. uint32_t
+  unsigned long ul;       // i.e. uint32_t
+  unsigned long long ull; // i.e. uint64_t
+
+  i = l;  // int and long are the same type.
+  i = ll; // int64_t does not fit in an int32_t
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  ll = ul;  // uint32_t fits into int64_t
+  ll = ull; // uint64_t does not fit in an int64_t
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-narrowingfloatingpoint-option.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -- -- -target x86_64-unknown-linux -fsigned-char
+
+namespace floats {
+
+void narrow_constant_floating_point_to_int_not_ok(double d) {
+  int i = 0;
+  i += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i *= 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i /= 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0;
+  i += 2.0f;
+}
+
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5;
+}
+
+void narrow_double_to_float_not_ok(double d) {
+  float f;
+  f = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = 15_double;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = narrow_double_to_float_return();
+}
+
+void narrow_fp_constants() {
+  float f;
+  f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+
+  f = __builtin_huge_valf();  // max float is not narrowing.
+  f = -__builtin_huge_valf(); // -max float is not narrowing.
+  f = __builtin_inff();       // float infinity is not narrowing.
+  f = __builtin_nanf("0");    // float NaN is not narrowing.
+
+  f = __builtin_huge_val(); // max double is not within-range of float.
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = -__builtin_huge_val(); // -max double is not within-range of float.
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = __builtin_inf(); // double infinity is not within-range of float.
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'double' to 'float' [cppcoreguidelines-narrowing-conversions]
+  f = __builtin_nan("0"); // double NaN is not narrowing.
+}
+
+} // namespace floats

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-pedanticmode-option.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.PedanticMode", value: 1} \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
+
+namespace floats {
+
+void triggers_wrong_constant_type_warning(double d) {
+  int i = 0.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'double' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constant value should be of type of type 'int' instead of 'float' [cppcoreguidelines-narrowing-conversions]
+}
+
+void triggers_narrowing_warning_when_overflowing() {
+  unsigned short us = 65537.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: narrowing conversion from constant 'double' to 'unsigned short' [cppcoreguidelines-narrowing-conversions]
+}
+
+} // namespace floats

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions-unsigned-char.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,83 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -- -- -target x86_64-unknown-linux -funsigned-char
+
+void narrow_integer_to_unsigned_integer_is_ok() {
+  signed char sc;
+  short s;
+  int i;
+  long l;
+  long long ll;
+
+  char c;
+  unsigned short us;
+  unsigned int ui;
+  unsigned long ul;
+  unsigned long long ull;
+
+  ui = sc;
+  c = s;
+  c = i;
+  c = l;
+  c = ll;
+
+  c = c;
+  c = us;
+  c = ui;
+  c = ul;
+  c = ull;
+}
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+  signed char sc;
+  short s;
+  int i;
+  long l;
+  long long ll;
+
+  char c;
+  unsigned short us;
+  unsigned int ui;
+  unsigned long ul;
+  unsigned long long ull;
+
+  sc = sc;
+  sc = s;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = ll;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+  sc = c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'char' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = us;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned short' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = ui;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  sc = ull;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_unsigned_integer_is_ok() {
+  char c1 = -128; // unsigned dst type is well defined.
+  char c2 = 127;  // unsigned dst type is well defined.
+  char c3 = -129; // unsigned dst type is well defined.
+  char c4 = 128;  // unsigned dst type is well defined.
+  unsigned char uc1 = 0;
+  unsigned char uc2 = 255;
+  unsigned char uc3 = -1;  // unsigned dst type is well defined.
+  unsigned char uc4 = 256; // unsigned dst type is well defined.
+  signed char sc = 128;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'signed char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {
+  // conversion to unsigned char type is well defined.
+  char c1 = b ? 1 : 0;
+  char c2 = b ? 1 : 256;
+  char c3 = b ? -1 : 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-narrowing-conversions.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,346 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-narrowing-conversions %t \
+// RUN: -config="{CheckOptions: [ \
+// RUN:   {key: "cppcoreguidelines-narrowing-conversions.WarnOnFloatingPointNarrowingConversion", value: 0}, \
+// RUN: ]}" \
+// RUN: -- -target x86_64-unknown-linux -fsigned-char
+
+float ceil(float);
+namespace std {
+double ceil(double);
+long double floor(long double);
+} // namespace std
+
+namespace floats {
+
+struct ConvertsToFloat {
+  operator float() const { return 0.5f; }
+};
+
+float operator"" _float(unsigned long long);
+
+void narrow_fp_to_int_not_ok(double d) {
+  int i = 0;
+  i = d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i = 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i = static_cast<float>(d);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i = ConvertsToFloat();
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i = 15_float;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += d;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 0.5;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i *= 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i /= 0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'float' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += (double)0.5f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from constant 'double' to 'int' [cppcoreguidelines-narrowing-conversions]
+  i += 2.0;
+  i += 2.0f;
+}
+
+double operator"" _double(unsigned long long);
+
+float narrow_double_to_float_return() {
+  return 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+}
+
+void narrow_double_to_float_ok(double d) {
+  float f;
+  f = d;
+  f = 15_double;
+}
+
+void narrow_fp_constants() {
+  float f;
+  f = 0.5; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+
+  f = __builtin_huge_valf();  // max float is not narrowing.
+  f = -__builtin_huge_valf(); // -max float is not narrowing.
+  f = __builtin_inff();       // float infinity is not narrowing.
+  f = __builtin_nanf("0");    // float NaN is not narrowing.
+
+  f = __builtin_huge_val();  // max double is not within-range of float.
+  f = -__builtin_huge_val(); // -max double is not within-range of float.
+  f = __builtin_inf();       // double infinity is not within-range of float.
+  f = __builtin_nan("0");    // double NaN is not narrowing.
+}
+
+void narrow_double_to_float_not_ok_binary_ops(double d) {
+  float f;
+  f += 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+  f += 2.0;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+  f *= 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+  f /= 0.5;          // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+  f += (double)0.5f; // [dcl.init.list] 7.2 : in-range fp constant to narrower float is not a narrowing.
+  f += d;            // We do not warn about floating point narrowing by default.
+}
+
+void narrow_fp_constant_to_bool_not_ok() {
+  bool b1 = 1.0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'double' to 'bool' [cppcoreguidelines-narrowing-conversions]
+  bool b2 = 1.0f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_integer_to_floating() {
+  {
+    long long ll; // 64 bits
+    float f = ll; // doesn't fit in 24 bits
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+    double d = ll; // doesn't fit in 53 bits.
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: narrowing conversion from 'long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+  }
+  {
+    int i;       // 32 bits
+    float f = i; // doesn't fit in 24 bits
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+    double d = i; // fits in 53 bits.
+  }
+  {
+    short n1, n2;
+    float f = n1 + n2; // 'n1 + n2' is of type 'int' because of integer rules
+    // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: narrowing conversion from 'int' to 'float' [cppcoreguidelines-narrowing-conversions]
+  }
+  {
+    short s;      // 16 bits
+    float f = s;  // fits in 24 bits
+    double d = s; // fits in 53 bits.
+  }
+}
+
+void narrow_integer_to_unsigned_integer_is_ok() {
+  char c;
+  short s;
+  int i;
+  long l;
+  long long ll;
+
+  unsigned char uc;
+  unsigned short us;
+  unsigned int ui;
+  unsigned long ul;
+  unsigned long long ull;
+
+  ui = c;
+  uc = s;
+  uc = i;
+  uc = l;
+  uc = ll;
+
+  uc = uc;
+  uc = us;
+  uc = ui;
+  uc = ul;
+  uc = ull;
+}
+
+void narrow_integer_to_signed_integer_is_not_ok() {
+  char c;
+  short s;
+  int i;
+  long l;
+  long long ll;
+
+  unsigned char uc;
+  unsigned short us;
+  unsigned int ui;
+  unsigned long ul;
+  unsigned long long ull;
+
+  c = c;
+  c = s;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = ll;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+  c = uc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned char' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = us;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned short' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = ui;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  c = ull;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+  i = c;
+  i = s;
+  i = i;
+  i = l;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  i = ll;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+  i = uc;
+  i = us;
+  i = ui;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned int' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  i = ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  i = ull;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'unsigned long long' to signed type 'int' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+  ll = c;
+  ll = s;
+  ll = i;
+  ll = l;
+  ll = ll;
+
+  ll = uc;
+  ll = us;
+  ll = ui;
+  ll = ul;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  ll = ull;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_unsigned_integer_is_ok() {
+  unsigned char uc1 = 0;
+  unsigned char uc2 = 255;
+  unsigned char uc3 = -1;  // unsigned dst type is well defined.
+  unsigned char uc4 = 256; // unsigned dst type is well defined.
+  unsigned short us1 = 0;
+  unsigned short us2 = 65535;
+  unsigned short us3 = -1;    // unsigned dst type is well defined.
+  unsigned short us4 = 65536; // unsigned dst type is well defined.
+}
+
+void narrow_constant_to_signed_integer_is_not_ok() {
+  char c1 = -128;
+  char c2 = 127;
+  char c3 = -129;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  char c4 = 128;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+
+  short s1 = -32768;
+  short s2 = 32767;
+  short s3 = -32769;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value -32769 (0xFFFF7FFF) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  short s4 = 32768;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: narrowing conversion from constant value 32768 (0x00008000) of type 'int' to signed type 'short' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_conditional_operator_contant_to_unsigned_is_ok(bool b) {
+  // conversion to unsigned dst type is well defined.
+  unsigned char c1 = b ? 1 : 0;
+  unsigned char c2 = b ? 1 : 256;
+  unsigned char c3 = b ? -1 : 0;
+}
+
+void narrow_conditional_operator_contant_to_signed_is_not_ok(bool b) {
+  char uc1 = b ? 1 : 0;
+  char uc2 = b ? 1 : 128;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: narrowing conversion from constant value 128 (0x00000080) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  char uc3 = b ? -129 : 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: narrowing conversion from constant value -129 (0xFFFFFF7F) of type 'int' to signed type 'char' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  unsigned long long ysize;
+  long long mirror = b ? -1 : ysize - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: narrowing conversion from constant value 18446744073709551615 (0xFFFFFFFFFFFFFFFF) of type 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+  // CHECK-MESSAGES: :[[@LINE-2]]:37: warning: narrowing conversion from 'unsigned long long' to signed type 'long long' is implementation-defined [cppcoreguidelines-narrowing-conversions]
+}
+
+void narrow_constant_to_floating_point() {
+  float f_ok = 1ULL << 24;              // fits in 24 bits mantissa.
+  float f_not_ok = (1ULL << 24) + 1ULL; // doesn't fit in 24 bits mantissa.
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: narrowing conversion from constant value 16777217 of type 'unsigned long long' to 'float' [cppcoreguidelines-narrowing-conversions]
+  double d_ok = 1ULL << 53;              // fits in 53 bits mantissa.
+  double d_not_ok = (1ULL << 53) + 1ULL; // doesn't fit in 53 bits mantissa.
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: narrowing conversion from constant value 9007199254740993 of type 'unsigned long long' to 'double' [cppcoreguidelines-narrowing-conversions]
+}
+
+void casting_integer_to_bool_is_ok() {
+  int i;
+  while (i) {
+  }
+  for (; i;) {
+  }
+  if (i) {
+  }
+}
+
+void casting_float_to_bool_is_not_ok() {
+  float f;
+  while (f) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+  }
+  for (; f;) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+  }
+  if (f) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: narrowing conversion from 'float' to 'bool' [cppcoreguidelines-narrowing-conversions]
+  }
+}
+
+void legitimate_comparison_do_not_warn(unsigned long long size) {
+  for (int i = 0; i < size; ++i) {
+  }
+}
+
+void ok(double d) {
+  int i = 0;
+  i = 1;
+  i = static_cast<int>(0.5);
+  i = static_cast<int>(d);
+  i = std::ceil(0.5);
+  i = ::std::floor(0.5);
+  {
+    using std::ceil;
+    i = ceil(0.5f);
+  }
+  i = ceil(0.5f);
+}
+
+void ok_binary_ops(double d) {
+  int i = 0;
+  i += 1;
+  i += static_cast<int>(0.5);
+  i += static_cast<int>(d);
+  i += (int)d;
+  i += std::ceil(0.5);
+  i += ::std::floor(0.5);
+  {
+    using std::ceil;
+    i += ceil(0.5f);
+  }
+  i += ceil(0.5f);
+}
+
+// We're bailing out in templates and macros.
+template <typename T1, typename T2>
+void f(T1 one, T2 two) {
+  one += two;
+}
+
+void template_context() {
+  f(1, 2);
+  f(1, .5f);
+  f(1, .5);
+  f(1, .5l);
+}
+
+#define DERP(i, j) (i += j)
+
+void macro_context() {
+  int i = 0;
+  DERP(i, 2);
+  DERP(i, .5f);
+  DERP(i, .5);
+  DERP(i, .5l);
+}
+
+} // namespace floats

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-custom.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,59 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: cppcoreguidelines-no-malloc.Allocations, value: "::malloc;::align_malloc;::calloc"},\
+// RUN:   {key: cppcoreguidelines-no-malloc.Reallocations, value: "::realloc;::align_realloc"},\
+// RUN:   {key: cppcoreguidelines-no-malloc.Deallocations, value: "::free;::align_free"}]}' \
+// RUN: --
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+void *align_malloc(size_t size, unsigned short aligmnent);
+void *calloc(size_t num, size_t size);
+void *realloc(void *ptr, size_t size);
+void *align_realloc(void *ptr, size_t size, unsigned short alignment);
+void free(void *ptr);
+void *align_free(void *ptr);
+
+void malloced_array() {
+  int *array0 = (int *)malloc(sizeof(int) * 20);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+  int *zeroed = (int *)calloc(20, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+  int *aligned = (int *)align_malloc(20 * sizeof(int), 16);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+  // reallocation memory, std::vector shall be used
+  char *realloced = (char *)realloc(array0, 50 * sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+  char *align_realloced = (char *)align_realloc(aligned, 50 * sizeof(int), 16);
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+  // freeing memory the bad way
+  free(realloced);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+  align_free(align_realloced);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+  
+  // check if a call to malloc as function argument is found as well
+  free(malloc(20));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+  // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
+
+/// newing an array is still not good, but not relevant to this checker
+void newed_array() {
+  int *new_array = new int[10]; // OK(1)
+}
+
+void arbitrary_call() {
+  // we dont want every function to raise the warning even if malloc is in the name
+  malloced_array(); // OK(2)
+
+  // completly unrelated function call to malloc
+  newed_array(); // OK(3)
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-no-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-no-functions.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-no-functions.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc-no-functions.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: cppcoreguidelines-no-malloc.Allocations, value: "::malloc"},\
+// RUN:   {key: cppcoreguidelines-no-malloc.Reallocations, value: ""},\
+// RUN:   {key: cppcoreguidelines-no-malloc.Deallocations, value: ""}]}' \
+// RUN: --
+
+// Just ensure, the check will not crash, when no functions shall be checked.
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+
+void malloced_array() {
+  int *array0 = (int *)malloc(sizeof(int) * 20);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-no-malloc.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-no-malloc %t
+
+using size_t = __SIZE_TYPE__;
+
+void *malloc(size_t size);
+void *calloc(size_t num, size_t size);
+void *realloc(void *ptr, size_t size);
+void free(void *ptr);
+
+void malloced_array() {
+  int *array0 = (int *)malloc(sizeof(int) * 20);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+  int *zeroed = (int *)calloc(20, sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+
+  // reallocation memory, std::vector shall be used
+  char *realloced = (char *)realloc(array0, 50 * sizeof(int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: do not manage memory manually; consider std::vector or std::string [cppcoreguidelines-no-malloc]
+
+  // freeing memory the bad way
+  free(realloced);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+
+  // check if a call to malloc as function argument is found as well
+  free(malloc(20));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not manage memory manually; use RAII [cppcoreguidelines-no-malloc]
+  // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: do not manage memory manually; consider a container or a smart pointer [cppcoreguidelines-no-malloc]
+}
+
+/// newing an array is still not good, but not relevant to this checker
+void newed_array() {
+  int *new_array = new int[10]; // OK(1)
+}
+
+void arbitrary_call() {
+  // we dont want every function to raise the warning even if malloc is in the name
+  malloced_array(); // OK(2)
+
+  // completly unrelated function call to malloc
+  newed_array(); // OK(3)
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-containers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-containers.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-containers.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-containers.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,62 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t
+
+namespace gsl {
+template <typename T>
+using owner = T;
+}
+
+namespace std {
+
+// Not actually a vector, but more a dynamic, fixed size array. Just to demonstrate
+// functionality or the lack of the same.
+template <typename T>
+class vector {
+public:
+  vector(unsigned long size, T val) : data{new T[size]}, size{size} {
+    for (unsigned long i = 0ul; i < size; ++i) {
+      data[i] = val;
+    }
+  }
+
+  T *begin() { return data; }
+  T *end() { return &data[size]; }
+  T &operator[](unsigned long index) { return data[index]; }
+
+private:
+  T *data;
+  unsigned long size;
+};
+
+} // namespace std
+
+// All of the following codesnippets should be valid with appropriate 'owner<>' anaylsis,
+// but currently the type information of 'gsl::owner<>' gets lost in typededuction.
+int main() {
+  std::vector<gsl::owner<int *>> OwnerStdVector(100, nullptr);
+
+  // Rangebased looping in resource vector.
+  for (auto *Element : OwnerStdVector) {
+    Element = new int(42);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+  }
+  for (auto *Element : OwnerStdVector) {
+    delete Element;
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+    // CHECK-NOTES: [[@LINE-3]]:8: note: variable declared here
+  }
+
+  // Indexbased looping in resource vector.
+  for (int i = 0; i < 100; ++i) {
+    OwnerStdVector[i] = new int(42);
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+  }
+  for (int i = 0; i < 100; ++i) {
+    delete OwnerStdVector[i];
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+    // CHECK-NOTES: [[@LINE-21]]:3: note: variable declared here
+    // A note gets emitted here pointing to the return value of the operator[] from the
+    // vector implementation. Maybe this is considered misleading.
+  }
+
+  return 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-legacy-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-legacy-functions.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-legacy-functions.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory-legacy-functions.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,194 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: cppcoreguidelines-owning-memory.LegacyResourceProducers, value: "::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile"}, \
+// RUN:   {key: cppcoreguidelines-owning-memory.LegacyResourceConsumers, value: "::free;::realloc;::freopen;::fclose"}]}' \
+// RUN: -- -nostdlib -nostdinc++
+
+namespace gsl {
+template <class T>
+using owner = T;
+} // namespace gsl
+
+extern "C" {
+using size_t = decltype(sizeof(void*));
+using FILE = int;
+
+void *malloc(size_t ByteCount);
+void *aligned_alloc(size_t Alignment, size_t Size);
+void *calloc(size_t Count, size_t SizeSingle);
+void *realloc(void *Resource, size_t NewByteCount);
+void free(void *Resource);
+
+FILE *tmpfile(void);
+FILE *fopen(const char *filename, const char *mode);
+FILE *freopen(const char *filename, const char *mode, FILE *stream);
+void fclose(FILE *Resource);
+}
+
+namespace std {
+using ::FILE;
+using ::size_t;
+
+using ::fclose;
+using ::fopen;
+using ::freopen;
+using ::tmpfile;
+
+using ::aligned_alloc;
+using ::calloc;
+using ::free;
+using ::malloc;
+using ::realloc;
+} // namespace std
+
+void nonOwningCall(int *Resource, size_t Size) {}
+void nonOwningCall(FILE *Resource) {}
+
+void consumesResource(gsl::owner<int *> Resource, size_t Size) {}
+void consumesResource(gsl::owner<FILE *> Resource) {}
+
+void testNonCasted(void *Resource) {}
+
+void testNonCastedOwner(gsl::owner<void *> Resource) {}
+
+FILE *fileFactory1() { return ::fopen("new_file.txt", "w"); }
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: returning a newly created resource of type 'FILE *' (aka 'int *') or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+gsl::owner<FILE *> fileFactory2() { return std::fopen("new_file.txt", "w"); } // Ok
+
+int *arrayFactory1() { return (int *)std::malloc(100); }
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: returning a newly created resource of type 'int *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+gsl::owner<int *> arrayFactory2() { return (int *)std::malloc(100); } // Ok
+void *dataFactory1() { return std::malloc(100); }
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: returning a newly created resource of type 'void *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+gsl::owner<void *> dataFactory2() { return std::malloc(100); } // Ok
+
+void test_resource_creators() {
+  const unsigned int ByteCount = 25 * sizeof(int);
+  int Bad = 42;
+
+  int *IntArray1 = (int *)std::malloc(ByteCount);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  int *IntArray2 = static_cast<int *>(std::malloc(ByteCount)); // Bad
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  void *IntArray3 = std::malloc(ByteCount);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'void *' with a newly created 'gsl::owner<>'
+
+  int *IntArray4 = (int *)::malloc(ByteCount);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  int *IntArray5 = static_cast<int *>(::malloc(ByteCount)); // Bad
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  void *IntArray6 = ::malloc(ByteCount);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'void *' with a newly created 'gsl::owner<>'
+
+  gsl::owner<int *> IntArray7 = (int *)malloc(ByteCount); // Ok
+  gsl::owner<void *> IntArray8 = malloc(ByteCount);       // Ok
+
+  gsl::owner<int *> IntArray9 = &Bad;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+  nonOwningCall((int *)malloc(ByteCount), 25);
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+  nonOwningCall((int *)::malloc(ByteCount), 25);
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+
+  consumesResource((int *)malloc(ByteCount), 25);   // Ok
+  consumesResource((int *)::malloc(ByteCount), 25); // Ok
+
+  testNonCasted(malloc(ByteCount));
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'void *' with a newly created 'gsl::owner<>'
+  testNonCastedOwner(gsl::owner<void *>(malloc(ByteCount))); // Ok
+  testNonCastedOwner(malloc(ByteCount));                     // Ok
+
+  FILE *File1 = std::fopen("test_name.txt", "w+");
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+  FILE *File2 = ::fopen("test_name.txt", "w+");
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+
+  gsl::owner<FILE *> File3 = ::fopen("test_name.txt", "w+"); // Ok
+
+  FILE *File4;
+  File4 = ::fopen("test_name.txt", "w+");
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: assigning newly created 'gsl::owner<>' to non-owner 'FILE *' (aka 'int *')
+
+  gsl::owner<FILE *> File5;
+  File5 = ::fopen("test_name.txt", "w+"); // Ok
+  File5 = File1;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'FILE *' (aka 'int *')
+
+  gsl::owner<FILE *> File6 = File1;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'FILE *' (aka 'int *')
+
+  FILE *File7 = tmpfile();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+  gsl::owner<FILE *> File8 = tmpfile(); // Ok
+
+  nonOwningCall(::fopen("test_name.txt", "r"));
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+  nonOwningCall(std::fopen("test_name.txt", "r"));
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+
+  consumesResource(::fopen("test_name.txt", "r")); // Ok
+
+  int *HeapPointer3 = (int *)aligned_alloc(16ul, 4ul * 32ul);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  gsl::owner<int *> HeapPointer4 = static_cast<int *>(aligned_alloc(16ul, 4ul * 32ul)); // Ok
+
+  void *HeapPointer5 = calloc(10ul, 4ul);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'void *' with a newly created 'gsl::owner<>'
+  gsl::owner<void *> HeapPointer6 = calloc(10ul, 4ul); // Ok
+}
+
+void test_legacy_consumers() {
+  int StackInteger = 42;
+
+  int *StackPointer = &StackInteger;
+  int *HeapPointer1 = (int *)malloc(100);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  gsl::owner<int *> HeapPointer2 = (int *)malloc(100);
+
+  std::free(StackPointer);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+  std::free(HeapPointer1);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+  std::free(HeapPointer2); // Ok
+  // CHECK MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+
+  // FIXME: the check complains about initialization of 'void *' with new created owner.
+  // This happens, because the argument of `free` is not marked as 'owner<>' (and cannot be),
+  // and the check will not figure out could be meant as owner.
+  // This property will probably never be fixed, because it is probably a rather rare
+  // use-case and 'owner<>' should be wrapped in RAII classes anyway!
+  std::free(std::malloc(100)); // Ok but silly :)
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: initializing non-owner argument of type 'void *' with a newly created 'gsl::owner<>'
+
+  // Demonstrate, that multi-argument functions are diagnosed as well.
+  std::realloc(StackPointer, 200);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+  std::realloc(HeapPointer1, 200);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+  std::realloc(HeapPointer2, 200);     // Ok
+  std::realloc(std::malloc(100), 200); // Ok but silly
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: initializing non-owner argument of type 'void *' with a newly created 'gsl::owner<>'
+
+  fclose(fileFactory1());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: calling legacy resource function without passing a 'gsl::owner<>'
+  fclose(fileFactory2()); // Ok, same as FIXME with `free(malloc(100))` applies here
+  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: initializing non-owner argument of type 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+
+  gsl::owner<FILE *> File1 = fopen("testfile.txt", "r"); // Ok
+  FILE *File2 = freopen("testfile.txt", "w", File1);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+  // CHECK-MESSAGES: [[@LINE-2]]:17: warning: calling legacy resource function without passing a 'gsl::owner<>'
+  // FIXME: The warning for not passing and owner<> is a false positive since both the filename and the
+  // mode are not supposed to be owners but still pointers. The check is to coarse for
+  // this function. Maybe `freopen` gets special treatment.
+
+  gsl::owner<FILE *> File3 = freopen("testfile.txt", "w", File2); // Bad, File2 no owner
+  // CHECK-MESSAGES: [[@LINE-1]]:30: warning: calling legacy resource function without passing a 'gsl::owner<>'
+
+  FILE *TmpFile = tmpfile();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+  FILE *File6 = freopen("testfile.txt", "w", TmpFile); // Bad, both return and argument
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: initializing non-owner 'FILE *' (aka 'int *') with a newly created 'gsl::owner<>'
+  // CHECK-MESSAGES: [[@LINE-2]]:17: warning: calling legacy resource function without passing a 'gsl::owner<>'
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-owning-memory.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,391 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-owning-memory %t
+
+namespace gsl {
+template <class T>
+using owner = T;
+} // namespace gsl
+
+template <typename T>
+class unique_ptr {
+public:
+  unique_ptr(gsl::owner<T> resource) : memory(resource) {}
+  unique_ptr(const unique_ptr<T> &) = default;
+
+  ~unique_ptr() { delete memory; }
+
+private:
+  gsl::owner<T> memory;
+};
+
+void takes_owner(gsl::owner<int *> owned_int) {
+}
+
+void takes_pointer(int *unowned_int) {
+}
+
+void takes_owner_and_more(int some_int, gsl::owner<int *> owned_int, float f) {
+}
+
+template <typename T>
+void takes_templated_owner(gsl::owner<T> owned_T) {
+}
+
+gsl::owner<int *> returns_owner1() { return gsl::owner<int *>(new int(42)); } // Ok
+gsl::owner<int *> returns_owner2() { return new int(42); }                    // Ok
+
+int *returns_no_owner1() { return nullptr; }
+int *returns_no_owner2() {
+  return new int(42);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: returning a newly created resource of type 'int *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+}
+int *returns_no_owner3() {
+  int *should_be_owner = new int(42);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  return should_be_owner;
+}
+int *returns_no_owner4() {
+  gsl::owner<int *> owner = new int(42);
+  return owner;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: returning a newly created resource of type 'int *' or 'gsl::owner<>' from a function whose return type is not 'gsl::owner<>'
+}
+
+unique_ptr<int *> returns_no_owner5() {
+  return unique_ptr<int *>(new int(42)); // Ok
+}
+
+/// FIXME: CSA finds it, but the report is misleading. Ownersemantics can catch this
+/// by flow analysis similar to bugprone-use-after-move.
+void csa_not_finding_leak() {
+  gsl::owner<int *> o1 = new int(42); // Ok
+
+  gsl::owner<int *> o2 = o1; // Ok
+  o2 = new int(45);          // conceptual leak, the memory from o1 is now leaked, since its considered moved in the guidelines
+
+  delete o2;
+  // actual leak occurs here, its found, but mixed
+  delete o1;
+}
+
+void test_assignment_and_initialization() {
+  int stack_int1 = 15;
+  int stack_int2;
+
+  gsl::owner<int *> owned_int1 = &stack_int1; // BAD
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+  gsl::owner<int *> owned_int2;
+  owned_int2 = &stack_int2; // BAD since no owner, bad since uninitialized
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'int *'
+
+  gsl::owner<int *> owned_int3 = new int(42); // Good
+  owned_int3 = nullptr;                       // Good
+
+  gsl::owner<int *> owned_int4(nullptr); // Ok
+  owned_int4 = new int(42);              // Good
+
+  gsl::owner<int *> owned_int5 = owned_int3; // Good
+
+  gsl::owner<int *> owned_int6{nullptr}; // Ok
+  owned_int6 = owned_int4;               // Good
+
+  // FIXME:, flow analysis for the case of reassignment. Value must be released before
+  owned_int6 = owned_int3; // BAD, because reassignment without resource release
+
+  auto owned_int7 = returns_owner1(); // Bad, since type deduction eliminates the owner wrapper
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+  const auto owned_int8 = returns_owner2(); // Bad, since type deduction eliminates the owner wrapper
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *const' with a newly created 'gsl::owner<>'
+  // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+  gsl::owner<int *> owned_int9 = returns_owner1(); // Ok
+  int *unowned_int3 = returns_owner1();            // Bad
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+
+  gsl::owner<int *> owned_int10;
+  owned_int10 = returns_owner1(); // Ok
+
+  int *unowned_int4;
+  unowned_int4 = returns_owner1(); // Bad
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+
+  gsl::owner<int *> owned_int11 = returns_no_owner1(); // Bad since no owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+  gsl::owner<int *> owned_int12;
+  owned_int12 = returns_no_owner1(); // Bad since no owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'int *'
+
+  int *unowned_int5 = returns_no_owner1(); // Ok
+  int *unowned_int6;
+  unowned_int6 = returns_no_owner1(); // Ok
+
+  int *unowned_int7 = new int(42); // Bad, since resource not assigned to an owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+
+  int *unowned_int8;
+  unowned_int8 = new int(42);
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: assigning newly created 'gsl::owner<>' to non-owner 'int *'
+
+  gsl::owner<int *> owned_int13 = nullptr; // Ok
+}
+
+void test_deletion() {
+  gsl::owner<int *> owned_int1 = new int(42);
+  delete owned_int1; // Good
+
+  gsl::owner<int *> owned_int2 = new int[42];
+  delete[] owned_int2; // Good
+
+  int *unowned_int1 = new int(42); // BAD, since new creates and owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  delete unowned_int1; // BAD, since no owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+  // CHECK-NOTES: [[@LINE-4]]:3: note: variable declared here
+
+  int *unowned_int2 = new int[42]; // BAD, since new creates and owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'int *' with a newly created 'gsl::owner<>'
+  delete[] unowned_int2; // BAD since no owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: deleting a pointer through a type that is not marked 'gsl::owner<>'; consider using a smart pointer instead
+  // CHECK-NOTES: [[@LINE-4]]:3: note: variable declared here
+
+  delete new int(42);   // Technically ok, but stupid
+  delete[] new int[42]; // Technically ok, but stupid
+}
+
+void test_owner_function_calls() {
+  int stack_int = 42;
+  int *unowned_int1 = &stack_int;
+  takes_owner(&stack_int); // BAD
+  // CHECK-NOTES: [[@LINE-1]]:15: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+  takes_owner(unowned_int1); // BAD
+  // CHECK-NOTES: [[@LINE-1]]:15: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+
+  gsl::owner<int *> owned_int1 = new int(42);
+  takes_owner(owned_int1); // Ok
+
+  takes_owner_and_more(42, &stack_int, 42.0f); // BAD
+  // CHECK-NOTES: [[@LINE-1]]:28: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+  takes_owner_and_more(42, unowned_int1, 42.0f); // BAD
+  // CHECK-NOTES: [[@LINE-1]]:28: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+
+  takes_owner_and_more(42, new int(42), 42.0f); // Ok, since new is consumed by owner
+  takes_owner_and_more(42, owned_int1, 42.0f);  // Ok, since owner as argument
+
+  takes_templated_owner(owned_int1);   // Ok
+  takes_templated_owner(new int(42));  // Ok
+  takes_templated_owner(unowned_int1); // Bad
+  // CHECK-NOTES: [[@LINE-1]]:25: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+
+  takes_owner(returns_owner1());    // Ok
+  takes_owner(returns_no_owner1()); // BAD
+  // CHECK-NOTES: [[@LINE-1]]:15: warning: expected argument of type 'gsl::owner<>'; got 'int *'
+}
+
+void test_unowned_function_calls() {
+  int stack_int = 42;
+  int *unowned_int1 = &stack_int;
+  gsl::owner<int *> owned_int1 = new int(42);
+
+  takes_pointer(&stack_int);   // Ok
+  takes_pointer(unowned_int1); // Ok
+  takes_pointer(owned_int1);   // Ok
+  takes_pointer(new int(42));  // Bad, since new creates and owner
+  // CHECK-NOTES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+
+  takes_pointer(returns_owner1()); // Bad
+  // CHECK-NOTES: [[@LINE-1]]:17: warning: initializing non-owner argument of type 'int *' with a newly created 'gsl::owner<>'
+
+  takes_pointer(returns_no_owner1()); // Ok
+}
+
+// FIXME: Typedefing owner<> to something else does not work.
+// This might be necessary for code already having a similar typedef like owner<> and
+// replacing it with owner<>. This might be the same problem as with templates.
+// The canonical type will ignore the owner<> alias, since its a typedef as well.
+//
+// Check, if owners hidden by typedef are handled the same as 'obvious' owners.
+#if 0
+using heap_int = gsl::owner<int *>;
+typedef gsl::owner<float *> heap_float;
+
+// This tests only a subset, assuming that the check will either see through the
+// typedef or not (it doesn't!).
+void test_typedefed_values() {
+  // Modern typedef.
+  int StackInt1 = 42;
+  heap_int HeapInt1 = &StackInt1;
+  // CHECK MESSAGES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'int *'
+
+  //FIXME: Typedef not considered correctly here.
+  // heap_int HeapInt2 = new int(42); // Ok
+  takes_pointer(HeapInt1); // Ok
+  takes_owner(HeapInt1);   // Ok
+
+  // Traditional typedef.
+  float StackFloat1 = 42.0f;
+  heap_float HeapFloat1 = &StackFloat1;
+  // CHECK MESSAGES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'float *'
+
+  //FIXME: Typedef not considered correctly here.
+  // heap_float HeapFloat2 = new float(42.0f);
+  HeapFloat2 = HeapFloat1; // Ok
+}
+#endif
+
+struct ArbitraryClass {};
+struct ClassWithOwner {                    // Does not define destructor, necessary with owner
+  ClassWithOwner() : owner_var(nullptr) {} // Ok
+
+  ClassWithOwner(ArbitraryClass &other) : owner_var(&other) {}
+  // CHECK-NOTES: [[@LINE-1]]:43: warning: expected initialization of owner member variable with value of type 'gsl::owner<>'; got 'ArbitraryClass *'
+
+  ClassWithOwner(gsl::owner<ArbitraryClass *> other) : owner_var(other) {} // Ok
+
+  ClassWithOwner(gsl::owner<ArbitraryClass *> data, int /* unused */) { // Ok
+    owner_var = data;                                                   // Ok
+  }
+
+  ClassWithOwner(ArbitraryClass *bad_data, int /* unused */, int /* unused */) {
+    owner_var = bad_data;
+    // CHECK-NOTES: [[@LINE-1]]:5: warning: expected assignment source to be of type 'gsl::owner<>'; got 'ArbitraryClass *'
+  }
+
+  ClassWithOwner(ClassWithOwner &&other) : owner_var{other.owner_var} {} // Ok
+
+  ClassWithOwner &operator=(ClassWithOwner &&other) {
+    owner_var = other.owner_var; // Ok
+    return *this;
+  }
+
+  // Returning means, that the owner is "moved", so the class should not access this
+  // variable anymore after this method gets called.
+  gsl::owner<ArbitraryClass *> buggy_but_returns_owner() { return owner_var; }
+
+  gsl::owner<ArbitraryClass *> owner_var;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: member variable of type 'gsl::owner<>' requires the class 'ClassWithOwner' to implement a destructor to release the owned resource
+};
+
+class DefaultedDestructor {         // Bad since default constructor with owner
+  ~DefaultedDestructor() = default; // Bad, since will not destroy the owner
+  gsl::owner<int *> Owner;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: member variable of type 'gsl::owner<>' requires the class 'DefaultedDestructor' to implement a destructor to release the owned resource
+};
+
+struct DeletedDestructor {
+  ~DeletedDestructor() = delete;
+  gsl::owner<int *> Owner;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: member variable of type 'gsl::owner<>' requires the class 'DeletedDestructor' to implement a destructor to release the owned resource
+};
+
+void test_class_with_owner() {
+  ArbitraryClass A;
+  ClassWithOwner C1;                                                   // Ok
+  ClassWithOwner C2{A};                                                // Bad, since the owner would be initialized with an non-owner, but catched in the class
+  ClassWithOwner C3{gsl::owner<ArbitraryClass *>(new ArbitraryClass)}; // Ok
+
+  const auto Owner1 = C3.buggy_but_returns_owner(); // BAD, deduces Owner1 to ArbitraryClass *const
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'ArbitraryClass *const' with a newly created 'gsl::owner<>'
+  // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+  auto Owner2 = C2.buggy_but_returns_owner(); // BAD, deduces Owner2 to ArbitraryClass *
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: initializing non-owner 'ArbitraryClass *' with a newly created 'gsl::owner<>'
+  // CHECK-NOTES: [[@LINE-2]]:3: note: type deduction did not result in an owner
+
+  Owner2 = &A; // Ok, since type deduction did NOT result in owner<int*>
+
+  gsl::owner<ArbitraryClass *> Owner3 = C1.buggy_but_returns_owner(); // Ok, still an owner
+  Owner3 = &A;                                                        // Bad, since assignment of non-owner to owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected assignment source to be of type 'gsl::owner<>'; got 'ArbitraryClass *'
+}
+
+template <typename T>
+struct HeapArray {                                          // Ok, since destructor with owner
+  HeapArray() : _data(nullptr), size(0) {}                  // Ok
+  HeapArray(int size) : _data(new int[size]), size(size) {} // Ok
+  HeapArray(int size, T val) {
+    _data = new int[size]; // Ok
+    size = size;
+    for (auto i = 0u; i < size; ++i)
+      _data[i] = val; // Ok
+  }
+  HeapArray(int size, T val, int *problematic) : _data{problematic}, size(size) {} // Bad
+  // CHECK-NOTES: [[@LINE-1]]:50: warning: expected initialization of owner member variable with value of type 'gsl::owner<>'; got 'void'
+  // FIXME: void is incorrect type, probably wrong thing matched
+
+  HeapArray(HeapArray &&other) : _data(other._data), size(other.size) { // Ok
+    other._data = nullptr;                                              // Ok
+    other.size = 0;
+  }
+
+  HeapArray<T> &operator=(HeapArray<T> &&other) {
+    _data = other._data; // Ok, NOLINT warning here about bad types, why?
+    size = other.size;
+    return *this;
+  }
+
+  ~HeapArray() { delete[] _data; } // Ok
+
+  T *data() { return _data; } // Ok NOLINT, because it "looks" like a factory
+
+  gsl::owner<T *> _data;
+  unsigned int size;
+};
+
+void test_inner_template() {
+  HeapArray<int> Array1;
+  HeapArray<int> Array2(100);
+  HeapArray<int> Array3(100, 0);
+  HeapArray<int> Array4(100, 0, nullptr);
+
+  Array1 = static_cast<HeapArray<int> &&>(Array2);
+  HeapArray<int> Array5(static_cast<HeapArray<int> &&>(Array3));
+
+  int *NonOwningPtr = Array1.data();           // Ok
+  gsl::owner<int *> OwningPtr = Array1.data(); // Bad, since it does not return the owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+}
+
+// FIXME: Typededuction removes the owner - wrapper, therefore gsl::owner can not be used
+// with Template classes like this. Is there a walkaround?
+template <typename T>
+struct TemplateValue {
+  TemplateValue() = default;
+  TemplateValue(T t) : val{t} {}
+
+  void setVal(const T &t) { val = t; }
+  const T getVal() const { return val; }
+
+  T val;
+};
+
+// FIXME: Same typededcution problems
+template <typename T>
+void template_function(T t) {
+  gsl::owner<int *> owner_t = t; // Probably bad, since type deduction still wrong
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'T'
+  // CHECK-NOTES: [[@LINE-2]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+}
+
+// FIXME: Same typededcution problems
+void test_templates() {
+  int stack_int = 42;
+  int *stack_ptr1 = &stack_int;
+
+  TemplateValue<gsl::owner<int *>> Owner0; // Ok, T should be owner, but is int*
+
+  TemplateValue<gsl::owner<int *>> Owner1(new int(42)); // Ok, T should be owner, but is int*
+  Owner1.setVal(&stack_int);                            // Bad since non-owner assignment
+  Owner1.setVal(stack_ptr1);                            // Bad since non-owner assignment
+  //Owner1.setVal(new int(42)); // Ok, but since type deduction is wrong, this one is considered harmful
+
+  int *stack_ptr2 = Owner1.getVal(); // Bad, initializing non-owner with owner
+
+  TemplateValue<int *> NonOwner1(new int(42));      // Bad, T is int *, hence dynamic memory to non-owner
+  gsl::owner<int *> IntOwner1 = NonOwner1.getVal(); // Bad, since owner initialized with non-owner
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: expected initialization with value of type 'gsl::owner<>'; got 'int *'
+
+  template_function(IntOwner1);  // Ok, but not actually ok, since type deduction removes owner
+  template_function(stack_ptr1); // Bad, but type deduction gets it wrong
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-array-to-pointer-decay.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-array-to-pointer-decay %t
+#include <stddef.h>
+
+namespace gsl {
+template <class T>
+class array_view {
+public:
+  template <class U, size_t N>
+  array_view(U (&arr)[N]);
+};
+}
+
+void pointerfun(int *p);
+void arrayfun(int p[]);
+void arrayviewfun(gsl::array_view<int> &p);
+size_t s();
+
+void f() {
+  int a[5];
+  pointerfun(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not implicitly decay an array into a pointer; consider using gsl::array_view or an explicit cast instead [cppcoreguidelines-pro-bounds-array-to-pointer-decay]
+  pointerfun((int *)a); // OK, explicit cast
+  arrayfun(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not implicitly decay an array into a pointer
+
+  pointerfun(a + s() - 10); // Convert to &a[g() - 10];
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not implicitly decay an array into a pointer
+
+  gsl::array_view<int> av(a);
+  arrayviewfun(av); // OK
+
+  int i = a[0];      // OK
+  int j = a[(1 + 2)];// OK
+  pointerfun(&a[0]); // OK
+
+  for (auto &e : a) // OK, iteration internally decays array to pointer
+    e = 1;
+}
+
+const char *g() {
+  return "clang"; // OK, decay string literal to pointer
+}
+const char *g2() {
+    return ("clang"); // OK, ParenExpr hides the literal-pointer decay
+}
+
+void f2(void *const *);
+void bug25362() {
+  void *a[2];
+  f2(static_cast<void *const*>(a)); // OK, explicit cast
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-c++03.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-c%2B%2B03.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-c++03.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-c++03.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy -std=c++98-or-later %s cppcoreguidelines-pro-bounds-constant-array-index %t
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+template <int index> struct B {
+  int get() {
+    // The next line used to crash the check (in C++03 mode only).
+    return x[index];
+    // CHECK-FIXES: return x[index];
+  }
+  int x[3];
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index-gslheader.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,80 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t -- \
+// RUN:     -config='{CheckOptions: [{key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader, value: "dir1/gslheader.h"}]}'
+// CHECK-FIXES: #include "dir1/gslheader.h"
+
+typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+  template<typename T, size_t N>
+  struct array {
+    T& operator[](size_t n);
+    T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template<class T, size_t N>
+  T& at( T(&a)[N], size_t index );
+
+  template<class T, size_t N>
+  T& at( std::array<T, N> &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  return base + 3;
+}
+
+void f(std::array<int, 10> a, int pos) {
+  a [ pos / 2 /*comment*/] = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+  // CHECK-FIXES: gsl::at(a,  pos / 2 /*comment*/) = 1;
+  int j = a[pos - 1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+  // CHECK-FIXES: int j = gsl::at(a, pos - 1);
+
+  a.at(pos-1) = 2; // OK, at() instead of []
+  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+  a[-1] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
+  a[10] = 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+  a[const_index(7)] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+  int a[10];
+  for (int i = 0; i < 10; ++i) {
+    a[i] = i;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+    // CHECK-FIXES: gsl::at(a, i) = i;
+    gsl::at(a, i) = i; // OK, gsl::at() instead of []
+  }
+
+  a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+  a[10] = 4; // flagged by clang-diagnostic-array-bounds
+  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+  int& operator[](int i);
+};
+
+void customOperator() {
+  S s;
+  int i = 0;
+  s[i] = 3; // OK, custom operator
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-constant-array-index.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,87 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-constant-array-index %t
+
+typedef __SIZE_TYPE__ size_t;
+
+namespace std {
+  template<typename T, size_t N>
+  struct array {
+    T& operator[](size_t n);
+    T& at(size_t n);
+  };
+}
+
+
+namespace gsl {
+  template<class T, size_t N>
+  T& at( T(&a)[N], size_t index );
+
+  template<class T, size_t N>
+  T& at( std::array<T, N> &a, size_t index );
+}
+
+constexpr int const_index(int base) {
+  return base + 3;
+}
+
+void f(std::array<int, 10> a, int pos) {
+  a [ pos / 2 /*comment*/] = 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead [cppcoreguidelines-pro-bounds-constant-array-index]
+  int j = a[pos - 1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+
+  a.at(pos-1) = 2; // OK, at() instead of []
+  gsl::at(a, pos-1) = 2; // OK, gsl::at() instead of []
+
+  a[-1] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index -1 is negative [cppcoreguidelines-pro-bounds-constant-array-index]
+  a[10] = 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements) [cppcoreguidelines-pro-bounds-constant-array-index]
+
+  a[const_index(7)] = 3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: std::array<> index 10 is past the end of the array (which contains 10 elements)
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+void g() {
+  int a[10];
+  for (int i = 0; i < 10; ++i) {
+    a[i] = i;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use array subscript when the index is not an integer constant expression; use gsl::at() instead
+    // CHECK-FIXES: gsl::at(a, i) = i;
+    gsl::at(a, i) = i; // OK, gsl::at() instead of []
+  }
+
+  a[-1] = 3; // flagged by clang-diagnostic-array-bounds
+  a[10] = 4; // flagged by clang-diagnostic-array-bounds
+  a[const_index(7)] = 3; // flagged by clang-diagnostic-array-bounds
+
+  a[0] = 3; // OK, constant index and inside bounds
+  a[1] = 3; // OK, constant index and inside bounds
+  a[9] = 3; // OK, constant index and inside bounds
+  a[const_index(6)] = 3; // OK, constant index and inside bounds
+}
+
+struct S {
+  int& operator[](int i);
+};
+
+void customOperator() {
+  S s;
+  int i = 0;
+  s[i] = 3; // OK, custom operator
+}
+
+struct A {
+  // The compiler-generated copy constructor uses an ArraySubscriptExpr. Don't warn.
+  int x[3];
+};
+
+void use_A() {
+  // Force the compiler to generate a copy constructor.
+  A a;
+  A a2(a);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic-pr36489.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,53 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+// Fix PR36489 and detect auto-deduced value correctly.
+char *getPtr();
+auto getPtrAuto() { return getPtr(); }
+decltype(getPtr()) getPtrDeclType();
+decltype(auto) getPtrDeclTypeAuto() { return getPtr(); }
+auto getPtrWithTrailingReturnType() -> char *;
+
+void auto_deduction_binary() {
+  auto p1 = getPtr() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: do not use pointer arithmetic
+  auto p2 = getPtrAuto() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: do not use pointer arithmetic
+  auto p3 = getPtrWithTrailingReturnType() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: do not use pointer arithmetic
+  auto p4 = getPtr();
+  auto *p5 = getPtr();
+  p4 = p4 + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use pointer arithmetic
+  p5 = p5 + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use pointer arithmetic
+  auto p6 = getPtrDeclType() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: do not use pointer arithmetic
+  auto p7 = getPtrDeclTypeAuto() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: do not use pointer arithmetic
+  auto *p8 = getPtrDeclType() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: do not use pointer arithmetic
+  auto *p9 = getPtrDeclTypeAuto() + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: do not use pointer arithmetic
+}
+
+void auto_deduction_subscript() {
+  char p1 = getPtr()[2];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+  auto p2 = getPtr()[3];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+
+  char p3 = getPtrAuto()[4];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+  auto p4 = getPtrAuto()[5];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+
+  char p5 = getPtrWithTrailingReturnType()[6];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+  auto p6 = getPtrWithTrailingReturnType()[7];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+
+  auto p7 = getPtrDeclType()[8];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+  auto p8 = getPtrDeclTypeAuto()[9];
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use pointer arithmetic
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-bounds-pointer-arithmetic.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,89 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-bounds-pointer-arithmetic %t
+
+enum E {
+  ENUM_LITERAL = 1
+};
+
+int i = 4;
+int j = 1;
+int *p = 0;
+int *q = 0;
+
+void fail() {
+  q = p + 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic [cppcoreguidelines-pro-bounds-pointer-arithmetic]
+  p = q + i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q + ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  q = p - 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+  p = q - ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+
+  p += 4;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  p += ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  q -= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+  q -= ENUM_LITERAL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not use pointer arithmetic
+
+  p++;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  ++p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  p--;
+  // CHECK-MESSAGES: :[[@LINE-1]]:4: warning: do not use pointer arithmetic
+  --p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+
+  i = p[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use pointer arithmetic
+}
+
+struct S {
+  operator int() const;
+};
+
+void f(S &s) {
+  int *i;
+  i = i + s;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not use pointer arithmetic
+}
+
+void f2(int i[]) {
+  i[1] = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use pointer arithmetic
+}
+
+void okay() {
+  int a[3];
+  i = a[2]; // OK, access to array
+
+  p = q;
+  p = &i;
+
+  i++;
+  ++i;
+  i--;
+  --i;
+  i += 1;
+  i -= 1;
+  i = j + 1;
+  i = j - 1;
+
+  auto diff = p - q; // OK, result is arithmetic
+
+  for(int ii : a) ; // OK, pointer arithmetic generated by compiler
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-const-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-const-cast.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-const-cast.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-const-cast.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,6 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-const-cast %t
+
+const int *i;
+int *j;
+void f() { j = const_cast<int *>(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use const_cast [cppcoreguidelines-pro-type-const-cast]

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-cstyle-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-cstyle-cast.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-cstyle-cast.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-cstyle-cast.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,141 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-cstyle-cast %t
+
+void reinterpretcast() {
+  int i = 0;
+  void *j;
+  j = (int*)j;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to convert between unrelated types [cppcoreguidelines-pro-type-cstyle-cast]
+}
+
+void constcast() {
+  int* i;
+  const int* j;
+  i = (int*)j;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to cast away constness
+  j = (const int*)i; // OK, const added
+  (void)j; // OK, not a const_cast
+}
+
+void const_and_reinterpret() {
+  int* i;
+  const void* j;
+  i = (int*)j;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not use C-style cast to convert between unrelated types
+}
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+  virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+  auto P0 = (Derived*)new Base();
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+
+  const Base* B0;
+  auto PC0 = (const Derived*)(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class
+
+  auto P1 = (Base*)new Derived(); // OK, upcast to a public base
+  auto P2 = (Base*)new MultiDerived(); // OK, upcast to a public base
+  auto P3 = (Base2*)new MultiDerived(); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+  auto PP0 = (PolymorphicDerived*)new PolymorphicBase();
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto PP0 = dynamic_cast<PolymorphicDerived*>(new PolymorphicBase());
+
+  const PolymorphicBase* B0;
+  auto PPC0 = (const PolymorphicDerived*)B0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto PPC0 = dynamic_cast<const PolymorphicDerived*>(B0);
+
+
+  auto B1 = (PolymorphicBase*)new PolymorphicDerived(); // OK, upcast to a public base
+  auto B2 = (PolymorphicBase*)new PolymorphicMultiDerived(); // OK, upcast to a public base
+  auto B3 = (Base*)new PolymorphicMultiDerived(); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto A0 = (Derived*)ArrayOfBase;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+}
+
+void arrays_polymorphic() {
+  PolymorphicBase ArrayOfPolymorphicBase[10];
+  auto AP0 = (PolymorphicDerived*)ArrayOfPolymorphicBase;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto AP0 = dynamic_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
+}
+
+void references() {
+  Base B0;
+  auto R0 = (Derived&)B0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+  Base& RefToBase = B0;
+  auto R1 = (Derived&)RefToBase;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use C-style cast to downcast from a base to a derived class
+
+  const Base& ConstRefToBase = B0;
+  auto RC1 = (const Derived&)ConstRefToBase;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class
+
+
+  Derived RD1;
+  auto R2 = (Base&)RD1; // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+  PolymorphicBase B0;
+  auto RP0 = (PolymorphicDerived&)B0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto RP0 = dynamic_cast<PolymorphicDerived&>(B0);
+
+  PolymorphicBase& RefToPolymorphicBase = B0;
+  auto RP1 = (PolymorphicDerived&)RefToPolymorphicBase;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto RP1 = dynamic_cast<PolymorphicDerived&>(RefToPolymorphicBase);
+
+  const PolymorphicBase& ConstRefToPolymorphicBase = B0;
+  auto RPC2 = (const PolymorphicDerived&)(ConstRefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use C-style cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto RPC2 = dynamic_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
+
+  PolymorphicDerived d1;
+  auto RP2 = (PolymorphicBase&)d1; // OK, upcast to a public base
+}
+
+template<class B, class D>
+void templ() {
+  auto B0 = (B*)new D();
+}
+
+void templ_bad_call() {
+  templ<Derived, Base>(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+  templ<Base, Derived>(); // OK, upcast to a public base
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx2a.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx2a.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx2a.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx2a.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,19 @@
+// RUN: %check_clang_tidy -std=c++2a %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing
+
+struct PositiveBitfieldMember {
+  PositiveBitfieldMember() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+  unsigned F : 5;
+  // CHECK-FIXES: unsigned F : 5{};
+};
+
+struct NegativeUnnamedBitfieldMember {
+  NegativeUnnamedBitfieldMember() {}
+  unsigned : 5;
+};
+
+struct NegativeInitializedBitfieldMembers {
+  NegativeInitializedBitfieldMembers() : F(3) { G = 2; }
+  unsigned F : 5;
+  unsigned G : 5;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx98.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx98.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx98.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-cxx98.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,116 @@
+// RUN: %check_clang_tidy -std=c++98 %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing
+
+struct PositiveFieldBeforeConstructor {
+  int F;
+  PositiveFieldBeforeConstructor() /* some comment */ {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+  // CHECK-FIXES: PositiveFieldBeforeConstructor() : F() /* some comment */ {}
+};
+
+struct PositiveFieldAfterConstructor {
+  PositiveFieldAfterConstructor() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G, H
+  // CHECK-FIXES: PositiveFieldAfterConstructor() : F(), G(), H() {}
+  int F;
+  bool G /* with comment */;
+  int *H;
+  PositiveFieldBeforeConstructor IgnoredField;
+};
+
+struct PositiveSeparateDefinition {
+  PositiveSeparateDefinition();
+  int F;
+};
+
+PositiveSeparateDefinition::PositiveSeparateDefinition() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+// CHECK-FIXES: PositiveSeparateDefinition::PositiveSeparateDefinition() : F() {}
+
+struct PositiveMixedFieldOrder {
+  PositiveMixedFieldOrder() : /* some comment */ J(0), L(0), M(0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: I, K, N
+  // CHECK-FIXES: PositiveMixedFieldOrder() : I(), /* some comment */ J(0), K(), L(0), M(0), N() {}
+  int I;
+  int J;
+  int K;
+  int L;
+  int M;
+  int N;
+};
+
+struct PositiveAfterBaseInitializer : public PositiveMixedFieldOrder {
+  PositiveAfterBaseInitializer() : PositiveMixedFieldOrder() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+  // CHECK-FIXES: PositiveAfterBaseInitializer() : PositiveMixedFieldOrder(), F() {}
+  int F;
+};
+
+struct NegativeFieldInitialized {
+  int F;
+
+  NegativeFieldInitialized() : F() {}
+};
+
+struct NegativeFieldInitializedInDefinition {
+  int F;
+
+  NegativeFieldInitializedInDefinition();
+};
+
+NegativeFieldInitializedInDefinition::NegativeFieldInitializedInDefinition() : F() {}
+
+struct NegativeInitializedInBody {
+  NegativeInitializedInBody() { I = 0; }
+  int I;
+};
+
+struct NegativeAggregateType {
+  int X;
+  int Y;
+  int Z;
+};
+
+struct TrivialType {
+  int X;
+  int Y;
+};
+
+struct PositiveUninitializedBaseOrdering : public NegativeAggregateType,
+                                           public TrivialType {
+  PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A
+  // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), TrivialType(), A(), B() {}
+
+  // This is somewhat pathological with the base class initializer at the end...
+  PositiveUninitializedBaseOrdering(int) : B(), TrivialType(), A() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
+  // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), TrivialType(), A() {}
+
+  PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), A() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: TrivialType
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: constructor does not initialize these fields: B
+  // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : NegativeAggregateType(), TrivialType(), A(), B() {}
+
+  int A, B;
+};
+
+template <class T>
+class PositiveTemplateBase : T {
+public:
+  PositiveTemplateBase() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: X
+  // CHECK-FIXES: PositiveTemplateBase() : X() {}
+
+  int X;
+};
+
+class PositiveIndirectMember {
+  struct {
+    int *A;
+  };
+
+  PositiveIndirectMember() : A() {}
+  PositiveIndirectMember(int) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A
+  // CHECK-FIXES: PositiveIndirectMember(int) : A() {}
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-delayed.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-delayed.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-delayed.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-delayed.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -- -fdelayed-template-parsing
+
+template <class T>
+struct PositiveFieldBeforeConstructor {
+  int F;
+  bool G /* with comment */;
+  int *H;
+  PositiveFieldBeforeConstructor() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G, H
+};
+// Explicit instantiation.
+template class PositiveFieldBeforeConstructor<int>;
+
+template <class T>
+struct PositiveFieldAfterConstructor {
+  PositiveFieldAfterConstructor() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G, H
+  int F;
+  bool G /* with comment */;
+  int *H;
+};
+// Explicit instantiation.
+template class PositiveFieldAfterConstructor<int>;
+
+// This declaration isn't used and won't be parsed 'delayed-template-parsing'.
+// The body of the declaration is 'null' and may cause crash if not handled
+// properly by checkers.
+template <class T>
+struct UnusedDelayedConstructor {
+  UnusedDelayedConstructor() {}
+  int F;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-no-crash.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-no-crash.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-no-crash.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-no-crash.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,7 @@
+// RUN: %check_clang_tidy -expect-clang-tidy-error %s cppcoreguidelines-pro-type-member-init %t
+
+struct X {
+  X x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: error: field has incomplete type 'X' [clang-diagnostic-error]
+  int a = 10;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-use-assignment.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-use-assignment.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-use-assignment.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init-use-assignment.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,40 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-member-init %t -- -config="{CheckOptions: [{key: "cppcoreguidelines-pro-type-member-init.UseAssignment", value: 1}]}" -- -fsigned-char
+
+struct T {
+  int i;
+};
+
+struct S {
+  bool b;
+  // CHECK-FIXES: bool b = false;
+  char c;
+  // CHECK-FIXES: char c = 0;
+  signed char sc;
+  // CHECK-FIXES: signed char sc = 0;
+  unsigned char uc;
+  // CHECK-FIXES: unsigned char uc = 0U;
+  int i;
+  // CHECK-FIXES: int i = 0;
+  unsigned u;
+  // CHECK-FIXES: unsigned u = 0U;
+  long l;
+  // CHECK-FIXES: long l = 0L;
+  unsigned long ul;
+  // CHECK-FIXES: unsigned long ul = 0UL;
+  long long ll;
+  // CHECK-FIXES: long long ll = 0LL;
+  unsigned long long ull;
+  // CHECK-FIXES: unsigned long long ull = 0ULL;
+  float f;
+  // CHECK-FIXES: float f = 0.0F;
+  double d;
+  // CHECK-FIXES: double d = 0.0;
+  long double ld;
+  // CHECK-FIXES: double ld = 0.0L;
+  int *ptr;
+  // CHECK-FIXES: int *ptr = nullptr;
+  T t;
+  // CHECK-FIXES: T t{};
+  S() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields:
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-member-init.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,503 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s cppcoreguidelines-pro-type-member-init %t -- -- -fno-delayed-template-parsing
+// FIXME: Fix the checker to work in C++2a mode.
+
+struct PositiveFieldBeforeConstructor {
+  int F;
+  // CHECK-FIXES: int F{};
+  PositiveFieldBeforeConstructor() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+  // CHECK-FIXES: PositiveFieldBeforeConstructor() {}
+};
+
+struct PositiveFieldAfterConstructor {
+  PositiveFieldAfterConstructor() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F, G
+  // CHECK-FIXES: PositiveFieldAfterConstructor() {}
+  int F;
+  // CHECK-FIXES: int F{};
+  bool G /* with comment */;
+  // CHECK-FIXES: bool G{} /* with comment */;
+  PositiveFieldBeforeConstructor IgnoredField;
+};
+
+struct PositiveSeparateDefinition {
+  PositiveSeparateDefinition();
+  int F;
+  // CHECK-FIXES: int F{};
+};
+
+PositiveSeparateDefinition::PositiveSeparateDefinition() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+// CHECK-FIXES: PositiveSeparateDefinition::PositiveSeparateDefinition() {}
+
+struct PositiveMixedFieldOrder {
+  PositiveMixedFieldOrder() : J(0) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: I, K
+  // CHECK-FIXES: PositiveMixedFieldOrder() : J(0) {}
+  int I;
+  // CHECK-FIXES: int I{};
+  int J;
+  int K;
+  // CHECK-FIXES: int K{};
+};
+
+template <typename T>
+struct Template {
+  Template() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+  int F;
+  // CHECK-FIXES: int F{};
+  T T1;
+  // CHECK-FIXES: T T1;
+};
+
+void instantiate() {
+  Template<int> TInt;
+}
+
+struct NegativeFieldInitialized {
+  int F;
+
+  NegativeFieldInitialized() : F() {}
+};
+
+struct NegativeFieldInitializedInDefinition {
+  int F;
+
+  NegativeFieldInitializedInDefinition();
+};
+NegativeFieldInitializedInDefinition::NegativeFieldInitializedInDefinition() : F() {}
+
+struct NegativeInClassInitialized {
+  int F = 0;
+
+  NegativeInClassInitialized() {}
+};
+
+struct NegativeInClassInitializedDefaulted {
+  int F = 0;
+  NegativeInClassInitializedDefaulted() = default;
+};
+
+struct NegativeConstructorDelegated {
+  int F;
+
+  NegativeConstructorDelegated(int F) : F(F) {}
+  NegativeConstructorDelegated() : NegativeConstructorDelegated(0) {}
+};
+
+struct NegativeInitializedInBody {
+  NegativeInitializedInBody() { I = 0; }
+  int I;
+};
+
+struct A {};
+template <class> class AA;
+template <class T> class NegativeTemplateConstructor {
+  NegativeTemplateConstructor(const AA<T> &, A) {}
+  bool Bool{false};
+  // CHECK-FIXES: bool Bool{false};
+};
+
+#define UNINITIALIZED_FIELD_IN_MACRO_BODY(FIELD) \
+  struct UninitializedField##FIELD {             \
+    UninitializedField##FIELD() {}               \
+    int FIELD;                                   \
+  };                                             \
+// Ensure FIELD is not initialized since fixes inside of macros are disabled.
+// CHECK-FIXES: int FIELD;
+
+UNINITIALIZED_FIELD_IN_MACRO_BODY(F);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+UNINITIALIZED_FIELD_IN_MACRO_BODY(G);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: G
+
+#define UNINITIALIZED_FIELD_IN_MACRO_ARGUMENT(ARGUMENT) \
+  ARGUMENT
+
+UNINITIALIZED_FIELD_IN_MACRO_ARGUMENT(struct UninitializedFieldInMacroArg {
+  UninitializedFieldInMacroArg() {}
+  int Field;
+});
+// CHECK-MESSAGES: :[[@LINE-3]]:3: warning: constructor does not initialize these fields: Field
+// Ensure FIELD is not initialized since fixes inside of macros are disabled.
+// CHECK-FIXES: int Field;
+
+struct NegativeAggregateType {
+  int X;
+  int Y;
+  int Z;
+};
+
+struct PositiveTrivialType {
+  PositiveTrivialType() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+
+  NegativeAggregateType F;
+  // CHECK-FIXES: NegativeAggregateType F{};
+};
+
+struct NegativeNonTrivialType {
+  PositiveTrivialType F;
+};
+
+static void PositiveUninitializedTrivialType() {
+  NegativeAggregateType X;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'X'
+  // CHECK-FIXES: NegativeAggregateType X{};
+
+  NegativeAggregateType A[10]; // Don't warn because this isn't an object type.
+}
+
+static void NegativeInitializedTrivialType() {
+  NegativeAggregateType X{};
+  NegativeAggregateType Y = {};
+  NegativeAggregateType Z = NegativeAggregateType();
+  NegativeAggregateType A[10]{};
+  NegativeAggregateType B[10] = {};
+  int C; // No need to initialize this because we don't have a constructor.
+  int D[8];
+  NegativeAggregateType E = {0, 1, 2};
+  NegativeAggregateType F({});
+}
+
+struct NonTrivialType {
+  NonTrivialType() = default;
+  NonTrivialType(const NonTrivialType &RHS) : X(RHS.X), Y(RHS.Y) {}
+
+  int X;
+  int Y;
+};
+
+static void PositiveNonTrivialTypeWithCopyConstructor() {
+  NonTrivialType T;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'T'
+  // CHECK-FIXES: NonTrivialType T{};
+
+  NonTrivialType A[8];
+  // Don't warn because this isn't an object type
+}
+
+struct ComplexNonTrivialType {
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: Y
+  NegativeFieldInitialized X;
+  int Y;
+  // CHECK-FIXES: int Y{};
+};
+
+static void PositiveComplexNonTrivialType() {
+  ComplexNonTrivialType T;
+}
+
+struct NegativeStaticMember {
+  static NonTrivialType X;
+  static NonTrivialType Y;
+  static constexpr NonTrivialType Z{};
+};
+
+NonTrivialType NegativeStaticMember::X;
+NonTrivialType NegativeStaticMember::Y{};
+
+struct PositiveMultipleConstructors {
+  PositiveMultipleConstructors() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B
+
+  PositiveMultipleConstructors(int) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B
+
+  PositiveMultipleConstructors(const PositiveMultipleConstructors &) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B
+
+  // FIXME: The fix-its here collide providing an erroneous fix
+  int A, B;
+  // CHECK-FIXES: int A{}{}{}, B{}{}{};
+};
+
+typedef struct {
+  int Member;
+} CStyleStruct;
+
+struct PositiveUninitializedBase : public NegativeAggregateType, CStyleStruct {
+  PositiveUninitializedBase() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType, CStyleStruct
+  // CHECK-FIXES: PositiveUninitializedBase() : NegativeAggregateType(), CStyleStruct() {}
+};
+
+struct PositiveUninitializedBaseOrdering : public NegativeAggregateType,
+                                           public NonTrivialType {
+  PositiveUninitializedBaseOrdering() : B() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType, NonTrivialType
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: constructor does not initialize these fields: A
+  // CHECK-FIXES: PositiveUninitializedBaseOrdering() : NegativeAggregateType(), NonTrivialType(), B() {}
+
+  // This is somewhat pathological with the base class initializer at the end...
+  PositiveUninitializedBaseOrdering(int) : B(), NonTrivialType(), A() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
+  // CHECK-FIXES: PositiveUninitializedBaseOrdering(int) : B(), NegativeAggregateType(), NonTrivialType(), A() {}
+
+  PositiveUninitializedBaseOrdering(float) : B(), NegativeAggregateType(), A() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NonTrivialType
+  // CHECK-FIXES: PositiveUninitializedBaseOrdering(float) : B(), NegativeAggregateType(), NonTrivialType(), A() {}
+
+  int A, B;
+  // CHECK-FIXES: int A{}, B;
+};
+
+// We shouldn't need to initialize anything because PositiveUninitializedBase
+// has a user-defined constructor.
+struct NegativeUninitializedBase : public PositiveUninitializedBase {
+  NegativeUninitializedBase() {}
+};
+
+struct InheritedAggregate : public NegativeAggregateType {
+  int F;
+};
+
+static InheritedAggregate NegativeGlobal;
+
+enum TestEnum {
+  A,
+  B,
+  C
+};
+
+enum class TestScopedEnum {
+  A,
+  B,
+  C
+};
+
+struct PositiveEnumType {
+  PositiveEnumType() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: X, Y
+  // No proposed fixes, as we don't know whether value initialization for these
+  // enums really makes sense.
+
+  TestEnum X;
+  TestScopedEnum Y;
+};
+
+extern "C" {
+struct NegativeCStruct {
+  int X, Y, Z;
+};
+
+static void PositiveCStructVariable() {
+  NegativeCStruct X;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: uninitialized record type: 'X'
+  // CHECK-FIXES: NegativeCStruct X{};
+}
+}
+
+static void NegativeStaticVariable() {
+  static NegativeCStruct S;
+  (void)S;
+}
+
+union NegativeUnionInClass {
+  NegativeUnionInClass() {} // No message as a union can only initialize one member.
+  int X = 0;
+  float Y;
+};
+
+union PositiveUnion {
+  PositiveUnion() : X() {} // No message as a union can only initialize one member.
+  PositiveUnion(int) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: union constructor should initialize one of these fields: X, Y
+
+  int X;
+  // CHECK-FIXES: int X{};
+
+  // Make sure we don't give Y an initializer.
+  float Y;
+  // CHECK-FIXES-NOT: float Y{};
+};
+
+union PositiveUnionReversed {
+  PositiveUnionReversed() : X() {} // No message as a union can only initialize one member.
+  PositiveUnionReversed(int) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: union constructor should initialize one of these fields: Y, X
+
+  // Make sure we don't give Y an initializer.
+  TestEnum Y;
+  // CHECK-FIXES-NOT: TestEnum Y{};
+
+  int X;
+  // CHECK-FIXES: int X{};
+};
+
+struct PositiveAnonymousUnionAndStruct {
+  PositiveAnonymousUnionAndStruct() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A, B, Y, Z, C, D, E, F, X
+
+  union {
+    int A;
+    // CHECK-FIXES: int A{};
+    short B;
+  };
+
+  struct {
+    int Y;
+    // CHECK-FIXES: int Y{};
+    char *Z;
+    // CHECK-FIXES: char *Z{};
+
+    struct {
+      short C;
+      // CHECK-FIXES: short C{};
+      double D;
+      // CHECK-FIXES: double D{};
+    };
+
+    union {
+      long E;
+      // CHECK-FIXES: long E{};
+      float F;
+    };
+  };
+  int X;
+  // CHECK-FIXES: int X{};
+};
+
+// This check results in a CXXConstructorDecl with no body.
+struct NegativeDeletedConstructor : NegativeAggregateType {
+  NegativeDeletedConstructor() = delete;
+
+  Template<int> F;
+};
+
+// This pathological template fails to compile if actually instantiated. It
+// results in the check seeing a null RecordDecl when examining the base class
+// initializer list.
+template <typename T>
+class PositiveSelfInitialization : NegativeAggregateType
+{
+  PositiveSelfInitialization() : PositiveSelfInitialization() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these bases: NegativeAggregateType
+  // CHECK-FIXES: PositiveSelfInitialization() : NegativeAggregateType(), PositiveSelfInitialization() {}
+};
+
+class PositiveIndirectMember {
+  struct {
+    int *A;
+    // CHECK-FIXES: int *A{};
+  };
+
+  PositiveIndirectMember() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: A
+};
+
+void Bug30487()
+{
+  NegativeInClassInitializedDefaulted s;
+}
+
+struct PositiveVirtualMethod {
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: F
+  int F;
+  // CHECK-FIXES: int F{};
+  virtual int f() = 0;
+};
+
+struct PositiveVirtualDestructor {
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: F
+  PositiveVirtualDestructor() = default;
+  int F;
+  // CHECK-FIXES: int F{};
+  virtual ~PositiveVirtualDestructor() {}
+};
+
+struct PositiveVirtualBase : public virtual NegativeAggregateType {
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these bases: NegativeAggregateType
+  // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: constructor does not initialize these fields: F
+  int F;
+  // CHECK-FIXES: int F{};
+};
+
+template <typename T>
+struct PositiveTemplateVirtualDestructor {
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: constructor does not initialize these fields: F
+  T Val;
+  int F;
+  // CHECK-FIXES: int F{};
+  virtual ~PositiveTemplateVirtualDestructor() = default;
+};
+
+template struct PositiveTemplateVirtualDestructor<int>;
+
+#define UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(FIELD) \
+  struct UninitializedFieldVirtual##FIELD {              \
+    int FIELD;                                           \
+    virtual ~UninitializedFieldVirtual##FIELD() {}       \
+  };                                                     \
+// Ensure FIELD is not initialized since fixes inside of macros are disabled.
+// CHECK-FIXES: int FIELD;
+
+UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(F);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: F
+UNINITIALIZED_FIELD_IN_MACRO_BODY_VIRTUAL(G);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: constructor does not initialize these fields: G
+
+struct NegativeEmpty {
+};
+
+static void NegativeEmptyVar() {
+  NegativeEmpty e;
+  (void)e;
+}
+
+struct NegativeEmptyMember {
+  NegativeEmptyMember() {}
+  NegativeEmpty e;
+};
+
+struct NegativeEmptyBase : NegativeEmpty {
+  NegativeEmptyBase() {}
+};
+
+struct NegativeEmptyArrayMember {
+  NegativeEmptyArrayMember() {}
+  char e[0];
+};
+
+struct NegativeIncompleteArrayMember {
+  NegativeIncompleteArrayMember() {}
+  char e[];
+};
+
+template <typename T> class NoCrash {
+  class B : public NoCrash {
+    template <typename U> B(U u) {}
+  };
+};
+
+struct PositiveBitfieldMember {
+  PositiveBitfieldMember() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructor does not initialize these fields: F
+  unsigned F : 5;
+  // CHECK-FIXES-NOT: unsigned F : 5{};
+};
+
+struct NegativeUnnamedBitfieldMember {
+  NegativeUnnamedBitfieldMember() {}
+  unsigned : 5;
+};
+
+struct NegativeInitializedBitfieldMembers {
+  NegativeInitializedBitfieldMembers() : F(3) { G = 2; }
+  unsigned F : 5;
+  unsigned G : 5;
+};
+
+struct NegativeImplicitInheritedCtorBase {
+  NegativeImplicitInheritedCtorBase(unsigned F) : F(F) {}
+  unsigned F;
+};
+
+struct NegativeImplicitInheritedCtor : NegativeImplicitInheritedCtorBase {
+  using NegativeImplicitInheritedCtorBase::NegativeImplicitInheritedCtorBase;
+};
+
+void Bug33557() {
+  NegativeImplicitInheritedCtor I(5);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-reinterpret-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-reinterpret-cast.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-reinterpret-cast.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-reinterpret-cast.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,6 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-reinterpret-cast %t
+
+int i = 0;
+void *j;
+void f() { j = reinterpret_cast<void *>(i); }
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: do not use reinterpret_cast [cppcoreguidelines-pro-type-reinterpret-cast]

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-static-cast-downcast.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-static-cast-downcast.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-static-cast-downcast.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-static-cast-downcast.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,118 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-static-cast-downcast %t
+
+class Base {
+};
+
+class Derived : public Base {
+};
+
+class Base2 {
+};
+
+class MultiDerived : public Base, public Base2 {
+};
+
+class PolymorphicBase {
+public:
+  virtual ~PolymorphicBase();
+};
+
+class PolymorphicDerived : public PolymorphicBase {
+};
+
+class PolymorphicMultiDerived : public Base, public PolymorphicBase {
+};
+
+void pointers() {
+
+  auto P0 = static_cast<Derived*>(new Base());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  const Base* B0;
+  auto PC0 = static_cast<const Derived*>(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  auto P1 = static_cast<Base*>(new Derived()); // OK, upcast to a public base
+  auto P2 = static_cast<Base*>(new MultiDerived()); // OK, upcast to a public base
+  auto P3 = static_cast<Base2*>(new MultiDerived()); // OK, upcast to a public base
+}
+
+void pointers_polymorphic() {
+
+  auto PP0 = static_cast<PolymorphicDerived*>(new PolymorphicBase());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PP0 = dynamic_cast<PolymorphicDerived*>(new PolymorphicBase());
+
+  const PolymorphicBase* B0;
+  auto PPC0 = static_cast<const PolymorphicDerived*>(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto PPC0 = dynamic_cast<const PolymorphicDerived*>(B0);
+
+
+  auto B1 = static_cast<PolymorphicBase*>(new PolymorphicDerived()); // OK, upcast to a public base
+  auto B2 = static_cast<PolymorphicBase*>(new PolymorphicMultiDerived()); // OK, upcast to a public base
+  auto B3 = static_cast<Base*>(new PolymorphicMultiDerived()); // OK, upcast to a public base
+}
+
+void arrays() {
+  Base ArrayOfBase[10];
+  auto A0 = static_cast<Derived*>(ArrayOfBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+}
+
+void arrays_polymorphic() {
+  PolymorphicBase ArrayOfPolymorphicBase[10];
+  auto AP0 = static_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto AP0 = dynamic_cast<PolymorphicDerived*>(ArrayOfPolymorphicBase);
+}
+
+void references() {
+  Base B0;
+  auto R0 = static_cast<Derived&>(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+  Base& RefToBase = B0;
+  auto R1 = static_cast<Derived&>(RefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+  const Base& ConstRefToBase = B0;
+  auto RC1 = static_cast<const Derived&>(ConstRefToBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class [cppcoreguidelines-pro-type-static-cast-downcast]
+
+
+  Derived RD1;
+  auto R2 = static_cast<Base&>(RD1); // OK, upcast to a public base
+}
+
+void references_polymorphic() {
+  PolymorphicBase B0;
+  auto RP0 = static_cast<PolymorphicDerived&>(B0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead
+  // CHECK-FIXES: auto RP0 = dynamic_cast<PolymorphicDerived&>(B0);
+
+  PolymorphicBase& RefToPolymorphicBase = B0;
+  auto RP1 = static_cast<PolymorphicDerived&>(RefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RP1 = dynamic_cast<PolymorphicDerived&>(RefToPolymorphicBase);
+
+  const PolymorphicBase& ConstRefToPolymorphicBase = B0;
+  auto RPC2 = static_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not use static_cast to downcast from a base to a derived class; use dynamic_cast instead [cppcoreguidelines-pro-type-static-cast-downcast]
+  // CHECK-FIXES: auto RPC2 = dynamic_cast<const PolymorphicDerived&>(ConstRefToPolymorphicBase);
+
+  PolymorphicDerived d1;
+  auto RP2 = static_cast<PolymorphicBase&>(d1); // OK, upcast to a public base
+}
+
+template<class B, class D>
+void templ() {
+  auto B0 = static_cast<B*>(new D());
+}
+
+void templ_bad_call() {
+  templ<Derived, Base>(); //FIXME: this should trigger a warning
+}
+
+void templ_good_call() {
+  templ<Base, Derived>(); // OK, upcast to a public base
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-union-access.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-union-access.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-union-access.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-union-access.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-union-access %t
+
+union U {
+  bool union_member1;
+  char union_member2;
+} u;
+
+struct S {
+  int non_union_member;
+  union {
+    bool union_member;
+  };
+  union {
+    char union_member2;
+  } u;
+} s;
+
+
+void f(char);
+void f2(U);
+void f3(U&);
+void f4(U*);
+
+void check()
+{
+  u.union_member1 = true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not access members of unions; use (boost::)variant instead [cppcoreguidelines-pro-type-union-access]
+  auto b = u.union_member2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: do not access members of unions; use (boost::)variant instead
+  auto a = &s.union_member;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: do not access members of unions; use (boost::)variant instead
+  f(s.u.union_member2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: do not access members of unions; use (boost::)variant instead
+
+  s.non_union_member = 2; // OK
+
+  U u2 = u; // OK
+  f2(u); // OK
+  f3(u); // OK
+  f4(&u); // OK
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-vararg.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-vararg.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-vararg.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-pro-type-vararg.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-pro-type-vararg %t
+
+void f(int i);
+void f_vararg(int i, ...);
+
+struct C {
+  void g_vararg(...);
+  void g(const char*);
+} c;
+
+template<typename... P>
+void cpp_vararg(P... p);
+
+void check() {
+  f_vararg(1, 7, 9);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call c-style vararg functions [cppcoreguidelines-pro-type-vararg]
+  c.g_vararg("foo");
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not call c-style vararg functions
+
+  f(3); // OK
+  c.g("foo"); // OK
+  cpp_vararg(1, 7, 9); // OK
+}
+
+// ... as a parameter is allowed (e.g. for SFINAE)
+template <typename T>
+void CallFooIfAvailableImpl(T& t, ...) {
+  // nothing
+}
+template <typename T>
+void CallFooIfAvailableImpl(T& t, decltype(t.foo())*) {
+  t.foo();
+}
+template <typename T>
+void CallFooIfAvailable(T& t) {
+  CallFooIfAvailableImpl(t, 0); // OK to call variadic function when the argument is a literal 0
+}
+
+#include <stdarg.h>
+void my_printf(const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not call c-style vararg functions
+  va_list n;
+  va_copy(n, ap); // Don't warn, va_copy is anyway useless without va_start
+  int i = va_arg(ap, int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not use va_start/va_arg to define c-style vararg functions; use variadic templates instead
+  va_end(ap); // Don't warn, va_end is anyway useless without va_start
+}
+
+int my_vprintf(const char* format, va_list arg ); // OK to declare function taking va_list

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-slicing.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-slicing.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-slicing.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-slicing.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,100 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-slicing %t
+
+class Base {
+  int i;
+  void f() {}
+  virtual void g() {}
+};
+
+class DerivedWithMemberVariables : public Base {
+  void f();
+  int j;
+};
+
+class TwiceDerivedWithNoMemberVariables : public DerivedWithMemberVariables {
+  void f();
+};
+
+class DerivedWithOverride : public Base {
+  void f();
+  void g() override {}
+};
+
+class TwiceDerivedWithNoOverride : public DerivedWithOverride {
+  void f();
+};
+
+void TakesBaseByValue(Base base);
+
+DerivedWithMemberVariables ReturnsDerived();
+
+void positivesWithMemberVariables() {
+  DerivedWithMemberVariables b;
+  Base a{b};
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state [cppcoreguidelines-slicing]
+  a = b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+  TakesBaseByValue(b);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+
+  TwiceDerivedWithNoMemberVariables c;
+  a = c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'TwiceDerivedWithNoMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+
+  a = ReturnsDerived();
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithMemberVariables' to 'Base' discards {{[0-9]*}} bytes of state
+}
+
+void positivesWithOverride() {
+  DerivedWithOverride b;
+  Base a{b};
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+  a = b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+  TakesBaseByValue(b);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+
+  TwiceDerivedWithNoOverride c;
+  a = c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedWithOverride' to 'Base' discards override 'g'
+}
+
+void TakesBaseByReference(Base &base);
+
+class DerivedThatAddsVirtualH : public Base {
+  virtual void h();
+};
+
+class DerivedThatOverridesH : public DerivedThatAddsVirtualH {
+  void h() override;
+};
+
+void negatives() {
+  // OK, simple copying from the same type.
+  Base a;
+  TakesBaseByValue(a);
+  DerivedWithMemberVariables b;
+  DerivedWithMemberVariables c{b};
+  b = c;
+
+  // OK, derived type does not have extra state.
+  TwiceDerivedWithNoMemberVariables d;
+  DerivedWithMemberVariables e{d};
+  e = d;
+
+  // OK, derived does not override any method.
+  TwiceDerivedWithNoOverride f;
+  DerivedWithOverride g{f};
+  g = f;
+
+  // OK, no copying.
+  TakesBaseByReference(d);
+  TakesBaseByReference(f);
+
+  // Derived type overrides methods, but these methods are not in the base type,
+  // so cannot be called accidentally. Right now this triggers, but we might
+  // want to allow it.
+  DerivedThatOverridesH h;
+  a = h;
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-cxx-03.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-cxx-03.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-cxx-03.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-cxx-03.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy -std=c++98 %s cppcoreguidelines-special-member-functions %t
+
+class DefinesDestructor {
+  ~DefinesDestructor();
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyConstructor {
+  DefinesCopyConstructor(const DefinesCopyConstructor &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyAssignment {
+  DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor or a copy constructor [cppcoreguidelines-special-member-functions]
+
+class DefinesNothing {
+};
+
+class DefinesEverything {
+  DefinesEverything(const DefinesEverything &);
+  DefinesEverything &operator=(const DefinesEverything &);
+  ~DefinesEverything();
+};
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-relaxed.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-relaxed.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-relaxed.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions-relaxed.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,71 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t -- -config="{CheckOptions: [{key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions, value: 1}, {key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor, value: 1}]}" --
+
+class DefinesDestructor {
+  ~DefinesDestructor();
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesDefaultedDestructor {
+  ~DefinesDefaultedDestructor() = default;
+};
+
+class DefinesCopyConstructor {
+  DefinesCopyConstructor(const DefinesCopyConstructor &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor or a copy assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyAssignment {
+  DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor or a copy constructor [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveConstructor {
+  DefinesMoveConstructor(DefinesMoveConstructor &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveConstructor' defines a move constructor but does not define a destructor, a copy constructor, a copy assignment operator or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveAssignment {
+  DefinesMoveAssignment &operator=(DefinesMoveAssignment &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveAssignment' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor [cppcoreguidelines-special-member-functions]
+class DefinesNothing {
+};
+
+class DefinesEverything {
+  DefinesEverything(const DefinesEverything &);
+  DefinesEverything &operator=(const DefinesEverything &);
+  DefinesEverything(DefinesEverything &&);
+  DefinesEverything &operator=(DefinesEverything &&);
+  ~DefinesEverything();
+};
+
+class DeletesEverything {
+  DeletesEverything(const DeletesEverything &) = delete;
+  DeletesEverything &operator=(const DeletesEverything &) = delete;
+  DeletesEverything(DeletesEverything &&) = delete;
+  DeletesEverything &operator=(DeletesEverything &&) = delete;
+  ~DeletesEverything() = delete;
+};
+
+class DeletesCopyDefaultsMove {
+  DeletesCopyDefaultsMove(const DeletesCopyDefaultsMove &) = delete;
+  DeletesCopyDefaultsMove &operator=(const DeletesCopyDefaultsMove &) = delete;
+  DeletesCopyDefaultsMove(DeletesCopyDefaultsMove &&) = default;
+  DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default;
+  ~DeletesCopyDefaultsMove() = default;
+};
+
+template <typename T>
+struct TemplateClass {
+  TemplateClass() = default;
+  TemplateClass(const TemplateClass &);
+  TemplateClass &operator=(const TemplateClass &);
+  TemplateClass(TemplateClass &&);
+  TemplateClass &operator=(TemplateClass &&);
+  ~TemplateClass();
+};
+
+// Multiple instantiations of a class template will trigger multiple matches for defined special members.
+// This should not cause problems.
+TemplateClass<int> InstantiationWithInt;
+TemplateClass<double> InstantiationWithDouble;

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/cppcoreguidelines-special-member-functions.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,72 @@
+// RUN: %check_clang_tidy %s cppcoreguidelines-special-member-functions %t
+
+class DefinesDestructor {
+  ~DefinesDestructor();
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDestructor' defines a non-default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesDefaultedDestructor {
+  ~DefinesDefaultedDestructor() = default;
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesDefaultedDestructor' defines a default destructor but does not define a copy constructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyConstructor {
+  DefinesCopyConstructor(const DefinesCopyConstructor &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyConstructor' defines a copy constructor but does not define a destructor, a copy assignment operator, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesCopyAssignment {
+  DefinesCopyAssignment &operator=(const DefinesCopyAssignment &);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesCopyAssignment' defines a copy assignment operator but does not define a destructor, a copy constructor, a move constructor or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveConstructor {
+  DefinesMoveConstructor(DefinesMoveConstructor &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveConstructor' defines a move constructor but does not define a destructor, a copy constructor, a copy assignment operator or a move assignment operator [cppcoreguidelines-special-member-functions]
+
+class DefinesMoveAssignment {
+  DefinesMoveAssignment &operator=(DefinesMoveAssignment &&);
+};
+// CHECK-MESSAGES: [[@LINE-3]]:7: warning: class 'DefinesMoveAssignment' defines a move assignment operator but does not define a destructor, a copy constructor, a copy assignment operator or a move constructor [cppcoreguidelines-special-member-functions]
+class DefinesNothing {
+};
+
+class DefinesEverything {
+  DefinesEverything(const DefinesEverything &);
+  DefinesEverything &operator=(const DefinesEverything &);
+  DefinesEverything(DefinesEverything &&);
+  DefinesEverything &operator=(DefinesEverything &&);
+  ~DefinesEverything();
+};
+
+class DeletesEverything {
+  DeletesEverything(const DeletesEverything &) = delete;
+  DeletesEverything &operator=(const DeletesEverything &) = delete;
+  DeletesEverything(DeletesEverything &&) = delete;
+  DeletesEverything &operator=(DeletesEverything &&) = delete;
+  ~DeletesEverything() = delete;
+};
+
+class DeletesCopyDefaultsMove {
+  DeletesCopyDefaultsMove(const DeletesCopyDefaultsMove &) = delete;
+  DeletesCopyDefaultsMove &operator=(const DeletesCopyDefaultsMove &) = delete;
+  DeletesCopyDefaultsMove(DeletesCopyDefaultsMove &&) = default;
+  DeletesCopyDefaultsMove &operator=(DeletesCopyDefaultsMove &&) = default;
+  ~DeletesCopyDefaultsMove() = default;
+};
+
+template <typename T>
+struct TemplateClass {
+  TemplateClass() = default;
+  TemplateClass(const TemplateClass &);
+  TemplateClass &operator=(const TemplateClass &);
+  TemplateClass(TemplateClass &&);
+  TemplateClass &operator=(TemplateClass &&);
+  ~TemplateClass();
+};
+
+// Multiple instantiations of a class template will trigger multiple matches for defined special members.
+// This should not cause problems.
+TemplateClass<int> InstantiationWithInt;
+TemplateClass<double> InstantiationWithDouble;

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-avoid-spinlock.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-avoid-spinlock.m?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-avoid-spinlock.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-avoid-spinlock.m Fri Oct 11 05:05:42 2019
@@ -0,0 +1,15 @@
+// RUN: %check_clang_tidy %s darwin-avoid-spinlock %t
+
+typedef int OSSpinLock;
+
+ at implementation Foo
+- (void)f {
+    int i = 1;
+    OSSpinlockLock(&i);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use os_unfair_lock_lock() or dispatch queue APIs instead of the deprecated OSSpinLock [darwin-avoid-spinlock]
+    OSSpinlockTry(&i);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use os_unfair_lock_lock() or dispatch queue APIs instead of the deprecated OSSpinLock [darwin-avoid-spinlock]
+    OSSpinlockUnlock(&i);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use os_unfair_lock_lock() or dispatch queue APIs instead of the deprecated OSSpinLock [darwin-avoid-spinlock]
+}
+ at end

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-dispatch-once-nonstatic.mm
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-dispatch-once-nonstatic.mm?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-dispatch-once-nonstatic.mm (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/darwin-dispatch-once-nonstatic.mm Fri Oct 11 05:05:42 2019
@@ -0,0 +1,48 @@
+// RUN: %check_clang_tidy %s darwin-dispatch-once-nonstatic %t
+
+typedef int dispatch_once_t;
+extern void dispatch_once(dispatch_once_t *pred, void(^block)(void));
+
+
+void bad_dispatch_once(dispatch_once_t once, void(^block)(void)) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: dispatch_once_t variables must have static or global storage duration; function parameters should be pointer references [darwin-dispatch-once-nonstatic]
+
+// file-scope dispatch_once_ts have static storage duration.
+dispatch_once_t global_once;
+static dispatch_once_t file_static_once;
+namespace {
+dispatch_once_t anonymous_once;
+} // end anonymous namespace
+
+int Correct(void) {
+  static int value;
+  static dispatch_once_t once;
+  dispatch_once(&once, ^{
+    value = 1;
+  });
+  return value;
+}
+
+int Incorrect(void) {
+  static int value;
+  dispatch_once_t once;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dispatch_once_t variables must have static or global storage duration [darwin-dispatch-once-nonstatic]
+  // CHECK-FIXES: static dispatch_once_t once;
+  dispatch_once(&once, ^{
+    value = 1;
+  });
+  return value;
+}
+
+struct OnceStruct {
+  static dispatch_once_t staticOnce; // Allowed
+  int value;
+  dispatch_once_t once;  // Allowed (at this time)
+};
+
+ at interface MyObject {
+  dispatch_once_t _once;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: dispatch_once_t variables must have static or global storage duration and cannot be Objective-C instance variables [darwin-dispatch-once-nonstatic]
+  // CHECK-FIXES: dispatch_once_t _once;
+}
+ at end

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-calls.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-calls.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-calls.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-calls.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,36 @@
+// RUN: %check_clang_tidy %s fuchsia-default-arguments-calls %t
+
+int foo(int value = 5) { return value; }
+
+int f() {
+  foo();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments-calls]
+  // CHECK-NOTES: [[@LINE-5]]:9: note: default parameter was declared here
+}
+
+int bar(int value) { return value; }
+
+int n() {
+  foo(0);
+  bar(0);
+}
+
+void x(int i = 12);
+
+struct S {
+  void x(int i);
+};
+
+void S::x(int i = 12) {}
+
+int main() {
+  S s;
+  s.x();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments-calls]
+  // CHECK-NOTES: [[@LINE-6]]:11: note: default parameter was declared here
+  // CHECK-NEXT: void S::x(int i = 12) {}
+  x();
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: calling a function that uses a default argument is disallowed [fuchsia-default-arguments-calls]
+  // CHECK-NOTES: [[@LINE-16]]:8: note: default parameter was declared here
+  // CHECK-NEXT: void x(int i = 12);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-declarations.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-declarations.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-declarations.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-default-arguments-declarations.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s fuchsia-default-arguments-declarations %t
+
+int foo(int value = 5) { return value; }
+// CHECK-NOTES: [[@LINE-1]]:9: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+// CHECK-FIXES: int foo(int value) { return value; }
+
+int bar(int value) { return value; }
+
+class Baz {
+public:
+  int a(int value = 5) { return value; }
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+  // CHECK-FIXES: int a(int value) { return value; }
+
+  int b(int value) { return value; }
+};
+
+class Foo {
+  // Fix should be suggested in declaration
+  int a(int value = 53);
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+  // CHECK-FIXES: int a(int value);
+};
+
+// Fix shouldn't be suggested in implementation
+int Foo::a(int value) {
+  return value;
+}
+
+// Elided functions
+void f(int = 5) {};
+// CHECK-NOTES: [[@LINE-1]]:8: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+// CHECK-FIXES: void f(int) {};
+
+void g(int) {};
+
+// Should not suggest fix for macro-defined parameters
+#define D(val) = val
+
+void h(int i D(5));
+// CHECK-NOTES: [[@LINE-1]]:8: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+// CHECK-FIXES-NOT: void h(int i);
+
+void x(int i);
+void x(int i = 12);
+// CHECK-NOTES: [[@LINE-1]]:8: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+// CHECK-FIXES: void x(int i);
+
+void x(int i) {}
+
+struct S {
+  void x(int i);
+};
+
+void S::x(int i = 12) {}
+// CHECK-NOTES: [[@LINE-1]]:11: warning: declaring a parameter with a default argument is disallowed [fuchsia-default-arguments-declarations]
+// CHECK-FIXES: void S::x(int i) {}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-multiple-inheritance.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,150 @@
+// RUN: %check_clang_tidy %s fuchsia-multiple-inheritance %t
+
+class Base_A {
+public:
+  virtual int foo() { return 0; }
+};
+
+class Base_B {
+public:
+  virtual int bar() { return 0; }
+};
+
+class Base_A_child : public Base_A {
+public:
+  virtual int baz() { return 0; }
+};
+
+class Interface_A {
+public:
+  virtual int foo() = 0;
+};
+
+class Interface_B {
+public:
+  virtual int bar() = 0;
+};
+
+class Interface_C {
+public:
+  virtual int blat() = 0;
+};
+
+class Interface_A_with_member {
+public:
+  virtual int foo() = 0;
+  int val = 0;
+};
+
+class Interface_with_A_Parent : public Base_A {
+public:
+  virtual int baz() = 0;
+};
+
+// Shouldn't warn on forward declarations.
+class Bad_Child1;
+
+// Inherits from multiple concrete classes.
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {};
+class Bad_Child1 : public Base_A, Base_B {};
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+class Bad_Child2 : public Base_A, Interface_A_with_member {
+  virtual int foo() override { return 0; }
+};
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+  virtual int baz() override { return 0; }
+};
+
+// Easy cases of single inheritance
+class Simple_Child1 : public Base_A {};
+class Simple_Child2 : public Interface_A {
+  virtual int foo() override { return 0; }
+};
+
+// Valid uses of multiple inheritance
+class Good_Child1 : public Interface_A, Interface_B {
+  virtual int foo() override { return 0; }
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child2 : public Base_A, Interface_B {
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child3 : public Base_A_child, Interface_C, Interface_B {
+  virtual int bar() override { return 0; }
+  virtual int blat() override { return 0; }
+};
+
+struct B1 { int x; };
+struct B2 { int x;};
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: struct D : B1, B2 {};
+struct D1 : B1, B2 {};
+
+struct Base1 { virtual void foo() = 0; };
+struct V1 : virtual Base1 {};
+struct V2 : virtual Base1 {};
+struct D2 : V1, V2 {};
+
+struct Base2 { virtual void foo(); };
+struct V3 : virtual Base2 {};
+struct V4 : virtual Base2 {};
+struct D3 : V3, V4 {};
+
+struct Base3 {};
+struct V5 : virtual Base3 { virtual void f(); };
+struct V6 : virtual Base3 { virtual void g(); };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: struct D4 : V5, V6 {};
+struct D4 : V5, V6 {};
+
+struct Base4 {};
+struct V7 : virtual Base4 { virtual void f() = 0; };
+struct V8 : virtual Base4 { virtual void g() = 0; };
+struct D5 : V7, V8 {};
+
+struct Base5 { virtual void f() = 0; };
+struct V9 : virtual Base5 { virtual void f(); };
+struct V10 : virtual Base5 { virtual void g() = 0; };
+struct D6 : V9, V10 {};
+
+struct Base6 { virtual void f(); };
+struct Base7 { virtual void g(); };
+struct V15 : virtual Base6 { virtual void f() = 0; };
+struct V16 : virtual Base7 { virtual void g() = 0; };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting mulitple classes that aren't pure virtual is discouraged [fuchsia-multiple-inheritance]
+// CHECK-NEXT: struct D9 : V15, V16 {};
+struct D9 : V15, V16 {};
+
+struct Static_Base { static void foo(); };
+struct V11 : virtual Static_Base {};
+struct V12 : virtual Static_Base {};
+struct D7 : V11, V12 {};
+
+struct Static_Base_2 {};
+struct V13 : virtual Static_Base_2 { static void f(); };
+struct V14 : virtual Static_Base_2 { static void g(); };
+struct D8 : V13, V14 {};
+
+template<typename T> struct A : T {};
+template<typename T> struct B : virtual T {};
+
+template<typename> struct C {};
+template<typename T> struct D : C<T> {};
+
+// Check clang_tidy does not crash on this code.
+template <class T>
+struct WithTemplBase : T {
+  WithTemplBase();
+};
+
+int test_no_crash() {
+  auto foo = []() {};
+  WithTemplBase<decltype(foo)>();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-overloaded-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-overloaded-operator.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-overloaded-operator.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-overloaded-operator.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s fuchsia-overloaded-operator %t
+
+class A {
+public:
+  int operator+(int);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: overloading 'operator+' is disallowed
+};
+
+class B {
+public:
+  B &operator=(const B &Other);
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:3: warning: overloading 'operator=' is disallowed
+  B &operator=(B &&Other);
+  // CHECK-MESSAGES-NOT: [[@LINE-1]]:3: warning: overloading 'operator=' is disallowed
+};
+
+A operator-(const A &A1, const A &A2);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: overloading 'operator-' is disallowed
+
+void operator delete(void*, void*) throw();
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: overloading 'operator delete' is disallowed
+
+auto x = []{};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-all.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-all.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-all.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-all.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN:     -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: ''}]}" \
+// RUN:     -- -I %S/Inputs/fuchsia-restrict-system-includes -isystem %S/Inputs/fuchsia-restrict-system-includes/system
+
+#include <cstdlib.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include cstdlib.h not allowed
+#include <cstdarg.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include cstdarg.h not allowed
+#include <t.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-glob.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-glob.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-glob.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-glob.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN:     -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: 'cstd*'}]}" \
+// RUN:     -- -I %S/Inputs/fuchsia-restrict-system-includes -isystem %S/Inputs/fuchsia-restrict-system-includes/system
+
+#include <cstdlib.h>
+#include <cstdarg.h>
+#include <t.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
+// CHECK-FIXES-NOT: #include <t.h>

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-headers.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-headers.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-headers.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes-headers.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,24 @@
+// RUN: rm -rf %T/Headers
+// RUN: mkdir %T/Headers
+// RUN: cp -r %S/Inputs/fuchsia-restrict-system-includes %T/Headers/fuchsia-restrict-system-includes
+// RUN: %check_clang_tidy -std=c++11 %s fuchsia-restrict-system-includes %t \
+// RUN:   -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: 'transitive.h,s.h'}]}" \
+// RUN:   -system-headers -header-filter=.* \
+// RUN:   -- -I %T/Headers/fuchsia-restrict-system-includes -isystem %T/Headers/fuchsia-restrict-system-includes/system
+// RUN: FileCheck -input-file=%T/Headers/fuchsia-restrict-system-includes/transitive2.h %s -check-prefix=CHECK-FIXES
+// RUN: rm -rf %T/Headers
+// FIXME: Make the test work in all language modes.
+
+// transitive.h includes <r.h> and <t.h>
+#include <transitive.h>
+// CHECK-MESSAGES: :1:1: warning: system include r.h not allowed, transitively included from {{.*}}
+// CHECK-MESSAGES: :2:1: warning: system include t.h not allowed, transitively included from {{.*}}
+
+// transitive.h includes <s.h> and <t.h>
+#include "transitive2.h"
+// CHECK-MESSAGES: :2:1: warning: system include t.h not allowed, transitively included from {{.*}}
+// CHECK-FIXES-NOT: #include <t.h>
+
+int main() {
+  // f() is declared in r.h
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-restrict-system-includes.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s fuchsia-restrict-system-includes %t \
+// RUN:     -- -config="{CheckOptions: [{key: fuchsia-restrict-system-includes.Includes, value: 's.h'}]}" \
+// RUN:     -- -I %S/Inputs/fuchsia-restrict-system-includes -isystem %S/Inputs/fuchsia-restrict-system-includes/system
+
+#include "a.h"
+
+#include <s.h>
+#include <t.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
+// CHECK-FIXES-NOT: #include <t.h>
+
+#include "s.h"
+#include "t.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include t.h not allowed
+// CHECK-FIXES-NOT: #include "t.h"
+
+#define foo <j.h>
+
+#include foo
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include j.h not allowed
+// CHECK-FIXES-NOT: #include foo
+
+#/* comment */ include /* comment */ foo
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: system include j.h not allowed
+// CHECK-FIXES-NOT: # /* comment */ include /* comment */ foo

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-statically-constructed-objects.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-statically-constructed-objects.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-statically-constructed-objects.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-statically-constructed-objects.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s fuchsia-statically-constructed-objects %t
+
+// Trivial static is fine
+static int i;
+
+class ClassWithNoCtor {};
+
+class ClassWithCtor {
+public:
+  ClassWithCtor(int Val) : Val(Val) {}
+private:
+  int Val;
+};
+
+class ClassWithConstexpr {
+public:
+  ClassWithConstexpr(int Val1, int Val2) : Val(Val1) {}
+  constexpr ClassWithConstexpr(int Val) : Val(Val) {}
+
+private:
+  int Val;
+};
+
+ClassWithNoCtor A;
+ClassWithConstexpr C(0);
+ClassWithConstexpr E(0, 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  ClassWithConstexpr E(0, 1);
+ClassWithCtor G(0);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  ClassWithCtor G(0);
+
+static ClassWithNoCtor A2;
+static ClassWithConstexpr C2(0);
+static ClassWithConstexpr E2(0, 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  static ClassWithConstexpr E2(0, 1);
+static ClassWithCtor G2(0);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  static ClassWithCtor G2(0);
+
+struct StructWithConstexpr { constexpr StructWithConstexpr(int Val) {} };
+struct StructWithNoCtor {};
+struct StructWithCtor { StructWithCtor(); };
+
+StructWithNoCtor SNoCtor;
+StructWithConstexpr SConstexpr(0);
+StructWithCtor SCtor;
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  StructWithCtor SCtor;
+
+static StructWithConstexpr SConstexpr2(0);
+static StructWithNoCtor SNoCtor2;
+static StructWithCtor SCtor2;
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  static StructWithCtor SCtor2;
+
+extern StructWithCtor SCtor3;
+
+class ClassWithStaticMember {
+private:
+  static StructWithNoCtor S;
+};
+
+ClassWithStaticMember Z();
+
+class S {
+  int Val;
+public:
+  constexpr S(int i) : Val(100 / i) {}
+  int getVal() const { return Val; }
+};
+
+static S s1(1);
+static S s2(0); 
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT: static S s2(0);
+
+extern int get_i();
+static S s3(get_i());
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: static objects are disallowed; if possible, use a constexpr constructor instead [fuchsia-statically-constructed-objects]
+// CHECK-MESSAGES-NEXT:  static S s3(get_i());
+
+void f() {
+  // Locally static is fine
+  static int i;
+  static ClassWithNoCtor A2;
+  static ClassWithConstexpr C2(0);
+  static ClassWithConstexpr E2(0, 1);
+  static ClassWithCtor G2(0);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-trailing-return.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-trailing-return.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-trailing-return.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-trailing-return.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,23 @@
+// RUN: %check_clang_tidy %s fuchsia-trailing-return %t
+
+int add_one(const int arg) { return arg; }
+
+auto get_add_one() -> int (*)(const int) {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: a trailing return type is disallowed for this type of declaration
+  // CHECK-NEXT: auto get_add_one() -> int (*)(const int) {
+  return add_one;
+}
+
+auto lambda = [](double x, double y) {return x + y;};
+
+auto lambda2 = [](double x, double y) -> double {return x + y;};
+
+int main() {
+  get_add_one()(5);
+  return 0;
+}
+
+template <typename T1, typename T2>
+auto fn(const T1 &lhs, const T2 &rhs) -> decltype(lhs + rhs) {
+  return lhs + rhs;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-virtual-inheritance.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-virtual-inheritance.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-virtual-inheritance.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/fuchsia-virtual-inheritance.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s fuchsia-virtual-inheritance %t
+
+class A {
+public:
+  A(int value) : val(value) {}
+
+  int do_A() { return val; }
+
+private:
+  int val;
+};
+
+class B : public virtual A {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: direct virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT: class B : public virtual A {
+public:
+  B() : A(0) {}
+  int do_B() { return 1 + do_A(); }
+};
+
+class C : public virtual A {
+  // CHECK-MESSAGES: [[@LINE-1]]:1: warning: direct virtual inheritance is disallowed [fuchsia-virtual-inheritance]
+  // CHECK-NEXT: class C : public virtual A {
+public:
+  C() : A(0) {}
+  int do_C() { return 2 + do_A(); }
+};
+
+class D : public B, public C {
+public:
+  D(int value) : A(value), B(), C() {}
+
+  int do_D() { return do_A() + do_B() + do_C(); }
+};
+
+int main() {
+  A *a = new A(0);
+  B *b = new B();
+  C *c = new C();
+  D *d = new D(0);
+  return 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-build-explicit-make-pair.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-build-explicit-make-pair.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-build-explicit-make-pair.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-build-explicit-make-pair.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,51 @@
+// RUN: %check_clang_tidy %s google-build-explicit-make-pair %t
+
+namespace std {
+template <class T1, class T2>
+struct pair {
+  pair(T1 x, T2 y) {}
+};
+
+template <class T1, class T2>
+pair<T1, T2> make_pair(T1 x, T2 y) {
+  return pair<T1, T2>(x, y);
+}
+}
+
+template <typename T>
+void templ(T a, T b) {
+  std::make_pair<T, unsigned>(a, b);
+  std::make_pair<int, int>(1, 2);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair
+// CHECK-FIXES: std::make_pair(1, 2)
+}
+
+template <typename T>
+int t();
+
+void test(int i) {
+  std::make_pair<int, int>(i, i);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, omit template arguments from make_pair
+// CHECK-FIXES: std::make_pair(i, i)
+
+  std::make_pair<unsigned, int>(i, i);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly
+// CHECK-FIXES: std::pair<unsigned, int>(i, i)
+
+  std::make_pair<int, unsigned>(i, i);
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly
+// CHECK-FIXES: std::pair<int, unsigned>(i, i)
+
+#define M std::make_pair<int, unsigned>(i, i);
+M
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: for C++11-compatibility, use pair directly
+// Can't fix in macros.
+// CHECK-FIXES: #define M std::make_pair<int, unsigned>(i, i);
+// CHECK-FIXES-NEXT: M
+
+  templ(i, i);
+  templ(1U, 2U);
+
+  std::make_pair(i, 1); // no-warning
+  std::make_pair(t<int>, 1);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-default-arguments.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-default-arguments.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-default-arguments.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-default-arguments.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s google-default-arguments %t
+
+struct A {
+  virtual void f(int I, int J = 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: default arguments on virtual or override methods are prohibited [google-default-arguments]
+};
+
+struct B : public A {
+  void f(int I, int J = 5);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: default arguments on virtual or override methods are prohibited
+};
+
+struct C : public B {
+  void f(int I, int J = 5) override;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: default arguments on virtual or override methods are prohibited
+};
+
+// Negatives.
+struct D : public B {
+  void f(int I, int J) override;
+};
+
+struct X {
+  void f(int I, int J = 3);
+};
+
+struct Y : public X {
+  void f(int I, int J = 5);
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-explicit-constructor.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-explicit-constructor.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-explicit-constructor.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-explicit-constructor.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,188 @@
+// RUN: %check_clang_tidy %s google-explicit-constructor %t
+
+namespace std {
+  typedef decltype(sizeof(int)) size_t;
+
+  // libc++'s implementation
+  template <class _E>
+  class initializer_list
+  {
+    const _E* __begin_;
+    size_t    __size_;
+
+    initializer_list(const _E* __b, size_t __s)
+      : __begin_(__b),
+        __size_(__s)
+    {}
+
+  public:
+    typedef _E        value_type;
+    typedef const _E& reference;
+    typedef const _E& const_reference;
+    typedef size_t    size_type;
+
+    typedef const _E* iterator;
+    typedef const _E* const_iterator;
+
+    initializer_list() : __begin_(nullptr), __size_(0) {}
+
+    size_t    size()  const {return __size_;}
+    const _E* begin() const {return __begin_;}
+    const _E* end()   const {return __begin_ + __size_;}
+  };
+}
+
+struct A {
+  A() {}
+  A(int x, int y) {}
+
+  explicit A(void *x) {}
+  explicit A(void *x, void *y) {}
+  explicit operator bool() const { return true; }
+
+  operator double() const = delete;
+
+  explicit A(const A& a) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: copy constructor should not be declared explicit [google-explicit-constructor]
+  // CHECK-FIXES: {{^  }}A(const A& a) {}
+
+  A(int x1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+  // CHECK-FIXES: {{^  }}explicit A(int x1);
+
+  A(double x2, double y = 3.14) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructors that are callable with a single argument must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+  // CHECK-FIXES: {{^  }}explicit A(double x2, double y = 3.14) {}
+
+  template <typename... T>
+  A(T&&... args);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: constructors that are callable with a single argument
+  // CHECK-FIXES: {{^  }}explicit A(T&&... args);
+};
+
+inline A::A(int x1) {}
+
+struct B {
+  B(std::initializer_list<int> list1) {}
+  B(const std::initializer_list<unsigned> &list2) {}
+  B(std::initializer_list<unsigned> &&list3) {}
+
+  operator bool() const { return true; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator bool' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+  // CHECK-FIXES: {{^  }}explicit operator bool() const { return true; }
+
+  operator double() const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator double' must be marked explicit to avoid unintentional implicit conversions [google-explicit-constructor]
+  // CHECK-FIXES: {{^  }}explicit operator double() const;
+
+  explicit B(::std::initializer_list<double> list4) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor]
+  // CHECK-FIXES: {{^  }}B(::std::initializer_list<double> list4) {}
+
+  explicit B(const ::std::initializer_list<char> &list5) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+  // CHECK-FIXES: {{^  }}B(const ::std::initializer_list<char> &list5) {}
+
+  explicit B(::std::initializer_list<char> &&list6) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+  // CHECK-FIXES: {{^  }}B(::std::initializer_list<char> &&list6) {}
+};
+
+inline B::operator double() const { return 0.0; }
+
+struct StructWithFnPointer {
+  void (*f)();
+} struct_with_fn_pointer = {[] {}};
+
+using namespace std;
+
+struct C {
+  C(initializer_list<int> list1) {}
+  C(const initializer_list<unsigned> &list2) {}
+  C(initializer_list<unsigned> &&list3) {}
+};
+
+template <typename T>
+struct C2 {
+  C2(initializer_list<int> list1) {}
+  C2(const initializer_list<unsigned> &list2) {}
+  C2(initializer_list<unsigned> &&list3) {}
+
+  explicit C2(initializer_list<double> list4) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor
+  // CHECK-FIXES: {{^  }}C2(initializer_list<double> list4) {}
+};
+
+template <typename T>
+struct C3 {
+  C3(initializer_list<T> list1) {}
+  C3(const std::initializer_list<T*> &list2) {}
+  C3(::std::initializer_list<T**> &&list3) {}
+
+  template <typename U>
+  C3(initializer_list<U> list3) {}
+};
+
+struct D {
+  template <typename T>
+  explicit D(T t) {}
+};
+
+template <typename T>
+struct E {
+  E(T *pt) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
+  // CHECK-FIXES: {{^  }}explicit E(T *pt) {}
+  template <typename U>
+  E(U *pu) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors
+  // CHECK-FIXES: {{^  }}explicit E(U *pu) {}
+
+  explicit E(T t) {}
+  template <typename U>
+  explicit E(U u) {}
+};
+
+void f(std::initializer_list<int> list) {
+  D d(list);
+  E<decltype(list)> e(list);
+  E<int> e2(list);
+}
+
+template <typename T>
+struct F {};
+
+template<typename T>
+struct G {
+  operator bool() const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator bool' must be marked
+  // CHECK-FIXES: {{^}}  explicit operator bool() const;
+  operator F<T>() const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator F<type-parameter-0-0>' must be marked
+  // CHECK-FIXES: {{^}}  explicit operator F<T>() const;
+  template<typename U>
+  operator F<U>*() const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'operator F<type-parameter-1-0> *' must be marked
+  // CHECK-FIXES: {{^}}  explicit operator F<U>*() const;
+};
+
+void f2() {
+  G<int> a;
+  (void)(F<int>)a;
+  if (a) {}
+  (void)(F<int>*)a;
+  (void)(F<int*>*)a;
+
+  G<double> b;
+  (void)(F<double>)b;
+  if (b) {}
+  (void)(F<double>*)b;
+  (void)(F<double*>*)b;
+}
+
+#define DEFINE_STRUCT_WITH_OPERATOR_BOOL(name) \
+  struct name {                                \
+    operator bool() const;                     \
+  }
+
+DEFINE_STRUCT_WITH_OPERATOR_BOOL(H);

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-module.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-module.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-module.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-module.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,10 @@
+// RUN: clang-tidy -checks='-*,google*' -config='{}' -dump-config - -- | FileCheck %s
+// CHECK: CheckOptions:
+// CHECK: {{- key: *google-readability-braces-around-statements.ShortStatementLines}}
+// CHECK-NEXT: {{value: *'1'}}
+// CHECK: {{- key: *google-readability-function-size.StatementThreshold}}
+// CHECK-NEXT: {{value: *'800'}}
+// CHECK: {{- key: *google-readability-namespace-comments.ShortNamespaceLines}}
+// CHECK-NEXT: {{value: *'10'}}
+// CHECK: {{- key: *google-readability-namespace-comments.SpacesBeforeComments}}
+// CHECK-NEXT: {{value: *'2'}}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-namespaces.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-namespaces.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-namespaces.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-namespaces.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,52 @@
+// RUN: clang-tidy %s -checks='-*,google-build-namespaces,google-build-using-namespace' -header-filter='.*' -- | FileCheck %s -implicit-check-not="{{warning|error}}:"
+#include "Inputs/google-namespaces.h"
+// CHECK: warning: do not use unnamed namespaces in header files [google-build-namespaces]
+
+using namespace spaaaace;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+using spaaaace::core; // no-warning
+
+namespace std {
+inline namespace literals {
+inline namespace chrono_literals {
+}
+inline namespace complex_literals {
+}
+inline namespace string_literals {
+}
+}
+}
+
+using namespace std::chrono_literals;            // no-warning
+using namespace std::complex_literals;           // no-warning
+using namespace std::literals;                   // no-warning
+using namespace std::literals::chrono_literals;  // no-warning
+using namespace std::literals::complex_literals; // no-warning
+using namespace std::literals::string_literals;  // no-warning
+using namespace std::string_literals;            // no-warning
+
+namespace literals {}
+
+using namespace literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+namespace foo {
+inline namespace literals {
+inline namespace bar_literals {}
+}
+}
+
+using namespace foo::literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+using namespace foo::bar_literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+using namespace foo::literals::bar_literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]
+
+namespace foo_literals {}
+
+using namespace foo_literals;
+// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives; use using-declarations instead [google-build-using-namespace]

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-nsobject-new.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-nsobject-new.m?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-nsobject-new.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-nsobject-new.m Fri Oct 11 05:05:42 2019
@@ -0,0 +1,80 @@
+// RUN: %check_clang_tidy %s google-objc-avoid-nsobject-new %t
+
+ at interface NSObject
++ (instancetype)new;
++ (instancetype)alloc;
+- (instancetype)init;
+ at end
+
+ at interface NSProxy  // Root class with no -init method.
+ at end
+
+// NSDate provides a specific factory method.
+ at interface NSDate : NSObject
++ (instancetype)date;
+ at end
+
+// For testing behavior with Objective-C Generics.
+ at interface NSMutableDictionary<__covariant KeyType, __covariant ObjectType> : NSObject
+ at end
+
+ at class NSString;
+
+#define ALLOCATE_OBJECT(_Type) [_Type new]
+
+void CheckSpecificInitRecommendations(void) {
+  NSObject *object = [NSObject new];
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
+  // CHECK-FIXES: [NSObject alloc] init];
+
+  NSDate *correctDate = [NSDate date];
+  NSDate *incorrectDate = [NSDate new];
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
+  // CHECK-FIXES: [NSDate date];
+
+  NSObject *macroCreated = ALLOCATE_OBJECT(NSObject);  // Shouldn't warn on macros.
+
+  NSMutableDictionary *dict = [NSMutableDictionary<NSString *, NSString *> new];
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
+  // CHECK-FIXES: [NSMutableDictionary<NSString *, NSString *> alloc] init];
+}
+
+ at interface Foo : NSObject
++ (instancetype)new; // Declare again to suppress warning.
+- (instancetype)initWithInt:(int)anInt;
+- (instancetype)init __attribute__((unavailable));
+
+- (id)new;
+ at end
+
+ at interface Baz : Foo // Check unavailable -init through inheritance.
+ at end
+
+ at interface ProxyFoo : NSProxy
++ (instancetype)new;
+ at end
+
+void CallNewWhenInitUnavailable(void) {
+  Foo *foo = [Foo new];
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
+
+  Baz *baz = [Baz new];
+  // CHECK-MESSAGES: [[@LINE-1]]:14: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
+
+  // Instance method -new calls may be weird, but are not strictly forbidden.
+  Foo *bar = [[Foo alloc] initWithInt:4];
+  [bar new];
+
+  ProxyFoo *proxy = [ProxyFoo new];
+  // CHECK-MESSAGES: [[@LINE-1]]:21: warning: do not create objects with +new [google-objc-avoid-nsobject-new]
+}
+
+ at interface HasNewOverride : NSObject
+ at end
+
+ at implementation HasNewOverride
++ (instancetype)new {
+  return [[self alloc] init];
+}
+// CHECK-MESSAGES: [[@LINE-3]]:1: warning: classes should not override +new [google-objc-avoid-nsobject-new]
+ at end

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-throwing-exception.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-throwing-exception.m?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-throwing-exception.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-avoid-throwing-exception.m Fri Oct 11 05:05:42 2019
@@ -0,0 +1,32 @@
+// RUN: %check_clang_tidy %s google-objc-avoid-throwing-exception %t
+ at class NSString;
+
+ at interface NSException
+
++ (void)raise:(NSString *)name format:(NSString *)format;
++ (void)raise:(NSString *)name format:(NSString *)format arguments:(NSString *)args; // using NSString type since va_list cannot be recognized here
+
+ at end
+
+ at interface NotException
+
++ (void)raise:(NSString *)name format:(NSString *)format;
+
+ at end
+
+ at implementation Foo
+- (void)f {
+    NSString *foo = @"foo";
+    @throw foo;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+}
+
+- (void)f2 {
+    [NSException raise:@"TestException" format:@"Test"];
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+    [NSException raise:@"TestException" format:@"Test %@" arguments:@"bar"];
+    // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: pass in NSError ** instead of throwing exception to indicate Objective-C errors [google-objc-avoid-throwing-exception]
+    [NotException raise:@"NotException" format:@"Test"];
+}
+ at end
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.m?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.m Fri Oct 11 05:05:42 2019
@@ -0,0 +1,71 @@
+// RUN: %check_clang_tidy %s google-objc-function-naming %t -- -- -isystem %S/Inputs/Headers
+
+#include <stdio.h>
+
+static void TestImplicitFunctionDeclaration(int a) {
+  // Call a builtin function so that the compiler generates an implicit
+  // function declaration.
+  printf("%d", a);
+}
+
+typedef _Bool bool;
+
+static bool ispositive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'ispositive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool Ispositive(int a) { return a > 0; }
+
+static bool is_positive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'is_positive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool IsPositive(int a) { return a > 0; }
+
+static bool isPositive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'isPositive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool IsPositive(int a) { return a > 0; }
+
+static bool Is_Positive(int a) { return a > 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: static function named 'Is_Positive'
+// must be in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static bool IsPositive(int a) { return a > 0; }
+
+static bool IsPositive(int a) { return a > 0; }
+
+bool ispalindrome(const char *str);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'ispalindrome' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+static const char *md5(const char *str) { return 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: static function named 'md5' must be
+// in Pascal case as required by Google Objective-C style guide
+// CHECK-FIXES: static const char *Md5(const char *str) { return 0; }
+
+static const char *MD5(const char *str) { return 0; }
+
+static const char *URL(void) { return "https://clang.llvm.org/"; }
+
+static const char *DEFURL(void) { return "https://clang.llvm.org/"; }
+
+static const char *DEFFooURL(void) { return "https://clang.llvm.org/"; }
+
+static const char *StringFromNSString(id str) { return ""; }
+
+void ABLog_String(const char *str);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'ABLog_String' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+void ABLogString(const char *str);
+
+bool IsPrime(int a);
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'IsPrime' must have an appropriate prefix followed by Pascal case as required
+// by Google Objective-C style guide
+
+const char *ABURL(void) { return "https://clang.llvm.org/"; }
+
+const char *ABFooURL(void) { return "https://clang.llvm.org/"; }
+
+int main(int argc, const char **argv) { return 0; }

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.mm
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.mm?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.mm (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-function-naming.mm Fri Oct 11 05:05:42 2019
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s google-objc-function-naming %t
+
+void printSomething() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'printSomething' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+void PrintSomething() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'PrintSomething' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+void ABCBad_Name() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function in global namespace named
+// 'ABCBad_Name' must have an appropriate prefix followed by Pascal case as
+// required by Google Objective-C style guide
+
+namespace {
+
+int foo() { return 0; }
+
+}
+
+namespace bar {
+
+int convert() { return 0; }
+
+}
+
+class Baz {
+public:
+  int value() { return 0; }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.m?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.m Fri Oct 11 05:05:42 2019
@@ -0,0 +1,66 @@
+// RUN: %check_clang_tidy %s google-objc-global-variable-declaration %t
+
+ at class NSString;
+
+static NSString* const myConstString = @"hello";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'myConstString' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const kMyConstString = @"hello";
+
+extern NSString* const GlobalConstant = @"hey";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'GlobalConstant' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+
+static NSString* MyString = @"hi";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'MyString' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* gMyString = @"hi";
+
+NSString* globalString = @"test";
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: non-const global variable 'globalString' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: NSString* gGlobalString = @"test";
+
+static NSString* a = @"too simple";
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'a' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* a = @"too simple";
+
+static NSString* noDef;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'noDef' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* gNoDef;
+
+static NSString* const _notAlpha = @"NotBeginWithAlpha";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable '_notAlpha' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const _notAlpha = @"NotBeginWithAlpha";
+
+static NSString* const notCap = @"NotBeginWithCap";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'notCap' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const kNotCap = @"NotBeginWithCap";
+
+static NSString* const k_Alpha = @"SecondNotAlpha";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'k_Alpha' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const k_Alpha = @"SecondNotAlpha";
+
+static NSString* const SecondNotCap = @"SecondNotCapOrNumber";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'SecondNotCap' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const kSecondNotCap = @"SecondNotCapOrNumber";
+
+extern NSString* Y2Bad;
+// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: non-const global variable 'Y2Bad' must have a name which starts with 'g[A-Z]' [google-objc-global-variable-declaration]
+// CHECK-FIXES: extern NSString* gY2Bad;
+
+static NSString* const kGood = @"hello";
+static NSString* const XYGood = @"hello";
+static NSString* const X1Good = @"hello";
+static NSString* gMyIntGood = 0;
+
+extern NSString* const GTLServiceErrorDomain;
+
+enum GTLServiceError {
+  GTLServiceErrorQueryResultMissing = -3000,
+  GTLServiceErrorWaitTimedOut       = -3001,
+};
+
+ at implementation Foo
+- (void)f {
+  int x = 0;
+  static int bar;
+  static const int baz = 42;
+}
+ at end

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.mm
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.mm?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.mm (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-objc-global-variable-declaration.mm Fri Oct 11 05:05:42 2019
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s google-objc-global-variable-declaration %t
+
+ at class NSString;
+static NSString* const myConstString = @"hello";
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: const global variable 'myConstString' must have a name which starts with an appropriate prefix [google-objc-global-variable-declaration]
+// CHECK-FIXES: static NSString* const kMyConstString = @"hello";
+
+class MyTest {
+  static int not_objc_style;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-overloaded-unary-and.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-overloaded-unary-and.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-overloaded-unary-and.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-overloaded-unary-and.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s google-runtime-operator %t
+
+struct Foo {
+  void *operator&();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator&, it is dangerous. [google-runtime-operator]
+};
+
+template <typename T>
+struct TFoo {
+  T *operator&();
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator&
+};
+
+TFoo<int> tfoo;
+
+struct Bar;
+void *operator&(Bar &b);
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not overload unary operator&
+
+// No warnings on binary operators.
+struct Qux {
+  void *operator&(Qux &q);
+};
+
+void *operator&(Qux &q, Qux &r);

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,24 @@
+// RUN: %check_clang_tidy %s google-readability-casting %t -- -- -x c
+// The testing script always adds .cpp extension to the input file name, so we
+// need to run clang-tidy directly in order to verify handling of .c files:
+// RUN: clang-tidy --checks=-*,google-readability-casting %s -- -x c++ | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not='{{warning|error}}:'
+// RUN: cp %s %t.main_file.cpp
+// RUN: clang-tidy --checks=-*,google-readability-casting -header-filter='.*' %t.main_file.cpp -- -I%S -DTEST_INCLUDE -x c++ | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not='{{warning|error}}:'
+
+#ifdef TEST_INCLUDE
+
+#undef TEST_INCLUDE
+#include "google-readability-casting.c"
+
+#else
+
+void f(const char *cpc) {
+  const char *cpc2 = (const char*)cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type [google-readability-casting]
+  // CHECK-FIXES: const char *cpc2 = cpc;
+  char *pc = (char*)cpc;
+  typedef const char *Typedef1;
+  (Typedef1)cpc;
+}
+
+#endif

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,324 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s google-readability-casting %t
+// FIXME: Fix the checker to work in C++17 mode.
+
+bool g() { return false; }
+
+enum Enum { Enum1 };
+struct X {};
+struct Y : public X {};
+
+void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
+  const char *cpc2 = (const char*)cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type [google-readability-casting]
+  // CHECK-FIXES: const char *cpc2 = cpc;
+
+  typedef const char *Typedef1;
+  typedef const char *Typedef2;
+  Typedef1 t1;
+  (Typedef2)t1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: C-style casts are discouraged; use static_cast (if needed, the cast may be redundant) [google-readability-casting]
+  // CHECK-FIXES: {{^}}  static_cast<Typedef2>(t1);
+  (const char*)t1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+  // CHECK-FIXES: {{^}}  static_cast<const char*>(t1);
+  (Typedef1)cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+  // CHECK-FIXES: {{^}}  static_cast<Typedef1>(cpc);
+  (Typedef1)t1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
+  // CHECK-FIXES: {{^}}  t1;
+
+  char *pc = (char*)cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use const_cast [google-readability-casting]
+  // CHECK-FIXES: char *pc = const_cast<char*>(cpc);
+  typedef char Char;
+  Char *pChar = (Char*)pc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}}; use static_cast (if needed
+  // CHECK-FIXES: {{^}}  Char *pChar = static_cast<Char*>(pc);
+
+  (Char)*cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+  // CHECK-FIXES: {{^}}  static_cast<Char>(*cpc);
+
+  (char)*pChar;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast (if needed
+  // CHECK-FIXES: {{^}}  static_cast<char>(*pChar);
+
+  (const char*)cpv;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: {{.*}}; use static_cast [
+  // CHECK-FIXES: static_cast<const char*>(cpv);
+
+  char *pc2 = (char*)(cpc + 33);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
+  // CHECK-FIXES: char *pc2 = const_cast<char*>(cpc + 33);
+
+  const char &crc = *cpc;
+  char &rc = (char&)crc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}}; use const_cast [
+  // CHECK-FIXES: char &rc = const_cast<char&>(crc);
+
+  char &rc2 = (char&)*cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
+  // CHECK-FIXES: char &rc2 = const_cast<char&>(*cpc);
+
+  char ** const* const* ppcpcpc;
+  char ****ppppc = (char****)ppcpcpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}}; use const_cast [
+  // CHECK-FIXES: char ****ppppc = const_cast<char****>(ppcpcpc);
+
+  char ***pppc = (char***)*(ppcpcpc);
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}; use const_cast [
+  // CHECK-FIXES: char ***pppc = const_cast<char***>(*(ppcpcpc));
+
+  char ***pppc2 = (char***)(*ppcpcpc);
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}; use const_cast [
+  // CHECK-FIXES: char ***pppc2 = const_cast<char***>(*ppcpcpc);
+
+  char *pc5 = (char*)(const char*)(cpv);
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use const_cast [
+  // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}}; use static_cast [
+  // CHECK-FIXES: char *pc5 = const_cast<char*>(static_cast<const char*>(cpv));
+
+  int b1 = (int)b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast [
+  // CHECK-FIXES: int b1 = static_cast<int>(b);
+  b1 = (const int&)b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+  // CHECK-FIXES: b1 = (const int&)b;
+
+  b1 = (int) b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+  // CHECK-FIXES: b1 = static_cast<int>(b);
+
+  b1 = (int)         b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+  // CHECK-FIXES: b1 = static_cast<int>(b);
+
+  b1 = (int) (b);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+  // CHECK-FIXES: b1 = static_cast<int>(b);
+
+  b1 = (int)         (b);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast {{.*}}
+  // CHECK-FIXES: b1 = static_cast<int>(b);
+
+  Y *pB = (Y*)pX;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+  Y &rB = (Y&)*pX;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+
+  const char *pc3 = (const char*)cpv;
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}}; use static_cast [
+  // CHECK-FIXES: const char *pc3 = static_cast<const char*>(cpv);
+
+  char *pc4 = (char*)cpv;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+  // CHECK-FIXES: char *pc4 = (char*)cpv;
+
+  b1 = (int)Enum1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: {{.*}}; use static_cast [
+  // CHECK-FIXES: b1 = static_cast<int>(Enum1);
+
+  Enum e = (Enum)b1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}; use static_cast [
+  // CHECK-FIXES: Enum e = static_cast<Enum>(b1);
+
+  e = (Enum)Enum1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+  // CHECK-FIXES: {{^}}  e = Enum1;
+
+  e = (Enum)e;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+  // CHECK-FIXES: {{^}}  e = e;
+
+  e = (Enum)           e;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+  // CHECK-FIXES: {{^}}  e = e;
+
+  e = (Enum)           (e);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: redundant cast to the same type
+  // CHECK-FIXES: {{^}}  e = (e);
+
+  static const int kZero = 0;
+  (int)kZero;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: redundant cast to the same type
+  // CHECK-FIXES: {{^}}  kZero;
+
+  int b2 = int(b);
+  int b3 = static_cast<double>(b);
+  int b4 = b;
+  double aa = a;
+  (void)b2;
+  return (void)g();
+}
+
+template <typename T>
+void template_function(T t, int n) {
+  int i = (int)t;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast [
+  // CHECK-FIXES: int i = (int)t;
+  int j = (int)n;
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant cast to the same type
+  // CHECK-FIXES: int j = n;
+}
+
+template <typename T>
+struct TemplateStruct {
+  void f(T t, int n) {
+    int k = (int)t;
+    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}}; use static_cast/const_cast/reinterpret_cast
+    // CHECK-FIXES: int k = (int)t;
+    int l = (int)n;
+    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant cast to the same type
+    // CHECK-FIXES: int l = n;
+  }
+};
+
+void test_templates() {
+  template_function(1, 42);
+  template_function(1.0, 42);
+  TemplateStruct<int>().f(1, 42);
+  TemplateStruct<double>().f(1.0, 42);
+}
+
+extern "C" {
+void extern_c_code(const char *cpc) {
+  const char *cpc2 = (const char*)cpc;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant cast to the same type
+  // CHECK-FIXES: const char *cpc2 = cpc;
+  char *pc = (char*)cpc;
+}
+}
+
+#define CAST(type, value) (type)(value)
+void macros(double d) {
+  int i = CAST(int, d);
+}
+
+enum E { E1 = 1 };
+template <E e>
+struct A {
+  // Usage of template argument e = E1 is represented as (E)1 in the AST for
+  // some reason. We have a special treatment of this case to avoid warnings
+  // here.
+  static const E ee = e;
+};
+struct B : public A<E1> {};
+
+
+void overloaded_function();
+void overloaded_function(int);
+
+template<typename Fn>
+void g(Fn fn) {
+  fn();
+}
+
+void function_casts() {
+  typedef void (*FnPtrVoid)();
+  typedef void (&FnRefVoid)();
+  typedef void (&FnRefInt)(int);
+
+  g((void (*)())overloaded_function);
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: g(static_cast<void (*)()>(overloaded_function));
+  g((void (*)())&overloaded_function);
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: g(static_cast<void (*)()>(&overloaded_function));
+  g((void (&)())overloaded_function);
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: g(static_cast<void (&)()>(overloaded_function));
+
+  g((FnPtrVoid)overloaded_function);
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: g(static_cast<FnPtrVoid>(overloaded_function));
+  g((FnPtrVoid)&overloaded_function);
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: g(static_cast<FnPtrVoid>(&overloaded_function));
+  g((FnRefVoid)overloaded_function);
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: g(static_cast<FnRefVoid>(overloaded_function));
+
+  FnPtrVoid fn0 = (void (*)())&overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: FnPtrVoid fn0 = static_cast<void (*)()>(&overloaded_function);
+  FnPtrVoid fn1 = (void (*)())overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: FnPtrVoid fn1 = static_cast<void (*)()>(overloaded_function);
+  FnPtrVoid fn1a = (FnPtrVoid)overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: FnPtrVoid fn1a = static_cast<FnPtrVoid>(overloaded_function);
+  FnRefInt fn2 = (void (&)(int))overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: FnRefInt fn2 = static_cast<void (&)(int)>(overloaded_function);
+  auto fn3 = (void (*)())&overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: auto fn3 = static_cast<void (*)()>(&overloaded_function);
+  auto fn4 = (void (*)())overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: auto fn4 = static_cast<void (*)()>(overloaded_function);
+  auto fn5 = (void (&)(int))overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: auto fn5 = static_cast<void (&)(int)>(overloaded_function);
+
+  void (*fn6)() = (void (*)())&overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: void (*fn6)() = static_cast<void (*)()>(&overloaded_function);
+  void (*fn7)() = (void (*)())overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: void (*fn7)() = static_cast<void (*)()>(overloaded_function);
+  void (*fn8)() = (FnPtrVoid)overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: void (*fn8)() = static_cast<FnPtrVoid>(overloaded_function);
+  void (&fn9)(int) = (void (&)(int))overloaded_function;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: void (&fn9)(int) = static_cast<void (&)(int)>(overloaded_function);
+
+  void (*correct1)() = static_cast<void (*)()>(overloaded_function);
+  FnPtrVoid correct2 = static_cast<void (*)()>(&overloaded_function);
+  FnRefInt correct3 = static_cast<void (&)(int)>(overloaded_function);
+}
+
+struct S {
+    S(const char *);
+};
+struct ConvertibleToS {
+  operator S() const;
+};
+struct ConvertibleToSRef {
+  operator const S&() const;
+};
+
+void conversions() {
+  //auto s1 = (const S&)"";
+  // C HECK-MESSAGES: :[[@LINE-1]]:10: warning: C-style casts are discouraged; use static_cast [
+  // C HECK-FIXES: S s1 = static_cast<const S&>("");
+  auto s2 = (S)"";
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
+  // CHECK-FIXES: auto s2 = S("");
+  auto s2a = (struct S)"";
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+  // CHECK-FIXES: auto s2a = static_cast<struct S>("");
+  auto s2b = (const S)"";
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: C-style casts are discouraged; use static_cast [
+  // FIXME: This should be constructor call syntax: S("").
+  // CHECK-FIXES: auto s2b = static_cast<const S>("");
+  ConvertibleToS c;
+  auto s3 = (const S&)c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [
+  // CHECK-FIXES: auto s3 = (const S&)c;
+  // FIXME: This should be a static_cast.
+  // C HECK-FIXES: auto s3 = static_cast<const S&>(c);
+  auto s4 = (S)c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
+  // CHECK-FIXES: auto s4 = S(c);
+  ConvertibleToSRef cr;
+  auto s5 = (const S&)cr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use static_cast/const_cast/reinterpret_cast [
+  // CHECK-FIXES: auto s5 = (const S&)cr;
+  // FIXME: This should be a static_cast.
+  // C HECK-FIXES: auto s5 = static_cast<const S&>(cr);
+  auto s6 = (S)cr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: C-style casts are discouraged; use constructor call syntax [
+  // CHECK-FIXES: auto s6 = S(cr);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.mm
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.mm?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.mm (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-casting.mm Fri Oct 11 05:05:42 2019
@@ -0,0 +1,179 @@
+// RUN: clang-tidy %s -checks=-*,google-readability-casting -- \
+// RUN:   -xobjective-c++ -fobjc-abi-version=2 -fobjc-arc | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+bool g() { return false; }
+
+enum Enum { Enum1 };
+struct X {};
+struct Y : public X {};
+
+void f(int a, double b, const char *cpc, const void *cpv, X *pX) {
+
+  typedef const char *Typedef1;
+  typedef const char *Typedef2;
+  Typedef1 t1;
+  (Typedef2)t1;
+  (const char*)t1;
+  (Typedef1)cpc;
+
+  typedef char Char;
+  char *pc;
+  Char *pChar = (Char*)pc;
+
+  (Char)*cpc;
+
+  (char)*pChar;
+
+  (const char*)cpv;
+
+  char *pc2 = (char*)(cpc + 33);
+
+  const char &crc = *cpc;
+  char &rc = (char&)crc;
+
+  char &rc2 = (char&)*cpc;
+
+  char ** const* const* ppcpcpc;
+  char ****ppppc = (char****)ppcpcpc;
+
+  char ***pppc = (char***)*(ppcpcpc);
+
+  char ***pppc2 = (char***)(*ppcpcpc);
+
+  char *pc5 = (char*)(const char*)(cpv);
+
+  int b1 = (int)b;
+  b1 = (const int&)b;
+
+  b1 = (int) b;
+
+  b1 = (int)         b;
+
+  b1 = (int) (b);
+
+  b1 = (int)         (b);
+
+  Y *pB = (Y*)pX;
+  Y &rB = (Y&)*pX;
+
+  const char *pc3 = (const char*)cpv;
+
+  char *pc4 = (char*)cpv;
+
+  b1 = (int)Enum1;
+
+  Enum e = (Enum)b1;
+
+  int b2 = int(b);
+  int b3 = static_cast<double>(b);
+  int b4 = b;
+  double aa = a;
+  (void)b2;
+  return (void)g();
+}
+
+template <typename T>
+void template_function(T t, int n) {
+  int i = (int)t;
+}
+
+template <typename T>
+struct TemplateStruct {
+  void f(T t, int n) {
+    int k = (int)t;
+  }
+};
+
+void test_templates() {
+  template_function(1, 42);
+  template_function(1.0, 42);
+  TemplateStruct<int>().f(1, 42);
+  TemplateStruct<double>().f(1.0, 42);
+}
+
+extern "C" {
+void extern_c_code(const char *cpc) {
+  char *pc = (char*)cpc;
+}
+}
+
+#define CAST(type, value) (type)(value)
+void macros(double d) {
+  int i = CAST(int, d);
+}
+
+enum E { E1 = 1 };
+template <E e>
+struct A {
+  // Usage of template argument e = E1 is represented as (E)1 in the AST for
+  // some reason. We have a special treatment of this case to avoid warnings
+  // here.
+  static const E ee = e;
+};
+struct B : public A<E1> {};
+
+
+void overloaded_function();
+void overloaded_function(int);
+
+template<typename Fn>
+void g(Fn fn) {
+  fn();
+}
+
+void function_casts() {
+  typedef void (*FnPtrVoid)();
+  typedef void (&FnRefVoid)();
+  typedef void (&FnRefInt)(int);
+
+  g((void (*)())overloaded_function);
+  g((void (*)())&overloaded_function);
+  g((void (&)())overloaded_function);
+
+  g((FnPtrVoid)overloaded_function);
+  g((FnPtrVoid)&overloaded_function);
+  g((FnRefVoid)overloaded_function);
+
+  FnPtrVoid fn0 = (void (*)())&overloaded_function;
+  FnPtrVoid fn1 = (void (*)())overloaded_function;
+  FnPtrVoid fn1a = (FnPtrVoid)overloaded_function;
+  FnRefInt fn2 = (void (&)(int))overloaded_function;
+  auto fn3 = (void (*)())&overloaded_function;
+  auto fn4 = (void (*)())overloaded_function;
+  auto fn5 = (void (&)(int))overloaded_function;
+
+  void (*fn6)() = (void (*)())&overloaded_function;
+  void (*fn7)() = (void (*)())overloaded_function;
+  void (*fn8)() = (FnPtrVoid)overloaded_function;
+  void (&fn9)(int) = (void (&)(int))overloaded_function;
+
+  void (*correct1)() = static_cast<void (*)()>(overloaded_function);
+  FnPtrVoid correct2 = static_cast<void (*)()>(&overloaded_function);
+  FnRefInt correct3 = static_cast<void (&)(int)>(overloaded_function);
+}
+
+struct S {
+    S(const char *);
+};
+struct ConvertibleToS {
+  operator S() const;
+};
+struct ConvertibleToSRef {
+  operator const S&() const;
+};
+
+void conversions() {
+  //auto s1 = (const S&)"";
+  auto s2 = (S)"";
+  auto s2a = (struct S)"";
+  auto s2b = (const S)"";
+  ConvertibleToS c;
+  auto s3 = (const S&)c;
+  auto s4 = (S)c;
+  ConvertibleToSRef cr;
+  auto s5 = (const S&)cr;
+  auto s6 = (S)cr;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-namespace-comments.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-namespace-comments.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-namespace-comments.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-namespace-comments.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,54 @@
+// RUN: %check_clang_tidy %s google-readability-namespace-comments %t
+
+namespace n1 {
+namespace n2 {
+
+
+void f(); // So that the namespace isn't empty.
+
+
+// CHECK-MESSAGES: :[[@LINE+4]]:1: warning: namespace 'n2' not terminated with a closing comment [google-readability-namespace-comments]
+// CHECK-MESSAGES: :[[@LINE-7]]:11: note: namespace 'n2' starts here
+// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: namespace 'n1' not terminated with
+// CHECK-MESSAGES: :[[@LINE-10]]:11: note: namespace 'n1' starts here
+}}
+// CHECK-FIXES: }  // namespace n2
+// CHECK-FIXES: }  // namespace n1
+
+#define MACRO macro_expansion
+namespace MACRO {
+void f(); // So that the namespace isn't empty.
+// 1
+// 2
+// 3
+// 4
+// 5
+// 6
+// 7
+// CHECK-MESSAGES: :[[@LINE+2]]:1: warning: namespace 'macro_expansion' not terminated with
+// CHECK-MESSAGES: :[[@LINE-10]]:11: note: namespace 'macro_expansion' starts here
+}
+// CHECK-FIXES: }  // namespace macro_expansion
+
+namespace short1 {
+namespace short2 {
+// Namespaces covering 10 lines or fewer are exempt from this rule.
+
+
+
+
+
+}
+}
+
+namespace n3 {
+
+
+
+
+
+
+
+
+
+}; // namespace n3

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-nested-namespace-comments.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-nested-namespace-comments.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-nested-namespace-comments.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-nested-namespace-comments.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s google-readability-namespace-comments %t
+
+namespace n1::n2 {
+namespace n3 {
+
+// So that namespace is not empty.
+void f();
+
+
+// CHECK-MESSAGES: :[[@LINE+4]]:1: warning: namespace 'n3' not terminated with
+// CHECK-MESSAGES: :[[@LINE-7]]:11: note: namespace 'n3' starts here
+// CHECK-MESSAGES: :[[@LINE+2]]:2: warning: namespace 'n1::n2' not terminated with a closing comment [google-readability-namespace-comments]
+// CHECK-MESSAGES: :[[@LINE-10]]:11: note: namespace 'n1::n2' starts here
+}}
+// CHECK-FIXES: }  // namespace n3
+// CHECK-FIXES: }  // namespace n1::n2
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-todo.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-todo.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-todo.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-readability-todo.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s google-readability-todo %t -- -config="{User: 'some user'}" --
+
+//   TODOfix this1
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this1
+
+//   TODO fix this2
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this2
+
+// TODO fix this3
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this3
+
+// TODO: fix this4
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: missing username/bug in TODO
+// CHECK-FIXES: // TODO(some user): fix this4
+
+//   TODO(clang)fix this5
+
+// TODO(foo):shave yaks
+// TODO(bar):
+// TODO(foo): paint bikeshed
+// TODO(b/12345): find the holy grail
+// TODO (b/12345): allow spaces before parentheses
+// TODO(asdf) allow missing semicolon

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int-std.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int-std.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int-std.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int-std.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s google-runtime-int %t -- \
+// RUN:   -config='{CheckOptions: [ \
+// RUN:     {key: google-runtime-int.UnsignedTypePrefix, value: "std::uint"}, \
+// RUN:     {key: google-runtime-int.SignedTypePrefix, value: "std::int"}, \
+// RUN:     {key: google-runtime-int.TypeSuffix, value: "_t"}, \
+// RUN:   ]}'
+
+long a();
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'std::int{{..}}_t'
+
+typedef unsigned long long uint64; // NOLINT
+
+long b(long = 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'std::int{{..}}_t'
+// CHECK-MESSAGES: [[@LINE-2]]:8: warning: consider replacing 'long' with 'std::int{{..}}_t'
+
+template <typename T>
+void tmpl() {
+  T i;
+}
+
+short bar(const short, unsigned short) {
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'short' with 'std::int16_t'
+// CHECK-MESSAGES: [[@LINE-2]]:17: warning: consider replacing 'short' with 'std::int16_t'
+// CHECK-MESSAGES: [[@LINE-3]]:24: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+  long double foo = 42;
+  uint64 qux = 42;
+  unsigned short port;
+
+  const unsigned short bar = 0;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+  long long *baar;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'std::int64_t'
+  const unsigned short &bara = bar;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+  long const long moo = 1;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'std::int64_t'
+  long volatile long wat = 42;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'std::int64_t'
+  unsigned long y;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long' with 'std::uint{{..}}_t'
+  unsigned long long **const *tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'std::uint64_t'
+  unsigned long long **const *&z = tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'std::uint64_t'
+  unsigned short porthole;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned short' with 'std::uint16_t'
+
+  uint64 cast = (short)42;
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: consider replacing 'short' with 'std::int16_t'
+
+#define l long
+  l x;
+
+  tmpl<short>();
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: consider replacing 'short' with 'std::int16_t'
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,27 @@
+// RUN: clang-tidy -checks=-*,google-runtime-int %s -- -x c 2>&1 | not grep 'warning:\|error:'
+
+long a();
+
+long b(long x);
+
+short bar(const short q, unsigned short w) {
+  long double foo;
+  unsigned short port;
+
+  const unsigned short bar;
+  long long *baar;
+  const unsigned short bara;
+  long const long moo;
+  long volatile long wat;
+  unsigned long y;
+  unsigned long long **const *tmp;
+  unsigned short porthole;
+
+  unsigned cast;
+  cast = (short)42;
+  return q;
+}
+
+void qux() {
+  short port;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,91 @@
+// RUN: %check_clang_tidy %s google-runtime-int %t
+
+long a();
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'int{{..}}'
+
+typedef unsigned long long uint64; // NOLINT
+
+long b(long = 1);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'long' with 'int{{..}}'
+// CHECK-MESSAGES: [[@LINE-2]]:8: warning: consider replacing 'long' with 'int{{..}}'
+
+template <typename T>
+void tmpl() {
+  T i;
+}
+
+short bar(const short, unsigned short) {
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: consider replacing 'short' with 'int16'
+// CHECK-MESSAGES: [[@LINE-2]]:17: warning: consider replacing 'short' with 'int16'
+// CHECK-MESSAGES: [[@LINE-3]]:24: warning: consider replacing 'unsigned short' with 'uint16'
+  long double foo = 42;
+  uint64 qux = 42;
+  unsigned short port;
+
+  const unsigned short bar = 0;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'uint16'
+  long long *baar;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'int64'
+  const unsigned short &bara = bar;
+// CHECK-MESSAGES: [[@LINE-1]]:9: warning: consider replacing 'unsigned short' with 'uint16'
+  long const long moo = 1;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'int64'
+  long volatile long wat = 42;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'long long' with 'int64'
+  unsigned long y;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long' with 'uint{{..}}'
+  unsigned long long **const *tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'uint64'
+  unsigned long long **const *&z = tmp;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned long long' with 'uint64'
+  unsigned short porthole;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'unsigned short' with 'uint16'
+
+  uint64 cast = (short)42;
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: consider replacing 'short' with 'int16'
+
+#define l long
+  l x;
+
+  tmpl<short>();
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: consider replacing 'short' with 'int16'
+  return 0;
+}
+
+void p(unsigned short port);
+
+void qux() {
+  short port;
+// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'short' with 'int16'
+}
+
+// FIXME: This shouldn't warn, as UD-literal operators require one of a handful
+// of types as an argument.
+struct some_value {};
+constexpr some_value operator"" _some_literal(unsigned long long int i);
+// CHECK-MESSAGES: [[@LINE-1]]:47: warning: consider replacing 'unsigned long long'
+
+struct A { A& operator=(const A&); };
+class B { A a[0]; };
+
+void fff() {
+  B a, b;
+  a = b;
+}
+
+__attribute__((__format__ (__printf__, 1, 2)))
+void myprintf(const char* s, ...);
+
+void doprint_no_warning() {
+  uint64 foo = 23;
+  myprintf("foo %lu %lu", (unsigned long)42, (unsigned long)foo);
+}
+
+void myprintf_no_attribute(const char* s, ...);
+
+void doprint_warning() {
+  uint64 foo = 23;
+  myprintf_no_attribute("foo %lu %lu", (unsigned long)42, (unsigned long)foo);
+// CHECK-MESSAGES: [[@LINE-1]]:41: warning: consider replacing 'unsigned long'
+// CHECK-MESSAGES: [[@LINE-2]]:60: warning: consider replacing 'unsigned long'
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.m
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.m?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.m (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-int.m Fri Oct 11 05:05:42 2019
@@ -0,0 +1,32 @@
+// RUN: clang-tidy -checks=-*,google-runtime-int %s 2>&1 -- | count 0
+// RUN: clang-tidy -checks=-*,google-runtime-int %s 2>&1 -- -x objective-c++ | count 0
+
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+
+ at interface NSString
+ at property(readonly) NSInteger integerValue;
+ at property(readonly) long long longLongValue;
+ at property(readonly) NSUInteger length;
+ at end
+
+NSInteger Foo(NSString *s) {
+  return [s integerValue];
+}
+
+long long Bar(NSString *s) {
+  return [s longLongValue];
+}
+
+NSUInteger Baz(NSString *s) {
+  return [s length];
+}
+
+unsigned short NSSwapShort(unsigned short inv);
+
+long DoSomeMath(long a, short b) {
+  short c = NSSwapShort(b);
+  long a2 = a * 5L;
+  return a2 + c;
+}
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-references.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-references.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-references.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-runtime-references.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,155 @@
+// RUN: %check_clang_tidy %s google-runtime-references %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:             [{key: google-runtime-references.WhiteListTypes, \
+// RUN:               value: 'whitelist::A; whitelist::B'}]}"
+
+int a;
+int &b = a;
+int *c;
+void f1(int a);
+void f2(int *b);
+void f3(const int &c);
+void f4(int const &d);
+
+// Don't warn on implicit operator= in c++11 mode.
+class A {
+  virtual void f() {}
+};
+// Don't warn on rvalue-references.
+struct A2 {
+  A2(A2&&) = default;
+  void f(A2&&) {}
+};
+
+// Don't warn on iostream parameters.
+namespace xxx {
+class istream { };
+class ostringstream { };
+}
+void g1(xxx::istream &istr);
+void g1(xxx::ostringstream &istr);
+
+void g1(int &a);
+// CHECK-MESSAGES: [[@LINE-1]]:14: warning: non-const reference parameter 'a', make it const or use a pointer [google-runtime-references]
+
+struct s {};
+void g2(int a, int b, s c, s &d);
+// CHECK-MESSAGES: [[@LINE-1]]:31: warning: non-const reference parameter 'd', {{.*}}
+
+typedef int &ref;
+void g3(ref a);
+// CHECK-MESSAGES: [[@LINE-1]]:13: warning: non-const reference {{.*}}
+
+void g4(int &a, int &b, int &);
+// CHECK-MESSAGES: [[@LINE-1]]:14: warning: non-const reference parameter 'a', {{.*}}
+// CHECK-MESSAGES: [[@LINE-2]]:22: warning: non-const reference parameter 'b', {{.*}}
+// CHECK-MESSAGES: [[@LINE-3]]:30: warning: non-const reference parameter at index 2, {{.*}}
+
+class B {
+  B(B& a) {}
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: non-const reference {{.*}}
+  virtual void f(int &a) {}
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: non-const reference {{.*}}
+  void g(int &b);
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: non-const reference {{.*}}
+
+  // Don't warn on the parameter of stream extractors defined as members.
+  B& operator>>(int& val) { return *this; }
+};
+
+// Only warn on the first declaration of each function to reduce duplicate
+// warnings.
+void B::g(int &b) {}
+
+// Don't warn on the first parameter of stream inserters.
+A& operator<<(A& s, int&) { return s; }
+// CHECK-MESSAGES: [[@LINE-1]]:25: warning: non-const reference parameter at index 1, {{.*}}
+
+// Don't warn on either parameter of stream extractors. Both need to be
+// non-const references by convention.
+A& operator>>(A& input, int& val) { return input; }
+
+// Don't warn on lambdas.
+auto lambda = [] (int&) {};
+
+// Don't warn on typedefs, as we'll warn on the function itself.
+typedef int (*fp)(int &);
+
+// Don't warn on function references.
+typedef void F();
+void g5(const F& func) {}
+void g6(F& func) {}
+
+template<typename T>
+void g7(const T& t) {}
+
+template<typename T>
+void g8(T t) {}
+
+void f5() {
+  g5(f5);
+  g6(f5);
+  g7(f5);
+  g7<F&>(f5);
+  g8(f5);
+  g8<F&>(f5);
+}
+
+// Don't warn on dependent types.
+template<typename T>
+void g9(T& t) {}
+template<typename T>
+void g10(T t) {}
+
+void f6() {
+  int i;
+  float f;
+  g9<int>(i);
+  g9<const int>(i);
+  g9<int&>(i);
+  g10<int&>(i);
+  g10<float&>(f);
+}
+
+// Warn only on the overridden methods from the base class, as the child class
+// only implements the interface.
+class C : public B {
+  C();
+  virtual void f(int &a) {}
+};
+
+// Don't warn on operator<< with streams-like interface.
+A& operator<<(A& s, int) { return s; }
+
+// Don't warn on swap().
+void swap(C& c1, C& c2) {}
+
+// Don't warn on standalone operator++, operator--, operator+=, operator-=,
+// operator*=, etc. that all need non-const references to be functional.
+A& operator++(A& a) { return a; }
+A operator++(A& a, int) { return a; }
+A& operator--(A& a) { return a; }
+A operator--(A& a, int) { return a; }
+A& operator+=(A& a, const A& b) { return a; }
+A& operator-=(A& a, const A& b) { return a; }
+A& operator*=(A& a, const A& b) { return a; }
+A& operator/=(A& a, const A& b) { return a; }
+A& operator%=(A& a, const A& b) { return a; }
+A& operator<<=(A& a, const A& b) { return a; }
+A& operator>>=(A& a, const A& b) { return a; }
+A& operator|=(A& a, const A& b) { return a; }
+A& operator^=(A& a, const A& b) { return a; }
+A& operator&=(A& a, const A& b) { return a; }
+
+namespace whitelist {
+class A {};
+class B {};
+void f7(A &);
+void f8(B &);
+}
+void f9(whitelist::A &);
+void f10(whitelist::B &);
+
+#define DEFINE_F(name) void name(int& a)
+
+DEFINE_F(func) {}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/google-upgrade-googletest-case.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/google-upgrade-googletest-case.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/google-upgrade-googletest-case.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/google-upgrade-googletest-case.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,1016 @@
+// RUN: %check_clang_tidy %s google-upgrade-googletest-case %t -- -- -I%S/Inputs
+// RUN: %check_clang_tidy -check-suffix=NOSUITE %s google-upgrade-googletest-case %t -- -- -DNOSUITE -I%S/Inputs/gtest/nosuite
+
+#include "gtest/gtest.h"
+
+// When including a version of googletest without the replacement names, this
+// check should not produce any diagnostics. The following dummy fix is present
+// because `check_clang_tidy.py` requires at least one warning, fix or note.
+void Dummy() {}
+// CHECK-FIXES-NOSUITE: void Dummy() {}
+
+// ----------------------------------------------------------------------------
+// Macros
+
+TYPED_TEST_CASE(FooTest, FooTypes);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Google Test APIs named with 'case' are deprecated; use equivalent APIs named with 'suite'
+// CHECK-FIXES: TYPED_TEST_SUITE(FooTest, FooTypes);
+TYPED_TEST_CASE_P(FooTest);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: TYPED_TEST_SUITE_P(FooTest);
+REGISTER_TYPED_TEST_CASE_P(FooTest, FooTestName);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: REGISTER_TYPED_TEST_SUITE_P(FooTest, FooTestName);
+INSTANTIATE_TYPED_TEST_CASE_P(FooPrefix, FooTest, FooTypes);
+// CHECK-MESSAGES: [[@LINE-1]]:1: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: INSTANTIATE_TYPED_TEST_SUITE_P(FooPrefix, FooTest, FooTypes);
+
+#ifdef TYPED_TEST_CASE
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Google Test APIs named with 'case'
+#undef TYPED_TEST_CASE
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+#define TYPED_TEST_CASE(CaseName, Types, ...)
+#endif
+
+#ifdef TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Google Test APIs named with 'case'
+#undef TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+#define TYPED_TEST_CASE_P(SuiteName)
+#endif
+
+#ifdef REGISTER_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Google Test APIs named with 'case'
+#undef REGISTER_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+#define REGISTER_TYPED_TEST_CASE_P(SuiteName, ...)
+#endif
+
+#ifdef INSTANTIATE_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:2: warning: Google Test APIs named with 'case'
+#undef INSTANTIATE_TYPED_TEST_CASE_P
+// CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, SuiteName, Types, ...)
+#endif
+
+TYPED_TEST_CASE(FooTest, FooTypes);
+TYPED_TEST_CASE_P(FooTest);
+REGISTER_TYPED_TEST_CASE_P(FooTest, FooTestName);
+INSTANTIATE_TYPED_TEST_CASE_P(FooPrefix, FooTest, FooTypes);
+
+// ----------------------------------------------------------------------------
+// testing::Test
+
+class FooTest : public testing::Test {
+public:
+  static void SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: static void SetUpTestSuite();
+  static void TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: static void TearDownTestSuite();
+};
+
+void FooTest::SetUpTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: void FooTest::SetUpTestSuite() {}
+
+void FooTest::TearDownTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: void FooTest::TearDownTestSuite() {}
+
+template <typename T> class FooTypedTest : public testing::Test {
+public:
+  static void SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: static void SetUpTestSuite();
+  static void TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: static void TearDownTestSuite();
+};
+
+template <typename T> void FooTypedTest<T>::SetUpTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: void FooTypedTest<T>::SetUpTestSuite() {}
+
+template <typename T> void FooTypedTest<T>::TearDownTestCase() {}
+// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: void FooTypedTest<T>::TearDownTestSuite() {}
+
+class BarTest : public testing::Test {
+public:
+  using Test::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using Test::SetUpTestSuite;
+  using Test::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using Test::TearDownTestSuite;
+};
+
+class BarTest2 : public FooTest {
+public:
+  using FooTest::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using FooTest::SetUpTestSuite;
+  using FooTest::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using FooTest::TearDownTestSuite;
+};
+
+// If a derived type already has the replacements, we only provide a warning
+// since renaming or deleting the old declarations may not be safe.
+class BarTest3 : public testing::Test {
+ public:
+  static void SetUpTestCase() {}
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  static void SetUpTestSuite() {}
+
+  static void TearDownTestCase() {}
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  static void TearDownTestSuite() {}
+};
+
+namespace nesting_ns {
+namespace testing {
+
+class Test {
+public:
+  static void SetUpTestCase();
+  static void TearDownTestCase();
+};
+
+} // namespace testing
+
+void Test() {
+  testing::Test::SetUpTestCase();
+  testing::Test::TearDownTestCase();
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void testInstantiationOnlyWarns() {
+  T::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:6: warning: Google Test APIs named with 'case'
+  T::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:6: warning: Google Test APIs named with 'case'
+}
+
+#define SET_UP_TEST_CASE_MACRO_REPLACE SetUpTestCase
+#define TEST_SET_UP_TEST_CASE_MACRO_WARN_ONLY ::testing::Test::SetUpTestCase
+
+void setUpTearDownCallAndReference() {
+  testing::Test::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::Test::SetUpTestSuite();
+  FooTest::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: FooTest::SetUpTestSuite();
+
+  testing::Test::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::Test::TearDownTestSuite();
+  FooTest::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: FooTest::TearDownTestSuite();
+
+  auto F = &testing::Test::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F = &testing::Test::SetUpTestSuite;
+  F = &testing::Test::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: F = &testing::Test::TearDownTestSuite;
+  F = &FooTest::SetUpTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: F = &FooTest::SetUpTestSuite;
+  F = &FooTest::TearDownTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:17: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: F = &FooTest::TearDownTestSuite;
+
+  using MyTest = testing::Test;
+  MyTest::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: MyTest::SetUpTestSuite();
+  MyTest::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: MyTest::TearDownTestSuite();
+
+  BarTest3::SetUpTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: BarTest3::SetUpTestSuite();
+  BarTest3::TearDownTestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: BarTest3::TearDownTestSuite();
+
+  testInstantiationOnlyWarns<testing::Test>();
+
+  testing::Test::SET_UP_TEST_CASE_MACRO_REPLACE();
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::Test::SetUpTestSuite();
+  TEST_SET_UP_TEST_CASE_MACRO_WARN_ONLY();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+}
+
+// ----------------------------------------------------------------------------
+// testing::TestInfo
+
+class FooTestInfo : public testing::TestInfo {
+public:
+  const char *test_case_name() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const char *test_suite_name() const;
+};
+
+const char *FooTestInfo::test_case_name() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:26: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: const char *FooTestInfo::test_suite_name() const {}
+
+class BarTestInfo : public testing::TestInfo {
+public:
+  using TestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:19: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using TestInfo::test_suite_name;
+};
+
+class BarTestInfo2 : public FooTestInfo {
+public:
+  using FooTestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using FooTestInfo::test_suite_name;
+};
+
+class BarTestInfo3 : public testing::TestInfo {
+ public:
+  const char* test_case_name() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: Google Test APIs named with 'case'
+  const char* test_suite_name() const;
+};
+
+namespace nesting_ns {
+namespace testing {
+
+class TestInfo {
+public:
+  const char *test_case_name() const;
+};
+
+} // namespace testing
+
+void FuncInfo() {
+  testing::TestInfo t;
+  (void)t.test_case_name();
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void testInfoInstantiationOnlyWarns() {
+  T t;
+  (void)t.test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+}
+
+#define TEST_CASE_NAME_MACRO_REPLACE test_case_name
+#define TEST_CASE_NAME_MACRO_WARN_ONLY testing::TestInfo().test_case_name
+
+void testInfoCallAndReference() {
+  (void)testing::TestInfo().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::TestInfo().test_suite_name();
+  (void)FooTestInfo().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooTestInfo().test_suite_name();
+  auto F1 = &testing::TestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F1 = &testing::TestInfo::test_suite_name;
+  auto F2 = &FooTestInfo::test_case_name;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F2 = &FooTestInfo::test_suite_name;
+  using MyTestInfo = testing::TestInfo;
+  (void)MyTestInfo().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyTestInfo().test_suite_name();
+  (void)BarTestInfo3().test_case_name();
+  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)BarTestInfo3().test_suite_name();
+
+  testInfoInstantiationOnlyWarns<testing::TestInfo>();
+
+  (void)testing::TestInfo().TEST_CASE_NAME_MACRO_REPLACE();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::TestInfo().test_suite_name();
+  (void)TEST_CASE_NAME_MACRO_WARN_ONLY();
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: Google Test APIs named with 'case'
+}
+
+// ----------------------------------------------------------------------------
+// testing::TestEventListener
+
+class FooTestEventListener : public testing::TestEventListener {
+public:
+  void OnTestCaseStart(const testing::TestCase &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:39: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: void OnTestSuiteStart(const testing::TestSuite &) override;
+  void OnTestCaseEnd(const testing::TestCase &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:37: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: void OnTestSuiteEnd(const testing::TestSuite &) override;
+};
+
+void FooTestEventListener::OnTestCaseStart(const testing::TestCase &) {}
+// CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+// CHECK-MESSAGES: [[@LINE-2]]:59: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: void FooTestEventListener::OnTestSuiteStart(const testing::TestSuite &) {}
+
+void FooTestEventListener::OnTestCaseEnd(const testing::TestCase &) {}
+// CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+// CHECK-MESSAGES: [[@LINE-2]]:57: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: void FooTestEventListener::OnTestSuiteEnd(const testing::TestSuite &) {}
+
+class BarTestEventListener : public testing::TestEventListener {
+public:
+  using TestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using TestEventListener::OnTestSuiteStart;
+  using TestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using TestEventListener::OnTestSuiteEnd;
+};
+
+class BarTestEventListener2 : public BarTestEventListener {
+public:
+  using BarTestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarTestEventListener::OnTestSuiteStart;
+  using BarTestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarTestEventListener::OnTestSuiteEnd;
+};
+
+#ifndef NOSUITE
+
+class BarTestEventListener3 : public testing::TestEventListener {
+public:
+  void OnTestCaseStart(const testing::TestSuite &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+  void OnTestSuiteStart(const testing::TestSuite &) override;
+
+  void OnTestCaseEnd(const testing::TestSuite &) override;
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: Google Test APIs named with 'case'
+  void OnTestSuiteEnd(const testing::TestSuite &) override;
+};
+
+#endif
+
+namespace nesting_ns {
+namespace testing {
+
+class TestEventListener {
+public:
+  virtual void OnTestCaseStart(const ::testing::TestCase &);
+  // CHECK-MESSAGES: [[@LINE-1]]:49: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: virtual void OnTestCaseStart(const ::testing::TestSuite &);
+  virtual void OnTestCaseEnd(const ::testing::TestCase &);
+  // CHECK-MESSAGES: [[@LINE-1]]:47: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: virtual void OnTestCaseEnd(const ::testing::TestSuite &);
+};
+
+} // namespace testing
+
+void FuncTestEventListener(::testing::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:39: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: void FuncTestEventListener(::testing::TestSuite &Case) {
+  testing::TestEventListener().OnTestCaseStart(Case);
+  testing::TestEventListener().OnTestCaseEnd(Case);
+}
+
+} // namespace nesting_ns
+
+#ifndef NOSUITE
+
+template <typename T>
+void testEventListenerInstantiationOnlyWarns() {
+  T().OnTestCaseStart(testing::TestSuite());
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  T().OnTestCaseEnd(testing::TestSuite());
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+}
+
+#endif
+
+#define ON_TEST_CASE_START_MACRO_REPLACE OnTestCaseStart
+#define ON_TEST_CASE_START_MACRO_WARN_ONLY                                     \
+  testing::TestEventListener().OnTestCaseStart
+
+#define ON_TEST_CASE_END_MACRO_REPLACE OnTestCaseEnd
+#define ON_TEST_CASE_END_MACRO_WARN_ONLY                                       \
+  testing::TestEventListener().OnTestCaseEnd
+
+void testEventListenerCallAndReference(testing::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:49: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: void testEventListenerCallAndReference(testing::TestSuite &Case) {
+  testing::TestEventListener().OnTestCaseStart(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteStart(Case);
+  testing::TestEventListener().OnTestCaseEnd(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteEnd(Case);
+
+  FooTestEventListener().OnTestCaseStart(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:26: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: FooTestEventListener().OnTestSuiteStart(Case);
+  FooTestEventListener().OnTestCaseEnd(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:26: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: FooTestEventListener().OnTestSuiteEnd(Case);
+
+  auto F1 = &testing::TestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:42: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F1 = &testing::TestEventListener::OnTestSuiteStart;
+  F1 = &testing::TestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:37: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: F1 = &testing::TestEventListener::OnTestSuiteEnd;
+
+  auto F2 = &FooTestEventListener::OnTestCaseStart;
+  // CHECK-MESSAGES: [[@LINE-1]]:36: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F2 = &FooTestEventListener::OnTestSuiteStart;
+  F2 = &FooTestEventListener::OnTestCaseEnd;
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: F2 = &FooTestEventListener::OnTestSuiteEnd;
+
+#ifndef NOSUITE
+
+  BarTestEventListener3().OnTestCaseStart(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: BarTestEventListener3().OnTestSuiteStart(Case);
+  BarTestEventListener3().OnTestCaseEnd(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: BarTestEventListener3().OnTestSuiteEnd(Case);
+
+  testEventListenerInstantiationOnlyWarns<testing::TestEventListener>();
+
+#endif
+
+  testing::TestEventListener().ON_TEST_CASE_START_MACRO_REPLACE(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteStart(Case);
+  ON_TEST_CASE_START_MACRO_WARN_ONLY(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+
+  testing::TestEventListener().ON_TEST_CASE_END_MACRO_REPLACE(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:32: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestEventListener().OnTestSuiteEnd(Case);
+  ON_TEST_CASE_END_MACRO_WARN_ONLY(Case);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+}
+
+// ----------------------------------------------------------------------------
+// testing::UnitTest
+
+class FooUnitTest : public testing::UnitTest {
+public:
+  testing::TestCase *current_test_case() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestSuite *current_test_suite() const;
+  int successful_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: int successful_test_suite_count() const;
+  int failed_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: int failed_test_suite_count() const;
+  int total_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: int total_test_suite_count() const;
+  int test_case_to_run_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: int test_suite_to_run_count() const;
+  const testing::TestCase *GetTestCase(int) const;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const testing::TestSuite *GetTestSuite(int) const;
+};
+
+testing::TestCase *FooUnitTest::current_test_case() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:10: warning: Google Test APIs named with 'case'
+// CHECK-MESSAGES: [[@LINE-2]]:33: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: testing::TestSuite *FooUnitTest::current_test_suite() const {}
+int FooUnitTest::successful_test_case_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: int FooUnitTest::successful_test_suite_count() const {}
+int FooUnitTest::failed_test_case_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: int FooUnitTest::failed_test_suite_count() const {}
+int FooUnitTest::total_test_case_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: int FooUnitTest::total_test_suite_count() const {}
+int FooUnitTest::test_case_to_run_count() const {}
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: int FooUnitTest::test_suite_to_run_count() const {}
+const testing::TestCase *FooUnitTest::GetTestCase(int) const {}
+// CHECK-MESSAGES: [[@LINE-1]]:16: warning: Google Test APIs named with 'case'
+// CHECK-MESSAGES: [[@LINE-2]]:39: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: const testing::TestSuite *FooUnitTest::GetTestSuite(int) const {}
+
+// Type derived from testing::TestCase
+class BarUnitTest : public testing::UnitTest {
+public:
+  using testing::UnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using testing::UnitTest::current_test_suite;
+  using testing::UnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using testing::UnitTest::successful_test_suite_count;
+  using testing::UnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using testing::UnitTest::failed_test_suite_count;
+  using testing::UnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using testing::UnitTest::total_test_suite_count;
+  using testing::UnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using testing::UnitTest::test_suite_to_run_count;
+  using testing::UnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using testing::UnitTest::GetTestSuite;
+};
+
+class BarUnitTest2 : public BarUnitTest {
+  using BarUnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarUnitTest::current_test_suite;
+  using BarUnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarUnitTest::successful_test_suite_count;
+  using BarUnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarUnitTest::failed_test_suite_count;
+  using BarUnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarUnitTest::total_test_suite_count;
+  using BarUnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarUnitTest::test_suite_to_run_count;
+  using BarUnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: using BarUnitTest::GetTestSuite;
+};
+
+#ifndef NOSUITE
+
+class BarUnitTest3 : public testing::UnitTest {
+  testing::TestSuite *current_test_case() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  int successful_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  int failed_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  int total_test_case_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  int test_case_to_run_count() const;
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  const testing::TestSuite *GetTestCase(int) const;
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+
+  testing::TestSuite *current_test_suite() const;
+  int successful_test_suite_count() const;
+  int failed_test_suite_count() const;
+  int total_test_suite_count() const;
+  int test_suite_to_run_count() const;
+  const testing::TestSuite *GetTestSuite(int) const;
+};
+
+#endif
+
+namespace nesting_ns {
+namespace testing {
+
+class TestSuite;
+
+class UnitTest {
+public:
+  TestSuite *current_test_case() const;
+  int successful_test_case_count() const;
+  int failed_test_case_count() const;
+  int total_test_case_count() const;
+  int test_case_to_run_count() const;
+  const TestSuite *GetTestCase(int) const;
+};
+
+} // namespace testing
+
+void FuncUnitTest() {
+  testing::UnitTest t;
+  (void)t.current_test_case();
+  (void)t.successful_test_case_count();
+  (void)t.failed_test_case_count();
+  (void)t.total_test_case_count();
+  (void)t.test_case_to_run_count();
+  (void)t.GetTestCase(0);
+}
+
+} // namespace nesting_ns
+
+template <typename T>
+void unitTestInstantiationOnlyWarns() {
+  T t;
+  (void)t.current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  (void)t.successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  (void)t.failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  (void)t.total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  (void)t.test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+  (void)t.GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+}
+
+#define UNIT_TEST_NAME_MACRO_REPLACE1 current_test_case
+#define UNIT_TEST_NAME_MACRO_REPLACE2 successful_test_case_count
+#define UNIT_TEST_NAME_MACRO_REPLACE3 failed_test_case_count
+#define UNIT_TEST_NAME_MACRO_REPLACE4 total_test_case_count
+#define UNIT_TEST_NAME_MACRO_REPLACE5 test_case_to_run_count
+#define UNIT_TEST_NAME_MACRO_REPLACE6 GetTestCase
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY1 testing::UnitTest().current_test_case
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY2                                        \
+  testing::UnitTest().successful_test_case_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY3                                        \
+  testing::UnitTest().failed_test_case_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY4                                        \
+  testing::UnitTest().total_test_case_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY5                                        \
+  testing::UnitTest().test_case_to_run_count
+#define UNIT_TEST_NAME_MACRO_WARN_ONLY6 testing::UnitTest().GetTestCase
+
+void unitTestCallAndReference() {
+  (void)testing::UnitTest().current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().current_test_suite();
+  (void)testing::UnitTest().successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().successful_test_suite_count();
+  (void)testing::UnitTest().failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().failed_test_suite_count();
+  (void)testing::UnitTest().total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().total_test_suite_count();
+  (void)testing::UnitTest().test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().test_suite_to_run_count();
+  (void)testing::UnitTest().GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().GetTestSuite(0);
+
+  (void)FooUnitTest().current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooUnitTest().current_test_suite();
+  (void)FooUnitTest().successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooUnitTest().successful_test_suite_count();
+  (void)FooUnitTest().failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooUnitTest().failed_test_suite_count();
+  (void)FooUnitTest().total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooUnitTest().total_test_suite_count();
+  (void)FooUnitTest().test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooUnitTest().test_suite_to_run_count();
+  (void)FooUnitTest().GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)FooUnitTest().GetTestSuite(0);
+
+  auto U1 = &testing::UnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto U1 = &testing::UnitTest::current_test_suite;
+  auto U2 = &testing::UnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto U2 = &testing::UnitTest::successful_test_suite_count;
+  auto U3 = &testing::UnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto U3 = &testing::UnitTest::failed_test_suite_count;
+  auto U4 = &testing::UnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto U4 = &testing::UnitTest::total_test_suite_count;
+  auto U5 = &testing::UnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto U5 = &testing::UnitTest::test_suite_to_run_count;
+  auto U6 = &testing::UnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto U6 = &testing::UnitTest::GetTestSuite;
+
+  auto F1 = &FooUnitTest::current_test_case;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F1 = &FooUnitTest::current_test_suite;
+  auto F2 = &FooUnitTest::successful_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F2 = &FooUnitTest::successful_test_suite_count;
+  auto F3 = &FooUnitTest::failed_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F3 = &FooUnitTest::failed_test_suite_count;
+  auto F4 = &FooUnitTest::total_test_case_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F4 = &FooUnitTest::total_test_suite_count;
+  auto F5 = &FooUnitTest::test_case_to_run_count;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F5 = &FooUnitTest::test_suite_to_run_count;
+  auto F6 = &FooUnitTest::GetTestCase;
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: auto F6 = &FooUnitTest::GetTestSuite;
+
+  using MyUnitTest = testing::UnitTest;
+  (void)MyUnitTest().current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyUnitTest().current_test_suite();
+  (void)MyUnitTest().successful_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyUnitTest().successful_test_suite_count();
+  (void)MyUnitTest().failed_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyUnitTest().failed_test_suite_count();
+  (void)MyUnitTest().total_test_case_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyUnitTest().total_test_suite_count();
+  (void)MyUnitTest().test_case_to_run_count();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyUnitTest().test_suite_to_run_count();
+  (void)MyUnitTest().GetTestCase(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)MyUnitTest().GetTestSuite(0);
+
+  unitTestInstantiationOnlyWarns<testing::UnitTest>();
+
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE1();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().current_test_suite();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE2();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().successful_test_suite_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE3();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().failed_test_suite_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE4();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().total_test_suite_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE5();
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().test_suite_to_run_count();
+  (void)testing::UnitTest().UNIT_TEST_NAME_MACRO_REPLACE6(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)testing::UnitTest().GetTestSuite(0);
+
+  UNIT_TEST_NAME_MACRO_WARN_ONLY1();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY2();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY3();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY4();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY5();
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+  UNIT_TEST_NAME_MACRO_WARN_ONLY6(0);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+}
+
+// ----------------------------------------------------------------------------
+// testing::TestCase
+
+template <typename T>
+void TestCaseInTemplate() {
+  T t;
+
+  testing::TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestSuite Case;
+}
+
+#define TEST_CASE_CAN_FIX TestCase
+#define TEST_CASE_WARN_ONLY testing::TestCase
+
+const testing::TestCase *testCaseUses(const testing::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:16: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:54: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const testing::TestSuite *testCaseUses(const testing::TestSuite &Case) {
+
+  // No change for implicit declarations:
+  auto Lambda = [&Case]() {};
+
+  TestCaseInTemplate<testing::TestCase>();
+  // CHECK-MESSAGES: [[@LINE-1]]:31: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: TestCaseInTemplate<testing::TestSuite>();
+
+  testing::TEST_CASE_CAN_FIX C1;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestSuite C1;
+  TEST_CASE_WARN_ONLY C2;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+
+  (void)new testing::TestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)new testing::TestSuite();
+  const testing::TestCase *Result = &Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const testing::TestSuite *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  testing::TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: testing::TestSuite Case;
+};
+
+class MyTest : public testing::TestCase {};
+// CHECK-MESSAGES: [[@LINE-1]]:32: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: class MyTest : public testing::TestSuite {};
+
+template <typename T = testing::TestCase>
+// CHECK-MESSAGES: [[@LINE-1]]:33: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: template <typename T = testing::TestSuite>
+class TestTypeHolder {};
+
+template <>
+class TestTypeHolder<testing::TestCase> {};
+// CHECK-MESSAGES: [[@LINE-1]]:31: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: class TestTypeHolder<testing::TestSuite> {};
+
+namespace shadow_using_ns {
+
+using testing::TestCase;
+// CHECK-MESSAGES: [[@LINE-1]]:16: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: using testing::TestSuite;
+
+const TestCase *testCaseUses(const TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-1]]:7: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:36: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const TestSuite *testCaseUses(const TestSuite &Case) {
+
+  // No change for implicit declarations:
+  auto Lambda = [&Case]() {};
+
+  (void)new TestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)new TestSuite();
+  const TestCase *Result = &Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:9: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const TestSuite *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: TestSuite Case;
+};
+
+class MyTest : public TestCase {};
+// CHECK-MESSAGES: [[@LINE-1]]:23: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: class MyTest : public TestSuite {};
+
+template <typename T = TestCase>
+// CHECK-MESSAGES: [[@LINE-1]]:24: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: template <typename T = TestSuite>
+class TestTypeHolder {};
+
+template <>
+class TestTypeHolder<TestCase> {};
+// CHECK-MESSAGES: [[@LINE-1]]:22: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: class TestTypeHolder<TestSuite> {};
+
+} // namespace shadow_using_ns
+
+const shadow_using_ns::TestCase *shadowTestCaseUses(
+    const shadow_using_ns::TestCase &Case) {
+  // CHECK-MESSAGES: [[@LINE-2]]:24: warning: Google Test APIs named with 'case'
+  // CHECK-MESSAGES: [[@LINE-2]]:28: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const shadow_using_ns::TestSuite *shadowTestCaseUses(
+  // CHECK-FIXES: const shadow_using_ns::TestSuite &Case) {
+
+  // No match for implicit declarations, as in the lambda capture:
+  auto Lambda = [&Case]() {};
+
+  (void)new shadow_using_ns::TestCase();
+  // CHECK-MESSAGES: [[@LINE-1]]:30: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: (void)new shadow_using_ns::TestSuite();
+  const shadow_using_ns::TestCase *Result = &Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:26: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: const shadow_using_ns::TestSuite *Result = &Case;
+  return Result;
+}
+
+struct ShadowTestCaseHolder {
+  shadow_using_ns::TestCase Case;
+  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: Google Test APIs named with 'case'
+  // CHECK-FIXES: shadow_using_ns::TestSuite Case;
+};
+
+class ShadowMyTest : public shadow_using_ns::TestCase {};
+// CHECK-MESSAGES: [[@LINE-1]]:46: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: class ShadowMyTest : public shadow_using_ns::TestSuite {};
+
+template <typename T = shadow_using_ns::TestCase>
+// CHECK-MESSAGES: [[@LINE-1]]:41: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: template <typename T = shadow_using_ns::TestSuite>
+class ShadowTestTypeHolder {};
+
+template <>
+class ShadowTestTypeHolder<shadow_using_ns::TestCase> {};
+// CHECK-MESSAGES: [[@LINE-1]]:45: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: class ShadowTestTypeHolder<shadow_using_ns::TestSuite> {};
+
+namespace typedef_ns {
+
+typedef testing::TestCase MyTestCase;
+// CHECK-MESSAGES: [[@LINE-1]]:18: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: typedef testing::TestSuite MyTestCase;
+
+const MyTestCase *testCaseUses(const MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new MyTestCase();
+  const MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  MyTestCase Case;
+};
+
+class MyTest : public MyTestCase {};
+
+template <typename T = MyTestCase>
+class TestTypeHolder {};
+
+template <>
+class TestTypeHolder<MyTestCase> {};
+
+} // namespace typedef_ns
+
+const typedef_ns::MyTestCase *typedefTestCaseUses(
+    const typedef_ns::MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new typedef_ns::MyTestCase();
+  const typedef_ns::MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct TypedefTestCaseHolder {
+  typedef_ns::MyTestCase Case;
+};
+
+class TypedefMyTest : public typedef_ns::MyTestCase {};
+template <typename T = typedef_ns::MyTestCase> class TypedefTestTypeHolder {};
+template <> class TypedefTestTypeHolder<typedef_ns::MyTestCase> {};
+
+namespace alias_ns {
+
+using MyTestCase = testing::TestCase;
+// CHECK-MESSAGES: [[@LINE-1]]:29: warning: Google Test APIs named with 'case'
+// CHECK-FIXES: using MyTestCase = testing::TestSuite;
+
+const MyTestCase *testCaseUses(const MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new MyTestCase();
+  const MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct TestCaseHolder {
+  MyTestCase Case;
+};
+
+class MyTest : public MyTestCase {};
+template <typename T = MyTestCase> class TestTypeHolder {};
+template <> class TestTypeHolder<MyTestCase> {};
+
+} // namespace alias_ns
+
+const alias_ns::MyTestCase *aliasTestCaseUses(
+    const alias_ns::MyTestCase &Case) {
+  auto Lambda = [&Case]() {};
+  (void)new alias_ns::MyTestCase();
+  const alias_ns::MyTestCase *Result = &Case;
+  return Result;
+}
+
+struct AliasTestCaseHolder {
+  alias_ns::MyTestCase Case;
+};
+
+class AliasMyTest : public alias_ns::MyTestCase {};
+template <typename T = alias_ns::MyTestCase> class AliasTestTypeHolder {};
+template <> class AliasTestTypeHolder<alias_ns::MyTestCase> {};
+
+template <typename T>
+void templateFunction(const T& t) {
+  (void)t.current_test_case();
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: Google Test APIs named with 'case'
+}
+
+void instantiateTemplateFunction(const testing::UnitTest &Test) {
+  templateFunction(Test);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-exception-baseclass.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-exception-baseclass.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-exception-baseclass.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-exception-baseclass.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,284 @@
+// RUN: %check_clang_tidy %s hicpp-exception-baseclass %t -- -- -fcxx-exceptions
+
+namespace std {
+class exception {};
+class invalid_argument : public exception {};
+} // namespace std
+
+class derived_exception : public std::exception {};
+class deep_hierarchy : public derived_exception {};
+class non_derived_exception {};
+class terrible_idea : public non_derived_exception, public derived_exception {};
+
+// FIXME: More complicated kinds of inheritance should be checked later, but there is
+// currently no way use ASTMatchers for this kind of task.
+#if 0
+class bad_inheritance : private std::exception {};
+class no_good_inheritance : protected std::exception {};
+class really_creative : public non_derived_exception, private std::exception {};
+#endif
+
+void problematic() {
+  try {
+    throw int(42);
+    // CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+  } catch (int e) {
+  }
+  throw int(42);
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+
+  try {
+    throw 12;
+    // CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+  } catch (...) {
+    throw; // Ok, even if the type is not known, conforming code can never rethrow a non-std::exception object.
+  }
+
+  try {
+    throw non_derived_exception();
+    // CHECK-NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
+    // CHECK-NOTES: 10:1: note: type defined here
+  } catch (non_derived_exception &e) {
+  }
+  throw non_derived_exception();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
+  // CHECK-NOTES: 10:1: note: type defined here
+
+// FIXME: More complicated kinds of inheritance should be checked later, but there is
+// currently no way use ASTMatchers for this kind of task.
+#if 0
+  // Handle private inheritance cases correctly.
+  try {
+    throw bad_inheritance();
+    // CHECK NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'bad_inheritance' is not derived from 'std::exception'
+    // CHECK NOTES: 11:1: note: type defined here
+    throw no_good_inheritance();
+    // CHECK NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'no_good_inheritance' is not derived from 'std::exception'
+    // CHECK NOTES: 12:1: note: type defined here
+    throw really_creative();
+    // CHECK NOTES: [[@LINE-1]]:11: warning: throwing an exception whose type 'really_creative' is not derived from 'std::exception'
+    // CHECK NOTES: 13:1: note: type defined here
+  } catch (...) {
+  }
+  throw bad_inheritance();
+  // CHECK NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_inheritance' is not derived from 'std::exception'
+  // CHECK NOTES: 11:1: note: type defined here
+  throw no_good_inheritance();
+  // CHECK NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'no_good_inheritance' is not derived from 'std::exception'
+  // CHECK NOTES: 12:1: note: type defined here
+  throw really_creative();
+  // CHECK NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'really_creative' is not derived from 'std::exception'
+  // CHECK NOTES: 13:1: note: type defined here
+#endif
+}
+
+void allowed_throws() {
+  try {
+    throw std::exception();     // Ok
+  } catch (std::exception &e) { // Ok
+  }
+  throw std::exception();
+
+  try {
+    throw derived_exception();     // Ok
+  } catch (derived_exception &e) { // Ok
+  }
+  throw derived_exception(); // Ok
+
+  try {
+    throw deep_hierarchy();     // Ok, multiple levels of inheritance
+  } catch (deep_hierarchy &e) { // Ok
+  }
+  throw deep_hierarchy(); // Ok
+
+  try {
+    throw terrible_idea();      // Ok, but multiple inheritance isn't clean
+  } catch (std::exception &e) { // Can be caught as std::exception, even with multiple inheritance
+  }
+  throw terrible_idea(); // Ok, but multiple inheritance
+}
+
+void test_lambdas() {
+  auto BadLambda = []() { throw int(42); };
+  // CHECK-NOTES: [[@LINE-1]]:33: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+  auto GoodLambda = []() { throw derived_exception(); };
+}
+
+// Templated function that throws exception based on template type
+template <typename T>
+void ThrowException() { throw T(); }
+// CHECK-NOTES: [[@LINE-1]]:31: warning: throwing an exception whose type 'bad_generic_exception<int>' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-2]]:31: note: type 'bad_generic_exception<int>' is a template instantiation of 'T'
+// CHECK-NOTES: [[@LINE+25]]:1: note: type defined here
+
+// CHECK-NOTES: [[@LINE-5]]:31: warning: throwing an exception whose type 'bad_generic_exception<std::exception>' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-6]]:31: note: type 'bad_generic_exception<std::exception>' is a template instantiation of 'T'
+// CHECK-NOTES: [[@LINE+21]]:1: note: type defined here
+
+// CHECK-NOTES: [[@LINE-9]]:31: warning: throwing an exception whose type 'exotic_exception<non_derived_exception>' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-10]]:31: note: type 'exotic_exception<non_derived_exception>' is a template instantiation of 'T'
+// CHECK-NOTES: [[@LINE+20]]:1: note: type defined here
+
+// CHECK-NOTES: [[@LINE-13]]:31: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-14]]:31: note: type 'int' is a template instantiation of 'T'
+
+// CHECK-NOTES: [[@LINE-16]]:31: warning: throwing an exception whose type 'non_derived_exception' is not derived from 'std::exception'
+// CHECK-NOTES: [[@LINE-17]]:31: note: type 'non_derived_exception' is a template instantiation of 'T'
+// CHECK-NOTES: 10:1: note: type defined here
+
+#define THROW_EXCEPTION(CLASS) ThrowException<CLASS>()
+#define THROW_BAD_EXCEPTION throw int(42);
+#define THROW_GOOD_EXCEPTION throw std::exception();
+#define THROW_DERIVED_EXCEPTION throw deep_hierarchy();
+
+template <typename T>
+class generic_exception : std::exception {};
+
+template <typename T>
+class bad_generic_exception {};
+
+template <typename T>
+class exotic_exception : public T {};
+
+void generic_exceptions() {
+  THROW_EXCEPTION(int);
+  THROW_EXCEPTION(non_derived_exception);
+  THROW_EXCEPTION(std::exception);    // Ok
+  THROW_EXCEPTION(derived_exception); // Ok
+  THROW_EXCEPTION(deep_hierarchy);    // Ok
+
+  THROW_BAD_EXCEPTION;
+  // CHECK-NOTES: [[@LINE-1]]:3: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-22]]:35: note: expanded from macro 'THROW_BAD_EXCEPTION'
+  THROW_GOOD_EXCEPTION;
+  THROW_DERIVED_EXCEPTION;
+
+  throw generic_exception<int>();            // Ok,
+  THROW_EXCEPTION(generic_exception<float>); // Ok
+
+  throw bad_generic_exception<int>();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_generic_exception<int>' is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-24]]:1: note: type defined here
+  throw bad_generic_exception<std::exception>();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'bad_generic_exception<std::exception>' is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-27]]:1: note: type defined here
+  THROW_EXCEPTION(bad_generic_exception<int>);
+  THROW_EXCEPTION(bad_generic_exception<std::exception>);
+
+  throw exotic_exception<non_derived_exception>();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'exotic_exception<non_derived_exception>' is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-30]]:1: note: type defined here
+  THROW_EXCEPTION(exotic_exception<non_derived_exception>);
+
+  throw exotic_exception<derived_exception>();          // Ok
+  THROW_EXCEPTION(exotic_exception<derived_exception>); // Ok
+}
+
+// Test for typedefed exception types
+typedef int TypedefedBad;
+typedef derived_exception TypedefedGood;
+using UsingBad = int;
+using UsingGood = deep_hierarchy;
+
+void typedefed() {
+  throw TypedefedBad();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'TypedefedBad' (aka 'int') is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-8]]:1: note: type defined here
+  throw TypedefedGood(); // Ok
+
+  throw UsingBad();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'UsingBad' (aka 'int') is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-11]]:1: note: type defined here
+  throw UsingGood(); // Ok
+}
+
+// Fix PR37913
+struct invalid_argument_maker {
+  ::std::invalid_argument operator()() const;
+};
+struct int_maker {
+  int operator()() const;
+};
+
+template <typename T>
+void templated_thrower() {
+  throw T{}();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+template <typename T>
+void templated_thrower2() {
+  T ExceptionFactory; // This test found a <dependant-type> which did not happend with 'throw T{}()'
+  throw ExceptionFactory();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+void exception_created_with_function() {
+  templated_thrower<invalid_argument_maker>();
+  templated_thrower<int_maker>();
+
+  templated_thrower2<invalid_argument_maker>();
+  templated_thrower2<int_maker>();
+
+  throw invalid_argument_maker{}();
+  throw int_maker{}();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+struct invalid_argument_factory {
+  ::std::invalid_argument make_exception() const;
+};
+
+struct int_factory {
+  int make_exception() const;
+};
+
+template <typename T>
+void templated_factory() {
+  T f;
+  throw f.make_exception();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+template <typename T>
+void templated_factory2() {
+  throw T().make_exception();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+void exception_from_factory() {
+  templated_factory<invalid_argument_factory>();
+  templated_factory<int_factory>();
+
+  templated_factory2<invalid_argument_factory>();
+  templated_factory2<int_factory>();
+
+  throw invalid_argument_factory().make_exception();
+  throw int_factory().make_exception();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+
+  invalid_argument_factory inv_f;
+  throw inv_f.make_exception();
+
+  int_factory int_f;
+  throw int_f.make_exception();
+  // CHECK-NOTES: [[@LINE-1]]:9: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+}
+
+template <typename T>
+struct ThrowClassTemplateParam {
+  ThrowClassTemplateParam() { throw T(); }
+  // CHECK-NOTES: [[@LINE-1]]:37: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+  // CHECK-NOTES: [[@LINE-2]]:37: note: type 'int' is a template instantiation of 'T'
+};
+
+template <int V>
+struct ThrowValueTemplate {
+  ThrowValueTemplate() { throw V; }
+  // CHECK-NOTES: [[@LINE-1]]:32: warning: throwing an exception whose type 'int' is not derived from 'std::exception'
+};
+
+void class_templates() {
+  ThrowClassTemplateParam<int> IntThrow;
+  ThrowClassTemplateParam<std::invalid_argument> ArgThrow;
+
+  ThrowValueTemplate<42> ValueThrow;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered-else.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered-else.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered-else.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered-else.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s hicpp-multiway-paths-covered %t \
+// RUN: -config='{CheckOptions: \
+// RUN:  [{key: hicpp-multiway-paths-covered.WarnOnMissingElse, value: 1}]}'\
+// RUN: --
+
+enum OS { Mac,
+          Windows,
+          Linux };
+
+void problematic_if(int i, enum OS os) {
+  if (i > 0) {
+    return;
+  } else if (i < 0) {
+    // CHECK-MESSAGES: [[@LINE-1]]:10: warning: potentially uncovered codepath; add an ending else statement
+    return;
+  }
+
+  // Could be considered as false positive because all paths are covered logically.
+  // I still think this is valid since the possibility of a final 'everything else'
+  // codepath is expected from if-else if.
+  if (i > 0) {
+    return;
+  } else if (i <= 0) {
+    // CHECK-MESSAGES: [[@LINE-1]]:10: warning: potentially uncovered codepath; add an ending else statement
+    return;
+  }
+
+  // Test if nesting of if-else chains does get caught as well.
+  if (os == Mac) {
+    return;
+  } else if (os == Linux) {
+    // These checks are kind of degenerated, but the check will not try to solve
+    // if logically all paths are covered, which is more the area of the static analyzer.
+    if (true) {
+      return;
+    } else if (false) {
+      // CHECK-MESSAGES: [[@LINE-1]]:12: warning: potentially uncovered codepath; add an ending else statement
+      return;
+    }
+    return;
+  } else {
+    /* unreachable */
+    if (true) // check if the parent would match here as well
+      return;
+    // No warning for simple if statements, since it is common to just test one condition
+    // and ignore the opposite.
+  }
+
+  // Ok, because all paths are covered
+  if (i > 0) {
+    return;
+  } else if (i < 0) {
+    return;
+  } else {
+    /* error, maybe precondition failed */
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-multiway-paths-covered.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,468 @@
+// RUN: %check_clang_tidy %s hicpp-multiway-paths-covered %t
+
+enum OS { Mac,
+          Windows,
+          Linux };
+
+struct Bitfields {
+  unsigned UInt : 3;
+  int SInt : 1;
+};
+
+int return_integer() { return 42; }
+
+void bad_switch(int i) {
+  switch (i) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch with only one case; use an if statement
+  case 0:
+    break;
+  }
+  // No default in this switch
+  switch (i) {
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+  case 0:
+    break;
+  case 1:
+    break;
+  case 2:
+    break;
+  }
+
+  // degenerate, maybe even warning
+  switch (i) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch statement without labels has no effect
+  }
+
+  switch (int j = return_integer()) {
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+  case 0:
+  case 1:
+  case 2:
+    break;
+  }
+
+  // Degenerated, only default case.
+  switch (i) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: degenerated switch with default label only
+  default:
+    break;
+  }
+
+  // Degenerated, only one case label and default case -> Better as if-stmt.
+  switch (i) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch could be better written as an if/else statement
+  case 0:
+    break;
+  default:
+    break;
+  }
+
+  unsigned long long BigNumber = 0;
+  switch (BigNumber) {
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+  case 0:
+  case 1:
+    break;
+  }
+
+  const int &IntRef = i;
+  switch (IntRef) {
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+  case 0:
+  case 1:
+    break;
+  }
+
+  char C = 'A';
+  switch (C) {
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+  case 'A':
+    break;
+  case 'B':
+    break;
+  }
+
+  Bitfields Bf;
+  // UInt has 3 bits size.
+  switch (Bf.UInt) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: potential uncovered code path; add a default label
+  case 0:
+  case 1:
+    break;
+  }
+  // All paths explicitly covered.
+  switch (Bf.UInt) {
+  case 0:
+  case 1:
+  case 2:
+  case 3:
+  case 4:
+  case 5:
+  case 6:
+  case 7:
+    break;
+  }
+  // SInt has 1 bit size, so this is somewhat degenerated.
+  switch (Bf.SInt) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: switch with only one case; use an if statement
+  case 0:
+    break;
+  }
+  // All paths explicitly covered.
+  switch (Bf.SInt) {
+  case 0:
+  case 1:
+    break;
+  }
+
+  bool Flag = false;
+  switch (Flag) {
+    // CHECK-MESSAGES:[[@LINE-1]]:3: warning: switch with only one case; use an if statement
+  case true:
+    break;
+  }
+
+  switch (Flag) {
+    // CHECK-MESSAGES: [[@LINE-1]]:3: warning: degenerated switch with default label only
+  default:
+    break;
+  }
+
+  // This `switch` will create a frontend warning from '-Wswitch-bool' but is
+  // ok for this check.
+  switch (Flag) {
+  case true:
+    break;
+  case false:
+    break;
+  }
+}
+
+void unproblematic_switch(unsigned char c) {
+  //
+  switch (c) {
+  case 0:
+  case 1:
+  case 2:
+  case 3:
+  case 4:
+  case 5:
+  case 6:
+  case 7:
+  case 8:
+  case 9:
+  case 10:
+  case 11:
+  case 12:
+  case 13:
+  case 14:
+  case 15:
+  case 16:
+  case 17:
+  case 18:
+  case 19:
+  case 20:
+  case 21:
+  case 22:
+  case 23:
+  case 24:
+  case 25:
+  case 26:
+  case 27:
+  case 28:
+  case 29:
+  case 30:
+  case 31:
+  case 32:
+  case 33:
+  case 34:
+  case 35:
+  case 36:
+  case 37:
+  case 38:
+  case 39:
+  case 40:
+  case 41:
+  case 42:
+  case 43:
+  case 44:
+  case 45:
+  case 46:
+  case 47:
+  case 48:
+  case 49:
+  case 50:
+  case 51:
+  case 52:
+  case 53:
+  case 54:
+  case 55:
+  case 56:
+  case 57:
+  case 58:
+  case 59:
+  case 60:
+  case 61:
+  case 62:
+  case 63:
+  case 64:
+  case 65:
+  case 66:
+  case 67:
+  case 68:
+  case 69:
+  case 70:
+  case 71:
+  case 72:
+  case 73:
+  case 74:
+  case 75:
+  case 76:
+  case 77:
+  case 78:
+  case 79:
+  case 80:
+  case 81:
+  case 82:
+  case 83:
+  case 84:
+  case 85:
+  case 86:
+  case 87:
+  case 88:
+  case 89:
+  case 90:
+  case 91:
+  case 92:
+  case 93:
+  case 94:
+  case 95:
+  case 96:
+  case 97:
+  case 98:
+  case 99:
+  case 100:
+  case 101:
+  case 102:
+  case 103:
+  case 104:
+  case 105:
+  case 106:
+  case 107:
+  case 108:
+  case 109:
+  case 110:
+  case 111:
+  case 112:
+  case 113:
+  case 114:
+  case 115:
+  case 116:
+  case 117:
+  case 118:
+  case 119:
+  case 120:
+  case 121:
+  case 122:
+  case 123:
+  case 124:
+  case 125:
+  case 126:
+  case 127:
+  case 128:
+  case 129:
+  case 130:
+  case 131:
+  case 132:
+  case 133:
+  case 134:
+  case 135:
+  case 136:
+  case 137:
+  case 138:
+  case 139:
+  case 140:
+  case 141:
+  case 142:
+  case 143:
+  case 144:
+  case 145:
+  case 146:
+  case 147:
+  case 148:
+  case 149:
+  case 150:
+  case 151:
+  case 152:
+  case 153:
+  case 154:
+  case 155:
+  case 156:
+  case 157:
+  case 158:
+  case 159:
+  case 160:
+  case 161:
+  case 162:
+  case 163:
+  case 164:
+  case 165:
+  case 166:
+  case 167:
+  case 168:
+  case 169:
+  case 170:
+  case 171:
+  case 172:
+  case 173:
+  case 174:
+  case 175:
+  case 176:
+  case 177:
+  case 178:
+  case 179:
+  case 180:
+  case 181:
+  case 182:
+  case 183:
+  case 184:
+  case 185:
+  case 186:
+  case 187:
+  case 188:
+  case 189:
+  case 190:
+  case 191:
+  case 192:
+  case 193:
+  case 194:
+  case 195:
+  case 196:
+  case 197:
+  case 198:
+  case 199:
+  case 200:
+  case 201:
+  case 202:
+  case 203:
+  case 204:
+  case 205:
+  case 206:
+  case 207:
+  case 208:
+  case 209:
+  case 210:
+  case 211:
+  case 212:
+  case 213:
+  case 214:
+  case 215:
+  case 216:
+  case 217:
+  case 218:
+  case 219:
+  case 220:
+  case 221:
+  case 222:
+  case 223:
+  case 224:
+  case 225:
+  case 226:
+  case 227:
+  case 228:
+  case 229:
+  case 230:
+  case 231:
+  case 232:
+  case 233:
+  case 234:
+  case 235:
+  case 236:
+  case 237:
+  case 238:
+  case 239:
+  case 240:
+  case 241:
+  case 242:
+  case 243:
+  case 244:
+  case 245:
+  case 246:
+  case 247:
+  case 248:
+  case 249:
+  case 250:
+  case 251:
+  case 252:
+  case 253:
+  case 254:
+  case 255:
+    break;
+  }
+
+  // Some paths are covered by the switch and a default case is present.
+  switch (c) {
+  case 1:
+  case 2:
+  case 3:
+  default:
+    break;
+  }
+}
+
+OS return_enumerator() {
+  return Linux;
+}
+
+// Enumpaths are already covered by a warning, this is just to ensure, that there is
+// no interference or false positives.
+// -Wswitch warns about uncovered enum paths and each here described case is already
+// covered.
+void switch_enums(OS os) {
+  switch (os) {
+  case Linux:
+    break;
+  }
+
+  switch (OS another_os = return_enumerator()) {
+  case Linux:
+    break;
+  }
+
+  switch (os) {
+  }
+}
+
+/// All of these cases will not emit a warning per default, but with explicit activation.
+/// Covered in extra test file.
+void problematic_if(int i, enum OS os) {
+  if (i > 0) {
+    return;
+  } else if (i < 0) {
+    return;
+  }
+
+  if (os == Mac) {
+    return;
+  } else if (os == Linux) {
+    if (true) {
+      return;
+    } else if (false) {
+      return;
+    }
+    return;
+  } else {
+    /* unreachable */
+    if (true) // check if the parent would match here as well
+      return;
+  }
+
+  // Ok, because all paths are covered
+  if (i > 0) {
+    return;
+  } else if (i < 0) {
+    return;
+  } else {
+    /* error, maybe precondition failed */
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler-msvc.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler-msvc.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler-msvc.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler-msvc.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,11 @@
+// REQUIRES: system-windows
+// FIXME: Re-enable test on windows (PR36855)
+// UNSUPPORTED: system-windows
+// RUN: %check_clang_tidy %s hicpp-no-assembler %t
+
+void f() {
+  _asm {
+    mov al, 2;
+    // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-no-assembler.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s hicpp-no-assembler %t
+
+__asm__(".symver foo, bar at v");
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+
+static int s asm("spam");
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+
+void f() {
+  __asm("mov al, 2");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not use inline assembler in safety-critical code [hicpp-no-assembler]
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-bug34747.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,29 @@
+// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t --
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+template <typename C>
+struct OutputStream {
+  OutputStream &operator<<(C);
+};
+
+template <typename C>
+struct foo {
+  typedef OutputStream<C> stream_type;
+  foo(stream_type &o) {
+    o << 'x'; // warning occured here, fixed now
+  }
+};
+
+void bar(OutputStream<signed char> &o) {
+  foo<signed char> f(o);
+}
+
+void silence_lit() {
+  int SValue = 42;
+  int SResult;
+
+  SResult = SValue & 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,198 @@
+// RUN: clang-tidy %s -checks='-*,hicpp-signed-bitwise' -- -std=c++11
+// FIXME: Make the test work in all language modes.
+
+#include "hicpp-signed-bitwise-standard-types.h"
+
+void pure_bitmask_types() {
+  // std::locale::category
+  int SResult = 0;
+  std::locale::category C = std::locale::category::ctype;
+
+  SResult = std::locale::category::none | std::locale::category::collate;
+  SResult|= std::locale::category::collate;
+  SResult = std::locale::category::ctype & std::locale::category::monetary;
+  SResult&= std::locale::category::monetary;
+  SResult = std::locale::category::numeric ^ std::locale::category::time;
+  SResult^= std::locale::category::time;
+  SResult = std::locale::category::messages | std::locale::category::all;
+
+  SResult = std::locale::category::all & C;
+  SResult&= std::locale::category::all;
+  SResult = std::locale::category::all | C;
+  SResult|= std::locale::category::all;
+  SResult = std::locale::category::all ^ C;
+  SResult^= std::locale::category::all;
+
+  // std::ctype_base::mask
+  std::ctype_base::mask M = std::ctype_base::mask::punct;
+
+  SResult = std::ctype_base::mask::space | std::ctype_base::mask::print;
+  SResult = std::ctype_base::mask::cntrl & std::ctype_base::mask::upper;
+  SResult = std::ctype_base::mask::lower ^ std::ctype_base::mask::alpha;
+  SResult|= std::ctype_base::mask::digit | std::ctype_base::mask::punct;
+  SResult&= std::ctype_base::mask::xdigit & std::ctype_base::mask::alnum;
+  SResult^= std::ctype_base::mask::alnum ^ std::ctype_base::mask::graph;
+
+  SResult&= std::ctype_base::mask::space & M;
+  SResult|= std::ctype_base::mask::space | M;
+  SResult^= std::ctype_base::mask::space ^ M;
+
+  // std::ios_base::fmtflags
+  std::ios_base::fmtflags F = std::ios_base::fmtflags::floatfield;
+
+  SResult = std::ios_base::fmtflags::dec | std::ios_base::fmtflags::oct;
+  SResult = std::ios_base::fmtflags::hex & std::ios_base::fmtflags::basefield;
+  SResult = std::ios_base::fmtflags::left ^ std::ios_base::fmtflags::right;
+  SResult|= std::ios_base::fmtflags::internal | std::ios_base::fmtflags::adjustfield;
+  SResult&= std::ios_base::fmtflags::scientific & std::ios_base::fmtflags::fixed;
+  SResult^= std::ios_base::fmtflags::floatfield ^ std::ios_base::fmtflags::boolalpha;
+  SResult = std::ios_base::fmtflags::showbase | std::ios_base::fmtflags::showpoint;
+  SResult = std::ios_base::fmtflags::showpos & std::ios_base::fmtflags::skipws;
+  SResult = std::ios_base::fmtflags::unitbuf ^ std::ios_base::fmtflags::uppercase;
+
+  SResult|= std::ios_base::fmtflags::unitbuf | F;
+  SResult&= std::ios_base::fmtflags::unitbuf & F;
+  SResult^= std::ios_base::fmtflags::unitbuf ^ F;
+
+  // std::ios_base::iostate
+  std::ios_base::iostate S = std::ios_base::iostate::goodbit;
+
+  SResult^= std::ios_base::iostate::goodbit | std::ios_base::iostate::badbit;
+  SResult|= std::ios_base::iostate::failbit & std::ios_base::iostate::eofbit;
+  SResult&= std::ios_base::iostate::failbit ^ std::ios_base::iostate::eofbit;
+
+  SResult = std::ios_base::iostate::goodbit | S;
+  SResult = std::ios_base::iostate::goodbit & S;
+  SResult = std::ios_base::iostate::goodbit ^ S;
+
+  // std::ios_base::openmode
+  std::ios_base::openmode B = std::ios_base::openmode::binary;
+
+  SResult = std::ios_base::openmode::app | std::ios_base::openmode::binary;
+  SResult = std::ios_base::openmode::in & std::ios_base::openmode::out;
+  SResult = std::ios_base::openmode::trunc ^ std::ios_base::openmode::ate;
+
+  SResult&= std::ios_base::openmode::trunc | B;
+  SResult^= std::ios_base::openmode::trunc & B;
+  SResult|= std::ios_base::openmode::trunc ^ B;
+}
+
+void still_forbidden() {
+  // std::locale::category
+  unsigned int UResult = 0u;
+  int SResult = 0;
+
+  SResult = std::ctype_base::mask::print ^ 8u;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult = std::ctype_base::mask::cntrl | 8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult = std::ctype_base::mask::upper & 8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult = std::ctype_base::mask::lower ^ -8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  
+  // Staying within the allowed standard types is ok for bitwise assignment
+  // operations.
+  std::ctype_base::mask var = std::ctype_base::mask::print;
+  SResult<<= std::ctype_base::mask::upper;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult>>= std::ctype_base::mask::upper;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult &= std::ctype_base::mask::upper;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult |= std::ctype_base::mask::upper;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult ^= std::ctype_base::mask::upper;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = std::locale::category::collate << 1u;
+  UResult = std::locale::category::ctype << 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::locale::category::monetary >> 1u;
+  UResult = std::locale::category::numeric >> 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = ~std::locale::category::messages;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+  SResult = ~std::locale::category::all;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+  // std::ctype_base::mask
+  UResult = std::ctype_base::mask::space | 8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ctype_base::mask::print & 8u;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ctype_base::mask::cntrl ^ -8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = std::ctype_base::mask::upper << 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ctype_base::mask::lower << 1u;
+  UResult = std::ctype_base::mask::alpha >> 1u;
+  UResult = std::ctype_base::mask::digit >> 1u;
+
+  UResult = ~std::ctype_base::mask::punct;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+  SResult = ~std::ctype_base::mask::xdigit;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+  // std::ios_base::fmtflags
+  UResult = std::ios_base::fmtflags::dec | 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::fmtflags::oct & 1u;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::fmtflags::hex ^ -1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = std::ios_base::fmtflags::basefield >> 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::fmtflags::left >> 1u;
+  UResult = std::ios_base::fmtflags::right << 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::fmtflags::internal << 1u;
+
+  UResult = ~std::ios_base::fmtflags::adjustfield;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+  SResult = ~std::ios_base::fmtflags::scientific;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+  // std::ios_base::iostate
+  UResult = std::ios_base::iostate::goodbit | 8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::iostate::badbit & 8u;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::iostate::failbit ^ -8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = std::ios_base::iostate::eofbit << 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::iostate::goodbit << 1u;
+  UResult = std::ios_base::iostate::badbit >> 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::iostate::failbit >> 1u;
+
+  UResult = ~std::ios_base::iostate::eofbit;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+  SResult = ~std::ios_base::iostate::goodbit;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+
+  // std::ios_base::openmode
+  UResult = std::ios_base::app | 8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::binary & 8u;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::in ^ -8;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = std::ios_base::out >> 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::trunc >> 1u;
+  UResult = std::ios_base::ate << 1;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = std::ios_base::ate << 1u;
+
+  UResult = ~std::ios_base::openmode::app;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+  SResult = ~std::ios_base::openmode::binary;
+  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: use of a signed integer operand with a unary bitwise operator
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.h?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.h (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise-standard-types.h Fri Oct 11 05:05:42 2019
@@ -0,0 +1,81 @@
+#pragma clang system_header
+
+// Implement standard types that are known to be defined as unsigned in some
+// implementations like MSVC.
+namespace std {
+namespace locale {
+enum category : int {
+  none = 0u,
+  collate = 1u << 1u,
+  ctype = 1u << 2u,
+  monetary = 1u << 3u,
+  numeric = 1u << 4u,
+  time = 1u << 5u,
+  messages = 1u << 6u,
+  all = none | collate | ctype | monetary | numeric | time | messages
+  // CHECK MESSAGES: [[@LINE-1]]:9: warning: use of a signed integer operand with a binary bitwise operator
+};
+} // namespace locale
+
+namespace ctype_base {
+enum mask : int {
+  space,
+  print,
+  cntrl,
+  upper,
+  lower,
+  alpha,
+  digit,
+  punct,
+  xdigit,
+  /* blank, // C++11 */
+  alnum = alpha | digit,
+  // CHECK MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+  graph = alnum | punct
+  // CHECK MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+};
+} // namespace ctype_base
+
+namespace ios_base {
+enum fmtflags : int {
+  dec = 0u,
+  oct = 1u << 2u,
+  hex = 1u << 3u,
+  basefield = dec | oct | hex | 0u,
+  // CHECK MESSAGES: [[@LINE-1]]:15: warning: use of a signed integer operand with a binary bitwise operator
+  left = 1u << 4u,
+  right = 1u << 5u,
+  internal = 1u << 6u,
+  adjustfield = left | right | internal,
+  // CHECK MESSAGES: [[@LINE-1]]:17: warning: use of a signed integer operand with a binary bitwise operator
+  scientific = 1u << 7u,
+  fixed = 1u << 8u,
+  floatfield = scientific | fixed | (scientific | fixed) | 0u,
+  // CHECK MESSAGES: [[@LINE-1]]:16: warning: use of a signed integer operand with a binary bitwise operator
+  // CHECK MESSAGES: [[@LINE-2]]:38: warning: use of a signed integer operand with a binary bitwise operator
+  boolalpha = 1u << 9u,
+  showbase = 1u << 10u,
+  showpoint = 1u << 11u,
+  showpos = 1u << 12u,
+  skipws = 1u << 13u,
+  unitbuf = 1u << 14u,
+  uppercase = 1u << 15u
+};
+
+enum iostate : int {
+  goodbit = 0u,
+  badbit = 1u << 1u,
+  failbit = 1u << 2u,
+  eofbit = 1u << 3u
+};
+
+enum openmode : int {
+  app = 0u,
+  binary = 0u << 1u,
+  in = 0u << 2u,
+  out = 0u << 3u,
+  trunc = 0u << 4u,
+  ate = 0u << 5u
+};
+} // namespace ios_base
+} // namespace std

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/hicpp-signed-bitwise.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,240 @@
+// RUN: %check_clang_tidy %s hicpp-signed-bitwise %t -- -- --target=x86_64-linux
+
+// These could cause false positives and should not be considered.
+struct StreamClass {
+};
+StreamClass &operator<<(StreamClass &os, unsigned int i) {
+  return os;
+}
+StreamClass &operator<<(StreamClass &os, int i) {
+  return os;
+}
+StreamClass &operator>>(StreamClass &os, unsigned int i) {
+  return os;
+}
+StreamClass &operator>>(StreamClass &os, int i) {
+  return os;
+}
+struct AnotherStream {
+  AnotherStream &operator<<(unsigned char c) { return *this; }
+  AnotherStream &operator<<(signed char c) { return *this; }
+
+  AnotherStream &operator>>(unsigned char c) { return *this; }
+  AnotherStream &operator>>(signed char c) { return *this; }
+};
+
+void binary_bitwise() {
+  int SValue = 42;
+  int SResult;
+
+  unsigned int UValue = 42;
+  unsigned int UResult;
+
+  SResult = SValue & 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult = SValue & -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  SResult = SValue & SValue;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = SValue & 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult = SValue & -1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  UResult&= 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+
+  UResult = UValue & 1u;     // Ok
+  UResult = UValue & UValue; // Ok
+  UResult&= 2u;              // Ok
+
+  unsigned char UByte1 = 0u;
+  unsigned char UByte2 = 16u;
+  signed char SByte1 = 0;
+  signed char SByte2 = 16;
+
+  UByte1 = UByte1 & UByte2; // Ok
+  UByte1 = SByte1 & UByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1 = SByte1 & SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+  SByte1 = SByte1 & SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+
+  // More complex expressions.
+  UResult = UValue & (SByte1 + (SByte1 | SByte2));
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use of a signed integer operand with a binary bitwise operator
+  // CHECK-MESSAGES: :[[@LINE-2]]:33: warning: use of a signed integer operand with a binary bitwise operator
+
+  // The rest is to demonstrate functionality but all operators are matched equally.
+  // Therefore functionality is the same for all binary operations.
+  UByte1 = UByte1 | UByte2; // Ok
+  UByte1 = UByte1 | SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1|= SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1|= UByte2; // Ok
+
+  UByte1 = UByte1 ^ UByte2; // Ok
+  UByte1 = UByte1 ^ SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1^= SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1^= UByte2; // Ok
+
+  UByte1 = UByte1 >> UByte2; // Ok
+  UByte1 = UByte1 >> SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1>>= SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1>>= UByte2; // Ok
+
+  UByte1 = UByte1 << UByte2; // Ok
+  UByte1 = UByte1 << SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1<<= SByte2;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  UByte1<<= UByte2; // Ok
+
+  int SignedInt1 = 1 << 12;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
+  int SignedInt2 = 1u << 12;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
+}
+
+void f1(unsigned char c) {}
+void f2(signed char c) {}
+void f3(int c) {}
+
+void unary_bitwise() {
+  unsigned char UByte1 = 0u;
+  signed char SByte1 = 0;
+
+  UByte1 = ~UByte1; // Ok
+  SByte1 = ~UByte1;
+  SByte1 = ~SByte1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator
+  UByte1 = ~SByte1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use of a signed integer operand with a unary bitwise operator
+
+  unsigned int UInt = 0u;
+  int SInt = 0;
+
+  f1(~UByte1); // Ok
+  f1(~SByte1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+  f1(~UInt);
+  f1(~SInt);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+  f2(~UByte1);
+  f2(~SByte1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+  f2(~UInt);
+  f2(~SInt);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+  f3(~UByte1); // Ok
+  f3(~SByte1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use of a signed integer operand with a unary bitwise operator
+}
+
+/// HICPP uses these examples to demonstrate the rule.
+void standard_examples() {
+  int i = 3;
+  unsigned int k = 0u;
+
+  int r = i << -1; // Emits -Wshift-count-negative from clang
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+  r = i << 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+
+  r = -1 >> -1; // Emits -Wshift-count-negative from clang
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+  r = -1 >> 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+
+  r = -1 >> i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+  r = -1 >> -i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+
+  r = ~0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a unary bitwise operator
+  r = ~0u; // Ok
+  k = ~k;  // Ok
+
+  unsigned int u = (-1) & 2u;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use of a signed integer operand with a binary bitwise operator
+  u = (-1) | 1u;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+  u = (-1) ^ 1u;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use of a signed integer operand with a binary bitwise operator
+}
+
+void streams_should_work() {
+  StreamClass s;
+  s << 1u; // Ok
+  s << 1;  // Ok
+  s >> 1;  // Ok
+  s >> 1u; // Ok
+
+  AnotherStream as;
+  unsigned char uc = 1u;
+  signed char sc = 1;
+  as << uc; // Ok
+  as << sc; // Ok
+  as >> uc; // Ok
+  as >> sc; // Ok
+}
+
+enum OldEnum {
+  ValueOne,
+  ValueTwo,
+};
+
+enum OldSigned : int {
+  IntOne,
+  IntTwo,
+};
+
+void classicEnums() {
+  OldEnum e1 = ValueOne, e2 = ValueTwo;
+  int e3;                   // Using the enum type, results in an error.
+  e3 = ValueOne | ValueTwo; // Ok
+  e3 = ValueOne & ValueTwo; // Ok
+  e3 = ValueOne ^ ValueTwo; // Ok
+  e3 = e1 | e2;             // Ok
+  e3 = e1 & e2;             // Ok
+  e3 = e1 ^ e2;             // Ok
+
+  OldSigned s1 = IntOne, s2 = IntTwo;
+  int s3;
+  s3 = IntOne | IntTwo; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+  s3|= IntTwo; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  s3 = IntOne & IntTwo; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+  s3&= IntTwo; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  s3 = IntOne ^ IntTwo; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+  s3^= IntTwo; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: use of a signed integer operand with a binary bitwise operator
+  s3 = s1 | s2; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+  s3 = s1 & s2; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+  s3 = s1 ^ s2; // Signed
+  // CHECK-MESSAGES: [[@LINE-1]]:8: warning: use of a signed integer operand with a binary bitwise operator
+}
+
+enum EnumConstruction {
+  one = 1,
+  two = 2,
+  test1 = 1 << 12,
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+  test2 = one << two,
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+  test3 = 1u << 12,
+  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: use of a signed integer operand with a binary bitwise operator
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/linuxkernel-must-check-errs.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/linuxkernel-must-check-errs.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/linuxkernel-must-check-errs.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/linuxkernel-must-check-errs.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,43 @@
+// RUN: %check_clang_tidy %s linuxkernel-must-check-errs %t
+
+#define __must_check __attribute__((warn_unused_result))
+
+// Prototypes of the error functions.
+void * __must_check ERR_PTR(long error);
+long  __must_check PTR_ERR(const void *ptr);
+int  __must_check IS_ERR(const void *ptr);
+int  __must_check IS_ERR_OR_NULL(const void *ptr);
+void * __must_check ERR_CAST(const void *ptr);
+int  __must_check PTR_ERR_OR_ZERO(const void *ptr);
+
+void f() {
+  ERR_PTR(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'ERR_PTR' is unused
+  PTR_ERR((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'PTR_ERR' is unused
+  IS_ERR((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'IS_ERR' is unused
+  ERR_CAST((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'ERR_CAST' is unused
+out:
+  PTR_ERR_OR_ZERO((void *)0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'PTR_ERR_OR_ZERO' is unused
+}
+
+void *f1() {
+  return ERR_PTR(0);
+}
+
+long f2() {
+  if (IS_ERR((void *)0)) {
+    return PTR_ERR((void *)0);
+  }
+  return -1;
+}
+
+void f3() {
+  f1();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'f1' is unused but represents an error value
+  f2();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: result from function 'f2' is unused but represents an error value
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-include-order.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-include-order.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-include-order.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-include-order.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,42 @@
+// RUN: %check_clang_tidy %s llvm-include-order %t -- -- -isystem %S/Inputs/Headers
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: #includes are not sorted properly
+#include "j.h"
+#include "gtest/foo.h"
+#include "i.h"
+#include <s.h>
+#include "llvm/a.h"
+#include "clang/b.h"
+#include "clang-c/c.h" // hi
+#include "llvm-c/d.h" // -c
+
+// CHECK-FIXES: #include "j.h"
+// CHECK-FIXES-NEXT: #include "i.h"
+// CHECK-FIXES-NEXT: #include "clang-c/c.h" // hi
+// CHECK-FIXES-NEXT: #include "clang/b.h"
+// CHECK-FIXES-NEXT: #include "llvm-c/d.h" // -c
+// CHECK-FIXES-NEXT: #include "llvm/a.h"
+// CHECK-FIXES-NEXT: #include "gtest/foo.h"
+// CHECK-FIXES-NEXT: #include <s.h>
+
+#include "b.h"
+#ifdef FOO
+#include "a.h"
+#endif
+
+// CHECK-FIXES: #include "b.h"
+// CHECK-FIXES-NEXT: #ifdef FOO
+// CHECK-FIXES-NEXT: #include "a.h"
+// CHECK-FIXES-NEXT: #endif
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: #includes are not sorted properly
+#include "b.h"
+#include "a.h"
+
+// CHECK-FIXES: #include "a.h"
+// CHECK-FIXES-NEXT: #include "b.h"
+
+// CHECK-MESSAGES-NOT: [[@LINE+1]]:1: warning: #includes are not sorted properly
+#include "cross-file-c.h"
+// This line number should correspond to the position of the #include in cross-file-c.h
+#include "cross-file-a.h"

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-isa-or-dyn-cast-in-conditionals.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,132 @@
+// RUN: %check_clang_tidy %s llvm-prefer-isa-or-dyn-cast-in-conditionals %t
+
+struct X;
+struct Y;
+struct Z {
+  int foo();
+  X *bar();
+  X *cast(Y*);
+  bool baz(Y*);
+};
+
+template <class X, class Y>
+bool isa(Y *);
+template <class X, class Y>
+X *cast(Y *);
+template <class X, class Y>
+X *dyn_cast(Y *);
+template <class X, class Y>
+X *dyn_cast_or_null(Y *);
+
+bool foo(Y *y, Z *z) {
+  if (auto x = cast<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: cast<> in conditional will assert rather than return a null pointer [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+  // CHECK-FIXES: if (auto x = dyn_cast<X>(y))
+
+  while (auto x = cast<X>(y))
+    break;
+  // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: cast<> in conditional
+  // CHECK-FIXES: while (auto x = dyn_cast<X>(y))
+
+  if (cast<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: cast<> in conditional
+  // CHECK-FIXES: if (isa<X>(y))
+
+  while (cast<X>(y))
+    break;
+  // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: cast<> in conditional
+  // CHECK-FIXES: while (isa<X>(y))
+
+  do {
+    break;
+  } while (cast<X>(y));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: cast<> in conditional
+  // CHECK-FIXES: while (isa<X>(y));
+
+  if (dyn_cast<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: return value from dyn_cast<> not used [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+  // CHECK-FIXES: if (isa<X>(y))
+
+  while (dyn_cast<X>(y))
+    break;
+  // CHECK-MESSAGES: :[[@LINE-2]]:10: warning: return value from dyn_cast<> not used
+  // CHECK-FIXES: while (isa<X>(y))
+
+  do {
+    break;
+  } while (dyn_cast<X>(y));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: return value from dyn_cast<> not used
+  // CHECK-FIXES: while (isa<X>(y));
+
+  if (y && isa<X>(y))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred over an explicit test for null followed by calling isa<> [llvm-prefer-isa-or-dyn-cast-in-conditionals]
+  // CHECK-FIXES: if (isa_and_nonnull<X>(y))
+
+  if (z->bar() && isa<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning:  isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  if (z->bar() && cast<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  if (z->bar() && dyn_cast<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  if (z->bar() && dyn_cast_or_null<Y>(z->bar()))
+    return true;
+  // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: if (isa_and_nonnull<Y>(z->bar()))
+
+  bool b = z->bar() && cast<Y>(z->bar());
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: isa_and_nonnull<> is preferred
+  // CHECK-FIXES: bool b = isa_and_nonnull<Y>(z->bar());
+
+  // These don't trigger a warning.
+  if (auto x = cast<Z>(y)->foo())
+    return true;
+  if (auto x = z->cast(y))
+    return true;
+  while (auto x = cast<Z>(y)->foo())
+    break;
+  if (cast<Z>(y)->foo())
+    return true;
+  if (z->cast(y))
+    return true;
+  while (cast<Z>(y)->foo())
+    break;
+  if (y && cast<X>(z->bar()))
+    return true;
+  if (z && cast<Z>(y)->foo())
+    return true;
+  bool b2 = y && cast<X>(z);
+  if(z->cast(y))
+    return true;
+  if (z->baz(cast<Y>(z)))
+    return true;
+
+#define CAST(T, Obj) cast<T>(Obj)
+#define AUTO_VAR_CAST(X, Y, Z) auto X = cast<Y>(Z)
+#define ISA(T, Obj) isa<T>(Obj)
+#define ISA_OR_NULL(T, Obj) Obj &&isa<T>(Obj)
+
+  // Macros don't trigger warning.
+  if (auto x = CAST(X, y))
+    return true;
+  if (AUTO_VAR_CAST(x, X, z))
+    return true;
+  if (z->bar() && ISA(Y, z->bar()))
+    return true;
+  if (ISA_OR_NULL(Y, z->bar()))
+    return true;
+
+  return false;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,143 @@
+// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t
+
+namespace llvm {
+class Register {
+public:
+  operator unsigned();
+
+  unsigned Reg;
+};
+
+// This class shouldn't trigger it despite the similarity.
+class RegisterLike {
+public:
+  operator unsigned();
+
+  unsigned Reg;
+};
+} // end namespace llvm
+
+llvm::Register getReg();
+llvm::RegisterLike getRegLike();
+
+void apply_1() {
+  unsigned Reg1 = getReg();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg1' declared as 'unsigned int'; use 'llvm::Register' instead [llvm-prefer-register-over-unsigned]
+  // CHECK-FIXES: apply_1()
+  // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg();
+}
+
+void apply_2() {
+  using namespace llvm;
+  unsigned Reg2 = getReg();
+  // FIXME: Function-scoped UsingDirectiveDecl's don't appear to be in the
+  //        DeclContext for the function so we can't elide the llvm:: in this
+  //        case. Fortunately, it doesn't actually occur in the LLVM code base.
+  // CHECK-MESSAGES: :[[@LINE-4]]:12: warning: variable 'Reg2' declared as 'unsigned int'; use 'llvm::Register' instead [llvm-prefer-register-over-unsigned]
+  // CHECK-FIXES: apply_2()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: llvm::Register Reg2 = getReg();
+}
+
+namespace llvm {
+void apply_3() {
+  unsigned Reg3 = getReg();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg3' declared as 'unsigned int'; use 'Register' instead [llvm-prefer-register-over-unsigned]
+  // CHECK-FIXES: apply_3()
+  // CHECK-FIXES-NEXT: Register Reg3 = getReg();
+}
+} // end namespace llvm
+
+void done_1() {
+  llvm::Register Reg1 = getReg();
+  // CHECK-FIXES: done_1()
+  // CHECK-FIXES-NEXT: llvm::Register Reg1 = getReg();
+}
+
+void done_2() {
+  using namespace llvm;
+  Register Reg2 = getReg();
+  // CHECK-FIXES: done_2()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: Register Reg2 = getReg();
+}
+
+namespace llvm {
+void done_3() {
+  Register Reg3 = getReg();
+  // CHECK-FIXES: done_3()
+  // CHECK-FIXES-NEXT: Register Reg3 = getReg();
+}
+} // end namespace llvm
+
+void do_nothing_1() {
+  unsigned Reg1 = getRegLike();
+  // CHECK-FIXES: do_nothing_1()
+  // CHECK-FIXES-NEXT: unsigned Reg1 = getRegLike();
+}
+
+void do_nothing_2() {
+  using namespace llvm;
+  unsigned Reg2 = getRegLike();
+  // CHECK-FIXES: do_nothing_2()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: unsigned Reg2 = getRegLike();
+}
+
+namespace llvm {
+void do_nothing_3() {
+  unsigned Reg3 = getRegLike();
+  // CHECK-FIXES: do_nothing_3()
+  // CHECK-FIXES-NEXT: unsigned Reg3 = getRegLike();
+}
+} // end namespace llvm
+
+void fn1(llvm::Register R);
+void do_nothing_4() {
+  fn1(getReg());
+  // CHECK-FIXES: do_nothing_4()
+  // CHECK-FIXES-NEXT: fn1(getReg());
+}
+
+void fn2(unsigned R);
+void do_nothing_5() {
+  fn2(getReg());
+  // CHECK-FIXES: do_nothing_5()
+  // CHECK-FIXES-NEXT: fn2(getReg());
+}
+
+void do_nothing_6() {
+  using namespace llvm;
+  Register Reg6{getReg()};
+  // CHECK-FIXES: do_nothing_6()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: Register Reg6{getReg()};
+}
+
+void do_nothing_7() {
+  using namespace llvm;
+  Register Reg7;
+  Reg7.Reg = getReg();
+  // CHECK-FIXES: do_nothing_7()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: Register Reg7;
+  // CHECK-FIXES-NEXT: Reg7.Reg = getReg();
+}
+
+void do_nothing_8() {
+  using namespace llvm;
+  RegisterLike Reg8{getReg()};
+  // CHECK-FIXES: do_nothing_8()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: RegisterLike Reg8{getReg()};
+}
+
+void do_nothing_9() {
+  using namespace llvm;
+  RegisterLike Reg9;
+  Reg9.Reg = getReg();
+  // CHECK-FIXES: do_nothing_9()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: RegisterLike Reg9;
+  // CHECK-FIXES-NEXT: Reg9.Reg = getReg();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned2.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned2.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned2.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned2.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t
+
+namespace llvm {
+class Register {
+public:
+  operator unsigned();
+};
+} // end namespace llvm
+
+llvm::Register getReg();
+
+using namespace llvm;
+
+void apply_1() {
+  unsigned Reg = getReg();
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: variable 'Reg' declared as 'unsigned int'; use 'Register' instead [llvm-prefer-register-over-unsigned]
+  // CHECK-FIXES: apply_1()
+  // CHECK-FIXES-NEXT: Register Reg = getReg();
+}
+
+void done_1() {
+  llvm::Register Reg = getReg();
+  // CHECK-FIXES: done_1()
+  // CHECK-FIXES-NEXT: llvm::Register Reg = getReg();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned3.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned3.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned3.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-prefer-register-over-unsigned3.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s llvm-prefer-register-over-unsigned %t
+
+namespace llvm { };
+
+// This class shouldn't trigger it despite the similarity as it's not inside the llvm namespace
+class Register {
+public:
+  operator unsigned();
+};
+
+Register getReg();
+
+void do_nothing_1() {
+  unsigned Reg1 = getReg();
+  // CHECK-FIXES: do_nothing_1()
+  // CHECK-FIXES-NEXT: unsigned Reg1 = getReg();
+}
+
+void do_nothing_2() {
+  using namespace llvm;
+  unsigned Reg2 = getReg();
+  // CHECK-FIXES: do_nothing_2()
+  // CHECK-FIXES-NEXT: using namespace llvm;
+  // CHECK-FIXES-NEXT: unsigned Reg2 = getReg();
+}
+
+namespace llvm {
+void do_nothing_3() {
+  unsigned Reg3 = getReg();
+  // CHECK-FIXES: do_nothing_3()
+  // CHECK-FIXES-NEXT: unsigned Reg3 = getReg();
+}
+} // end namespace llvm

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-twine-local.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-twine-local.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-twine-local.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/llvm-twine-local.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,64 @@
+// RUN: %check_clang_tidy %s llvm-twine-local %t
+
+namespace llvm {
+class Twine {
+public:
+  Twine(const char *);
+  Twine(int);
+  Twine();
+  Twine &operator+(const Twine &);
+};
+}
+
+using namespace llvm;
+
+void foo(const Twine &x);
+
+static Twine Moo = Twine("bark") + "bah";
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: static std::string Moo = (Twine("bark") + "bah").str();
+
+int main() {
+  const Twine t = Twine("a") + "b" + Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t = (Twine("a") + "b" + Twine(42)).str();
+  foo(Twine("a") + "b");
+
+  Twine Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: const char * Prefix = false ? "__INT_FAST" : "__UINT_FAST";
+
+  const Twine t2 = Twine();
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t2 = (Twine()).str();
+  foo(Twine() + "b");
+
+  const Twine t3 = Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t3 = (Twine(42)).str();
+
+  const Twine t4 = Twine(42) + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t4 = (Twine(42) + "b").str();
+
+  const Twine t5 = Twine() + "b";
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t5 = (Twine() + "b").str();
+
+  const Twine t6 = true ? Twine() : Twine(42);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t6 = (true ? Twine() : Twine(42)).str();
+
+  const Twine t7 = false ? Twine() : Twine("b");
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: twine variables are prone to use-after-free bugs
+// CHECK-MESSAGES: note: FIX-IT applied suggested code changes
+// CHECK-FIXES: std::string t7 = (false ? Twine() : Twine("b")).str();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers-1z.hpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers-1z.hpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers-1z.hpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers-1z.hpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,10 @@
+// RUN: %check_clang_tidy %s misc-definitions-in-headers %t -- -- -std=c++1z
+
+class CE {
+  constexpr static int i = 5; // OK: inline variable definition.
+};
+
+inline int i = 5; // OK: inline variable definition.
+
+int b = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'b' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers]

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers.hpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers.hpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers.hpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-definitions-in-headers.hpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,194 @@
+// RUN: %check_clang_tidy %s misc-definitions-in-headers %t
+
+int f() {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: function 'f' defined in a header file; function definitions in header files can lead to ODR violations [misc-definitions-in-headers]
+// CHECK-MESSAGES: :[[@LINE-2]]:5: note: make as 'inline'
+// CHECK-FIXES: inline int f() {
+  return 1;
+}
+
+class CA {
+  void f1() {} // OK: inline class member function definition.
+  void f2();
+  template<typename T>
+  T f3() {
+    T a = 1;
+    return a;
+  }
+  template<typename T>
+  struct CAA {
+    struct CAB {
+      void f4();
+    };
+  };
+};
+
+void CA::f2() { }
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: function 'f2' defined in a header file;
+// CHECK-FIXES: inline void CA::f2() {
+
+template <>
+int CA::f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: full function template specialization 'f3<int>' defined in a header file;
+// CHECK-FIXES: inline int CA::f3() {
+  int a = 1;
+  return a;
+}
+
+template <typename T>
+void CA::CAA<T>::CAB::f4() {
+// OK: member function definition of a nested template class in a class.
+}
+
+template <typename T>
+struct CB {
+  void f1();
+  struct CCA {
+    void f2(T a);
+  };
+  struct CCB;  // OK: forward declaration.
+  static int a; // OK: class static data member declaration.
+};
+
+template <typename T>
+void CB<T>::f1() { // OK: Member function definition of a class template.
+}
+
+template <typename T>
+void CB<T>::CCA::f2(T a) {
+// OK: member function definition of a nested class in a class template.
+}
+
+template <typename T>
+struct CB<T>::CCB {
+  void f3();
+};
+
+template <typename T>
+void CB<T>::CCB::f3() {
+// OK: member function definition of a nested class in a class template.
+}
+
+template <typename T>
+int CB<T>::a = 2; // OK: static data member definition of a class template.
+
+template class CB<int>; // OK: explicitly instantiated static data member of a class template.
+inline int callCB() {
+  CB<double> cb; // OK: implicitly instantiated static data member of a class template.
+  return cb.a;
+}
+
+template <typename T>
+T tf() { // OK: template function definition.
+  T a;
+  return a;
+}
+
+
+namespace NA {
+  int f() { return 1; }
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f' defined in a header file;
+// CHECK-FIXES: inline int f() { return 1; }
+}
+
+template <typename T>
+T f3() {
+  T a = 1;
+  return a;
+}
+
+template <>
+int f3() {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full function template specialization 'f3<int>' defined in a header file;
+// CHECK-FIXES: inline int f3() {
+  int a = 1;
+  return a;
+}
+
+int f5(); // OK: function declaration.
+inline int f6() { return 1; } // OK: inline function definition.
+namespace {
+  int f7() { return 1; }
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: function 'f7' defined in a header file;
+}
+
+int f8() = delete; // OK: the function being marked delete is not callable.
+
+template <typename T>
+int f9(T t) { return 1; }
+
+inline void callF9() { f9(1); } // OK: implicitly instantiated function.
+template int f9(double); // OK: explicitly instantiated function.
+
+int a = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: variable 'a' defined in a header file; variable definitions in header files can lead to ODR violations [misc-definitions-in-headers]
+CA a1;
+// CHECK-MESSAGES: :[[@LINE-1]]:4: warning: variable 'a1' defined in a header file;
+
+namespace NB {
+  int b = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'b' defined in a header file;
+  const int c = 1; // OK: internal linkage variable definition.
+}
+
+class CC {
+  static int d; // OK: class static data member declaration.
+};
+
+int CC::d = 1;
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: variable 'd' defined in a header file;
+
+const char* ca = "foo";
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: variable 'ca' defined in a header file;
+
+namespace {
+  int e = 2;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: variable 'e' defined in a header file;
+}
+
+const char* const g = "foo"; // OK: internal linkage variable definition.
+static int h = 1; // OK: internal linkage variable definition.
+const int i = 1; // OK: internal linkage variable definition.
+extern int j; // OK: internal linkage variable definition.
+
+template <typename T, typename U>
+struct CD {
+  int f();
+};
+
+template <typename T>
+struct CD<T, int> {
+  int f();
+};
+
+template <>
+struct CD<int, int> {
+  int f();
+};
+
+int CD<int, int>::f() {
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: function 'f' defined in a header file;
+// CHECK-FIXES: inline int CD<int, int>::f() {
+  return 0;
+}
+
+template <typename T>
+int CD<T, int>::f() { // OK: partial template specialization.
+  return 0;
+}
+
+constexpr int k = 1; // OK: constexpr variable has internal linkage.
+
+constexpr int f10() { return 0; } // OK: constexpr function definition.
+
+const int f11() { return 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: function 'f11' defined in a header file;
+// CHECK-FIXES: inline const int f11() { return 0; }
+
+template <typename T>
+const T f12();
+
+template <>
+const int f12() { return 0; }
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: full function template specialization 'f12<int>' defined in a header file;
+// CHECK-FIXES: inline const int f12() { return 0; }

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const-cxx17.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const-cxx17.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const-cxx17.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const-cxx17.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,15 @@
+// RUN: %check_clang_tidy -expect-clang-tidy-error %s misc-misplaced-const %t -- -- -std=c++17
+
+// This test previously would cause a failed assertion because the structured
+// binding declaration had no valid type associated with it. This ensures the
+// expected clang diagnostic is generated instead.
+// CHECK-MESSAGES: :[[@LINE+1]]:6: error: decomposition declaration '[x]' requires an initializer [clang-diagnostic-error]
+auto [x];
+
+struct S { int a; };
+S f();
+
+int main() {
+  auto [x] = f();
+}
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,45 @@
+// RUN: %check_clang_tidy %s misc-misplaced-const %t
+
+typedef int plain_i;
+typedef int *ip;
+typedef const int *cip;
+
+typedef void (*func_ptr)(void);
+
+void func(void) {
+  // ok
+  const int *i0 = 0;
+  const plain_i *i1 = 0;
+  const cip i2 = 0; // const applies to both pointer and pointee.
+
+  // Not ok
+  const ip i3 = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i3' declared with a const-qualified typedef type; results in the type being 'int *const' instead of 'const int *'
+
+  ip const i4 = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i4' declared with a const-qualified
+
+  const volatile ip i5 = 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'i5' declared with a const-qualified typedef type; results in the type being 'int *const volatile' instead of 'const int *volatile'
+}
+
+void func2(const plain_i *i1,
+           const cip i2,
+           const ip i3,
+           // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: 'i3' declared with a const-qualified
+           const int *i4) {
+}
+
+struct S {
+  const int *i0;
+  const plain_i *i1;
+  const cip i2;
+  const ip i3;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'i3' declared with a const-qualified
+};
+
+// Function pointers should not be diagnosed because a function
+// pointer type can never be const.
+void func3(const func_ptr fp) {
+  const func_ptr fp2 = fp;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-misplaced-const.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,44 @@
+// RUN: %check_clang_tidy %s misc-misplaced-const %t
+
+typedef int plain_i;
+typedef int *ip;
+typedef const int *cip;
+
+void func() {
+  if (const int *i = 0)
+    ;
+  if (const plain_i *i = 0)
+    ;
+  if (const cip i = 0)
+    ;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: 'i' declared with a const-qualified typedef type; results in the type being 'int *const' instead of 'const int *'
+  if (const ip i = 0)
+    ;
+}
+
+template <typename Ty>
+struct S {
+  const Ty *i;
+  const Ty &i2;
+};
+
+template struct S<int>;
+template struct S<ip>; // ok
+template struct S<cip>;
+
+template <typename Ty>
+struct U {
+  const Ty *i;
+  const Ty &i2;
+};
+
+template struct U<int *>; // ok
+
+struct T {
+  typedef void (T::*PMF)();
+
+  void f() {
+    const PMF val = &T::f; // ok
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads-sized-dealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads-sized-dealloc.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads-sized-dealloc.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads-sized-dealloc.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s misc-new-delete-overloads %t -- -- -fsized-deallocation
+
+typedef decltype(sizeof(int)) size_t;
+
+struct S {
+  // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope [misc-new-delete-overloads]
+  void operator delete(void *ptr, size_t) noexcept; // not a placement delete
+};
+
+struct T {
+  // Because we have enabled sized deallocations explicitly, this new/delete
+  // pair matches.
+  void *operator new(size_t size) noexcept;
+  void operator delete(void *ptr, size_t) noexcept; // ok because sized deallocation is enabled
+};
+
+// While we're here, check that global operator delete with no operator new
+// is also matched.
+// CHECK-MESSAGES: :[[@LINE+1]]:6: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope
+void operator delete(void *ptr) noexcept;

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-new-delete-overloads.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,81 @@
+// RUN: %check_clang_tidy %s misc-new-delete-overloads %t
+
+typedef decltype(sizeof(int)) size_t;
+
+struct S {
+  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope [misc-new-delete-overloads]
+  void *operator new(size_t size) noexcept;
+  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new[]' has no matching declaration of 'operator delete[]' at the same scope
+  void *operator new[](size_t size) noexcept;
+};
+
+// CHECK-MESSAGES: :[[@LINE+1]]:7: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+void *operator new(size_t size) noexcept(false);
+
+struct T {
+  // Sized deallocations are not enabled by default, and so this new/delete pair
+  // does not match. However, we expect only one warning, for the new, because
+  // the operator delete is a placement delete and we do not warn on mismatching
+  // placement operations.
+  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+  void *operator new(size_t size) noexcept;
+  void operator delete(void *ptr, size_t) noexcept; // ok only if sized deallocation is enabled
+};
+
+struct U {
+  void *operator new(size_t size) noexcept;
+  void operator delete(void *ptr) noexcept;
+
+  void *operator new[](size_t) noexcept;
+  void operator delete[](void *) noexcept;
+};
+
+struct Z {
+  // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete' has no matching declaration of 'operator new' at the same scope
+  void operator delete(void *ptr) noexcept;
+  // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: declaration of 'operator delete[]' has no matching declaration of 'operator new[]' at the same scope
+  void operator delete[](void *ptr) noexcept;
+};
+
+struct A {
+  void *operator new(size_t size, Z) noexcept; // ok, placement new
+};
+
+struct B {
+  void operator delete(void *ptr, A) noexcept; // ok, placement delete
+};
+
+// It is okay to have a class with an inaccessible free store operator.
+struct C {
+  void *operator new(size_t, A) noexcept; // ok, placement new
+private:
+  void operator delete(void *) noexcept;
+};
+
+// It is also okay to have a class with a delete free store operator.
+struct D {
+  void *operator new(size_t, A) noexcept; // ok, placement new
+  void operator delete(void *) noexcept = delete;
+};
+
+struct E : U {
+  void *operator new(size_t) noexcept; // okay, we inherit operator delete from U
+};
+
+struct F : S {
+  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+  void *operator new(size_t) noexcept;
+};
+
+class G {
+  void operator delete(void *) noexcept;
+};
+
+struct H : G {
+  // CHECK-MESSAGES: :[[@LINE+1]]:9: warning: declaration of 'operator new' has no matching declaration of 'operator delete' at the same scope
+  void *operator new(size_t) noexcept; // base class operator is inaccessible
+};
+
+template <typename Base> struct Derived : Base {
+  void operator delete(void *);
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,43 @@
+// RUN: %check_clang_tidy %s misc-non-copyable-objects %t
+
+typedef struct FILE {} FILE;
+typedef struct pthread_cond_t {} pthread_cond_t;
+typedef int pthread_mutex_t;
+
+// CHECK-MESSAGES: :[[@LINE+1]]:13: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'? [misc-non-copyable-objects]
+void g(FILE f);
+// CHECK-MESSAGES: :[[@LINE+1]]:24: warning: 'm' declared as type 'pthread_mutex_t', which is unsafe to copy; did you mean 'pthread_mutex_t *'?
+void h(pthread_mutex_t m);
+// CHECK-MESSAGES: :[[@LINE+1]]:23: warning: 'c' declared as type 'pthread_cond_t', which is unsafe to copy; did you mean 'pthread_cond_t *'?
+void i(pthread_cond_t c);
+
+struct S {
+  pthread_cond_t c; // ok
+  // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  FILE f;
+};
+
+void func(FILE *f) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:8: warning: 'f1' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  FILE f1; // match
+  // CHECK-MESSAGES: :[[@LINE+2]]:8: warning: 'f2' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  // CHECK-MESSAGES: :[[@LINE+1]]:13: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+  FILE f2 = *f;
+  // CHECK-MESSAGES: :[[@LINE+1]]:15: warning: 'f3' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  struct FILE f3;
+  // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+  (void)sizeof(*f);
+  (void)sizeof(FILE);
+  // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+  g(*f);
+
+  pthread_mutex_t m; // ok
+  h(m); // ok
+
+  pthread_cond_t c; // ok
+  i(c); // ok
+
+  pthread_mutex_t *m1 = &m; // ok
+  // CHECK-MESSAGES: :[[@LINE+1]]:5: warning: expression has opaque data structure type 'pthread_mutex_t'; type should only be used as a pointer and not dereferenced
+  h(*m1);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-copyable-objects.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,26 @@
+// RUN: %check_clang_tidy %s misc-non-copyable-objects %t
+
+namespace std {
+typedef struct FILE {} FILE;
+}
+using namespace std;
+
+// CHECK-MESSAGES: :[[@LINE+1]]:18: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'? [misc-non-copyable-objects]
+void g(std::FILE f);
+
+struct S {
+  // CHECK-MESSAGES: :[[@LINE+1]]:10: warning: 'f' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  ::FILE f;
+};
+
+void func(FILE *f) {
+  // CHECK-MESSAGES: :[[@LINE+1]]:13: warning: 'f1' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  std::FILE f1; // match
+  // CHECK-MESSAGES: :[[@LINE+2]]:10: warning: 'f2' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  // CHECK-MESSAGES: :[[@LINE+1]]:15: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+  ::FILE f2 = *f; // match, match
+  // CHECK-MESSAGES: :[[@LINE+1]]:15: warning: 'f3' declared as type 'FILE', which is unsafe to copy; did you mean 'FILE *'?
+  struct FILE f3; // match
+  // CHECK-MESSAGES: :[[@LINE+1]]:16: warning: expression has opaque data structure type 'FILE'; type should only be used as a pointer and not dereferenced
+  (void)sizeof(*f); // match
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-private-member-variables-in-classes.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-private-member-variables-in-classes.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-private-member-variables-in-classes.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-non-private-member-variables-in-classes.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,397 @@
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s cppcoreguidelines-non-private-member-variables-in-classes %t -- --
+// RUN: %check_clang_tidy -check-suffixes=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
+
+//----------------------------------------------------------------------------//
+
+// Only data, do not warn
+
+struct S0 {
+  int S0_v0;
+
+public:
+  int S0_v1;
+
+protected:
+  int S0_v2;
+
+private:
+  int S0_v3;
+};
+
+class S1 {
+  int S1_v0;
+
+public:
+  int S1_v1;
+
+protected:
+  int S1_v2;
+
+private:
+  int S1_v3;
+};
+
+// Only data and implicit or static methods, do not warn
+
+class C {
+public:
+  C() {}
+  ~C() {}
+};
+
+struct S1Implicit {
+  C S1Implicit_v0;
+};
+
+struct S1ImplicitAndStatic {
+  C S1Implicit_v0;
+  static void s() {}
+};
+
+//----------------------------------------------------------------------------//
+
+// All functions are static, do not warn.
+
+struct S2 {
+  static void S2_m0();
+  int S2_v0;
+
+public:
+  static void S2_m1();
+  int S2_v1;
+
+protected:
+  static void S2_m3();
+  int S2_v2;
+
+private:
+  static void S2_m4();
+  int S2_v3;
+};
+
+class S3 {
+  static void S3_m0();
+  int S3_v0;
+
+public:
+  static void S3_m1();
+  int S3_v1;
+
+protected:
+  static void S3_m3();
+  int S3_v2;
+
+private:
+  static void S3_m4();
+  int S3_v3;
+};
+
+//============================================================================//
+
+// union != struct/class. do not diagnose.
+
+union U0 {
+  void U0_m0();
+  int U0_v0;
+
+public:
+  void U0_m1();
+  int U0_v1;
+
+protected:
+  void U0_m2();
+  int U0_v2;
+
+private:
+  void U0_m3();
+  int U0_v3;
+};
+
+//============================================================================//
+
+// Has non-static method with default visibility.
+
+struct S4 {
+  void S4_m0();
+
+  int S4_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v0' has public visibility
+public:
+  int S4_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v1' has public visibility
+protected:
+  int S4_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S4_v2' has protected visibility
+private:
+  int S4_v3;
+};
+
+class S5 {
+  void S5_m0();
+
+  int S5_v0;
+
+public:
+  int S5_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S5_v1' has public visibility
+protected:
+  int S5_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S5_v2' has protected visibility
+private:
+  int S5_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with public visibility.
+
+struct S6 {
+  int S6_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v0' has public visibility
+public:
+  void S6_m0();
+  int S6_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v1' has public visibility
+protected:
+  int S6_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S6_v2' has protected visibility
+private:
+  int S6_v3;
+};
+
+class S7 {
+  int S7_v0;
+
+public:
+  void S7_m0();
+  int S7_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S7_v1' has public visibility
+protected:
+  int S7_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S7_v2' has protected visibility
+private:
+  int S7_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with protected visibility.
+
+struct S8 {
+  int S8_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v0' has public visibility
+public:
+  int S8_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v1' has public visibility
+protected:
+  void S8_m0();
+  int S8_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S8_v2' has protected visibility
+private:
+  int S8_v3;
+};
+
+class S9 {
+  int S9_v0;
+
+public:
+  int S9_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S9_v1' has public visibility
+protected:
+  void S9_m0();
+  int S9_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S9_v2' has protected visibility
+private:
+  int S9_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with private visibility.
+
+struct S10 {
+  int S10_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v0' has public visibility
+public:
+  int S10_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v1' has public visibility
+protected:
+  int S10_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S10_v2' has protected visibility
+private:
+  void S10_m0();
+  int S10_v3;
+};
+
+class S11 {
+  int S11_v0;
+
+public:
+  int S11_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S11_v1' has public visibility
+protected:
+  int S11_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S11_v2' has protected visibility
+private:
+  void S11_m0();
+  int S11_v3;
+};
+
+//============================================================================//
+
+// Static variables are ignored.
+// Has non-static methods and static variables.
+
+struct S12 {
+  void S12_m0();
+  static int S12_v0;
+
+public:
+  void S12_m1();
+  static int S12_v1;
+
+protected:
+  void S12_m2();
+  static int S12_v2;
+
+private:
+  void S12_m3();
+  static int S12_v3;
+};
+
+class S13 {
+  void S13_m0();
+  static int S13_v0;
+
+public:
+  void S13_m1();
+  static int S13_v1;
+
+protected:
+  void S13_m2();
+  static int S13_v2;
+
+private:
+  void S13_m3();
+  static int S13_v3;
+};
+
+struct S14 {
+  void S14_m0();
+  int S14_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v0' has public visibility
+
+public:
+  void S14_m1();
+  int S14_v1;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v1' has public visibility
+
+protected:
+  void S14_m2();
+
+private:
+  void S14_m3();
+};
+
+class S15 {
+  void S15_m0();
+
+public:
+  void S15_m1();
+  int S15_v1;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S15_v1' has public visibility
+
+protected:
+  void S15_m2();
+
+private:
+  void S15_m3();
+};
+
+//----------------------------------------------------------------------------//
+
+template <typename T>
+struct S97 {
+  void method();
+  T S97_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:5: warning: member variable 'S97_v0' has public visibility
+};
+
+template struct S97<char *>;
+
+template <>
+struct S97<double> {
+  void method();
+  double S97d_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:10: warning: member variable 'S97d_v0' has public visibility
+};
+
+//----------------------------------------------------------------------------//
+
+#define FIELD(x) int x;
+
+// Do diagnose fields originating from macros.
+struct S98 {
+  void method();
+  FIELD(S98_v0);
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:9: warning: member variable 'S98_v0' has public visibility
+};
+
+//----------------------------------------------------------------------------//
+
+// Don't look in descendant classes.
+class S99 {
+  void method();
+
+  struct S99_0 {
+    int S99_S0_v0;
+  };
+
+public:
+  struct S99_1 {
+    int S99_S0_v0;
+  };
+
+protected:
+  struct S99_2 {
+    int S99_S0_v0;
+  };
+
+private:
+  struct S99_3 {
+    int S99_S0_v0;
+  };
+};
+
+//----------------------------------------------------------------------------//
+
+// Only diagnose once, don't let the inheritance fool you.
+struct S100 {
+  int S100_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S100_v0' has public visibility
+  void m0();
+};
+struct S101_default_inheritance : S100 {
+  int S101_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S101_v0' has public visibility
+  void m1();
+};
+struct S102_public_inheritance : public S100 {
+  int S102_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S102_v0' has public visibility
+  void m1();
+};
+struct S103_protected_inheritance : protected S100 {
+  int S103_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S103_v0' has public visibility
+  void m1();
+};
+struct S104_private_inheritance : private S100 {
+  int S104_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S104_v0' has public visibility
+  void m1();
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-redundant-expression.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-redundant-expression.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-redundant-expression.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-redundant-expression.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,753 @@
+// RUN: %check_clang_tidy %s misc-redundant-expression %t -- -- -fno-delayed-template-parsing
+
+typedef __INT64_TYPE__ I64;
+
+struct Point {
+  int x;
+  int y;
+  int a[5];
+} P;
+
+extern Point P1;
+extern Point P2;
+
+extern int foo(int x);
+extern int bar(int x);
+extern int bat(int x, int y);
+
+int TestSimpleEquivalent(int X, int Y) {
+  if (X - X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent [misc-redundant-expression]
+  if (X / X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X % X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+  if (X & X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X | X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X ^ X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+  if (X < X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X <= X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X > X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X >= X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+  if (X && X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+  if (X || X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+  if (X != (((X)))) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of operator are equivalent
+
+  if (X + 1 == X + 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+  if (X + 1 != X + 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+  if (X + 1 <= X + 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+  if (X + 1 >= X + 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+
+  if ((X != 1 || Y != 1) && (X != 1 || Y != 1)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent
+  if (P.a[X - P.x] != P.a[X - P.x]) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: both sides of operator are equivalent
+
+  if ((int)X < (int)X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+  if (int(X) < int(X)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+
+  if ( + "dummy" == + "dummy") return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
+  if (L"abc" == L"abc") return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+
+  if (foo(0) - 2 < foo(0) - 2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: both sides of operator are equivalent
+  if (foo(bar(0)) < (foo(bar((0))))) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent
+
+  if (P1.x < P2.x && P1.x < P2.x) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: both sides of operator are equivalent
+  if (P2.a[P1.x + 2] < P2.x && P2.a[(P1.x) + (2)] < (P2.x)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: both sides of operator are equivalent
+
+  return 0;
+}
+
+template <int DX>
+int TestSimpleEquivalentDependent() {
+  if (DX > 0 && DX > 0) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+
+  return 0;
+}
+
+int Valid(int X, int Y) {
+  if (X != Y) return 1;
+  if (X == Y + 0) return 1;
+  if (P.x == P.y) return 1;
+  if (P.a[P.x] < P.a[P.y]) return 1;
+  if (P.a[0] < P.a[1]) return 1;
+
+  if (P.a[0] < P.a[0ULL]) return 1;
+  if (0 < 0ULL) return 1;
+  if ((int)0 < (int)0ULL) return 1;
+
+  if (++X != ++X) return 1;
+  if (P.a[X]++ != P.a[X]++) return 1;
+  if (P.a[X++] != P.a[X++]) return 1;
+
+  if ("abc" == "ABC") return 1;
+  if (foo(bar(0)) < (foo(bat(0, 1)))) return 1;
+  return 0;
+}
+
+#define COND_OP_MACRO 9
+#define COND_OP_OTHER_MACRO 9
+int TestConditional(int x, int y) {
+  int k = 0;
+  k += (y < 0) ? x : x;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'true' and 'false' expressions are equivalent
+  k += (y < 0) ? x + 1 : x + 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'true' and 'false' expressions are equivalent
+  k += (y < 0) ? COND_OP_MACRO : COND_OP_MACRO;
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'true' and 'false' expressions are equivalent
+
+  // Do not match for conditional operators with a macro and a const.
+  k += (y < 0) ? COND_OP_MACRO : 9;
+  // Do not match for conditional operators with expressions from different macros.
+  k += (y < 0) ? COND_OP_MACRO : COND_OP_OTHER_MACRO;
+  return k;
+}
+#undef COND_OP_MACRO
+#undef COND_OP_OTHER_MACRO
+
+// Overloaded operators that compare two instances of a struct.
+struct MyStruct {
+  int x;  
+  bool operator==(const MyStruct& rhs) const {return this->x == rhs.x; } // not modifing
+  bool operator>=(const MyStruct& rhs) const { return this->x >= rhs.x; } // not modifing
+  bool operator<=(MyStruct& rhs) const { return this->x <= rhs.x; }
+  bool operator&&(const MyStruct& rhs){ this->x++; return this->x && rhs.x; }
+} Q;
+
+bool operator!=(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x == rhs.x; } // not modifing
+bool operator<(const MyStruct& lhs, const MyStruct& rhs) { return lhs.x < rhs.x; } // not modifing
+bool operator>(const MyStruct& lhs, MyStruct& rhs) { rhs.x--; return lhs.x > rhs.x; }
+bool operator||(MyStruct& lhs, const MyStruct& rhs) { lhs.x++; return lhs.x || rhs.x; }
+
+bool TestOverloadedOperator(MyStruct& S) {
+  if (S == Q) return false;
+
+  if (S <= S) return false;
+  if (S && S) return false;
+  if (S > S) return false;
+  if (S || S) return false;
+
+  if (S == S) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+  if (S < S) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+  if (S != S) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+  if (S >= S) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: both sides of overloaded operator are equivalent
+
+  return true;
+}
+
+#define LT(x, y) (void)((x) < (y))
+#define COND(x, y, z) ((x)?(y):(z))
+#define EQUALS(x, y) (x) == (y)
+
+int TestMacro(int X, int Y) {
+  LT(0, 0);
+  LT(1, 0);
+  LT(X, X);
+  LT(X+1, X + 1);
+  COND(X < Y, X, X);
+  EQUALS(Q, Q);
+  return 0;
+}
+
+int TestFalsePositive(int* A, int X, float F) {
+  // Produced by bison.
+  X = A[(2) - (2)];
+  X = A['a' - 'a'];
+
+  // Testing NaN.
+  if (F != F && F == F) return 1;
+  return 0;
+}
+
+int TestBannedMacros() {
+#define EAGAIN 3
+#define NOT_EAGAIN 3
+  if (EAGAIN == 0 | EAGAIN == 0) return 0;
+  if (NOT_EAGAIN == 0 | NOT_EAGAIN == 0) return 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: both sides of operator are equivalent
+  return 0;
+}
+
+struct MyClass {
+static const int Value = 42;
+};
+template <typename T, typename U>
+void TemplateCheck() {
+  static_assert(T::Value == U::Value, "should be identical");
+  static_assert(T::Value == T::Value, "should be identical");
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: both sides of operator are equivalent
+}
+void TestTemplate() { TemplateCheck<MyClass, MyClass>(); }
+
+int TestArithmetic(int X, int Y) {
+  if (X + 1 == X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X + 1 != X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+  if (X - 1 == X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X - 1 != X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if (X + 1LL == X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (X + 1ULL == X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
+
+  if (X == X + 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
+  if (X != X + 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+  if (X == X - 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
+  if (X != X - 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+
+  if (X != X - 1U) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+  if (X != X - 1LL) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always true
+
+  if ((X+X) != (X+X) - 1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if (X + 1 == X + 2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X + 1 != X + 2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if (X - 1 == X - 2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X - 1 != X - 2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if (X + 1 == X - -1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+  if (X + 1 != X - -1) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X + 1 == X - -2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X + 1 != X - -2) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if (X + 1 == X - (~0)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+  if (X + 1 == X - (~0U)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if (X + 1 == X - (~0ULL)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  // Should not match.
+  if (X + 0.5 == X) return 1;
+  if (X + 1 == Y) return 1;
+  if (X + 1 == Y + 1) return 1;
+  if (X + 1 == Y + 2) return 1;
+
+  return 0;
+}
+
+int TestBitwise(int X, int Y) {
+
+  if ((X & 0xFF) == 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+  if ((X & 0xFF) != 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+  if ((X | 0xFF) == 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+  if ((X | 0xFF) != 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+
+  if ((X | 0xFFULL) != 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always true
+  if ((X | 0xFF) != 0xF00ULL) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+
+  if ((0xFF & X) == 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+  if ((0xFF & X) != 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+  if ((0xFF & X) == 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+  if ((0xFF & X) != 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always true
+
+  if ((0xFFLL & X) == 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
+  if ((0xFF & X) == 0xF00ULL) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+
+  return 0;
+}
+
+// Overloaded operators that compare an instance of a struct and an integer
+// constant.
+struct S {
+  S() { x = 1; }
+  int x;
+  // Overloaded comparison operators without any possible side effect.
+  bool operator==(const int &i) const { return x == i; } // not modifying
+  bool operator!=(int i) const { return x != i; } // not modifying
+  bool operator>(const int &i) const { return x > i; } // not modifying
+  bool operator<(int i) const { return x < i; } // not modifying
+};
+
+bool operator<=(const S &s, int i) { return s.x <= i; } // not modifying
+bool operator>=(const S &s, const int &i) { return s.x >= i; } // not modifying
+
+struct S2 {
+  S2() { x = 1; }
+  int x;
+  // Overloaded comparison operators that are able to modify their params.
+  bool operator==(const int &i) {
+    this->x++;
+    return x == i;
+  }
+  bool operator!=(int i) { return x != i; }
+  bool operator>(const int &i) { return x > i; }
+  bool operator<(int i) {
+    this->x--;
+    return x < i;
+  }
+};
+
+bool operator>=(S2 &s, const int &i) { return s.x >= i; }
+bool operator<=(S2 &s, int i) {
+  s.x++;
+  return s.x <= i;
+}
+
+int TestLogical(int X, int Y){
+#define CONFIG 0
+  if (CONFIG && X) return 1;
+#undef CONFIG
+#define CONFIG 1
+  if (CONFIG || X) return 1;
+#undef CONFIG
+
+  if (X == 10 && X != 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (X == 10 && (X != 10)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (X == 10 && !(X == 10)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (!(X != 10) && !(X == 10)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+
+  if (X == 10ULL && X != 10ULL) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+  if (!(X != 10U) && !(X == 10)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
+  if (!(X != 10LL) && !(X == 10)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: logical expression is always false
+  if (!(X != 10ULL) && !(X == 10)) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: logical expression is always false
+
+  if (X == 0 && X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+  if (X != 0 && !X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+  if (X && !X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: logical expression is always false
+
+  if (X && !!X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: equivalent expression on both sides of logical operator
+  if (X != 0 && X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+  if (X != 0 && !!X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+  if (X == 0 && !X) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+
+  // Should not match.
+  if (X == 10 && Y == 10) return 1;
+  if (X != 10 && X != 12) return 1;
+  if (X == 10 || X == 12) return 1;
+  if (!X && !Y) return 1;
+  if (!X && Y) return 1;
+  if (!X && Y == 0) return 1;
+  if (X == 10 && Y != 10) return 1;
+
+  // Test for overloaded operators with constant params.
+  S s1;
+  if (s1 == 1 && s1 == 1) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: equivalent expression on both sides of logical operator
+  if (s1 == 1 || s1 != 1) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+  if (s1 > 1 && s1 < 1) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+  if (s1 >= 1 || s1 <= 1) return true;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+
+  // Test for overloaded operators that may modify their params.
+  S2 s2;
+  if (s2 == 1 || s2 != 1) return true;
+  if (s2 == 1 || s2 == 1) return true;
+  if (s2 > 1 && s2 < 1) return true;
+  if (s2 >= 1 || s2 <= 1) return true;
+}
+
+int TestRelational(int X, int Y) {
+  if (X == 10 && X > 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (X == 10 && X < 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (X < 10 && X > 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+  if (X <= 10 && X > 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always false
+  if (X < 10 && X >= 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+  if (X < 10 && X == 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+
+  if (X > 5 && X <= 5) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always false
+  if (X > -5 && X <= -5) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always false
+
+  if (X < 10 || X >= 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
+  if (X <= 10 || X > 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+  if (X <= 10 || X >= 11) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: logical expression is always true
+  if (X != 7 || X != 14) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
+  if (X == 7 || X != 5) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X != 7 || X == 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: logical expression is always true
+
+  if (X < 7 && X < 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X < 7 && X < 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+  if (X < 7 && X < 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+
+  if (X < 7 && X <= 5) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X < 7 && X <= 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: equivalent expression on both sides of logical operator
+  if (X < 7 && X <= 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+  if (X < 7 && X <= 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+
+  if (X <= 7 && X < 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X <= 7 && X < 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X <= 7 && X < 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+
+  if (X >= 7 && X > 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: equivalent expression on both sides of logical operator
+  if (X >= 7 && X > 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X >= 7 && X > 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+  if (X <= 7 && X <= 5) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X <= 7 && X <= 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X <= 7 && X <= 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: both sides of operator are equivalent
+  if (X <= 7 && X <= 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: expression is redundant
+
+  if (X == 11 && X > 10) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
+  if (X == 11 && X < 12) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: expression is redundant
+  if (X > 10 && X == 11) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X < 12 && X == 11) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+  if (X != 11 && X == 42) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X != 11 && X > 11) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X != 11 && X < 11) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X != 11 && X < 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X != 11 && X > 14) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+  if (X < 7 || X < 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+  if (X < 7 || X < 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+  if (X < 7 || X < 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+  if (X > 7 || X > 6) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X > 7 || X > 7) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: both sides of operator are equivalent
+  if (X > 7 || X > 8) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: expression is redundant
+
+  // Should not match.
+  if (X < 10 || X > 12) return 1;
+  if (X > 10 && X < 12) return 1;
+  if (X < 10 || X >= 12) return 1;
+  if (X > 10 && X <= 12) return 1;
+  if (X <= 10 || X > 12) return 1;
+  if (X >= 10 && X < 12) return 1;
+  if (X <= 10 || X >= 12) return 1;
+  if (X >= 10 && X <= 12) return 1;
+  if (X >= 10 && X <= 11) return 1;
+  if (X >= 10 && X < 11) return 1;
+  if (X > 10 && X <= 11) return 1;
+  if (X > 10 && X != 11) return 1;
+  if (X >= 10 && X <= 10) return 1;
+  if (X <= 10 && X >= 10) return 1;
+  if (X < 0 || X > 0) return 1;
+}
+
+int TestRelationalMacros(int X){
+#define SOME_MACRO 3
+#define SOME_MACRO_SAME_VALUE 3
+#define SOME_OTHER_MACRO 9
+  // Do not match for redundant relational macro expressions that can be
+  // considered intentional, and for some particular values, non redundant.
+
+  // Test cases for expressions with the same macro on both sides.
+  if (X < SOME_MACRO && X > SOME_MACRO) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
+  if (X < SOME_MACRO && X == SOME_MACRO) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always false
+  if (X < SOME_MACRO || X >= SOME_MACRO) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
+  if (X <= SOME_MACRO || X > SOME_MACRO) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: logical expression is always true
+  if (X != SOME_MACRO && X > SOME_MACRO) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+  if (X != SOME_MACRO && X < SOME_MACRO) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: expression is redundant
+
+  // Test cases for two different macros.
+  if (X < SOME_MACRO && X > SOME_OTHER_MACRO) return 1;
+  if (X != SOME_MACRO && X >= SOME_OTHER_MACRO) return 1;
+  if (X != SOME_MACRO && X != SOME_OTHER_MACRO) return 1;
+  if (X == SOME_MACRO || X == SOME_MACRO_SAME_VALUE) return 1;
+  if (X == SOME_MACRO || X <= SOME_MACRO_SAME_VALUE) return 1;
+  if (X == SOME_MACRO || X > SOME_MACRO_SAME_VALUE) return 1;
+  if (X < SOME_MACRO && X <= SOME_OTHER_MACRO) return 1;
+  if (X == SOME_MACRO && X > SOME_OTHER_MACRO) return 1;
+  if (X == SOME_MACRO && X != SOME_OTHER_MACRO) return 1;
+  if (X == SOME_MACRO && X != SOME_MACRO_SAME_VALUE) return 1;
+  if (X == SOME_MACRO_SAME_VALUE && X == SOME_MACRO ) return 1;
+
+  // Test cases for a macro and a const.
+  if (X < SOME_MACRO && X > 9) return 1;
+  if (X != SOME_MACRO && X >= 9) return 1;
+  if (X != SOME_MACRO && X != 9) return 1;
+  if (X == SOME_MACRO || X == 3) return 1;
+  if (X == SOME_MACRO || X <= 3) return 1;
+  if (X < SOME_MACRO && X <= 9) return 1;
+  if (X == SOME_MACRO && X != 9) return 1;
+  if (X == SOME_MACRO && X == 9) return 1;
+
+#undef SOME_OTHER_MACRO
+#undef SOME_MACRO_SAME_VALUE
+#undef SOME_MACRO
+  return 0;
+}
+
+int TestValidExpression(int X) {
+  if (X - 1 == 1 - X) return 1;
+  if (2 * X == X) return 1;
+  if ((X << 1) == X) return 1;
+
+  return 0;
+}
+
+enum Color { Red, Yellow, Green };
+int TestRelationalWithEnum(enum Color C) {
+  if (C == Red && C == Yellow) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
+  if (C == Red && C != Red) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always false
+  if (C != Red || C != Yellow) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: logical expression is always true
+
+  // Should not match.
+  if (C == Red || C == Yellow) return 1;
+  if (C != Red && C != Yellow) return 1;
+
+  return 0;
+}
+
+template<class T>
+int TestRelationalTemplated(int X) {
+  // This test causes a corner case with |isIntegerConstantExpr| where the type
+  // is dependent. There is an assert failing when evaluating
+  // sizeof(<incomplet-type>).
+  if (sizeof(T) == 4 || sizeof(T) == 8) return 1;
+
+  if (X + 0 == -X) return 1;
+  if (X + 0 < X) return 1;
+
+  return 0;
+}
+
+int TestWithSignedUnsigned(int X) {
+  if (X + 1 == X + 1ULL) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: logical expression is always true
+
+  if ((X & 0xFFU) == 0xF00) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
+
+  if ((X & 0xFF) == 0xF00U) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: logical expression is always false
+
+  if ((X & 0xFFU) == 0xF00U) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: logical expression is always false
+
+  return 0;
+}
+
+int TestWithLong(int X, I64 Y) {
+  if (X + 0ULL == -X) return 1;
+  if (Y + 0 == -Y) return 1;
+  if (Y <= 10 && X >= 10LL) return 1;
+  if (Y <= 10 && X >= 10ULL) return 1;
+  if (X <= 10 || X > 12LL) return 1;
+  if (X <= 10 || X > 12ULL) return 1;
+  if (Y <= 10 || Y > 12) return 1;
+
+  return 0;
+}
+
+int TestWithMinMaxInt(int X) {
+  if (X <= X + 0xFFFFFFFFU) return 1;
+  if (X <= X + 0x7FFFFFFF) return 1;
+  if (X <= X + 0x80000000) return 1;
+
+  if (X <= 0xFFFFFFFFU && X > 0) return 1;
+  if (X <= 0xFFFFFFFFU && X > 0U) return 1;
+
+  if (X + 0x80000000 == X - 0x80000000) return 1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: logical expression is always true
+
+  if (X > 0x7FFFFFFF || X < ((-0x7FFFFFFF)-1)) return 1;
+  if (X <= 0x7FFFFFFF && X >= ((-0x7FFFFFFF)-1)) return 1;
+
+  return 0;
+}
+
+#define FLAG1 1
+#define FLAG2 2
+#define FLAG3 4
+#define FLAGS (FLAG1 | FLAG2 | FLAG3)
+#define NOTFLAGS !(FLAG1 | FLAG2 | FLAG3)
+int TestOperatorConfusion(int X, int Y, long Z)
+{
+  // Ineffective & expressions.
+  Y = (Y << 8) & 0xff;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
+  Y = (Y << 12) & 0xfff;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+  Y = (Y << 12) & 0xff;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+  Y = (Y << 8) & 0x77;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
+  Y = (Y << 5) & 0x11;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
+
+  // Tests for unmatched types
+  Z = (Z << 8) & 0xff;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and operation
+  Y = (Y << 12) & 0xfffL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+  Z = (Y << 12) & 0xffLL;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+  Y = (Z << 8L) & 0x77L;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: ineffective bitwise and
+
+  Y = (Y << 8) & 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: ineffective bitwise and
+
+  Y = (Y << 8) & -1;
+
+  // Effective expressions. Do not check.
+  Y = (Y << 4) & 0x15;
+  Y = (Y << 3) & 0x250;
+  Y = (Y << 9) & 0xF33;
+
+  int K = !(1 | 2 | 4);
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: ineffective logical negation operator used; did you mean '~'?
+  // CHECK-FIXES: {{^}}  int K = ~(1 | 2 | 4);{{$}}
+  K = !(FLAG1 & FLAG2 & FLAG3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
+  // CHECK-FIXES: {{^}}  K = ~(FLAG1 & FLAG2 & FLAG3);{{$}}
+  K = !(3 | 4);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: ineffective logical negation operator
+  // CHECK-FIXES: {{^}}  K = ~(3 | 4);{{$}}
+  int NotFlags = !FLAGS;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: ineffective logical negation operator
+  // CHECK-FIXES: {{^}}  int NotFlags = ~FLAGS;{{$}}
+  NotFlags = NOTFLAGS;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: ineffective logical negation operator
+  return !(1 | 2 | 4);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: ineffective logical negation operator
+  // CHECK-FIXES: {{^}}  return ~(1 | 2 | 4);{{$}}
+}
+
+template <int Shift, int Mask>
+int TestOperatorConfusionDependent(int Y) {
+  int r1 = (Y << Shift) & 0xff;
+  int r2 = (Y << 8) & Mask;
+}
+#undef FLAG1
+#undef FLAG2
+#undef FLAG3
+
+namespace no_crash {
+struct Foo {};
+bool operator<(const Foo&, const Foo&);
+template <class T>
+struct Bar {
+  static const Foo &GetFoo();
+  static bool Test(const T & maybe_foo, const Foo& foo) {
+    return foo < GetFoo() && foo < maybe_foo;
+  }
+};
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,27 @@
+// RUN: %check_clang_tidy %s misc-static-assert %t -- -- -std=c11
+// RUN: clang-tidy %s -checks=-*,misc-static-assert -- -std=c99 | count 0
+
+void abort() {}
+#ifdef NDEBUG
+#define assert(x) 1
+#else
+#define assert(x)                                                              \
+  if (!(x))                                                                    \
+  abort()
+#endif
+
+void f(void) {
+  int x = 1;
+  assert(x == 0);
+  // CHECK-FIXES: {{^  }}assert(x == 0);
+
+  #define static_assert(x, msg) _Static_assert(x, msg)
+  assert(11 == 5 + 6);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(11 == 5 + 6, "");
+  #undef static_assert
+
+  assert(10 == 5 + 5);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(10 == 5 + 5, "");
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-static-assert.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,143 @@
+// RUN: %check_clang_tidy %s misc-static-assert %t
+
+void abort() {}
+#ifdef NDEBUG
+#define assert(x) 1
+#else
+#define assert(x)                                                              \
+  if (!(x))                                                                    \
+  abort()
+#endif
+
+void print(...);
+
+#define ZERO_MACRO 0
+
+#define False false
+#define FALSE 0
+
+#define my_macro() assert(0 == 1)
+// CHECK-FIXES: #define my_macro() assert(0 == 1)
+
+constexpr bool myfunc(int a, int b) { return a * b == 0; }
+
+typedef __SIZE_TYPE__ size_t;
+extern "C" size_t strlen(const char *s);
+
+class A {
+public:
+  bool method() { return true; }
+};
+
+class B {
+public:
+  constexpr bool method() { return true; }
+};
+
+template <class T> void doSomething(T t) {
+  assert(myfunc(1, 2));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be replaced by static_assert() [misc-static-assert]
+  // CHECK-FIXES: {{^  }}static_assert(myfunc(1, 2), "");
+
+  assert(t.method());
+  // CHECK-FIXES: {{^  }}assert(t.method());
+
+  assert(sizeof(T) == 123);
+}
+
+int main() {
+  my_macro();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}my_macro();
+
+  assert(myfunc(1, 2) && (3 == 4));
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(myfunc(1, 2) && (3 == 4), "");
+
+  int x = 1;
+  assert(x == 0);
+  // CHECK-FIXES: {{^  }}assert(x == 0);
+
+  A a;
+  B b;
+
+  doSomething<A>(a);
+  doSomething<B>(b);
+
+  assert(false);
+  // CHECK-FIXES: {{^  }}assert(false);
+
+  assert(False);
+  // CHECK-FIXES: {{^  }}assert(False);
+  assert(FALSE);
+  // CHECK-FIXES: {{^  }}assert(FALSE);
+
+  assert(ZERO_MACRO);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(ZERO_MACRO, "");
+
+  assert(!"Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(!"Don't report me!");
+
+  assert(0 && "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(0 && "Don't report me!");
+
+  assert(false && "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(false && "Don't report me!");
+
+#define NULL ((void*)0)
+  assert(NULL && "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(NULL && "Don't report me!");
+
+  assert(NULL == "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(NULL == "Don't report me!");
+
+  assert("Don't report me!" == NULL);
+  // CHECK-FIXES: {{^  }}assert("Don't report me!" == NULL);
+
+  assert(0 == "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(0 == "Don't report me!");
+
+#define NULL ((unsigned int)0)
+  assert(NULL && "Report me!");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(NULL , "Report me!");
+
+#define NULL __null
+  assert(__null == "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(__null == "Don't report me!");
+  assert(NULL == "Don't report me!");
+  // CHECK-FIXES: {{^  }}assert(NULL == "Don't report me!");
+#undef NULL
+
+  assert(ZERO_MACRO && "Report me!");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(ZERO_MACRO , "Report me!");
+
+  assert(0);
+
+#define false false
+  assert(false);
+
+#define false 0
+  assert(false);
+#undef false
+
+  assert(10==5 && "Report me!");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(10==5 , "Report me!");
+
+  assert(strlen("12345") == 5);
+  // CHECK-FIXES: {{^  }}assert(strlen("12345") == 5);
+
+#define assert(e) (__builtin_expect(!(e), 0) ? print (#e, __FILE__, __LINE__) : (void)0)
+  assert(false);
+  // CHECK-FIXES: {{^  }}assert(false);
+
+  assert(10 == 5 + 5);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: found assert() that could be
+  // CHECK-FIXES: {{^  }}static_assert(10 == 5 + 5, "");
+#undef assert
+
+  return 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-throw-by-value-catch-by-reference.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-throw-by-value-catch-by-reference.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-throw-by-value-catch-by-reference.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-throw-by-value-catch-by-reference.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,156 @@
+// RUN: %check_clang_tidy %s misc-throw-by-value-catch-by-reference %t -- -- -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
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator-cxx17.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator-cxx17.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator-cxx17.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator-cxx17.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s misc-unconventional-assign-operator %t -- -- -fno-delayed-template-parsing
+
+struct BadModifier {
+  BadModifier& operator=(const BadModifier&) const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
+};
+
+struct PR35468 {
+  template<typename T> auto &operator=(const T &) {
+    return *this;
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,111 @@
+// RUN: %check_clang_tidy %s misc-unconventional-assign-operator %t -- -- -isystem %S/Inputs/Headers -fno-delayed-template-parsing
+
+namespace std {
+template <typename T>
+struct remove_reference { typedef T type; };
+template <typename T>
+struct remove_reference<T &> { typedef T type; };
+template <typename T>
+struct remove_reference<T &&> { typedef T type; };
+template <typename T>
+typename remove_reference<T>::type &&move(T &&t);
+}
+
+
+struct Good {
+  Good& operator=(const Good&);
+  Good& operator=(Good&&);
+
+  // Assign from other types is fine too.
+  Good& operator=(int);
+};
+
+struct AlsoGood {
+  // By value is also fine.
+  AlsoGood& operator=(AlsoGood);
+};
+
+struct BadReturnType {
+  void operator=(const BadReturnType&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturnType&' [misc-unconventional-assign-operator]
+  const BadReturnType& operator=(BadReturnType&&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+  void operator=(int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+};
+
+struct BadReturnType2 {
+  BadReturnType2&& operator=(const BadReturnType2&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+  int operator=(BadReturnType2&&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+};
+
+struct BadArgument {
+  BadArgument& operator=(BadArgument&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadArgument const&', 'BadArgument&&' or 'BadArgument'
+  BadArgument& operator=(const BadArgument&&);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should take 'BadAr
+};
+
+struct BadModifier {
+  BadModifier& operator=(const BadModifier&) const;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'const'
+};
+
+struct Deleted {
+  // We don't check the return value of deleted operators.
+  void operator=(const Deleted&) = delete;
+  void operator=(Deleted&&) = delete;
+};
+
+class Private {
+  // We don't check the return value of private operators.
+  // Pre-C++11 way of disabling assignment.
+  void operator=(const Private &);
+};
+
+struct Virtual {
+  virtual Virtual& operator=(const Virtual &);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should not be marked 'virtual'
+};
+
+class BadReturnStatement {
+  int n;
+
+public:
+  BadReturnStatement& operator=(BadReturnStatement&& rhs) {
+    n = std::move(rhs.n);
+    return rhs;
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always return '*this'
+  }
+
+  // Do not check if return type is different from '&BadReturnStatement'
+  int operator=(int i) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad
+    n = i;
+    return n;
+  }
+};
+
+namespace pr31531 {
+enum E { e };
+// This declaration makes the 'return *this' below have an unresolved operator
+// in the class template, but not in an instantiation.
+E operator*(E, E);
+
+template <typename>
+struct UnresolvedOperator {
+  UnresolvedOperator &operator=(const UnresolvedOperator &) { return *this; }
+};
+
+UnresolvedOperator<int> UnresolvedOperatorInt;
+
+template <typename>
+struct Template {
+  Template &operator=(const Template &) { return this; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:43: warning: operator=() should always return '*this'
+};
+
+Template<int> TemplateInt;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-uniqueptr-reset-release.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-uniqueptr-reset-release.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-uniqueptr-reset-release.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-uniqueptr-reset-release.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,69 @@
+// RUN: %check_clang_tidy %s misc-uniqueptr-reset-release %t
+
+namespace std {
+
+template <typename T>
+struct default_delete {};
+
+template <typename T, class Deleter = std::default_delete<T>>
+struct unique_ptr {
+  unique_ptr();
+  explicit unique_ptr(T *);
+  template <typename U, typename E>
+  unique_ptr(unique_ptr<U, E> &&);
+  void reset(T *);
+  T *release();
+};
+} // namespace std
+
+struct Foo {};
+struct Bar : Foo {};
+
+std::unique_ptr<Foo> Create();
+std::unique_ptr<Foo> &Look();
+std::unique_ptr<Foo> *Get();
+
+using FooFunc = void (*)(Foo *);
+using BarFunc = void (*)(Bar *);
+
+void f() {
+  std::unique_ptr<Foo> a, b;
+  std::unique_ptr<Bar> c;
+  std::unique_ptr<Foo> *x = &a;
+  std::unique_ptr<Foo> *y = &b;
+
+  a.reset(b.release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2) over ptr1.reset(ptr2.release()) [misc-uniqueptr-reset-release]
+  // CHECK-FIXES: a = std::move(b);
+  a.reset(c.release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: a = std::move(c);
+  a.reset(Create().release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: prefer ptr = ReturnUnique() over ptr.reset(ReturnUnique().release()) [misc-uniqueptr-reset-release]
+  // CHECK-FIXES: a = Create();
+  x->reset(y->release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: *x = std::move(*y);
+  Look().reset(Look().release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: Look() = std::move(Look());
+  Get()->reset(Get()->release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: *Get() = std::move(*Get());
+
+  std::unique_ptr<Bar, FooFunc> func_a, func_b;
+  func_a.reset(func_b.release());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: prefer ptr1 = std::move(ptr2)
+  // CHECK-FIXES: func_a = std::move(func_b);
+}
+
+void negatives() {
+  std::unique_ptr<Foo> src;
+  struct OtherDeleter {};
+  std::unique_ptr<Foo, OtherDeleter> dest;
+  dest.reset(src.release());
+
+  std::unique_ptr<Bar, FooFunc> func_a;
+  std::unique_ptr<Bar, BarFunc> func_b;
+  func_a.reset(func_b.release());
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-alias-decls.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-alias-decls.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-alias-decls.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-alias-decls.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy %s misc-unused-alias-decls %t
+
+namespace my_namespace {
+class C {};
+}
+
+namespace unused_alias = ::my_namespace; // eol-comments aren't removed (yet)
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: namespace alias decl 'unused_alias' is unused
+// CHECK-FIXES: {{^}}// eol-comments aren't removed (yet)
+
+namespace used_alias = ::my_namespace;
+void f() { used_alias::C c; }

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters-strict.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters-strict.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters-strict.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters-strict.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s misc-unused-parameters %t -- \
+// RUN:   -config="{CheckOptions: [{key: StrictMode, value: 1}]}" --
+
+// Warn on empty function bodies in StrictMode.
+namespace strict_mode {
+void f(int foo) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'foo' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void f(int  /*foo*/) {}{{$}}
+class E {
+  int i;
+
+public:
+  E(int j) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}}  E(int  /*j*/) {}{{$}}
+};
+class F {
+  int i;
+
+public:
+  F(int j) : i() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}}  F(int  /*j*/) : i() {}{{$}}
+};
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s misc-unused-parameters %t -- -- -xc
+
+// Basic removal
+// =============
+void a(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void a(int i) {;}{{$}}
+
+static void b(); // In C, forward declarations can leave out parameters.
+static void b(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}static void b() {;}{{$}}
+
+// Unchanged cases
+// ===============
+void h(i, c, d) int i; char *c, *d; {} // Don't mess with K&R style
+

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-parameters.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,278 @@
+// RUN: echo "static void staticFunctionHeader(int i) {;}" > %T/header.h
+// RUN: echo "static void staticFunctionHeader(int  /*i*/) {;}" > %T/header-fixed.h
+// RUN: %check_clang_tidy -std=c++11 %s misc-unused-parameters %t -- -header-filter='.*' -- -fno-delayed-template-parsing
+// RUN: diff %T/header.h %T/header-fixed.h
+// FIXME: Make the test work in all language modes.
+
+#include "header.h"
+// CHECK-MESSAGES: header.h:1:38: warning
+
+// Basic removal
+// =============
+void a(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void a(int  /*i*/) {;}{{$}}
+
+void b(int i = 1) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void b(int  /*i*/ = 1) {;}{{$}}
+
+void c(int *i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void c(int * /*i*/) {;}{{$}}
+
+void d(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void d(int  /*i*/[]) {;}{{$}}
+
+void e(int i[1]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: parameter 'i' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void e(int  /*i*/[1]) {;}{{$}}
+
+void f(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: parameter 'fn' is unused [misc-unused-parameters]
+// CHECK-FIXES: {{^}}void f(void (* /*fn*/)()) {;}{{$}}
+
+// Unchanged cases
+// ===============
+void f(int i); // Don't remove stuff in declarations
+void g(int i = 1);
+void h(int i[]);
+void s(int i[1]);
+void u(void (*fn)());
+void w(int i) { (void)i; } // Don't remove used parameters
+
+bool useLambda(int (*fn)(int));
+static bool static_var = useLambda([] (int a) { return a; });
+
+// Remove parameters of local functions
+// ====================================
+static void staticFunctionA(int i);
+// CHECK-FIXES: {{^}}static void staticFunctionA();
+static void staticFunctionA(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionA()
+
+static void staticFunctionB(int i, int j) { (void)i; }
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
+// CHECK-FIXES: {{^}}static void staticFunctionB(int i)
+
+static void staticFunctionC(int i, int j) { (void)j; }
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionC(int j)
+
+static void staticFunctionD(int i, int j, int k) { (void)i; (void)k; }
+// CHECK-MESSAGES: :[[@LINE-1]]:40: warning
+// CHECK-FIXES: {{^}}static void staticFunctionD(int i, int k)
+
+static void staticFunctionE(int i = 4) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionE()
+
+static void staticFunctionF(int i = 4);
+// CHECK-FIXES: {{^}}static void staticFunctionF();
+static void staticFunctionF(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionF()
+
+static void staticFunctionG(int i[]);
+// CHECK-FIXES: {{^}}static void staticFunctionG();
+static void staticFunctionG(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning
+// CHECK-FIXES: {{^}}static void staticFunctionG()
+
+static void staticFunctionH(void (*fn)());
+// CHECK-FIXES: {{^}}static void staticFunctionH();
+static void staticFunctionH(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning
+// CHECK-FIXES: {{^}}static void staticFunctionH()
+
+static void someCallSites() {
+  staticFunctionA(1);
+// CHECK-FIXES: staticFunctionA();
+  staticFunctionB(1, 2);
+// CHECK-FIXES: staticFunctionB(1);
+  staticFunctionC(1, 2);
+// CHECK-FIXES: staticFunctionC(2);
+  staticFunctionD(1, 2, 3);
+// CHECK-FIXES: staticFunctionD(1, 3);
+  staticFunctionE(1);
+// CHECK-FIXES: staticFunctionE();
+  staticFunctionF(1);
+// CHECK-FIXES: staticFunctionF();
+  staticFunctionF();
+// CHECK-FIXES: staticFunctionF();
+  int t[] = {1};
+  staticFunctionG(t);
+// CHECK-FIXES: staticFunctionG();
+  void func();
+  staticFunctionH(&func);
+// CHECK-FIXES: staticFunctionH();
+}
+
+/*
+ * FIXME: This fails because the removals overlap and ClangTidy doesn't apply
+ *        them.
+ * static void bothVarsUnused(int a, int b) {;}
+ */
+
+// Regression test for long variable names and expressions
+// =======================================================
+static int variableWithLongName1(int LongName1, int LongName2) {
+// CHECK-MESSAGES: :[[@LINE-1]]:53: warning: parameter 'LongName2' is unused
+// CHECK-FIXES: {{^}}static int variableWithLongName1(int LongName1) {
+  return LongName1;
+}
+static int variableWithLongName2(int LongName1, int LongName2) {
+// CHECK-MESSAGES: :[[@LINE-1]]:38: warning: parameter 'LongName1' is unused
+// CHECK-FIXES: {{^}}static int variableWithLongName2(int LongName2) {
+  return LongName2;
+}
+static void someLongNameCallSites() {
+  int LongName1 = 7, LongName2 = 17;
+  variableWithLongName1(LongName1, LongName2);
+// CHECK-FIXES: variableWithLongName1(LongName1);
+  variableWithLongName2(LongName1, LongName2);
+// CHECK-FIXES: variableWithLongName2(LongName2);
+}
+
+class SomeClass {
+  static void f(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
+// CHECK-FIXES: static void f(int  /*i*/) {;}
+  static void g(int i = 1) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
+// CHECK-FIXES: static void g(int  /*i*/ = 1) {;}
+  static void h(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning
+// CHECK-FIXES: static void h(int  /*i*/[]) {;}
+  static void s(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning
+// CHECK-FIXES: static void s(void (* /*fn*/)()) {;}
+};
+
+namespace {
+class C {
+public:
+  void f(int i);
+// CHECK-FIXES: void f();
+  void g(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void g() {;}
+  void h(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void h(int  /*i*/) {;}
+  void s(int i = 1) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void s(int  /*i*/ = 1) {;}
+  void u(int i[]) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void u(int  /*i*/[]) {;}
+  void w(void (*fn)()) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning
+// CHECK-FIXES: void w(void (* /*fn*/)()) {;}
+};
+
+void C::f(int i) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning
+// CHECK-FIXES: void C::f() {;}
+
+template <typename T>
+void useFunction(T t);
+
+void someMoreCallSites() {
+  C c;
+  c.f(1);
+// CHECK-FIXES: c.f();
+  c.g(1);
+// CHECK-FIXES: c.g();
+
+  useFunction(&C::h);
+  useFunction(&C::s);
+  useFunction(&C::u);
+  useFunction(&C::w);
+}
+
+class Base {
+  virtual void f(int i);
+};
+
+class Derived : public Base {
+  void f(int i) override {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning
+// CHECK-FIXES: void f(int  /*i*/) override {;}
+};
+
+} // end namespace
+
+template <typename T> void someFunctionTemplate(T b, T e) { (void)b; (void)e; }
+
+template <typename T> void someFunctionTemplateOneUnusedParam(T b, T e) { (void)e; }
+// CHECK-MESSAGES: :[[@LINE-1]]:65: warning
+// CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateOneUnusedParam(T  /*b*/, T e) { (void)e; }
+
+template <typename T> void someFunctionTemplateAllUnusedParams(T b, T e) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:66: warning
+// CHECK-MESSAGES: :[[@LINE-2]]:71: warning
+// CHECK-FIXES: {{^}}template <typename T> void someFunctionTemplateAllUnusedParams(T  /*b*/, T  /*e*/) {;}
+
+static void dontGetConfusedByParametersInFunctionTypes() { void (*F)(int i); }
+
+template <typename T> class Function {};
+static Function<void(int, int i)> dontGetConfusedByFunctionReturnTypes() {
+  return Function<void(int, int)>();
+}
+
+namespace PR38055 {
+namespace {
+struct a {
+  void b(int c) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: parameter 'c' is unused
+// CHECK-FIXES: {{^}}  void b() {;}{{$}}
+};
+template <class>
+class d {
+  a e;
+  void f() { e.b(); }
+};
+}  // namespace
+}  // namespace PR38055
+
+namespace strict_mode_off {
+// Do not warn on empty function bodies.
+void f1(int foo1) {}
+void f2(int foo2) {
+  // "empty" in the AST sense, not in textual sense.
+}
+void f3(int foo3) {;}
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: parameter 'foo3' is unused
+// CHECK-FIXES: {{^}}void f3(int  /*foo3*/) {;}{{$}}
+
+class E {
+  int i;
+
+public:
+  E(int j) {}
+};
+class F {
+  int i;
+
+public:
+  // Constructor initializer counts as a non-empty body.
+  F(int j) : i() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'j' is unused
+// CHECK-FIXES: {{^}}  F(int  /*j*/) : i() {}{{$}}
+};
+
+class A {
+public:
+  A();
+  A(int);
+};
+class B : public A {
+public:
+  B(int i) : A() {}
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: parameter 'i' is unused
+// CHECK-FIXES: {{^}}  B(int  /*i*/) : A() {}{{$}}
+};
+} // namespace strict_mode_off

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls-errors.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls-errors.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls-errors.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls-errors.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: %check_clang_tidy -expect-clang-tidy-error %s misc-unused-using-decls %t
+
+namespace n {
+class C;
+}
+
+using n::C;
+
+void f() {
+  for (C *p : unknown()) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: error: use of undeclared identifier 'unknown' [clang-diagnostic-error]
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/misc-unused-using-decls.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,213 @@
+// RUN: %check_clang_tidy %s misc-unused-using-decls %t -- -- -fno-delayed-template-parsing -isystem %S/Inputs/
+
+
+// ----- Definitions -----
+template <typename T> class vector {};
+namespace n {
+class A;
+class B;
+class C;
+class D;
+class D { public: static int i; };
+template <typename T> class E {};
+template <typename T> class F {};
+class G { public: static void func() {} };
+class H { public: static int i; };
+class I {
+ public:
+  static int ii;
+};
+template <typename T> class J {};
+class G;
+class H;
+
+template <typename T> class K {};
+template <template <typename> class S>
+class L {};
+
+template <typename T> class M {};
+class N {};
+
+template <int T> class P {};
+const int Constant = 0;
+
+template <typename T> class Q {};
+
+class Base {
+ public:
+  void f();
+};
+
+D UsedInstance;
+D UnusedInstance;
+
+int UsedFunc() { return 1; }
+int UnusedFunc() { return 1; }
+template <typename T> int UsedTemplateFunc() { return 1; }
+template <typename T> int UnusedTemplateFunc() { return 1; }
+template <typename T> int UsedInTemplateFunc() { return 1; }
+void OverloadFunc(int);
+void OverloadFunc(double);
+int FuncUsedByUsingDeclInMacro() { return 1; }
+
+class ostream {
+public:
+  ostream &operator<<(ostream &(*PF)(ostream &));
+};
+extern ostream cout;
+ostream &endl(ostream &os);
+
+enum Color1 { Green };
+
+enum Color2 { Red };
+
+enum Color3 { Yellow };
+
+enum Color4 { Blue };
+
+}  // namespace n
+
+#include "unused-using-decls.h"
+namespace ns {
+template <typename T>
+class AA {
+  T t;
+};
+template <typename T>
+T ff() { T t; return t; }
+} // namespace ns
+
+// ----- Using declarations -----
+// eol-comments aren't removed (yet)
+using n::A; // A
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'A' is unused
+// CHECK-MESSAGES: :[[@LINE-2]]:10: note: remove the using
+// CHECK-FIXES: {{^}}// A
+using n::B;
+using n::C;
+using n::D;
+using n::E; // E
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'E' is unused
+// CHECK-FIXES: {{^}}// E
+using n::F;
+using n::G;
+using n::H;
+using n::I;
+int I::ii = 1;
+class Derived : public n::Base {
+ public:
+  using Base::f;
+};
+using n::UsedInstance;
+using n::UsedFunc;
+using n::UsedTemplateFunc;
+using n::UnusedInstance; // UnusedInstance
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedInstance' is unused
+// CHECK-FIXES: {{^}}// UnusedInstance
+using n::UnusedFunc; // UnusedFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'UnusedFunc' is unused
+// CHECK-FIXES: {{^}}// UnusedFunc
+using n::cout;
+using n::endl;
+
+using n::UsedInTemplateFunc;
+using n::J;
+template <typename T> void Callee() {
+  J<T> j;
+  UsedInTemplateFunc<T>();
+}
+
+using n::OverloadFunc; // OverloadFunc
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'OverloadFunc' is unused
+// CHECK-FIXES: {{^}}// OverloadFunc
+
+#define DEFINE_INT(name)        \
+  namespace INT {               \
+  static const int _##name = 1; \
+  }                             \
+  using INT::_##name
+DEFINE_INT(test);
+#undef DEFIND_INT
+
+#define USING_FUNC \
+  using n::FuncUsedByUsingDeclInMacro;
+USING_FUNC
+#undef USING_FUNC
+
+namespace N1 {
+// n::G is used in namespace N2.
+// Currently, the check doesn't support multiple scopes. All the relevant
+// using-decls will be marked as used once we see an usage even the usage is in
+// other scope.
+using n::G;
+}
+
+namespace N2 {
+using n::G;
+void f(G g);
+}
+
+void IgnoreFunctionScope() {
+// Using-decls defined in function scope will be ignored.
+using n::H;
+}
+
+using n::Color1;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Color1' is unused
+using n::Green;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Green' is unused
+using n::Color2;
+using n::Color3;
+using n::Blue;
+
+using ns::AA;
+using ns::ff;
+
+using n::K;
+
+using n::N;
+
+// FIXME: Currently non-type template arguments are not supported.
+using n::Constant;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: using decl 'Constant' is unused
+
+using n::Q;
+
+// ----- Usages -----
+void f(B b);
+void g() {
+  vector<C> data;
+  D::i = 1;
+  F<int> f;
+  void (*func)() = &G::func;
+  int *i = &H::i;
+  UsedInstance.i;
+  UsedFunc();
+  UsedTemplateFunc<int>();
+  cout << endl;
+  Color2 color2;
+  int t1 = Color3::Yellow;
+  int t2 = Blue;
+
+  MyClass a;
+  int t3 = 0;
+  a.func1<AA>(&t3);
+  a.func2<int, ff>(t3);
+
+  n::L<K> l;
+}
+
+template<class T>
+void h(n::M<T>* t) {}
+// n::N is used the explicit template instantiation.
+template void h(n::M<N>* t);
+
+// Test on Non-type template arguments.
+template <int T>
+void i(n::P<T>* t) {}
+template void i(n::P<Constant>* t);
+
+template <typename T, template <typename> class U> class Bar {};
+// We used to report Q unsued, because we only checked the first template
+// argument.
+Bar<int, Q> *bar;

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-bind.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-bind.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-bind.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-bind.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,123 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-avoid-bind %t
+
+namespace std {
+inline namespace impl {
+template <class Fp, class... Arguments>
+class bind_rt {};
+
+template <class Fp, class... Arguments>
+bind_rt<Fp, Arguments...> bind(Fp &&, Arguments &&...);
+}
+}
+
+int add(int x, int y) { return x + y; }
+
+void f() {
+  auto clj = std::bind(add, 2, 2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind [modernize-avoid-bind]
+  // CHECK-FIXES: auto clj = [] { return add(2, 2); };
+}
+
+void g() {
+  int x = 2;
+  int y = 2;
+  auto clj = std::bind(add, x, y);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: auto clj = [=] { return add(x, y); };
+}
+
+struct placeholder {};
+placeholder _1;
+placeholder _2;
+
+void h() {
+  int x = 2;
+  auto clj = std::bind(add, x, _1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: auto clj = [=](auto && arg1) { return add(x, arg1); };
+}
+
+struct A;
+struct B;
+bool ABTest(const A &, const B &);
+
+void i() {
+  auto BATest = std::bind(ABTest, _2, _1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: auto BATest = [](auto && arg1, auto && arg2) { return ABTest(arg2, arg1); };
+}
+
+void j() {
+  auto clj = std::bind(add, 2, 2, 2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // No fix is applied for argument mismatches.
+  // CHECK-FIXES: auto clj = std::bind(add, 2, 2, 2);
+}
+
+void k() {
+  auto clj = std::bind(add, _1, _1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // No fix is applied for reused placeholders.
+  // CHECK-FIXES: auto clj = std::bind(add, _1, _1);
+}
+
+void m() {
+  auto clj = std::bind(add, 1, add(2, 5));
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // No fix is applied for nested calls.
+  // CHECK-FIXES: auto clj = std::bind(add, 1, add(2, 5));
+}
+
+namespace C {
+  int add(int x, int y){ return x + y; }
+}
+
+void n() {
+  auto clj = std::bind(C::add, 1, 1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: auto clj = [] { return C::add(1, 1); };
+}
+
+// Let's fake a minimal std::function-like facility.
+namespace std {
+template <typename _Tp>
+_Tp declval();
+
+template <typename _Functor, typename... _ArgTypes>
+struct __res {
+  template <typename... _Args>
+  static decltype(declval<_Functor>()(_Args()...)) _S_test(int);
+
+  template <typename...>
+  static void _S_test(...);
+
+  using type = decltype(_S_test<_ArgTypes...>(0));
+};
+
+template <typename>
+struct function;
+
+template <typename... _ArgTypes>
+struct function<void(_ArgTypes...)> {
+  template <typename _Functor,
+            typename = typename __res<_Functor, _ArgTypes...>::type>
+  function(_Functor) {}
+};
+} // namespace std
+
+struct Thing {};
+void UseThing(Thing *);
+
+struct Callback {
+  Callback();
+  Callback(std::function<void()>);
+  void Reset(std::function<void()>);
+};
+
+void test(Thing *t) {
+  Callback cb;
+  if (t)
+    cb.Reset(std::bind(UseThing, t));
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: prefer a lambda to std::bind
+  // CHECK-FIXES: cb.Reset([=] { return UseThing(t); });
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-main.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-main.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-main.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-main.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int not_main(int argc, char *argv[]) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead
+  int f4[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+int main(int argc, char *argv[]) {
+  int f5[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  auto not_main = [](int argc, char *argv[]) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead
+    int f6[] = {1, 2};
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead
+  };
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-three-arg-main.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-three-arg-main.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-three-arg-main.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays-ignores-three-arg-main.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,20 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int not_main(int argc, char *argv[], char *argw[]) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: do not declare C-style arrays, use std::array<> instead
+  // CHECK-MESSAGES: :[[@LINE-2]]:38: warning: do not declare C-style arrays, use std::array<> instead
+  int f4[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+}
+
+int main(int argc, char *argv[], char *argw[]) {
+  int f5[] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  auto not_main = [](int argc, char *argv[], char *argw[]) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: do not declare C-style arrays, use std::array<> instead
+    // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: do not declare C-style arrays, use std::array<> instead
+    int f6[] = {1, 2};
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: do not declare C-style arrays, use std::array<> instead
+  };
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-avoid-c-arrays.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,88 @@
+// RUN: %check_clang_tidy %s modernize-avoid-c-arrays %t
+
+int a[] = {1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+int b[1];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+void foo() {
+  int c[b[0]];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C VLA arrays, use std::vector<> instead
+
+  using d = decltype(c);
+  d e;
+  // Semi-FIXME: we do not diagnose these last two lines separately,
+  // because we point at typeLoc.getBeginLoc(), which is the decl before that
+  // (int c[b[0]];), which is already diagnosed.
+}
+
+template <typename T, int Size>
+class array {
+  T d[Size];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  int e[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+array<int[4], 2> d;
+// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: do not declare C-style arrays, use std::array<> instead
+
+using k = int[4];
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: do not declare C-style arrays, use std::array<> instead
+
+array<k, 2> dk;
+
+template <typename T>
+class unique_ptr {
+  T *d;
+
+  int e[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+
+unique_ptr<int[]> d2;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+using k2 = int[];
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: do not declare C-style arrays, use std::array<> instead
+
+unique_ptr<k2> dk2;
+
+// Some header
+extern "C" {
+
+int f[] = {1, 2};
+
+int j[1];
+
+inline void bar() {
+  {
+    int j[j[0]];
+  }
+}
+
+extern "C++" {
+int f3[] = {1, 2};
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+int j3[1];
+// CHECK-MESSAGES: :[[@LINE-1]]:1: warning: do not declare C-style arrays, use std::array<> instead
+
+struct Foo {
+  int f3[3] = {1, 2};
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+
+  int j3[1];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not declare C-style arrays, use std::array<> instead
+};
+}
+
+struct Bar {
+
+  int f[3] = {1, 2};
+
+  int j[1];
+};
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-concat-nested-namespaces.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,161 @@
+// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-concat-nested-namespaces %t
+
+namespace n1 {}
+
+namespace n2 {
+namespace n3 {
+void t();
+}
+namespace n4 {
+void t();
+}
+} // namespace n2
+
+namespace n5 {
+inline namespace n6 {
+void t();
+}
+} // namespace n5
+
+namespace n7 {
+void t();
+
+namespace n8 {
+void t();
+}
+} // namespace n7
+
+namespace n9 {
+namespace n10 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n9::n10
+void t();
+} // namespace n10
+} // namespace n9
+// CHECK-FIXES: }
+
+namespace n11 {
+namespace n12 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n11::n12
+namespace n13 {
+void t();
+}
+namespace n14 {
+void t();
+}
+} // namespace n12
+} // namespace n11
+// CHECK-FIXES: }
+
+namespace n15 {
+namespace n16 {
+void t();
+}
+
+inline namespace n17 {
+void t();
+}
+
+namespace n18 {
+namespace n19 {
+namespace n20 {
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n18::n19::n20
+void t();
+} // namespace n20
+} // namespace n19
+} // namespace n18
+// CHECK-FIXES: }
+
+namespace n21 {
+void t();
+}
+} // namespace n15
+
+namespace n22 {
+namespace {
+void t();
+}
+} // namespace n22
+
+namespace n23 {
+namespace {
+namespace n24 {
+namespace n25 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n24::n25
+void t();
+} // namespace n25
+} // namespace n24
+// CHECK-FIXES: }
+} // namespace
+} // namespace n23
+
+namespace n26::n27 {
+namespace n28 {
+namespace n29::n30 {
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n26::n27::n28::n29::n30
+void t() {}
+} // namespace n29::n30
+} // namespace n28
+} // namespace n26::n27
+// CHECK-FIXES: }
+
+namespace n31 {
+namespace n32 {}
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+} // namespace n31
+// CHECK-FIXES-EMPTY
+
+namespace n33 {
+namespace n34 {
+namespace n35 {}
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+} // namespace n34
+// CHECK-FIXES-EMPTY
+namespace n36 {
+void t();
+}
+} // namespace n33
+
+namespace n37::n38 {
+void t();
+}
+
+#define IEXIST
+namespace n39 {
+namespace n40 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n39::n40
+#ifdef IEXIST
+void t() {}
+#endif
+} // namespace n40
+} // namespace n39
+// CHECK-FIXES: }
+
+namespace n41 {
+namespace n42 {
+// CHECK-MESSAGES: :[[@LINE-2]]:1: warning: nested namespaces can be concatenated [modernize-concat-nested-namespaces]
+// CHECK-FIXES: namespace n41::n42
+#ifdef IDONTEXIST
+void t() {}
+#endif
+} // namespace n42
+} // namespace n41
+// CHECK-FIXES: }
+
+int main() {
+  n26::n27::n28::n29::n30::t();
+#ifdef IEXIST
+  n39::n40::t();
+#endif
+
+#ifdef IDONTEXIST
+  n41::n42::t();
+#endif
+
+  return 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx03.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,148 @@
+// RUN: %check_clang_tidy -std=c++98 %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers
+
+#include <assert.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers]
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include <complex.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include <ctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include <errno.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include <float.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include <limits.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include <locale.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include <math.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include <setjmp.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include <signal.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include <stdarg.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include <stddef.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include <stdio.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include <stdlib.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include <string.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include <time.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include <wchar.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include <wctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>{{$}}
+
+// Headers that have no effect in C++; remove them
+#include <stdalign.h> // <stdalign.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdalign.h>{{$}}
+#include <stdbool.h> // <stdbool.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdbool.h>{{$}}
+#include <iso646.h> // <iso646.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <iso646.h>{{$}}
+
+// Headers deprecated since C++11: expect no diagnostics.
+#include <fenv.h>
+#include <inttypes.h>
+#include <stdint.h>
+#include <tgmath.h>
+#include <uchar.h>
+
+
+#include "assert.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include "complex.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include "ctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include "errno.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include "float.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include "limits.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include "locale.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include "math.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include "setjmp.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include "signal.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include "stdarg.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include "stddef.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include "stdio.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include "stdlib.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include "string.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include "time.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include "wchar.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include "wctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>
+
+// Headers that have no effect in C++; remove them
+#include "stdalign.h" // "stdalign.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdalign.h"{{$}}
+#include "stdbool.h" // "stdbool.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdbool.h"{{$}}
+#include "iso646.h" // "iso646.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "iso646.h"{{$}}
+
+// Headers deprecated since C++11; expect no diagnostics
+#include "fenv.h"
+#include "inttypes.h"
+#include "stdint.h"
+#include "tgmath.h"
+#include "uchar.h"

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-headers-cxx11.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,163 @@
+// RUN: %check_clang_tidy -std=c++11-or-later %s modernize-deprecated-headers %t -- -extra-arg-before=-isystem%S/Inputs/modernize-deprecated-headers
+
+#include <assert.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead [modernize-deprecated-headers]
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include <complex.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include <ctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include <errno.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include <fenv.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'fenv.h'; consider using 'cfenv' instead
+// CHECK-FIXES: {{^}}#include <cfenv>{{$}}
+#include <float.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include <inttypes.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'inttypes.h'; consider using 'cinttypes' instead
+// CHECK-FIXES: {{^}}#include <cinttypes>{{$}}
+#include <limits.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include <locale.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include <math.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include <setjmp.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include <signal.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include <stdarg.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include <stddef.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include <stdint.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdint.h'; consider using 'cstdint' instead
+// CHECK-FIXES: {{^}}#include <cstdint>{{$}}
+#include <stdio.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include <stdlib.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include <string.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include <tgmath.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'tgmath.h'; consider using 'ctgmath' instead
+// CHECK-FIXES: {{^}}#include <ctgmath>{{$}}
+#include <time.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include <uchar.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'uchar.h'; consider using 'cuchar' instead
+// CHECK-FIXES: {{^}}#include <cuchar>{{$}}
+#include <wchar.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include <wctype.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>
+
+// Headers that have no effect in C++; remove them
+#include <stdalign.h> // <stdalign.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdalign.h>{{$}}
+#include <stdbool.h> // <stdbool.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <stdbool.h>{{$}}
+#include <iso646.h> // <iso646.h>
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// <iso646.h>{{$}}
+
+#include "assert.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'assert.h'; consider using 'cassert' instead
+// CHECK-FIXES: {{^}}#include <cassert>{{$}}
+#include "complex.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'complex.h'; consider using 'complex' instead
+// CHECK-FIXES: {{^}}#include <complex>{{$}}
+#include "ctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'ctype.h'; consider using 'cctype' instead
+// CHECK-FIXES: {{^}}#include <cctype>{{$}}
+#include "errno.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'errno.h'; consider using 'cerrno' instead
+// CHECK-FIXES: {{^}}#include <cerrno>{{$}}
+#include "fenv.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'fenv.h'; consider using 'cfenv' instead
+// CHECK-FIXES: {{^}}#include <cfenv>{{$}}
+#include "float.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'float.h'; consider using 'cfloat' instead
+// CHECK-FIXES: {{^}}#include <cfloat>{{$}}
+#include "inttypes.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'inttypes.h'; consider using 'cinttypes' instead
+// CHECK-FIXES: {{^}}#include <cinttypes>{{$}}
+#include "limits.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'limits.h'; consider using 'climits' instead
+// CHECK-FIXES: {{^}}#include <climits>{{$}}
+#include "locale.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'locale.h'; consider using 'clocale' instead
+// CHECK-FIXES: {{^}}#include <clocale>{{$}}
+#include "math.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'math.h'; consider using 'cmath' instead
+// CHECK-FIXES: {{^}}#include <cmath>{{$}}
+#include "setjmp.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'setjmp.h'; consider using 'csetjmp' instead
+// CHECK-FIXES: {{^}}#include <csetjmp>{{$}}
+#include "signal.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'signal.h'; consider using 'csignal' instead
+// CHECK-FIXES: {{^}}#include <csignal>{{$}}
+#include "stdarg.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdarg.h'; consider using 'cstdarg' instead
+// CHECK-FIXES: {{^}}#include <cstdarg>{{$}}
+#include "stddef.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stddef.h'; consider using 'cstddef' instead
+// CHECK-FIXES: {{^}}#include <cstddef>{{$}}
+#include "stdint.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdint.h'; consider using 'cstdint' instead
+// CHECK-FIXES: {{^}}#include <cstdint>{{$}}
+#include "stdio.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdio.h'; consider using 'cstdio' instead
+// CHECK-FIXES: {{^}}#include <cstdio>{{$}}
+#include "stdlib.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'stdlib.h'; consider using 'cstdlib' instead
+// CHECK-FIXES: {{^}}#include <cstdlib>{{$}}
+#include "string.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'string.h'; consider using 'cstring' instead
+// CHECK-FIXES: {{^}}#include <cstring>{{$}}
+#include "tgmath.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'tgmath.h'; consider using 'ctgmath' instead
+// CHECK-FIXES: {{^}}#include <ctgmath>{{$}}
+#include "time.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'time.h'; consider using 'ctime' instead
+// CHECK-FIXES: {{^}}#include <ctime>{{$}}
+#include "uchar.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'uchar.h'; consider using 'cuchar' instead
+// CHECK-FIXES: {{^}}#include <cuchar>{{$}}
+#include "wchar.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wchar.h'; consider using 'cwchar' instead
+// CHECK-FIXES: {{^}}#include <cwchar>{{$}}
+#include "wctype.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: inclusion of deprecated C++ header 'wctype.h'; consider using 'cwctype' instead
+// CHECK-FIXES: {{^}}#include <cwctype>
+
+// Headers that have no effect in C++; remove them
+#include "stdalign.h" // "stdalign.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdalign.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdalign.h"{{$}}
+#include "stdbool.h" // "stdbool.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'stdbool.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "stdbool.h"{{$}}
+#include "iso646.h" // "iso646.h"
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: including 'iso646.h' has no effect in C++; consider removing it
+// CHECK-FIXES: {{^}}// "iso646.h"{{$}}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-ios-base-aliases.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-ios-base-aliases.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-ios-base-aliases.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-deprecated-ios-base-aliases.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,239 @@
+// RUN: %check_clang_tidy %s modernize-deprecated-ios-base-aliases %t
+
+namespace std {
+class ios_base {
+public:
+  typedef int io_state;
+  typedef int open_mode;
+  typedef int seek_dir;
+
+  typedef int streampos;
+  typedef int streamoff;
+};
+
+template <class CharT>
+class basic_ios : public ios_base {
+};
+} // namespace std
+
+// Test function return values (declaration)
+std::ios_base::io_state f_5();
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'std::ios_base::io_state' is deprecated; use 'std::ios_base::iostate' instead [modernize-deprecated-ios-base-aliases]
+// CHECK-FIXES: std::ios_base::iostate f_5();
+
+// Test function parameters.
+void f_6(std::ios_base::open_mode);
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::open_mode' is deprecated
+// CHECK-FIXES: void f_6(std::ios_base::openmode);
+void f_7(const std::ios_base::seek_dir &);
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'std::ios_base::seek_dir' is deprecated
+// CHECK-FIXES: void f_7(const std::ios_base::seekdir &);
+
+// Test on record type fields.
+struct A {
+  std::ios_base::io_state field;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::ios_base::iostate field;
+
+  typedef std::ios_base::io_state int_ptr_type;
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: typedef std::ios_base::iostate int_ptr_type;
+};
+
+struct B : public std::ios_base {
+  io_state a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: iostate a;
+};
+
+struct C : public std::basic_ios<char> {
+  io_state a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: iostate a;
+};
+
+void f_1() {
+  std::ios_base::io_state a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::ios_base::iostate a;
+
+  // Check that spaces aren't modified unnecessarily.
+  std :: ios_base :: io_state b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std :: ios_base :: iostate b;
+
+  // Test construction from a temporary.
+  std::ios_base::io_state c = std::ios_base::io_state{};
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-MESSAGES: :[[@LINE-2]]:46: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::ios_base::iostate c = std::ios_base::iostate{};
+
+  typedef std::ios_base::io_state alias1;
+  // CHECK-MESSAGES: :[[@LINE-1]]:26: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: typedef std::ios_base::iostate alias1;
+  alias1 d(a);
+
+  using alias2 = std::ios_base::io_state;
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: using alias2 = std::ios_base::iostate;
+  alias2 e;
+
+  // Test pointers.
+  std::ios_base::io_state *f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::ios_base::iostate *f;
+
+  // Test 'static' declarations.
+  static std::ios_base::io_state g;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: static std::ios_base::iostate g;
+
+  // Test with cv-qualifiers.
+  const std::ios_base::io_state h(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: const std::ios_base::iostate h(0);
+  volatile std::ios_base::io_state i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: volatile std::ios_base::iostate i;
+  const volatile std::ios_base::io_state j(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: const volatile std::ios_base::iostate j(0);
+
+  // Test auto and initializer-list.
+  auto k = std::ios_base::io_state{};
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: auto k = std::ios_base::iostate{};
+
+  std::ios_base::io_state l{std::ios_base::io_state()};
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-MESSAGES: :[[@LINE-2]]:44: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::ios_base::iostate l{std::ios_base::iostate()};
+
+  // Test temporaries.
+  std::ios_base::io_state();
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::ios_base::iostate();
+
+  // Test inherited type usage
+  std::basic_ios<char>::io_state m;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: std::basic_ios<char>::iostate m;
+
+  std::ios_base::streampos n;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::streampos' is deprecated [modernize-deprecated-ios-base-aliases]
+
+  std::ios_base::streamoff o;
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'std::ios_base::streamoff' is deprecated [modernize-deprecated-ios-base-aliases]
+}
+
+// Test without the nested name specifiers.
+void f_2() {
+  using namespace std;
+
+  ios_base::io_state a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: ios_base::iostate a;
+}
+
+// Test messing-up with macros.
+void f_4() {
+#define MACRO_1 std::ios_base::io_state
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: 'std::ios_base::io_state' is deprecated
+  MACRO_1 a;
+
+#define MACRO_2 io_state
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: 'std::ios_base::io_state' is deprecated
+  std::ios_base::MACRO_2 b;
+
+#define MACRO_3 std::ios_base
+  MACRO_3::io_state c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: 'std::ios_base::io_state' is deprecated
+
+#define MACRO_4(type) type::io_state
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: 'std::ios_base::io_state' is deprecated
+  MACRO_4(std::ios_base) d;
+
+#undef MACRO_1
+#undef MACRO_2
+#undef MACRO_3
+#undef MACRO_4
+}
+
+// Test function return values (definition).
+std::ios_base::io_state f_5()
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'std::ios_base::io_state' is deprecated
+// CHECK-FIXES: std::ios_base::iostate f_5()
+{
+  // Test constructor.
+  return std::ios_base::io_state(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: return std::ios_base::iostate(0);
+}
+
+// Test that other aliases with same name aren't replaced
+struct my_ios_base {
+  typedef int io_state;
+};
+
+namespace ns_1 {
+struct my_ios_base2 {
+  typedef int io_state;
+};
+} // namespace ns_1
+
+void f_8() {
+  my_ios_base::io_state a;
+
+  ns_1::my_ios_base2::io_state b;
+}
+
+// Test templates
+template <typename X>
+void f_9() {
+  typename std::basic_ios<X>::io_state p;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'std::ios_base::io_state' is deprecated
+  typename std::ios_base::io_state q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:27: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: typename std::ios_base::iostate q;
+}
+
+template <typename T>
+void f_10(T arg) {
+  T x(arg);
+}
+
+template <typename T>
+void f_11() {
+  typename T::io_state x{};
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: 'std::ios_base::io_state' is deprecated
+}
+
+template <typename T>
+struct D : std::ios_base {
+  io_state a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: iostate a;
+
+  typename std::basic_ios<T>::io_state b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: 'std::ios_base::io_state' is deprecated
+};
+
+template <typename T>
+struct E {
+  T t;
+};
+
+void f_12() {
+  f_9<char>();
+
+  f_10<std::ios_base::io_state>(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: f_10<std::ios_base::iostate>(0);
+
+  f_11<std::ios_base>();
+  D<char> d;
+
+  E<std::ios_base::io_state> e;
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: 'std::ios_base::io_state' is deprecated
+  // CHECK-FIXES: E<std::ios_base::iostate> e;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-assert-failure.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-assert-failure.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-assert-failure.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-assert-failure.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,18 @@
+// RUN: not clang-tidy %s -checks=-*,modernize-loop-convert --
+
+// Note: this test expects no assert failure happened in clang-tidy.
+
+class LinguisticItem {
+  LinguisticItem *x0;
+  class x1 {
+    bool operator!= ( const x1 &;
+    operator* ( ;
+    LinguisticItem * &operator-> ( ;
+    operator++ (
+  } begin() const;
+  x1 end() const {
+    LinguisticStream x2;
+    for (x1 x3 = x2.begin x3 != x2.end; ++x3)
+      x3->x0
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-basic.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,796 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+namespace Array {
+
+const int N = 6;
+const int NMinusOne = N - 1;
+int Arr[N] = {1, 2, 3, 4, 5, 6};
+const int ConstArr[N] = {1, 2, 3, 4, 5, 6};
+int (*PArr)[N] = &Arr;
+
+void f() {
+  int Sum = 0;
+
+  for (int I = 0; I < N; ++I) {
+    Sum += Arr[I];
+    int K;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: Sum += I;
+  // CHECK-FIXES-NEXT: int K;
+
+  for (int I = 0; I < N; ++I) {
+    printf("Fibonacci number is %d\n", Arr[I]);
+    Sum += Arr[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0; I < N; ++I) {
+    int X = Arr[I];
+    int Y = Arr[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: int X = I;
+  // CHECK-FIXES-NEXT: int Y = I + 2;
+
+  for (int I = 0; I < N; ++I) {
+    int X = N;
+    X = Arr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: int X = N;
+  // CHECK-FIXES-NEXT: X = I;
+
+  for (int I = 0; I < N; ++I) {
+    Arr[I] += 1;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: I += 1;
+
+  for (int I = 0; I < N; ++I) {
+    int X = Arr[I] + 2;
+    Arr[I]++;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: int X = I + 2;
+  // CHECK-FIXES-NEXT: I++;
+
+  for (int I = 0; I < N; ++I) {
+    Arr[I] = 4 + Arr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: I = 4 + I;
+
+  for (int I = 0; I < NMinusOne + 1; ++I) {
+    Sum += Arr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: Sum += I;
+
+  for (int I = 0; I < N; ++I) {
+    printf("Fibonacci number %d has address %p\n", Arr[I], &Arr[I]);
+    Sum += Arr[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number %d has address %p\n", I, &I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  Val Teas[N];
+  for (int I = 0; I < N; ++I) {
+    Teas[I].g();
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Tea : Teas)
+  // CHECK-FIXES-NEXT: Tea.g();
+}
+
+const int *constArray() {
+  for (int I = 0; I < N; ++I) {
+    printf("2 * %d = %d\n", ConstArr[I], ConstArr[I] + ConstArr[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : ConstArr)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I, I + I);
+
+  const NonTriviallyCopyable NonCopy[N]{};
+  for (int I = 0; I < N; ++I) {
+    printf("2 * %d = %d\n", NonCopy[I].X, NonCopy[I].X + NonCopy[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & I : NonCopy)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);
+
+  const TriviallyCopyableButBig Big[N]{};
+  for (int I = 0; I < N; ++I) {
+    printf("2 * %d = %d\n", Big[I].X, Big[I].X + Big[I].X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & I : Big)
+  // CHECK-FIXES-NEXT: printf("2 * %d = %d\n", I.X, I.X + I.X);
+
+  bool Something = false;
+  for (int I = 0; I < N; ++I) {
+    if (Something)
+      return &ConstArr[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const int & I : ConstArr)
+  // CHECK-FIXES-NEXT: if (Something)
+  // CHECK-FIXES-NEXT: return &I;
+}
+
+struct HasArr {
+  int Arr[N];
+  Val ValArr[N];
+  void implicitThis() {
+    for (int I = 0; I < N; ++I) {
+      printf("%d", Arr[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int I : Arr)
+    // CHECK-FIXES-NEXT: printf("%d", I);
+
+    for (int I = 0; I < N; ++I) {
+      printf("%d", ValArr[I].X);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : ValArr)
+    // CHECK-FIXES-NEXT: printf("%d", I.X);
+  }
+
+  void explicitThis() {
+    for (int I = 0; I < N; ++I) {
+      printf("%d", this->Arr[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int I : this->Arr)
+    // CHECK-FIXES-NEXT: printf("%d", I);
+
+    for (int I = 0; I < N; ++I) {
+      printf("%d", this->ValArr[I].X);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : this->ValArr)
+    // CHECK-FIXES-NEXT: printf("%d", I.X);
+  }
+};
+
+struct HasIndirectArr {
+  HasArr HA;
+  void implicitThis() {
+    for (int I = 0; I < N; ++I) {
+      printf("%d", HA.Arr[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int I : HA.Arr)
+    // CHECK-FIXES-NEXT: printf("%d", I);
+
+    for (int I = 0; I < N; ++I) {
+      printf("%d", HA.ValArr[I].X);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : HA.ValArr)
+    // CHECK-FIXES-NEXT: printf("%d", I.X);
+  }
+
+  void explicitThis() {
+    for (int I = 0; I < N; ++I) {
+      printf("%d", this->HA.Arr[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int I : this->HA.Arr)
+    // CHECK-FIXES-NEXT: printf("%d", I);
+
+    for (int I = 0; I < N; ++I) {
+      printf("%d", this->HA.ValArr[I].X);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : this->HA.ValArr)
+    // CHECK-FIXES-NEXT: printf("%d", I.X);
+  }
+};
+
+// Loops whose bounds are value-dependent should not be converted.
+template <int N>
+void dependentExprBound() {
+  for (int I = 0; I < N; ++I)
+    Arr[I] = 0;
+}
+template void dependentExprBound<20>();
+
+void memberFunctionPointer() {
+  Val V;
+  void (Val::*mfpArr[N])(void) = {&Val::g};
+  for (int I = 0; I < N; ++I)
+    (V.*mfpArr[I])();
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : mfpArr)
+  // CHECK-FIXES-NEXT: (V.*I)();
+
+  struct Foo {
+    int (Val::*f)();
+  } Foo[N];
+
+  for (int I = 0; I < N; ++I)
+    int R = (V.*(Foo[I].f))();
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Foo)
+  // CHECK-FIXES-NEXT: int R = (V.*(I.f))();
+
+}
+
+} // namespace Array
+
+namespace Iterator {
+
+void f() {
+  /// begin()/end() - based for loops here:
+  T Tt;
+  for (T::iterator It = Tt.begin(), E = Tt.end(); It != E; ++It) {
+    printf("I found %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : Tt)
+  // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+  T *Pt;
+  for (T::iterator It = Pt->begin(), E = Pt->end(); It != E; ++It) {
+    printf("I found %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : *Pt)
+  // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+  S Ss;
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  S *Ps;
+  for (S::iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & P : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+  for (S::const_iterator It = Ss.cbegin(), E = Ss.cend(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    printf("s has value %d\n", It->X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    It->X = 3;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: It.X = 3;
+
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    (*It).X = 3;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: It.X = 3;
+
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    It->nonConstFun(4, 5);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
+
+  U Uu;
+  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
+    printf("s has value %d\n", It->X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Uu)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Uu)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (U::iterator It = Uu.begin(), E = Uu.end(); It != E; ++It) {
+    Val* a = It.operator->();
+  }
+
+  U::iterator A;
+  for (U::iterator I = Uu.begin(), E = Uu.end(); I != E; ++I)
+    int K = A->X + I->X;
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Uu)
+  // CHECK-FIXES-NEXT: int K = A->X + I.X;
+
+  dependent<int> V;
+  for (dependent<int>::iterator It = V.begin(), E = V.end();
+       It != E; ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+  for (dependent<int>::iterator It(V.begin()), E = V.end();
+       It != E; ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+  doublyDependent<int, int> Intmap;
+  for (doublyDependent<int, int>::iterator It = Intmap.begin(), E = Intmap.end();
+       It != E; ++It) {
+    printf("Intmap[%d] = %d", It->first, It->second);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Intmap)
+  // CHECK-FIXES: printf("Intmap[%d] = %d", It.first, It.second);
+
+  // PtrSet's iterator dereferences by value so auto & can't be used.
+  {
+    PtrSet<int *> Val_int_ptrs;
+    for (PtrSet<int *>::iterator I = Val_int_ptrs.begin(),
+                                 E = Val_int_ptrs.end();
+         I != E; ++I) {
+      (void) *I;
+    }
+    // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto Val_int_ptr : Val_int_ptrs)
+  }
+
+  // This container uses an iterator where the dereference type is a typedef of
+  // a reference type. Make sure non-const auto & is still used. A failure here
+  // means canonical types aren't being tested.
+  {
+    TypedefDerefContainer<int> Int_ptrs;
+    for (TypedefDerefContainer<int>::iterator I = Int_ptrs.begin(),
+                                              E = Int_ptrs.end();
+         I != E; ++I) {
+      (void) *I;
+    }
+    // CHECK-MESSAGES: :[[@LINE-5]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int & Int_ptr : Int_ptrs)
+  }
+
+  {
+    // Iterators returning an rvalue reference should disqualify the loop from
+    // transformation.
+    RValueDerefContainer<int> Container;
+    for (RValueDerefContainer<int>::iterator I = Container.begin(),
+                                             E = Container.end();
+         I != E; ++I) {
+      (void) *I;
+    }
+  }
+
+  dependent<Val *> Dpp;
+  for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
+    printf("%d\n", (**I).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Dpp)
+  // CHECK-FIXES-NEXT: printf("%d\n", (*I).X);
+
+  for (dependent<Val *>::iterator I = Dpp.begin(), E = Dpp.end(); I != E; ++I) {
+    printf("%d\n", (*I)->X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Dpp)
+  // CHECK-FIXES-NEXT: printf("%d\n", I->X);
+}
+
+// Tests to verify the proper use of auto where the init variable type and the
+// initializer type differ or are mostly the same except for const qualifiers.
+void different_type() {
+  // Ss.begin() returns a type 'iterator' which is just a non-const pointer and
+  // differs from const_iterator only on the const qualification.
+  S Ss;
+  for (S::const_iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  S *Ps;
+  for (S::const_iterator It = Ps->begin(), E = Ps->end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+  dependent<int> V;
+  for (dependent<int>::const_iterator It = V.begin(), E = V.end();
+       It != E; ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+  for (dependent<int>::const_iterator It(V.begin()), E = V.end();
+       It != E; ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+}
+
+// Tests to ensure that an implicit 'this' is picked up as the container.
+// If member calls are made to 'this' within the loop, the transform becomes
+// risky as these calls may affect state that affects the loop.
+class C {
+public:
+  typedef MutableVal *iterator;
+  typedef const MutableVal *const_iterator;
+
+  iterator begin();
+  iterator end();
+  const_iterator begin() const;
+  const_iterator end() const;
+
+  void doSomething();
+  void doSomething() const;
+
+  void doLoop() {
+    for (iterator I = begin(), E = end(); I != E; ++I)
+      (void) *I;
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : *this)
+
+    for (iterator I = C::begin(), E = C::end(); I != E; ++I)
+      (void) *I;
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : *this)
+
+    for (iterator I = begin(), E = end(); I != E; ++I) {
+      (void) *I;
+      doSomething();
+    }
+
+    for (iterator I = begin(); I != end(); ++I)
+      (void) *I;
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : *this)
+
+    for (iterator I = begin(); I != end(); ++I) {
+      (void) *I;
+      doSomething();
+    }
+  }
+
+  void doLoop() const {
+    for (const_iterator I = begin(), E = end(); I != E; ++I)
+      (void) *I;
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto I : *this)
+
+    for (const_iterator I = C::begin(), E = C::end(); I != E; ++I)
+      (void) *I;
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto I : *this)
+
+    for (const_iterator I = begin(), E = end(); I != E; ++I) {
+      (void) *I;
+      doSomething();
+    }
+  }
+};
+
+class C2 {
+public:
+  typedef MutableVal *iterator;
+
+  iterator begin() const;
+  iterator end() const;
+
+  void doLoop() {
+    // The implicit 'this' will have an Implicit cast to const C2* wrapped
+    // around it. Make sure the replacement still happens.
+    for (iterator I = begin(), E = end(); I != E; ++I)
+      (void) *I;
+    // CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (auto & I : *this)
+  }
+};
+
+} // namespace Iterator
+
+namespace PseudoArray {
+
+const int N = 6;
+dependent<int> V;
+dependent<int> *Pv;
+const dependent<NonTriviallyCopyable> Constv;
+const dependent<NonTriviallyCopyable> *Pconstv;
+
+transparent<dependent<int>> Cv;
+
+void f() {
+  int Sum = 0;
+  for (int I = 0, E = V.size(); I < E; ++I) {
+    printf("Fibonacci number is %d\n", V[I]);
+    Sum += V[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = V.size(); I < E; ++I) {
+    printf("Fibonacci number is %d\n", V.at(I));
+    Sum += V.at(I) + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0, E = Pv->size(); I < E; ++I) {
+    printf("Fibonacci number is %d\n", Pv->at(I));
+    Sum += Pv->at(I) + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : *Pv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  // This test will fail if size() isn't called repeatedly, since it
+  // returns unsigned int, and 0 is deduced to be signed int.
+  // FIXME: Insert the necessary explicit conversion, or write out the types
+  // explicitly.
+  for (int I = 0; I < Pv->size(); ++I) {
+    printf("Fibonacci number is %d\n", (*Pv).at(I));
+    Sum += (*Pv)[I] + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : *Pv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+
+  for (int I = 0; I < Cv->size(); ++I) {
+    printf("Fibonacci number is %d\n", Cv->at(I));
+    Sum += Cv->at(I) + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : *Cv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2;
+}
+
+// Ensure that 'const auto &' is used with containers of non-trivial types.
+void constness() {
+  int Sum = 0;
+  for (int I = 0, E = Constv.size(); I < E; ++I) {
+    printf("Fibonacci number is %d\n", Constv[I].X);
+    Sum += Constv[I].X + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & I : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+  // CHECK-FIXES-NEXT: Sum += I.X + 2;
+
+  for (int I = 0, E = Constv.size(); I < E; ++I) {
+    printf("Fibonacci number is %d\n", Constv.at(I).X);
+    Sum += Constv.at(I).X + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & I : Constv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+  // CHECK-FIXES-NEXT: Sum += I.X + 2;
+
+  for (int I = 0, E = Pconstv->size(); I < E; ++I) {
+    printf("Fibonacci number is %d\n", Pconstv->at(I).X);
+    Sum += Pconstv->at(I).X + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & I : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+  // CHECK-FIXES-NEXT: Sum += I.X + 2;
+
+  // This test will fail if size() isn't called repeatedly, since it
+  // returns unsigned int, and 0 is deduced to be signed int.
+  // FIXME: Insert the necessary explicit conversion, or write out the types
+  // explicitly.
+  for (int I = 0; I < Pconstv->size(); ++I) {
+    printf("Fibonacci number is %d\n", (*Pconstv).at(I).X);
+    Sum += (*Pconstv)[I].X + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (const auto & I : *Pconstv)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I.X);
+  // CHECK-FIXES-NEXT: Sum += I.X + 2;
+}
+
+void constRef(const dependent<int>& ConstVRef) {
+  int sum = 0;
+  // FIXME: This does not work with size_t (probably due to the implementation
+  // of dependent); make dependent work exactly like a std container type.
+  for (int I = 0; I < ConstVRef.size(); ++I) {
+    sum += ConstVRef[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : ConstVRef)
+  // CHECK-FIXES-NEXT: sum += I;
+
+  for (auto I = ConstVRef.begin(), E = ConstVRef.end(); I != E; ++I) {
+    sum += *I;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : ConstVRef)
+  // CHECK-FIXES-NEXT: sum += I;
+}
+
+// Check for loops that don't mention containers.
+void noContainer() {
+  for (auto I = 0; I < V.size(); ++I) {
+  }
+
+  for (auto I = 0; I < V.size(); ++I)
+    ;
+}
+
+struct NoBeginEnd {
+  unsigned size() const;
+  unsigned& operator[](int);
+  const unsigned& operator[](int) const;
+};
+
+struct NoConstBeginEnd {
+  NoConstBeginEnd();
+  unsigned size() const;
+  unsigned* begin();
+  unsigned* end();
+  unsigned& operator[](int);
+  const unsigned& operator[](int) const;
+};
+
+struct ConstBeginEnd {
+  ConstBeginEnd();
+  unsigned size() const;
+  unsigned* begin() const;
+  unsigned* end() const;
+  unsigned& operator[](int);
+  const unsigned& operator[](int) const;
+};
+
+// Shouldn't transform pseudo-array uses if the container doesn't provide
+// begin() and end() of the right const-ness.
+void NoBeginEndTest() {
+  NoBeginEnd NBE;
+  for (unsigned I = 0, E = NBE.size(); I < E; ++I)
+    printf("%d\n", NBE[I]);
+
+  const NoConstBeginEnd Const_NCBE;
+  for (unsigned I = 0, E = Const_NCBE.size(); I < E; ++I)
+    printf("%d\n", Const_NCBE[I]);
+
+  ConstBeginEnd CBE;
+  for (unsigned I = 0, E = CBE.size(); I < E; ++I)
+    printf("%d\n", CBE[I]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (unsigned int I : CBE)
+  // CHECK-FIXES-NEXT: printf("%d\n", I);
+
+  const ConstBeginEnd Const_CBE;
+  for (unsigned I = 0, E = Const_CBE.size(); I < E; ++I)
+    printf("%d\n", Const_CBE[I]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (unsigned int I : Const_CBE)
+  // CHECK-FIXES-NEXT: printf("%d\n", I);
+}
+
+struct DerefByValue {
+  DerefByValue();
+  struct iter { unsigned operator*(); };
+  unsigned size() const;
+  iter begin();
+  iter end();
+  unsigned operator[](int);
+};
+
+void derefByValueTest() {
+  DerefByValue DBV;
+  for (unsigned I = 0, E = DBV.size(); I < E; ++I) {
+    printf("%d\n", DBV[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (unsigned int I : DBV)
+  // CHECK-FIXES-NEXT: printf("%d\n", I);
+
+  for (unsigned I = 0, E = DBV.size(); I < E; ++I) {
+    auto f = [DBV, I]() {};
+    printf("%d\n", DBV[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (unsigned int I : DBV)
+  // CHECK-FIXES-NEXT: auto f = [DBV, &I]() {};
+  // CHECK-FIXES-NEXT: printf("%d\n", I);
+}
+
+void fundamentalTypesTest() {
+  const int N = 10;
+  bool Bools[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", Bools[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (bool Bool : Bools)
+
+  int Ints[N];
+  unsigned short int Shorts[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", Shorts[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (unsigned short Short : Shorts)
+
+  signed long Longs[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", Longs[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (long Long : Longs)
+
+  long long int LongLongs[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", LongLongs[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (long long LongLong : LongLongs)
+
+  char Chars[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", Chars[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (char Char : Chars)
+
+  wchar_t WChars[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", WChars[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (wchar_t WChar : WChars)
+
+  float Floats[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", Floats[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (float Float : Floats)
+
+  double Doubles[N];
+  for (int i = 0; i < N; ++i)
+    printf("%d", Doubles[i]);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (double Double : Doubles)
+}
+
+} // namespace PseudoArray

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-camelback.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-camelback.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-camelback.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-camelback.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-loop-convert.NamingStyle, value: 'camelBack'}]}" \
+// RUN:   -- -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+const int n = 10;
+int arr[n];
+int nums[n];
+
+void naming() {
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", arr[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+  // CHECK-FIXES: for (int i : arr)
+  // CHECK-FIXES-NEXT: printf("%d\n", i);
+
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", nums[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int num : nums)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
+  int num = 0;
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", nums[i] + num);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int i : nums)
+  // CHECK-FIXES-NEXT: printf("%d\n", i + num);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-const.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-const.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-const.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-const.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,360 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t
+
+struct Str {
+  Str() = default;
+  Str(const Str &) = default;
+  void constMember(int) const;
+  void nonConstMember(int);
+  bool operator<(const Str &str) const;     // const operator.
+  Str &operator=(const Str &str) = default; // non const operator.
+};
+
+// This class is non-trivially copyable because the copy-constructor and copy
+// assignment take non-const references.
+struct ModifiesRightSide {
+  ModifiesRightSide() = default;
+  ModifiesRightSide(ModifiesRightSide &) = default;
+  bool operator<(ModifiesRightSide &) const;
+  ModifiesRightSide &operator=(ModifiesRightSide &) = default;
+};
+
+template <typename T>
+void copyArg(T);
+
+template <typename T>
+void nonConstRefArg(T &);
+
+// If we define this as a template, the type is deduced to "T&",
+// and "const (T&) &" is the same as "T& &", and this collapses to "T&".
+void constRefArg(const Str &);
+void constRefArg(const ModifiesRightSide &);
+void constRefArg(const int &);
+
+void foo();
+
+const int N = 10;
+Str Array[N], OtherStr;
+ModifiesRightSide Right[N], OtherRight;
+int Ints[N], OtherInt;
+
+void memberFunctionsAndOperators() {
+  // Calling const member functions or operator is a const usage.
+  for (int I = 0; I < N; ++I) {
+    Array[I].constMember(0);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+  // CHECK-FIXES: for (auto I : Array)
+  // CHECK-FIXES-NEXT: I.constMember(0);
+
+  for (int I = 0; I < N; ++I) {
+    if (Array[I] < OtherStr)
+      foo();
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto I : Array)
+  // CHECK-FIXES-NEXT: if (I < OtherStr)
+  for (int I = 0; I < N; ++I) {
+    if (Right[I] < OtherRight)
+      foo();
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (const auto & I : Right)
+  // CHECK-FIXES-NEXT: if (I < OtherRight)
+
+  // Calling non-const member functions is not.
+  for (int I = 0; I < N; ++I) {
+    Array[I].nonConstMember(0);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Array)
+  // CHECK-FIXES-NEXT: I.nonConstMember(0);
+
+  for (int I = 0; I < N; ++I) {
+    Array[I] = OtherStr;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Array)
+  // CHECK-FIXES-NEXT: I = OtherStr;
+
+  for (int I = 0; I < N; ++I) {
+    Right[I] = OtherRight;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Right)
+  // CHECK-FIXES-NEXT: I = OtherRight;
+}
+
+void usedAsParameterToFunctionOrOperator() {
+  // Copying is OK, as long as the copy constructor takes a const-reference.
+  for (int I = 0; I < N; ++I) {
+    copyArg(Array[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto I : Array)
+  // CHECK-FIXES-NEXT: copyArg(I);
+
+  for (int I = 0; I < N; ++I) {
+    copyArg(Right[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Right)
+  // CHECK-FIXES-NEXT: copyArg(I);
+
+  // Using as a const reference argument is allowed.
+  for (int I = 0; I < N; ++I) {
+    constRefArg(Array[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto I : Array)
+  // CHECK-FIXES-NEXT: constRefArg(I);
+
+  for (int I = 0; I < N; ++I) {
+    if (OtherStr < Array[I])
+      foo();
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto I : Array)
+  // CHECK-FIXES-NEXT: if (OtherStr < I)
+
+  for (int I = 0; I < N; ++I) {
+    constRefArg(Right[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (const auto & I : Right)
+  // CHECK-FIXES-NEXT: constRefArg(I);
+
+  // Using as a non-const reference is not.
+  for (int I = 0; I < N; ++I) {
+    nonConstRefArg(Array[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Array)
+  // CHECK-FIXES-NEXT: nonConstRefArg(I);
+  for (int I = 0; I < N; ++I) {
+    nonConstRefArg(Right[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Right)
+  // CHECK-FIXES-NEXT: nonConstRefArg(I);
+  for (int I = 0; I < N; ++I) {
+    if (OtherRight < Right[I])
+      foo();
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Right)
+  // CHECK-FIXES-NEXT: if (OtherRight < I)
+}
+
+void primitiveTypes() {
+  // As argument to a function.
+  for (int I = 0; I < N; ++I) {
+    copyArg(Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: copyArg(Int);
+  for (int I = 0; I < N; ++I) {
+    constRefArg(Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: constRefArg(Int);
+  for (int I = 0; I < N; ++I) {
+    nonConstRefArg(Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int & Int : Ints)
+  // CHECK-FIXES-NEXT: nonConstRefArg(Int);
+
+  // Builtin operators.
+  // Comparisons.
+  for (int I = 0; I < N; ++I) {
+    if (Ints[I] < N)
+      foo();
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: if (Int < N)
+
+  for (int I = 0; I < N; ++I) {
+    if (N == Ints[I])
+      foo();
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: if (N == Int)
+
+  // Assignment.
+  for (int I = 0; I < N; ++I) {
+    Ints[I] = OtherInt;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int & Int : Ints)
+  // CHECK-FIXES-NEXT: Int = OtherInt;
+
+  for (int I = 0; I < N; ++I) {
+    OtherInt = Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: OtherInt = Int;
+
+  for (int I = 0; I < N; ++I) {
+    OtherInt = Ints[I] = OtherInt;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int & Int : Ints)
+  // CHECK-FIXES-NEXT: OtherInt = Int = OtherInt;
+
+  // Arithmetic operations.
+  for (int I = 0; I < N; ++I) {
+    OtherInt += Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: OtherInt += Int;
+
+  for (int I = 0; I < N; ++I) {
+    Ints[I] += Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int & Int : Ints)
+  // CHECK-FIXES-NEXT: Int += Int;
+
+  for (int I = 0; I < N; ++I) {
+    int Res = 5 * (Ints[I] + 1) - Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: int Res = 5 * (Int + 1) - Int;
+}
+
+void takingReferences() {
+  // We do it twice to prevent the check from thinking that they are aliases.
+
+  // Class type.
+  for (int I = 0; I < N; ++I) {
+    Str &J = Array[I];
+    Str &K = Array[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & I : Array)
+  // CHECK-FIXES-NEXT: Str &J = I;
+  // CHECK-FIXES-NEXT: Str &K = I;
+  for (int I = 0; I < N; ++I) {
+    const Str &J = Array[I];
+    const Str &K = Array[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto I : Array)
+  // CHECK-FIXES-NEXT: const Str &J = I;
+  // CHECK-FIXES-NEXT: const Str &K = I;
+
+  // Primitive type.
+  for (int I = 0; I < N; ++I) {
+    int &J = Ints[I];
+    int &K = Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int & Int : Ints)
+  // CHECK-FIXES-NEXT: int &J = Int;
+  // CHECK-FIXES-NEXT: int &K = Int;
+  for (int I = 0; I < N; ++I) {
+    const int &J = Ints[I];
+    const int &K = Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: const int &J = Int;
+  // CHECK-FIXES-NEXT: const int &K = Int;
+
+  // Aliases.
+  for (int I = 0; I < N; ++I) {
+    const Str &J = Array[I];
+    (void)J;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto J : Array)
+  for (int I = 0; I < N; ++I) {
+    Str &J = Array[I];
+    (void)J;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto & J : Array)
+
+  for (int I = 0; I < N; ++I) {
+    const int &J = Ints[I];
+    (void)J;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int J : Ints)
+
+  for (int I = 0; I < N; ++I) {
+    int &J = Ints[I];
+    (void)J;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int & J : Ints)
+}
+
+template <class T>
+struct vector {
+  unsigned size() const;
+  const T &operator[](int) const;
+  T &operator[](int);
+  T *begin();
+  T *end();
+  const T *begin() const;
+  const T *end() const;
+};
+
+// If the elements are already constant, we won't do any ImplicitCast to const.
+void testContainerOfConstIents() {
+  const int Ints[N]{};
+  for (int I = 0; I < N; ++I) {
+    OtherInt -= Ints[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (int Int : Ints)
+
+  vector<const Str> Strs;
+  for (int I = 0; I < Strs.size(); ++I) {
+    Strs[I].constMember(0);
+    constRefArg(Strs[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop
+  // CHECK-FIXES: for (auto Str : Strs)
+}
+
+// When we are inside a const-qualified member functions, all the data members
+// are implicitly set as const. As before, there won't be any ImplicitCast to
+// const in their usages.
+class TestInsideConstFunction {
+  const static int N = 10;
+  int Ints[N];
+  Str Array[N];
+  vector<int> V;
+
+  void foo() const {
+    for (int I = 0; I < N; ++I) {
+      if (Ints[I])
+        copyArg(Ints[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+    // CHECK-FIXES: for (int Int : Ints)
+
+    for (int I = 0; I < N; ++I) {
+      Array[I].constMember(0);
+      constRefArg(Array[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+    // CHECK-FIXES: for (auto I : Array)
+
+    for (int I = 0; I < V.size(); ++I) {
+      if (V[I])
+        copyArg(V[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop
+    // CHECK-FIXES: for (int I : V)
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-extra.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-extra.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-extra.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-extra.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,1085 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+namespace Dependency {
+
+void f() {
+  const int N = 6;
+  const int M = 8;
+  int Arr[N][M];
+
+  for (int I = 0; I < N; ++I) {
+    int A = 0;
+    int B = Arr[I][A];
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Arr)
+  // CHECK-FIXES-NEXT: int A = 0;
+  // CHECK-FIXES-NEXT: int B = I[A];
+
+  for (int J = 0; J < M; ++J) {
+    int A = 0;
+    int B = Arr[A][J];
+  }
+}
+
+} // namespace Dependency
+
+namespace NamingAlias {
+
+const int N = 10;
+
+Val Arr[N];
+dependent<Val> V;
+dependent<Val> *Pv;
+Val &func(Val &);
+void sideEffect(int);
+
+void aliasing() {
+  // If the loop container is only used for a declaration of a temporary
+  // variable to hold each element, we can name the new variable for the
+  // converted range-based loop as the temporary variable's name.
+
+  // In the following case, "T" is used as a temporary variable to hold each
+  // element, and thus we consider the name "T" aliased to the loop.
+  // The extra blank braces are left as a placeholder for after the variable
+  // declaration is deleted.
+  for (int I = 0; I < N; ++I) {
+    Val &T = Arr[I];
+    {}
+    int Y = T.X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & T : Arr)
+  // CHECK-FIXES-NOT: Val &{{[a-z_]+}} =
+  // CHECK-FIXES-NEXT: {}
+  // CHECK-FIXES-NEXT: int Y = T.X;
+
+  // The container was not only used to initialize a temporary loop variable for
+  // the container's elements, so we do not alias the new loop variable.
+  for (int I = 0; I < N; ++I) {
+    Val &T = Arr[I];
+    int Y = T.X;
+    int Z = Arr[I].X + T.X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Arr)
+  // CHECK-FIXES-NEXT: Val &T = I;
+  // CHECK-FIXES-NEXT: int Y = T.X;
+  // CHECK-FIXES-NEXT: int Z = I.X + T.X;
+
+  for (int I = 0; I < N; ++I) {
+    Val T = Arr[I];
+    int Y = T.X;
+    int Z = Arr[I].X + T.X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Arr)
+  // CHECK-FIXES-NEXT: Val T = I;
+  // CHECK-FIXES-NEXT: int Y = T.X;
+  // CHECK-FIXES-NEXT: int Z = I.X + T.X;
+
+  // The same for pseudo-arrays like std::vector<T> (or here dependent<Val>)
+  // which provide a subscript operator[].
+  for (int I = 0; I < V.size(); ++I) {
+    Val &T = V[I];
+    {}
+    int Y = T.X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & T : V)
+  // CHECK-FIXES-NEXT: {}
+  // CHECK-FIXES-NEXT: int Y = T.X;
+
+  // The same with a call to at()
+  for (int I = 0; I < Pv->size(); ++I) {
+    Val &T = Pv->at(I);
+    {}
+    int Y = T.X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & T : *Pv)
+  // CHECK-FIXES-NEXT: {}
+  // CHECK-FIXES-NEXT: int Y = T.X;
+
+  for (int I = 0; I < N; ++I) {
+    Val &T = func(Arr[I]);
+    int Y = T.X;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Arr)
+  // CHECK-FIXES-NEXT: Val &T = func(I);
+  // CHECK-FIXES-NEXT: int Y = T.X;
+
+  int IntArr[N];
+  for (unsigned I = 0; I < N; ++I) {
+    if (int Alias = IntArr[I]) {
+      sideEffect(Alias);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Alias : IntArr)
+  // CHECK-FIXES-NEXT: if (Alias)
+
+  for (unsigned I = 0; I < N; ++I) {
+    while (int Alias = IntArr[I]) {
+      sideEffect(Alias);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Alias : IntArr)
+  // CHECK-FIXES-NEXT: while (Alias)
+
+  for (unsigned I = 0; I < N; ++I) {
+    switch (int Alias = IntArr[I]) {
+    default:
+      sideEffect(Alias);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Alias : IntArr)
+  // CHECK-FIXES-NEXT: switch (Alias)
+
+  for (unsigned I = 0; I < N; ++I) {
+    for (int Alias = IntArr[I]; Alias < N; ++Alias) {
+      sideEffect(Alias);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Alias : IntArr)
+  // CHECK-FIXES-NEXT: for (; Alias < N; ++Alias)
+
+  for (unsigned I = 0; I < N; ++I) {
+    for (unsigned J = 0; int Alias = IntArr[I]; ++J) {
+      sideEffect(Alias);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Alias : IntArr)
+  // CHECK-FIXES-NEXT: for (unsigned J = 0; Alias; ++J)
+
+  struct IntRef { IntRef(); IntRef(const int& i); operator int*(); };
+  for (int I = 0; I < N; ++I) {
+    IntRef Int(IntArr[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : IntArr)
+  // CHECK-FIXES-NEXT: IntRef Int(I);
+
+  int *PtrArr[N];
+  for (unsigned I = 0; I < N; ++I) {
+    const int* const P = PtrArr[I];
+    printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : PtrArr)
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+  IntRef Refs[N];
+  for (unsigned I = 0; I < N; ++I) {
+    int *P = Refs[I];
+    printf("%d\n", *P);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Ref : Refs)
+  // CHECK-FIXES-NEXT: int *P = Ref;
+  // CHECK-FIXES-NEXT: printf("%d\n", *P);
+
+  // Ensure that removing the alias doesn't leave empty lines behind.
+  for (int I = 0; I < N; ++I) {
+    auto &X = IntArr[I];
+    X = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & X : IntArr) {
+  // CHECK-FIXES-NEXT: {{^    X = 0;$}}
+  // CHECK-FIXES-NEXT: {{^  }$}}
+}
+
+void refs_and_vals() {
+  // The following tests check that the transform correctly preserves the
+  // reference or value qualifiers of the aliased variable. That is, if the
+  // variable was declared as a value, the loop variable will be declared as a
+  // value and vice versa for references.
+
+  S Ss;
+  const S S_const = Ss;
+
+  for (S::const_iterator It = S_const.begin(); It != S_const.end(); ++It) {
+    MutableVal Alias = *It;
+    {}
+    Alias.X = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Alias : S_const)
+  // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
+  // CHECK-FIXES-NEXT: {}
+  // CHECK-FIXES-NEXT: Alias.X = 0;
+
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    MutableVal Alias = *It;
+    {}
+    Alias.X = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Alias : Ss)
+  // CHECK-FIXES-NOT: MutableVal {{[a-z_]+}} =
+  // CHECK-FIXES-NEXT: {}
+  // CHECK-FIXES-NEXT: Alias.X = 0;
+
+  for (S::iterator It = Ss.begin(), E = Ss.end(); It != E; ++It) {
+    MutableVal &Alias = *It;
+    {}
+    Alias.X = 0;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Alias : Ss)
+  // CHECK-FIXES-NOT: MutableVal &{{[a-z_]+}} =
+  // CHECK-FIXES-NEXT: {}
+  // CHECK-FIXES-NEXT: Alias.X = 0;
+
+  dependent<int> Dep, Other;
+  for (dependent<int>::iterator It = Dep.begin(), E = Dep.end(); It != E; ++It) {
+    printf("%d\n", *It);
+    const int& Idx = Other[0];
+    unsigned Othersize = Other.size();
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : Dep)
+  // CHECK-FIXES-NEXT: printf("%d\n", It);
+  // CHECK-FIXES-NEXT: const int& Idx = Other[0];
+  // CHECK-FIXES-NEXT: unsigned Othersize = Other.size();
+
+  for (int i = 0; i <  Other.size(); ++i) {
+    Other.at(i);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & i : Other)
+  // CHECK-FIXES: i;
+
+  for (int I = 0, E = Dep.size(); I != E; ++I) {
+    int Idx = Other.at(I);
+    Other.at(I, I);  // Should not trigger assert failure.
+  }
+}
+
+struct MemberNaming {
+  const static int N = 10;
+  int Ints[N], Ints_[N];
+  dependent<int> DInts;
+  void loops() {
+    for (int I = 0; I < N; ++I) {
+      printf("%d\n", Ints[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int Int : Ints)
+    // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+    for (int I = 0; I < N; ++I) {
+      printf("%d\n", Ints_[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int Int : Ints_)
+    // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+    for (int I = 0; I < DInts.size(); ++I) {
+      printf("%d\n", DInts[I]);
+    }
+    // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: use range-based for loop instead
+    // CHECK-FIXES: for (int DInt : DInts)
+    // CHECK-FIXES-NEXT: printf("%d\n", DInt);
+  }
+
+  void outOfLine();
+};
+void MemberNaming::outOfLine() {
+  for (int I = 0; I < N; ++I) {
+    printf("%d\n", Ints[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+
+  for (int I = 0; I < N; ++I) {
+    printf("%d\n", Ints_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Int : Ints_)
+  // CHECK-FIXES-NEXT: printf("%d\n", Int);
+}
+
+} // namespace NamingAlias
+
+namespace NamingConlict {
+
+#define MAX(a, b) (a > b) ? a : b
+#define DEF 5
+
+const int N = 10;
+int Nums[N];
+int Sum = 0;
+
+namespace ns {
+struct St {
+  int X;
+};
+}
+
+void sameNames() {
+  int Num = 0;
+  for (int I = 0; I < N; ++I) {
+    printf("Fibonacci number is %d\n", Nums[I]);
+    Sum += Nums[I] + 2 + Num;
+    (void)Nums[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Nums)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2 + Num;
+  // CHECK-FIXES-NEXT: (void)I;
+
+  int Elem = 0;
+  for (int I = 0; I < N; ++I) {
+    printf("Fibonacci number is %d\n", Nums[I]);
+    Sum += Nums[I] + 2 + Num + Elem;
+    (void)Nums[I];
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Nums)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", I);
+  // CHECK-FIXES-NEXT: Sum += I + 2 + Num + Elem;
+  // CHECK-FIXES-NEXT: (void)I;
+}
+
+void oldIndexConflict() {
+  for (int Num = 0; Num < N; ++Num) {
+    printf("Num: %d\n", Nums[Num]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int Num : Nums)
+  // CHECK-FIXES-NEXT: printf("Num: %d\n", Num);
+
+  S Things;
+  for (S::iterator Thing = Things.begin(), End = Things.end(); Thing != End; ++Thing) {
+    printf("Thing: %d %d\n", Thing->X, (*Thing).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Thing : Things)
+  // CHECK-FIXES-NEXT: printf("Thing: %d %d\n", Thing.X, Thing.X);
+}
+
+void macroConflict() {
+  S MAXs;
+  for (S::iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+    printf("Max of 3 and 5: %d\n", MAX(3, 5));
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : MAXs)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+  // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
+
+  for (S::const_iterator It = MAXs.begin(), E = MAXs.end(); It != E; ++It) {
+    printf("s has value %d\n", (*It).X);
+    printf("Max of 3 and 5: %d\n", MAX(3, 5));
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : MAXs)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+  // CHECK-FIXES-NEXT: printf("Max of 3 and 5: %d\n", MAX(3, 5));
+
+  T DEFs;
+  for (T::iterator It = DEFs.begin(), E = DEFs.end(); It != E; ++It) {
+    if (*It == DEF) {
+      printf("I found %d\n", *It);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : DEFs)
+  // CHECK-FIXES-NEXT: if (It == DEF)
+  // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+}
+
+void keywordConflict() {
+  T ints;
+  for (T::iterator It = ints.begin(), E = ints.end(); It != E; ++It) {
+    *It = 5;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : ints)
+  // CHECK-FIXES-NEXT: It = 5;
+
+  U __FUNCTION__s;
+  for (U::iterator It = __FUNCTION__s.begin(), E = __FUNCTION__s.end();
+       It != E; ++It) {
+    int __FUNCTION__s_It = (*It).X + 2;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : __FUNCTION__s)
+  // CHECK-FIXES-NEXT: int __FUNCTION__s_It = It.X + 2;
+}
+
+void typeConflict() {
+  T Vals;
+  // Using the name "Val", although it is the name of an existing struct, is
+  // safe in this loop since it will only exist within this scope.
+  for (T::iterator It = Vals.begin(), E = Vals.end(); It != E; ++It)
+    (void) *It;
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & Val : Vals)
+
+  // We cannot use the name "Val" in this loop since there is a reference to
+  // it in the body of the loop.
+  for (T::iterator It = Vals.begin(), E = Vals.end(); It != E; ++It) {
+    *It = sizeof(Val);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : Vals)
+  // CHECK-FIXES-NEXT: It = sizeof(Val);
+
+  typedef struct Val TD;
+  U TDs;
+  // Naming the variable "TD" within this loop is safe because the typedef
+  // was never used within the loop.
+  for (U::iterator It = TDs.begin(), E = TDs.end(); It != E; ++It)
+    (void) *It;
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & TD : TDs)
+
+  // "TD" cannot be used in this loop since the typedef is being used.
+  for (U::iterator It = TDs.begin(), E = TDs.end(); It != E; ++It) {
+    TD V;
+    V.X = 5;
+    (void) *It;
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : TDs)
+  // CHECK-FIXES-NEXT: TD V;
+  // CHECK-FIXES-NEXT: V.X = 5;
+
+  using ns::St;
+  T Sts;
+  for (T::iterator It = Sts.begin(), E = Sts.end(); It != E; ++It) {
+    *It = sizeof(St);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : Sts)
+  // CHECK-FIXES-NEXT: It = sizeof(St);
+}
+
+} // namespace NamingConflict
+
+namespace FreeBeginEnd {
+
+// FIXME: Loop Convert should detect free begin()/end() functions.
+
+struct MyArray {
+  unsigned size();
+};
+
+template <typename T>
+struct MyContainer {
+};
+
+int *begin(const MyArray &Arr);
+int *end(const MyArray &Arr);
+
+template <typename T>
+T *begin(const MyContainer<T> &C);
+template <typename T>
+T *end(const MyContainer<T> &C);
+
+// The Loop Convert Transform doesn't detect free functions begin()/end() and
+// so fails to transform these cases which it should.
+void f() {
+  MyArray Arr;
+  for (unsigned I = 0, E = Arr.size(); I < E; ++I) {
+  }
+
+  MyContainer<int> C;
+  for (int *I = begin(C), *E = end(C); I != E; ++I) {
+  }
+}
+
+} // namespace FreeBeginEnd
+
+namespace Nesting {
+
+void g(S::iterator It);
+void const_g(S::const_iterator It);
+class Foo {
+ public:
+  void g(S::iterator It);
+  void const_g(S::const_iterator It);
+};
+
+void f() {
+  const int N = 10;
+  const int M = 15;
+  Val Arr[N];
+  for (int I = 0; I < N; ++I) {
+    for (int J = 0; J < N; ++J) {
+      int K = Arr[I].X + Arr[J].X;
+      // The repeat is there to allow FileCheck to make sure the two variable
+      // names aren't the same.
+      int L = Arr[I].X + Arr[J].X;
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-8]]:3: warning: use range-based for loop instead
+  // CHECK-MESSAGES: :[[@LINE-8]]:5: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Arr)
+  // CHECK-FIXES-NEXT: for (auto & J : Arr)
+  // CHECK-FIXES-NEXT: int K = I.X + J.X;
+  // CHECK-FIXES-NOT: int L = I.X + I.X;
+
+  // The inner loop is also convertible, but doesn't need to be converted
+  // immediately. FIXME: update this test when that changes.
+  Val Nest[N][M];
+  for (int I = 0; I < N; ++I) {
+    for (int J = 0; J < M; ++J) {
+      printf("Got item %d", Nest[I][J].X);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Nest)
+  // CHECK-FIXES-NEXT: for (int J = 0; J < M; ++J)
+  // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
+
+  // Note that the order of M and N are switched for this test.
+  for (int J = 0; J < M; ++J) {
+    for (int I = 0; I < N; ++I) {
+      printf("Got item %d", Nest[I][J].X);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:5: warning: use range-based for loop instead
+  // CHECK-FIXES-NOT: for (auto & {{[a-zA-Z_]+}} : Nest[I])
+  // CHECK-FIXES: for (int J = 0; J < M; ++J)
+  // CHECK-FIXES-NEXT: for (auto & I : Nest)
+  // CHECK-FIXES-NEXT: printf("Got item %d", I[J].X);
+
+  // The inner loop is also convertible.
+  Nested<T> NestT;
+  for (Nested<T>::iterator I = NestT.begin(), E = NestT.end(); I != E; ++I) {
+    for (T::iterator TI = (*I).begin(), TE = (*I).end(); TI != TE; ++TI) {
+      printf("%d", *TI);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : NestT)
+  // CHECK-FIXES-NEXT: for (T::iterator TI = I.begin(), TE = I.end(); TI != TE; ++TI)
+  // CHECK-FIXES-NEXT: printf("%d", *TI);
+
+  // The inner loop is also convertible.
+  Nested<S> NestS;
+  for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+    for (S::const_iterator SI = (*I).begin(), SE = (*I).end(); SI != SE; ++SI) {
+      printf("%d", *SI);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto I : NestS)
+  // CHECK-FIXES-NEXT: for (S::const_iterator SI = I.begin(), SE = I.end(); SI != SE; ++SI)
+  // CHECK-FIXES-NEXT: printf("%d", *SI);
+
+  for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+    const S &Ss = *I;
+    for (S::const_iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+      printf("%d", *SI);
+      const_g(SI);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Ss : NestS)
+
+  for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+    S &Ss = *I;
+    for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+      printf("%d", *SI);
+      g(SI);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Ss : NestS)
+
+  Foo foo;
+  for (Nested<S>::const_iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+    const S &Ss = *I;
+    for (S::const_iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+      printf("%d", *SI);
+      foo.const_g(SI);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto Ss : NestS)
+
+  for (Nested<S>::iterator I = NestS.begin(), E = NestS.end(); I != E; ++I) {
+    S &Ss = *I;
+    for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI) {
+      printf("%d", *SI);
+      foo.g(SI);
+    }
+  }
+  // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & Ss : NestS)
+
+}
+
+} // namespace Nesting
+
+namespace SingleIterator {
+
+void complexContainer() {
+  X Exes[5];
+  int Index = 0;
+
+  for (S::iterator I = Exes[Index].getS().begin(), E = Exes[Index].getS().end(); I != E; ++I) {
+    MutableVal K = *I;
+    MutableVal J = *I;
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Exes[Index].getS())
+  // CHECK-FIXES-NEXT: MutableVal K = I;
+  // CHECK-FIXES-NEXT: MutableVal J = I;
+}
+
+void f() {
+  /// begin()/end() - based for loops here:
+  T Tt;
+  for (T::iterator It = Tt.begin(); It != Tt.end(); ++It) {
+    printf("I found %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : Tt)
+  // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+  T *Pt;
+  for (T::iterator It = Pt->begin(); It != Pt->end(); ++It) {
+    printf("I found %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : *Pt)
+  // CHECK-FIXES-NEXT: printf("I found %d\n", It);
+
+  S Ss;
+  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  S *Ps;
+  for (S::iterator It = Ps->begin(); It != Ps->end(); ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & P : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+    printf("s has value %d\n", It->X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+    It->X = 3;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: It.X = 3;
+
+  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+    (*It).X = 3;
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: It.X = 3;
+
+  for (S::iterator It = Ss.begin(); It != Ss.end(); ++It) {
+    It->nonConstFun(4, 5);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Ss)
+  // CHECK-FIXES-NEXT: It.nonConstFun(4, 5);
+
+  U Uu;
+  for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
+    printf("s has value %d\n", It->X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Uu)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  for (U::iterator It = Uu.begin(); It != Uu.end(); ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : Uu)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  U::iterator A;
+  for (U::iterator I = Uu.begin(); I != Uu.end(); ++I)
+    int K = A->X + I->X;
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & I : Uu)
+  // CHECK-FIXES-NEXT: int K = A->X + I.X;
+
+  dependent<int> V;
+  for (dependent<int>::iterator It = V.begin();
+       It != V.end(); ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+  for (dependent<int>::iterator It(V.begin());
+       It != V.end(); ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+  doublyDependent<int, int> intmap;
+  for (doublyDependent<int, int>::iterator It = intmap.begin();
+       It != intmap.end(); ++It) {
+    printf("intmap[%d] = %d", It->first, It->second);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & It : intmap)
+  // CHECK-FIXES-NEXT: printf("intmap[%d] = %d", It.first, It.second);
+}
+
+void different_type() {
+  // Tests to verify the proper use of auto where the init variable type and the
+  // initializer type differ or are mostly the same except for const qualifiers.
+
+  // Ss.begin() returns a type 'iterator' which is just a non-const pointer and
+  // differs from const_iterator only on the const qualification.
+  S Ss;
+  for (S::const_iterator It = Ss.begin(); It != Ss.end(); ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto It : Ss)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", It.X);
+
+  S *Ps;
+  for (S::const_iterator It = Ps->begin(); It != Ps->end(); ++It) {
+    printf("s has value %d\n", (*It).X);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto P : *Ps)
+  // CHECK-FIXES-NEXT: printf("s has value %d\n", P.X);
+
+  dependent<int> V;
+  for (dependent<int>::const_iterator It = V.begin(); It != V.end(); ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+
+  for (dependent<int>::const_iterator It(V.begin()); It != V.end(); ++It) {
+    printf("Fibonacci number is %d\n", *It);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int It : V)
+  // CHECK-FIXES-NEXT: printf("Fibonacci number is %d\n", It);
+}
+
+} // namespace SingleIterator
+
+
+namespace Macros {
+
+#define TWO_PARAM(x, y) if (x == y) {}
+#define THREE_PARAM(x, y, z) if (x == y) {z;}
+
+const int N = 10;
+int Arr[N];
+
+void messing_with_macros() {
+  for (int I = 0; I < N; ++I) {
+    printf("Value: %d\n", Arr[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT:  printf("Value: %d\n", I);
+
+  for (int I = 0; I < N; ++I) {
+    printf("Value: %d\n", CONT Arr[I]);
+  }
+
+  // Multiple macro arguments.
+  for (int I = 0; I < N; ++I) {
+    TWO_PARAM(Arr[I], Arr[I]);
+    THREE_PARAM(Arr[I], Arr[I], Arr[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: TWO_PARAM(I, I);
+  // CHECK-FIXES-NEXT: THREE_PARAM(I, I, I);
+}
+
+} // namespace Macros
+
+namespace Templates {
+
+template <class Container>
+void set_union(Container &container) {
+  for (typename Container::const_iterator SI = container.begin(),
+       SE = container.end(); SI != SE; ++SI) {
+    (void) *SI;
+  }
+
+  S Ss;
+  for (S::iterator SI = Ss.begin(), SE = Ss.end(); SI != SE; ++SI)
+    (void) *SI;
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (auto & SI : Ss)
+}
+
+void template_instantiation() {
+  S Ss;
+  set_union(Ss);
+}
+
+} // namespace Templates
+
+namespace Lambdas {
+
+void capturesIndex() {
+  const int N = 10;
+  int Arr[N];
+  // FIXME: the next four loops could be convertible, if the capture list is
+  // also changed.
+
+  for (int I = 0; I < N; ++I)
+    auto F1 = [Arr, I]() { int R1 = Arr[I] + 1; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto F1 = [Arr, &I]() { int R1 = I + 1; };
+
+  for (int I = 0; I < N; ++I)
+    auto F2 = [Arr, &I]() { int R2 = Arr[I] + 3; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto F2 = [Arr, &I]() { int R2 = I + 3; };
+
+  // FIXME: alias don't work if the index is captured.
+  // Alias declared inside lambda (by value).
+  for (int I = 0; I < N; ++I)
+    auto F3 = [&Arr, I]() { int R3 = Arr[I]; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto F3 = [&Arr, &I]() { int R3 = I; };
+
+
+  for (int I = 0; I < N; ++I)
+    auto F4 = [&Arr, &I]() { int R4 = Arr[I]; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto F4 = [&Arr, &I]() { int R4 = I; };
+
+  // Alias declared inside lambda (by reference).
+  for (int I = 0; I < N; ++I)
+    auto F5 = [&Arr, I]() { int &R5 = Arr[I]; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: auto F5 = [&Arr, &I]() { int &R5 = I; };
+
+
+  for (int I = 0; I < N; ++I)
+    auto F6 = [&Arr, &I]() { int &R6 = Arr[I]; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Arr)
+  // CHECK-FIXES-NEXT: auto F6 = [&Arr, &I]() { int &R6 = I; };
+
+  for (int I = 0; I < N; ++I) {
+    auto F = [Arr, I](int k) {
+      printf("%d\n", Arr[I] + k);
+    };
+    F(Arr[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto F = [Arr, &I](int k)
+  // CHECK-FIXES-NEXT: printf("%d\n", I + k);
+  // CHECK-FIXES: F(I);
+}
+
+void implicitCapture() {
+  const int N = 10;
+  int Arr[N];
+  // Index is used, not convertible.
+  for (int I = 0; I < N; ++I) {
+    auto G1 = [&]() {
+      int R = Arr[I];
+      int J = I;
+    };
+  }
+
+  for (int I = 0; I < N; ++I) {
+    auto G2 = [=]() {
+      int R = Arr[I];
+      int J = I;
+    };
+  }
+
+  // Convertible.
+  for (int I = 0; I < N; ++I) {
+    auto G3 = [&]() {
+      int R3 = Arr[I];
+      int J3 = Arr[I] + R3;
+    };
+  }
+  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto G3 = [&]()
+  // CHECK-FIXES-NEXT: int R3 = I;
+  // CHECK-FIXES-NEXT: int J3 = I + R3;
+
+  for (int I = 0; I < N; ++I) {
+    auto G4 = [=]() {
+      int R4 = Arr[I] + 5;
+    };
+  }
+  // CHECK-MESSAGES: :[[@LINE-5]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto G4 = [=]()
+  // CHECK-FIXES-NEXT: int R4 = I + 5;
+
+  // Alias by value.
+  for (int I = 0; I < N; ++I) {
+    auto G5 = [&]() {
+      int R5 = Arr[I];
+      int J5 = 8 + R5;
+    };
+  }
+  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int R5 : Arr)
+  // CHECK-FIXES-NEXT: auto G5 = [&]()
+  // CHECK-FIXES-NEXT: int J5 = 8 + R5;
+
+  // Alias by reference.
+  for (int I = 0; I < N; ++I) {
+    auto G6 = [&]() {
+      int &R6 = Arr[I];
+      int J6 = -1 + R6;
+    };
+  }
+  // CHECK-MESSAGES: :[[@LINE-6]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & R6 : Arr)
+  // CHECK-FIXES-NEXT: auto G6 = [&]()
+  // CHECK-FIXES-NEXT: int J6 = -1 + R6;
+}
+
+void iterators() {
+  dependent<int> Dep;
+
+  for (dependent<int>::iterator I = Dep.begin(), E = Dep.end(); I != E; ++I)
+    auto H1 = [&I]() { int R = *I; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Dep)
+  // CHECK-FIXES-NEXT: auto H1 = [&I]() { int R = I; };
+
+  for (dependent<int>::iterator I = Dep.begin(), E = Dep.end(); I != E; ++I)
+    auto H2 = [&]() { int R = *I + 2; };
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int & I : Dep)
+  // CHECK-FIXES-NEXT: auto H2 = [&]() { int R = I + 2; };
+
+  for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
+       I != E; ++I)
+    auto H3 = [I]() { int R = *I; };
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Dep)
+  // CHECK-FIXES-NEXT: auto H3 = [&I]() { int R = I; };
+
+  for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
+       I != E; ++I)
+    auto H4 = [&]() { int R = *I + 1; };
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Dep)
+  // CHECK-FIXES-NEXT: auto H4 = [&]() { int R = I + 1; };
+
+  for (dependent<int>::const_iterator I = Dep.begin(), E = Dep.end();
+       I != E; ++I)
+    auto H5 = [=]() { int R = *I; };
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int R : Dep)
+  // CHECK-FIXES-NEXT: auto H5 = [=]() { };
+}
+
+void captureByValue() {
+  // When the index is captured by value, we should replace this by a capture
+  // by reference. This avoids extra copies.
+  // FIXME: this could change semantics on array or pseudoarray loops if the
+  // container is captured by copy.
+  const int N = 10;
+  int Arr[N];
+  dependent<int> Dep;
+
+  for (int I = 0; I < N; ++I) {
+    auto C1 = [&Arr, I]() { if (Arr[I] == 1); };
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Arr)
+  // CHECK-FIXES-NEXT: auto C1 = [&Arr, &I]() { if (I == 1); };
+
+  for (unsigned I = 0; I < Dep.size(); ++I) {
+    auto C2 = [&Dep, I]() { if (Dep[I] == 2); };
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Dep)
+  // CHECK-FIXES-NEXT: auto C2 = [&Dep, &I]() { if (I == 2); };
+}
+
+} // namespace Lambdas
+
+namespace InitLists {
+
+struct D { int Ii; };
+struct E { D Dd; };
+int g(int B);
+
+void f() {
+  const unsigned N = 3;
+  int Array[N];
+
+  // Subtrees of InitListExpr are visited twice. Test that we do not do repeated
+  // replacements.
+  for (unsigned I = 0; I < N; ++I) {
+    int A{ Array[I] };
+    int B{ g(Array[I]) };
+    int C{ g( { Array[I] } ) };
+    D Dd{ { g( { Array[I] } ) } };
+    E Ee{ { { g( { Array[I] } ) } } };
+  }
+  // CHECK-MESSAGES: :[[@LINE-7]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : Array)
+  // CHECK-FIXES-NEXT: int A{ I };
+  // CHECK-FIXES-NEXT: int B{ g(I) };
+  // CHECK-FIXES-NEXT: int C{ g( { I } ) };
+  // CHECK-FIXES-NEXT: D Dd{ { g( { I } ) } };
+  // CHECK-FIXES-NEXT: E Ee{ { { g( { I } ) } } };
+}
+
+} // namespace InitLists
+
+void bug28341() {
+  char v[5];
+  for(int i = 0; i < 5; ++i) {
+      unsigned char value = v[i];
+      if (value > 127)
+        ;
+  // CHECK-MESSAGES: :[[@LINE-4]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for(unsigned char value : v)
+  // CHECK-FIXES-NEXT: if (value > 127)
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-lowercase.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-lowercase.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-lowercase.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-lowercase.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-loop-convert.NamingStyle, value: 'lower_case'}]}" \
+// RUN:   -- -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+const int n = 10;
+int arr[n];
+int nums[n];
+int nums_[n];
+
+void naming() {
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", arr[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+  // CHECK-FIXES: for (int i : arr)
+  // CHECK-FIXES-NEXT: printf("%d\n", i);
+
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", nums[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int num : nums)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", nums_[i]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int num : nums_)
+  // CHECK-FIXES-NEXT: printf("%d\n", num);
+
+  int num = 0;
+  for (int i = 0; i < n; ++i) {
+    printf("%d\n", nums[i] + num);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int i : nums)
+  // CHECK-FIXES-NEXT: printf("%d\n", i + num);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-negative.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-negative.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-negative.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-negative.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,485 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- -- -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+// CHECK-FIXES-NOT: for ({{.*[^:]:[^:].*}})
+// CHECK-MESSAGES-NOT: modernize-loop-convert
+
+namespace Negative {
+
+const int N = 6;
+int Arr[N] = {1, 2, 3, 4, 5, 6};
+int (*pArr)[N] = &Arr;
+int Sum = 0;
+
+// Checks for the Index start and end:
+void IndexStartAndEnd() {
+  for (int I = 0; I < N + 1; ++I)
+    Sum += Arr[I];
+
+  for (int I = 0; I < N - 1; ++I)
+    Sum += Arr[I];
+
+  for (int I = 1; I < N; ++I)
+    Sum += Arr[I];
+
+  for (int I = 1; I < N; ++I)
+    Sum += Arr[I];
+
+  for (int I = 0;; ++I)
+    Sum += (*pArr)[I];
+}
+
+// Checks for invalid increment steps:
+void increment() {
+  for (int I = 0; I < N; --I)
+    Sum += Arr[I];
+
+  for (int I = 0; I < N; I)
+    Sum += Arr[I];
+
+  for (int I = 0; I < N;)
+    Sum += Arr[I];
+
+  for (int I = 0; I < N; I += 2)
+    Sum++;
+}
+
+// Checks to make sure that the Index isn't used outside of the array:
+void IndexUse() {
+  for (int I = 0; I < N; ++I)
+    Arr[I] += 1 + I;
+}
+
+// Check for loops that don't mention arrays
+void noArray() {
+  for (int I = 0; I < N; ++I)
+    Sum += I;
+
+  for (int I = 0; I < N; ++I) {
+  }
+
+  for (int I = 0; I < N; ++I)
+    ;
+}
+
+// Checks for incorrect loop variables.
+void mixedVariables() {
+  int BadIndex;
+  for (int I = 0; BadIndex < N; ++I)
+    Sum += Arr[I];
+
+  for (int I = 0; I < N; ++BadIndex)
+    Sum += Arr[I];
+
+  for (int I = 0; BadIndex < N; ++BadIndex)
+    Sum += Arr[I];
+
+  for (int I = 0; BadIndex < N; ++BadIndex)
+    Sum += Arr[BadIndex];
+}
+
+// Checks for multiple arrays Indexed.
+void multipleArrays() {
+  int BadArr[N];
+
+  for (int I = 0; I < N; ++I)
+    Sum += Arr[I] + BadArr[I];
+
+  for (int I = 0; I < N; ++I) {
+    int K = BadArr[I];
+    Sum += Arr[I] + K;
+  }
+}
+
+}
+
+namespace NegativeIterator {
+
+S Ss;
+T Tt;
+U Tu;
+
+struct BadBeginEnd : T {
+  iterator notBegin();
+  iterator notEnd();
+};
+
+void notBeginOrEnd() {
+  BadBeginEnd Bad;
+  for (T::iterator I = Bad.notBegin(), E = Bad.end();  I != E; ++I)
+    int K = *I;
+
+  for (T::iterator I = Bad.begin(), E = Bad.notEnd();  I != E; ++I)
+    int K = *I;
+}
+
+void badLoopShapes() {
+  for (T::iterator I = Tt.begin(), E = Tt.end(), F = E;  I != E; ++I)
+    int K = *I;
+
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E;)
+    int K = *I;
+
+  for (T::iterator I = Tt.begin(), E = Tt.end();; ++I)
+    int K = *I;
+
+  T::iterator OutsideI;
+  T::iterator OutsideE;
+
+  for (; OutsideI != OutsideE; ++OutsideI)
+    int K = *OutsideI;
+}
+
+void iteratorArrayMix() {
+  int Lower;
+  const int N = 6;
+  for (T::iterator I = Tt.begin(), E = Tt.end(); Lower < N; ++I)
+    int K = *I;
+
+  for (T::iterator I = Tt.begin(), E = Tt.end(); Lower < N; ++Lower)
+    int K = *I;
+}
+
+struct ExtraConstructor : T::iterator {
+  ExtraConstructor(T::iterator, int);
+  explicit ExtraConstructor(T::iterator);
+};
+
+void badConstructor() {
+  for (T::iterator I = ExtraConstructor(Tt.begin(), 0), E = Tt.end();
+        I != E; ++I)
+    int K = *I;
+  for (T::iterator I = ExtraConstructor(Tt.begin()), E = Tt.end();  I != E; ++I)
+    int K = *I;
+}
+
+void foo(S::iterator It) {}
+class Foo {public: void bar(S::iterator It); };
+Foo Fo;
+
+void iteratorUsed() {
+  for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
+    foo(I);
+
+  for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
+    Fo.bar(I);
+
+  S::iterator Ret;
+  for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
+    Ret = I;
+}
+
+void iteratorMemberUsed() {
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    I.X = *I;
+
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    int K = I.X + *I;
+
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    int K = E.X + *I;
+}
+
+void iteratorMethodCalled() {
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    I.insert(3);
+
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    if (I != I)
+      int K = 3;
+}
+
+void iteratorOperatorCalled() {
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    int K = *(++I);
+
+  for (S::iterator I = Ss.begin(), E = Ss.end();  I != E; ++I)
+    MutableVal K = *(++I);
+}
+
+void differentContainers() {
+  T Other;
+  for (T::iterator I = Tt.begin(), E = Other.end();  I != E; ++I)
+    int K = *I;
+
+  for (T::iterator I = Other.begin(), E = Tt.end();  I != E; ++I)
+    int K = *I;
+
+  S OtherS;
+  for (S::iterator I = Ss.begin(), E = OtherS.end();  I != E; ++I)
+    MutableVal K = *I;
+
+  for (S::iterator I = OtherS.begin(), E = Ss.end();  I != E; ++I)
+    MutableVal K = *I;
+}
+
+void wrongIterators() {
+  T::iterator Other;
+  for (T::iterator I = Tt.begin(), E = Tt.end(); I != Other; ++I)
+    int K = *I;
+}
+
+struct EvilArrow : U {
+  // Please, no one ever write code like this.
+  U *operator->();
+};
+
+void differentMemberAccessTypes() {
+  EvilArrow A;
+  for (EvilArrow::iterator I = A.begin(), E = A->end();  I != E; ++I)
+    Val K = *I;
+  for (EvilArrow::iterator I = A->begin(), E = A.end();  I != E; ++I)
+    Val K = *I;
+}
+
+void f(const T::iterator &It, int);
+void f(const T &It, int);
+void g(T &It, int);
+
+void iteratorPassedToFunction() {
+  for (T::iterator I = Tt.begin(), E = Tt.end();  I != E; ++I)
+    f(I, *I);
+}
+
+// FIXME: These tests can be removed if this tool ever does enough analysis to
+// decide that this is a safe transformation. Until then, we don't want it
+// applied.
+void iteratorDefinedOutside() {
+  T::iterator TheEnd = Tt.end();
+  for (T::iterator I = Tt.begin(); I != TheEnd; ++I)
+    int K = *I;
+
+  T::iterator TheBegin = Tt.begin();
+  for (T::iterator E = Tt.end(); TheBegin != E; ++TheBegin)
+    int K = *TheBegin;
+}
+
+} // namespace NegativeIterator
+
+namespace NegativePseudoArray {
+
+const int N = 6;
+dependent<int> V;
+dependent<int> *Pv;
+
+int Sum = 0;
+
+// Checks for the Index start and end:
+void IndexStartAndEnd() {
+  for (int I = 0; I < V.size() + 1; ++I)
+    Sum += V[I];
+
+  for (int I = 0; I < V.size() - 1; ++I)
+    Sum += V[I];
+
+  for (int I = 1; I < V.size(); ++I)
+    Sum += V[I];
+
+  for (int I = 1; I < V.size(); ++I)
+    Sum += V[I];
+
+  for (int I = 0;; ++I)
+    Sum += (*Pv)[I];
+}
+
+// Checks for invalid increment steps:
+void increment() {
+  for (int I = 0; I < V.size(); --I)
+    Sum += V[I];
+
+  for (int I = 0; I < V.size(); I)
+    Sum += V[I];
+
+  for (int I = 0; I < V.size();)
+    Sum += V[I];
+
+  for (int I = 0; I < V.size(); I += 2)
+    Sum++;
+}
+
+// Checks to make sure that the Index isn't used outside of the container:
+void IndexUse() {
+  for (int I = 0; I < V.size(); ++I)
+    V[I] += 1 + I;
+}
+
+// Checks for incorrect loop variables.
+void mixedVariables() {
+  int BadIndex;
+  for (int I = 0; BadIndex < V.size(); ++I)
+    Sum += V[I];
+
+  for (int I = 0; I < V.size(); ++BadIndex)
+    Sum += V[I];
+
+  for (int I = 0; BadIndex < V.size(); ++BadIndex)
+    Sum += V[I];
+
+  for (int I = 0; BadIndex < V.size(); ++BadIndex)
+    Sum += V[BadIndex];
+}
+
+// Checks for an array Indexed in addition to the container.
+void multipleArrays() {
+  int BadArr[N];
+
+  for (int I = 0; I < V.size(); ++I)
+    Sum += V[I] + BadArr[I];
+
+  for (int I = 0; I < V.size(); ++I)
+    Sum += BadArr[I];
+
+  for (int I = 0; I < V.size(); ++I) {
+    int K = BadArr[I];
+    Sum += K + 2;
+  }
+
+  for (int I = 0; I < V.size(); ++I) {
+    int K = BadArr[I];
+    Sum += V[I] + K;
+  }
+}
+
+// Checks for multiple containers being Indexed container.
+void multipleContainers() {
+  dependent<int> BadArr;
+
+  for (int I = 0; I < V.size(); ++I)
+    Sum += V[I] + BadArr[I];
+
+  for (int I = 0; I < V.size(); ++I)
+    Sum += BadArr[I];
+
+  for (int I = 0; I < V.size(); ++I) {
+    int K = BadArr[I];
+    Sum += K + 2;
+  }
+
+  for (int I = 0; I < V.size(); ++I) {
+    int K = BadArr[I];
+    Sum += V[I] + K;
+  }
+}
+
+// Check to make sure that dereferenced pointers-to-containers behave nicely.
+void derefContainer() {
+  // Note the dependent<T>::operator*() returns another dependent<T>.
+  // This test makes sure that we don't allow an arbitrary number of *'s.
+  for (int I = 0; I < Pv->size(); ++I)
+    Sum += (**Pv).at(I);
+
+  for (int I = 0; I < Pv->size(); ++I)
+    Sum += (**Pv)[I];
+}
+
+void wrongEnd() {
+  int Bad;
+  for (int I = 0, E = V.size(); I < Bad; ++I)
+    Sum += V[I];
+}
+
+// Checks to see that non-const member functions are not called on the container
+// object.
+// These could be conceivably allowed with a lower required confidence level.
+void memberFunctionCalled() {
+  for (int I = 0; I < V.size(); ++I) {
+    Sum += V[I];
+    V.foo();
+  }
+
+  for (int I = 0; I < V.size(); ++I) {
+    Sum += V[I];
+    dependent<int>::iterator It = V.begin();
+  }
+}
+
+} // namespace NegativePseudoArray
+
+namespace NegativeMultiEndCall {
+
+S Ss;
+T Tt;
+U Uu;
+
+void f(X);
+void f(S);
+void f(T);
+
+void complexContainer() {
+  X Xx;
+  for (S::iterator I = Xx.Ss.begin(), E = Xx.Ss.end();  I != E; ++I) {
+    f(Xx);
+    MutableVal K = *I;
+  }
+
+  for (T::iterator I = Xx.Tt.begin(), E = Xx.Tt.end();  I != E; ++I) {
+    f(Xx);
+    int K = *I;
+  }
+
+  for (S::iterator I = Xx.Ss.begin(), E = Xx.Ss.end();  I != E; ++I) {
+    f(Xx.Ss);
+    MutableVal K = *I;
+  }
+
+  for (T::iterator I = Xx.Tt.begin(), E = Xx.Tt.end();  I != E; ++I) {
+    f(Xx.Tt);
+    int K = *I;
+  }
+
+  for (S::iterator I = Xx.getS().begin(), E = Xx.getS().end();  I != E; ++I) {
+    f(Xx.getS());
+    MutableVal K = *I;
+  }
+
+  X Exes[5];
+  int Index = 0;
+
+  for (S::iterator I = Exes[Index].getS().begin(),
+                   E = Exes[Index].getS().end();
+        I != E; ++I) {
+    Index++;
+    MutableVal K = *I;
+  }
+}
+
+} // namespace NegativeMultiEndCall
+
+namespace NoUsages {
+
+const int N = 6;
+int Arr[N] = {1, 2, 3, 4, 5, 6};
+S Ss;
+dependent<int> V;
+int Count = 0;
+
+void foo();
+
+void f() {
+  for (int I = 0; I < N; ++I) {}
+  for (int I = 0; I < N; ++I)
+    printf("Hello world\n");
+  for (int I = 0; I < N; ++I)
+    ++Count;
+  for (int I = 0; I < N; ++I)
+    foo();
+
+  for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I) {}
+  for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+    printf("Hello world\n");
+  for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+    ++Count;
+  for (S::iterator I = Ss.begin(), E = Ss.end(); I != E; ++I)
+    foo();
+
+  for (int I = 0; I < V.size(); ++I) {}
+  for (int I = 0; I < V.size(); ++I)
+    printf("Hello world\n");
+  for (int I = 0; I < V.size(); ++I)
+    ++Count;
+  for (int I = 0; I < V.size(); ++I)
+    foo();
+}
+
+} // namespace NoUsages

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-uppercase.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-uppercase.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-uppercase.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert-uppercase.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,41 @@
+// RUN: %check_clang_tidy %s modernize-loop-convert %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-loop-convert.NamingStyle, value: 'UPPER_CASE'}]}" \
+// RUN:   -- -I %S/Inputs/modernize-loop-convert
+
+#include "structures.h"
+
+const int N = 10;
+int ARR[N];
+int NUMS[N];
+int NUMS_[N];
+
+void naming() {
+  for (int I = 0; I < N; ++I) {
+    printf("%d\n", ARR[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead [modernize-loop-convert]
+  // CHECK-FIXES: for (int I : ARR)
+  // CHECK-FIXES-NEXT: printf("%d\n", I);
+
+  for (int I = 0; I < N; ++I) {
+    printf("%d\n", NUMS[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int NUM : NUMS)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
+  for (int I = 0; I < N; ++I) {
+    printf("%d\n", NUMS_[I]);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int NUM : NUMS_)
+  // CHECK-FIXES-NEXT: printf("%d\n", NUM);
+
+  int NUM = 0;
+  for (int I = 0; I < N; ++I) {
+    printf("%d\n", NUMS[I] + NUM);
+  }
+  // CHECK-MESSAGES: :[[@LINE-3]]:3: warning: use range-based for loop instead
+  // CHECK-FIXES: for (int I : NUMS)
+  // CHECK-FIXES-NEXT: printf("%d\n", I + NUM);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-loop-convert.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: clang-tidy %s -checks=-*,modernize-loop-convert -- -std=c11 | count 0
+
+// Note: this test expects no diagnostics, but FileCheck cannot handle that,
+// hence the use of | count 0.
+
+int arr[6] = {1, 2, 3, 4, 5, 6};
+
+void f(void) {
+  for (int i = 0; i < 6; ++i) {
+    (void)arr[i];
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared-header.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared-header.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared-header.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared-header.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s modernize-make-shared %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:     [{key: modernize-make-shared.MakeSmartPtrFunction, \
+// RUN:       value: 'my::MakeShared'}, \
+// RUN:      {key: modernize-make-shared.MakeSmartPtrFunctionHeader, \
+// RUN:       value: 'make_shared_util.h'} \
+// RUN:     ]}" \
+// RUN:   -- -I %S/Inputs/modernize-smart-ptr
+
+#include "shared_ptr.h"
+// CHECK-FIXES: #include "make_shared_util.h"
+
+void f() {
+  std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeShared instead
+  // CHECK-FIXES: std::shared_ptr<int> P1 = my::MakeShared<int>();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-shared.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,297 @@
+// RUN: %check_clang_tidy %s modernize-make-shared %t -- -- -I %S/Inputs/modernize-smart-ptr
+
+#include "shared_ptr.h"
+// CHECK-FIXES: #include <memory>
+
+struct Base {
+  Base();
+  Base(int, int);
+};
+
+struct Derived : public Base {
+  Derived();
+  Derived(int, int);
+};
+
+struct APair {
+  int a, b;
+};
+
+struct DPair {
+  DPair() : a(0), b(0) {}
+  DPair(int x, int y) : a(y), b(x) {}
+  int a, b;
+};
+
+struct Empty {};
+
+template <class T>
+using shared_ptr_ = std::shared_ptr<T>;
+
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
+
+int g(std::shared_ptr<int> P);
+
+std::shared_ptr<Base> getPointer() {
+  return std::shared_ptr<Base>(new Base);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_shared instead
+  // CHECK-FIXES: return std::make_shared<Base>();
+}
+
+void basic() {
+  std::shared_ptr<int> P1 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: std::shared_ptr<int> P1 = std::make_shared<int>();
+
+  P1.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P1 = std::make_shared<int>();
+
+  P1 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P1 = std::make_shared<int>();
+
+  // Without parenthesis.
+  std::shared_ptr<int> P2 = std::shared_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: std::shared_ptr<int> P2 = std::make_shared<int>();
+
+  P2.reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P2 = std::make_shared<int>();
+
+  P2 = std::shared_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P2 = std::make_shared<int>();
+
+  // With auto.
+  auto P3 = std::shared_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
+  // CHECK-FIXES: auto P3 = std::make_shared<int>();
+
+  std::shared_ptr<int> P4 = std::shared_ptr<int>((new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: std::shared_ptr<int> P4 = std::make_shared<int>();
+
+  P4.reset((((new int()))));
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P4 = std::make_shared<int>();
+
+  P4 = std::shared_ptr<int>(((new int)));
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead [modernize-make-shared]
+  // CHECK-FIXES: P4 = std::make_shared<int>();
+
+  {
+    // No std.
+    using namespace std;
+    shared_ptr<int> Q = shared_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_shared instead
+    // CHECK-FIXES: shared_ptr<int> Q = std::make_shared<int>();
+
+    Q = shared_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+    // CHECK-FIXES: Q = std::make_shared<int>();
+  }
+
+  std::shared_ptr<int> R(new int());
+
+  // Create the shared_ptr as a parameter to a function.
+  int T = g(std::shared_ptr<int>(new int()));
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_shared instead
+  // CHECK-FIXES: int T = g(std::make_shared<int>());
+
+  // Only replace if the type in the template is the same as the type returned
+  // by the new operator.
+  auto Pderived = std::shared_ptr<Base>(new Derived());
+
+  // OK to replace for reset and assign
+  Pderived.reset(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_shared instead
+  // CHECK-FIXES: Pderived = std::make_shared<Derived>();
+
+  Pderived = std::shared_ptr<Derived>(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_shared instead
+  // CHECK-FIXES: Pderived = std::make_shared<Derived>();
+
+  // FIXME: OK to replace if assigned to shared_ptr<Base>
+  Pderived = std::shared_ptr<Base>(new Derived());
+
+  // FIXME: OK to replace when auto is not used
+  std::shared_ptr<Base> PBase = std::shared_ptr<Base>(new Derived());
+
+  // The pointer is returned by the function, nothing to do.
+  std::shared_ptr<Base> RetPtr = getPointer();
+
+  // This emulates std::move.
+  std::shared_ptr<int> Move = static_cast<std::shared_ptr<int> &&>(P1);
+
+  // Placement arguments should not be removed.
+  int *PInt = new int;
+  std::shared_ptr<int> Placement = std::shared_ptr<int>(new (PInt) int{3});
+  Placement.reset(new (PInt) int{3});
+  Placement = std::shared_ptr<int>(new (PInt) int{3});
+}
+
+// Calling make_smart_ptr from within a member function of a type with a
+// private or protected constructor would be ill-formed.
+class Private {
+private:
+  Private(int z) {}
+
+public:
+  Private() {}
+  void create() {
+    auto callsPublic = std::shared_ptr<Private>(new Private);
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+    // CHECK-FIXES: auto callsPublic = std::make_shared<Private>();
+    auto ptr = std::shared_ptr<Private>(new Private(42));
+    ptr.reset(new Private(42));
+    ptr = std::shared_ptr<Private>(new Private(42));
+  }
+
+  virtual ~Private();
+};
+
+class Protected {
+protected:
+  Protected() {}
+
+public:
+  Protected(int, int) {}
+  void create() {
+    auto callsPublic = std::shared_ptr<Protected>(new Protected(1, 2));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+    // CHECK-FIXES: auto callsPublic = std::make_shared<Protected>(1, 2);
+    auto ptr = std::shared_ptr<Protected>(new Protected);
+    ptr.reset(new Protected);
+    ptr = std::shared_ptr<Protected>(new Protected);
+  }
+};
+
+void initialization(int T, Base b) {
+  // Test different kinds of initialization of the pointee.
+
+  // Direct initialization with parenthesis.
+  std::shared_ptr<DPair> PDir1 = std::shared_ptr<DPair>(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir1 = std::make_shared<DPair>(1, T);
+  PDir1.reset(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: PDir1 = std::make_shared<DPair>(1, T);
+
+  // Direct initialization with braces.
+  std::shared_ptr<DPair> PDir2 = std::shared_ptr<DPair>(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir2 = std::make_shared<DPair>(2, T);
+  PDir2.reset(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: PDir2 = std::make_shared<DPair>(2, T);
+
+  // Aggregate initialization.
+  std::shared_ptr<APair> PAggr = std::shared_ptr<APair>(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<APair> PAggr = std::make_shared<APair>(APair{T, 1});
+  PAggr.reset(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: std::make_shared<APair>(APair{T, 1});
+
+  // Test different kinds of initialization of the pointee, when the shared_ptr
+  // is initialized with braces.
+
+  // Direct initialization with parenthesis.
+  std::shared_ptr<DPair> PDir3 = std::shared_ptr<DPair>{new DPair(3, T)};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir3 = std::make_shared<DPair>(3, T);
+
+  // Direct initialization with braces.
+  std::shared_ptr<DPair> PDir4 = std::shared_ptr<DPair>{new DPair{4, T}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir4 = std::make_shared<DPair>(4, T);
+
+  // Aggregate initialization.
+  std::shared_ptr<APair> PAggr2 = std::shared_ptr<APair>{new APair{T, 2}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<APair> PAggr2 = std::make_shared<APair>(APair{T, 2});
+
+  // Direct initialization with parenthesis, without arguments.
+  std::shared_ptr<DPair> PDir5 = std::shared_ptr<DPair>(new DPair());
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir5 = std::make_shared<DPair>();
+
+  // Direct initialization with braces, without arguments.
+  std::shared_ptr<DPair> PDir6 = std::shared_ptr<DPair>(new DPair{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<DPair> PDir6 = std::make_shared<DPair>();
+
+  // Aggregate initialization without arguments.
+  std::shared_ptr<Empty> PEmpty = std::shared_ptr<Empty>(new Empty{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<Empty> PEmpty = std::make_shared<Empty>(Empty{});
+}
+
+void aliases() {
+  typedef std::shared_ptr<int> IntPtr;
+  IntPtr Typedef = IntPtr(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_shared instead
+  // CHECK-FIXES: IntPtr Typedef = std::make_shared<int>();
+
+  // We use 'bool' instead of '_Bool'.
+  typedef std::shared_ptr<bool> BoolPtr;
+  BoolPtr BoolType = BoolPtr(new bool);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_shared instead
+  // CHECK-FIXES: BoolPtr BoolType = std::make_shared<bool>();
+
+  // We use 'Base' instead of 'struct Base'.
+  typedef std::shared_ptr<Base> BasePtr;
+  BasePtr StructType = BasePtr(new Base);
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_shared instead
+// CHECK-FIXES: BasePtr StructType = std::make_shared<Base>();
+
+#define PTR shared_ptr<int>
+  std::shared_ptr<int> Macro = std::PTR(new int);
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
+// CHECK-FIXES: std::shared_ptr<int> Macro = std::make_shared<int>();
+#undef PTR
+
+  std::shared_ptr<int> Using = shared_ptr_<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_shared instead
+  // CHECK-FIXES: std::shared_ptr<int> Using = std::make_shared<int>();
+}
+
+void whitespaces() {
+  // clang-format off
+  auto Space = std::shared_ptr <int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_shared instead
+  // CHECK-FIXES: auto Space = std::make_shared<int>();
+
+  auto Spaces = std  ::    shared_ptr  <int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_shared instead
+  // CHECK-FIXES: auto Spaces = std::make_shared<int>();
+  // clang-format on
+}
+
+void nesting() {
+  auto Nest = std::shared_ptr<std::shared_ptr<int>>(new std::shared_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_shared instead
+  // CHECK-FIXES: auto Nest = std::make_shared<std::shared_ptr<int>>(new int);
+  Nest.reset(new std::shared_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_shared instead
+  // CHECK-FIXES: Nest = std::make_shared<std::shared_ptr<int>>(new int);
+  Nest->reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_shared instead
+  // CHECK-FIXES: *Nest = std::make_shared<int>();
+}
+
+void reset() {
+  std::shared_ptr<int> P;
+  P.reset();
+  P.reset(nullptr);
+  P.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_shared instead
+  // CHECK-FIXES: P = std::make_shared<int>();
+
+  auto Q = &P;
+  Q->reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_shared instead
+  // CHECK-FIXES: *Q = std::make_shared<int>();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-cxx11.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-cxx11.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-cxx11.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy -std=c++11 %s modernize-make-unique %t -- -- -I %S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+// CHECK-FIXES: #include "unique_ptr.h"
+
+void f() {
+  auto my_ptr = std::unique_ptr<int>(new int(1));
+  // CHECK-FIXES: auto my_ptr = std::unique_ptr<int>(new int(1));
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-header.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-header.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-header.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-header.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,17 @@
+// RUN: %check_clang_tidy %s modernize-make-unique %t -- \
+// RUN:   -config="{CheckOptions: \
+// RUN:     [{key: modernize-make-unique.MakeSmartPtrFunction, \
+// RUN:       value: 'my::MakeUnique'}, \
+// RUN:      {key: modernize-make-unique.MakeSmartPtrFunctionHeader, \
+// RUN:       value: 'make_unique_util.h'} \
+// RUN:     ]}" \
+// RUN:   -- -I %S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+// CHECK-FIXES: #include "make_unique_util.h"
+
+void f() {
+  std::unique_ptr<int> P1 = std::unique_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use my::MakeUnique instead
+  // CHECK-FIXES: std::unique_ptr<int> P1 = my::MakeUnique<int>();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-inaccessible-ctors.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-inaccessible-ctors.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-inaccessible-ctors.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-inaccessible-ctors.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,113 @@
+// RUN: %check_clang_tidy -std=c++14,c++17 -check-suffix=CXX-14-17 %s modernize-make-unique %t -- -- -I %S/Inputs/modernize-smart-ptr -D CXX_14_17=1
+// RUN: %check_clang_tidy -std=c++2a -check-suffix=CXX-2A %s modernize-make-unique %t -- -- -I %S/Inputs/modernize-smart-ptr -D CXX_2A=1
+
+#include "unique_ptr.h"
+// CHECK-FIXES: #include <memory>
+
+struct NoCopyMoveCtor {
+#ifdef CXX_2A
+  // C++2a requires to see the default constructor, otherwise it is illgal.
+  NoCopyMoveCtor() = default;
+#endif
+#ifdef CXX_14_17
+  int a, b;
+#endif
+  NoCopyMoveCtor(const NoCopyMoveCtor &) = delete; // implies move ctor is deleted
+};
+
+struct NoCopyMoveCtorVisible {
+#ifdef CXX_2A
+  NoCopyMoveCtorVisible() = default;
+#endif
+private:
+  NoCopyMoveCtorVisible(const NoCopyMoveCtorVisible&) = default;
+  NoCopyMoveCtorVisible(NoCopyMoveCtorVisible&&) = default;
+};
+
+struct OnlyMoveCtor {
+  OnlyMoveCtor() = default;
+  OnlyMoveCtor(OnlyMoveCtor&&) = default;
+  OnlyMoveCtor(const OnlyMoveCtor &) = delete;
+};
+
+struct OnlyCopyCtor {
+#ifdef CXX_2A
+  OnlyCopyCtor() = default;
+#endif
+  OnlyCopyCtor(const OnlyCopyCtor&) = default;
+  OnlyCopyCtor(OnlyCopyCtor&&) = delete;
+};
+
+struct OnlyCopyCtorVisible {
+#ifdef CXX_2A
+  OnlyCopyCtorVisible() = default;
+#endif
+  OnlyCopyCtorVisible(const OnlyCopyCtorVisible &) = default;
+
+private:
+  OnlyCopyCtorVisible(OnlyCopyCtorVisible &&) = default;
+};
+
+struct ImplicitDeletedCopyCtor {
+  const OnlyMoveCtor ctor;
+};
+
+void f() {
+  auto my_ptr = std::unique_ptr<int>(new int(1));
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:17: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto my_ptr = std::make_unique<int>(1);
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:17: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto my_ptr = std::make_unique<int>(1);
+
+  // "new NoCopyMoveCtor{}" is processed differently in C++14/17 and C++2a:
+  //   * In C++14/17, it is recognized as aggregate initialization,
+  //     no fixes will be generated although the generated fix is compilable.
+  //   * In C++2a, it is is recognized as default constructor initialization (
+  //     similar to "new NoCopyMoveCtor()"), the check will emit the fix and the
+  //     fix is correct.
+  auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:26: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtor = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{});
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:26: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto PNoCopyMoveCtor = std::make_unique<NoCopyMoveCtor>();
+
+  auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:33: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtorVisible = std::unique_ptr<NoCopyMoveCtorVisible>(new NoCopyMoveCtorVisible{});
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:33: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto PNoCopyMoveCtorVisible = std::make_unique<NoCopyMoveCtorVisible>();
+
+  auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto POnlyMoveCtor = std::unique_ptr<OnlyMoveCtor>(new OnlyMoveCtor{});
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto POnlyMoveCtor = std::make_unique<OnlyMoveCtor>();
+
+  auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto POnlyCopyCtor = std::unique_ptr<OnlyCopyCtor>(new OnlyCopyCtor{});
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:24: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto POnlyCopyCtor = std::make_unique<OnlyCopyCtor>();
+
+  auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:31: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto POnlyCopyCtorVisible = std::unique_ptr<OnlyCopyCtorVisible>(new OnlyCopyCtorVisible{});
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:31: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto POnlyCopyCtorVisible = std::make_unique<OnlyCopyCtorVisible>();
+
+  // This is aggregate initialization in C++2a, no fix will be generated.
+  auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+  // CHECK-MESSAGES-CXX-2A: :[[@LINE-3]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-2A: auto PImplicitDeletedCopyCtor = std::unique_ptr<ImplicitDeletedCopyCtor>(new ImplicitDeletedCopyCtor{});
+
+
+#ifdef CXX_14_17
+  // FIXME: it is impossible to use make_unique for this case, the check should
+  // stop emitting the message.
+  auto PNoCopyMoveCtor2 = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{1, 2});
+  // CHECK-MESSAGES-CXX-14-17: :[[@LINE-1]]:27: warning: use std::make_unique instead
+  // CHECK-FIXES-CXX-14-17: auto PNoCopyMoveCtor2 = std::unique_ptr<NoCopyMoveCtor>(new NoCopyMoveCtor{1, 2});
+#endif
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-macros.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-macros.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-macros.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique-macros.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-make-unique %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-make-unique.IgnoreMacros, value: 0}]}" \
+// RUN:   -- -I %S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+
+class Foo {};
+class Bar {};
+#define DEFINE(...) __VA_ARGS__
+// CHECK-FIXES: {{^}}#define DEFINE(...) __VA_ARGS__{{$}}
+template<typename T>
+void g2(std::unique_ptr<Foo> *t) {
+  DEFINE(
+  // CHECK-FIXES: {{^ *}}DEFINE({{$}}
+      auto p = std::unique_ptr<Foo>(new Foo);
+      // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_unique instead
+      // CHECK-FIXES: {{^ *}}auto p = std::unique_ptr<Foo>(new Foo);{{$}}
+      t->reset(new Foo);
+      // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_unique instead
+      // CHECK-FIXES: {{^ *}}t->reset(new Foo);{{$}}
+      );
+      // CHECK-FIXES: {{^ *}});{{$}}
+}
+void macro() {
+  std::unique_ptr<Foo> *t;
+  g2<Bar>(t);
+}
+#undef DEFINE

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-make-unique.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,570 @@
+// RUN: %check_clang_tidy -std=c++14-or-later %s modernize-make-unique %t -- -- -I %S/Inputs/modernize-smart-ptr
+
+#include "unique_ptr.h"
+#include "initializer_list.h"
+// CHECK-FIXES: #include <memory>
+
+struct Base {
+  Base();
+  Base(int, int);
+};
+
+struct Derived : public Base {
+  Derived();
+  Derived(int, int);
+};
+
+struct APair {
+  int a, b;
+};
+
+struct DPair {
+  DPair() : a(0), b(0) {}
+  DPair(int x, int y) : a(y), b(x) {}
+  int a, b;
+};
+
+template<typename T>
+struct MyVector {
+  MyVector(std::initializer_list<T>);
+};
+
+struct Empty {};
+
+
+struct E {
+  E(std::initializer_list<int>);
+  E();
+};
+
+struct F {
+  F(std::initializer_list<int>);
+  F();
+  int a;
+};
+
+struct G {
+  G(std::initializer_list<int>);
+  G(int);
+};
+
+struct H {
+  H(std::vector<int>);
+  H(std::vector<int> &, double);
+  H(MyVector<int>, int);
+};
+
+struct I {
+  I(G);
+};
+
+struct J {
+  J(E e, int);
+};
+
+namespace {
+class Foo {};
+} // namespace
+
+namespace bar {
+class Bar {};
+} // namespace bar
+
+template <class T>
+using unique_ptr_ = std::unique_ptr<T>;
+
+void *operator new(__SIZE_TYPE__ Count, void *Ptr);
+
+int g(std::unique_ptr<int> P);
+
+std::unique_ptr<Base> getPointer() {
+  return std::unique_ptr<Base>(new Base);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use std::make_unique instead
+  // CHECK-FIXES: return std::make_unique<Base>();
+}
+
+void basic() {
+  std::unique_ptr<int> P1 = std::unique_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: std::unique_ptr<int> P1 = std::make_unique<int>();
+
+  P1.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P1 = std::make_unique<int>();
+
+  P1 = std::unique_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P1 = std::make_unique<int>();
+
+  // Without parenthesis.
+  std::unique_ptr<int> P2 = std::unique_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: std::unique_ptr<int> P2 = std::make_unique<int>();
+
+  P2.reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P2 = std::make_unique<int>();
+
+  P2 = std::unique_ptr<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P2 = std::make_unique<int>();
+
+  // With auto.
+  auto P3 = std::unique_ptr<int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+  // CHECK-FIXES: auto P3 = std::make_unique<int>();
+
+  std::unique_ptr<int> P4 = std::unique_ptr<int>((new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: std::unique_ptr<int> P4 = std::make_unique<int>();
+  P4.reset((new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P4 = std::make_unique<int>();
+  std::unique_ptr<int> P5 = std::unique_ptr<int>((((new int))));
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: std::unique_ptr<int> P5 = std::make_unique<int>();
+  P5.reset(((((new int)))));
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead [modernize-make-unique]
+  // CHECK-FIXES: P5 = std::make_unique<int>();
+
+  {
+    // No std.
+    using namespace std;
+    unique_ptr<int> Q = unique_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: use std::make_unique instead
+    // CHECK-FIXES: unique_ptr<int> Q = std::make_unique<int>();
+
+    Q = unique_ptr<int>(new int());
+    // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+    // CHECK-FIXES: Q = std::make_unique<int>();
+  }
+
+  std::unique_ptr<int> R(new int());
+
+  // Create the unique_ptr as a parameter to a function.
+  int T = g(std::unique_ptr<int>(new int()));
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+  // CHECK-FIXES: int T = g(std::make_unique<int>());
+
+  // Only replace if the type in the template is the same as the type returned
+  // by the new operator.
+  auto Pderived = std::unique_ptr<Base>(new Derived());
+
+  // OK to replace for reset and assign
+  Pderived.reset(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_unique instead
+  // CHECK-FIXES: Pderived = std::make_unique<Derived>();
+
+  Pderived = std::unique_ptr<Derived>(new Derived());
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: use std::make_unique instead
+  // CHECK-FIXES: Pderived = std::make_unique<Derived>();
+
+  // FIXME: OK to replace if assigned to unique_ptr<Base>
+  Pderived = std::unique_ptr<Base>(new Derived());
+
+  // FIXME: OK to replace when auto is not used
+  std::unique_ptr<Base> PBase = std::unique_ptr<Base>(new Derived());
+
+  // The pointer is returned by the function, nothing to do.
+  std::unique_ptr<Base> RetPtr = getPointer();
+
+  // This emulates std::move.
+  std::unique_ptr<int> Move = static_cast<std::unique_ptr<int> &&>(P1);
+
+  // Placement arguments should not be removed.
+  int *PInt = new int;
+  std::unique_ptr<int> Placement = std::unique_ptr<int>(new (PInt) int{3});
+  Placement.reset(new (PInt) int{3});
+  Placement = std::unique_ptr<int>(new (PInt) int{3});
+}
+
+// Calling make_smart_ptr from within a member function of a type with a
+// private or protected constructor would be ill-formed.
+class Private {
+private:
+  Private(int z) {}
+
+public:
+  Private() {}
+  void create() {
+    auto callsPublic = std::unique_ptr<Private>(new Private);
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+    // CHECK-FIXES: auto callsPublic = std::make_unique<Private>();
+    auto ptr = std::unique_ptr<Private>(new Private(42));
+    ptr.reset(new Private(42));
+    ptr = std::unique_ptr<Private>(new Private(42));
+  }
+
+  virtual ~Private();
+};
+
+class Protected {
+protected:
+  Protected() {}
+
+public:
+  Protected(int, int) {}
+  void create() {
+    auto callsPublic = std::unique_ptr<Protected>(new Protected(1, 2));
+    // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+    // CHECK-FIXES: auto callsPublic = std::make_unique<Protected>(1, 2);
+    auto ptr = std::unique_ptr<Protected>(new Protected);
+    ptr.reset(new Protected);
+    ptr = std::unique_ptr<Protected>(new Protected);
+  }
+};
+
+void initialization(int T, Base b) {
+  // Test different kinds of initialization of the pointee.
+
+  // Direct initialization with parenthesis.
+  std::unique_ptr<DPair> PDir1 = std::unique_ptr<DPair>(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<DPair> PDir1 = std::make_unique<DPair>(1, T);
+  PDir1.reset(new DPair(1, T));
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: PDir1 = std::make_unique<DPair>(1, T);
+
+  // Direct initialization with braces.
+  std::unique_ptr<DPair> PDir2 = std::unique_ptr<DPair>(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<DPair> PDir2 = std::make_unique<DPair>(2, T);
+  PDir2.reset(new DPair{2, T});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: PDir2 = std::make_unique<DPair>(2, T);
+
+  // Aggregate initialization.
+  std::unique_ptr<APair> PAggr = std::unique_ptr<APair>(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<APair> PAggr = std::make_unique<APair>(APair{T, 1});
+  PAggr.reset(new APair{T, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: std::make_unique<APair>(APair{T, 1});
+
+  // Check aggregate init with intermediate temporaries.
+  std::unique_ptr<APair> PAggrTemp = std::unique_ptr<APair>(new APair({T, 1}));
+  // CHECK-MESSAGES: :[[@LINE-1]]:38: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<APair> PAggrTemp = std::unique_ptr<APair>(new APair({T, 1}));
+  PAggrTemp.reset(new APair({T, 1}));
+  // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+  // CHECK-FIXES: PAggrTemp.reset(new APair({T, 1}));
+
+  // Test different kinds of initialization of the pointee, when the unique_ptr
+  // is initialized with braces.
+
+  // Direct initialization with parenthesis.
+  std::unique_ptr<DPair> PDir3 = std::unique_ptr<DPair>{new DPair(3, T)};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<DPair> PDir3 = std::make_unique<DPair>(3, T);
+
+  // Direct initialization with braces.
+  std::unique_ptr<DPair> PDir4 = std::unique_ptr<DPair>{new DPair{4, T}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<DPair> PDir4 = std::make_unique<DPair>(4, T);
+
+  // Aggregate initialization.
+  std::unique_ptr<APair> PAggr2 = std::unique_ptr<APair>{new APair{T, 2}};
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<APair> PAggr2 = std::make_unique<APair>(APair{T, 2});
+
+  // Direct initialization with parenthesis, without arguments.
+  std::unique_ptr<DPair> PDir5 = std::unique_ptr<DPair>(new DPair());
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<DPair> PDir5 = std::make_unique<DPair>();
+
+  // Direct initialization with braces, without arguments.
+  std::unique_ptr<DPair> PDir6 = std::unique_ptr<DPair>(new DPair{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<DPair> PDir6 = std::make_unique<DPair>();
+
+  // Aggregate initialization without arguments.
+  std::unique_ptr<Empty> PEmpty = std::unique_ptr<Empty>(new Empty{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:35: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<Empty> PEmpty = std::make_unique<Empty>(Empty{});
+
+  // Initialization with default constructor.
+  std::unique_ptr<E> PE1 = std::unique_ptr<E>(new E{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<E> PE1 = std::make_unique<E>();
+  PE1.reset(new E{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PE1 = std::make_unique<E>();
+
+  // No warnings for `auto` new expression.
+  PE1.reset(new auto(E()));
+
+  //============================================================================
+  //  NOTE: For initlializer-list constructors, the check only gives warnings,
+  //  and no fixes are generated.
+  //============================================================================
+
+  // Initialization with the initializer-list constructor.
+  std::unique_ptr<E> PE2 = std::unique_ptr<E>(new E{1, 2});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<E> PE2 = std::unique_ptr<E>(new E{1, 2});
+  PE2.reset(new E{1, 2});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PE2.reset(new E{1, 2});
+
+  // Initialization with default constructor.
+  std::unique_ptr<F> PF1 = std::unique_ptr<F>(new F());
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<F> PF1 = std::make_unique<F>();
+  PF1.reset(new F());
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PF1 = std::make_unique<F>();
+
+  // Initialization with default constructor.
+  std::unique_ptr<F> PF2 = std::unique_ptr<F>(new F{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<F> PF2 = std::make_unique<F>();
+  PF2.reset(new F());
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PF2 = std::make_unique<F>();
+
+  // Initialization with the initializer-list constructor.
+  std::unique_ptr<F> PF3 = std::unique_ptr<F>(new F{1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<F> PF3 = std::unique_ptr<F>(new F{1});
+  PF3.reset(new F{1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PF3.reset(new F{1});
+
+  // Initialization with the initializer-list constructor.
+  std::unique_ptr<F> PF4 = std::unique_ptr<F>(new F{1, 2});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<F> PF4 = std::unique_ptr<F>(new F{1, 2});
+
+  // Initialization with the initializer-list constructor.
+  std::unique_ptr<F> PF5 = std::unique_ptr<F>(new F({1, 2}));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<F> PF5 = std::unique_ptr<F>(new F({1, 2}));
+
+  // Initialization with the initializer-list constructor as the default
+  // constructor is not present.
+  std::unique_ptr<G> PG1 = std::unique_ptr<G>(new G{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<G> PG1 = std::unique_ptr<G>(new G{});
+  PG1.reset(new G{});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PG1.reset(new G{});
+
+  // Initialization with the initializer-list constructor.
+  std::unique_ptr<G> PG2 = std::unique_ptr<G>(new G{1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<G> PG2 = std::unique_ptr<G>(new G{1});
+
+  // Initialization with the initializer-list constructor.
+  std::unique_ptr<G> PG3 = std::unique_ptr<G>(new G{1, 2});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<G> PG3 = std::unique_ptr<G>(new G{1, 2});
+
+  std::unique_ptr<H> PH1 = std::unique_ptr<H>(new H({1, 2, 3}));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<H> PH1 = std::unique_ptr<H>(new H({1, 2, 3}));
+  PH1.reset(new H({1, 2, 3}));
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PH1.reset(new H({1, 2, 3}));
+
+  std::unique_ptr<H> PH2 = std::unique_ptr<H>(new H({1, 2, 3}, 1));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<H> PH2 = std::unique_ptr<H>(new H({1, 2, 3}, 1));
+  PH2.reset(new H({1, 2, 3}, 1));
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PH2.reset(new H({1, 2, 3}, 1));
+
+  std::unique_ptr<H> PH3 = std::unique_ptr<H>(new H({1, 2, 3}, 1.0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<H> PH3 = std::unique_ptr<H>(new H({1, 2, 3}, 1.0));
+  PH3.reset(new H({1, 2, 3}, 1.0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PH3.reset(new H({1, 2, 3}, 1.0));
+
+  std::unique_ptr<I> PI1 = std::unique_ptr<I>(new I(G({1, 2, 3})));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<I> PI1 = std::make_unique<I>(G({1, 2, 3}));
+  PI1.reset(new I(G({1, 2, 3})));
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PI1 = std::make_unique<I>(G({1, 2, 3}));
+
+  std::unique_ptr<J> PJ1 = std::unique_ptr<J>(new J({1, 2}, 1));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<J> PJ1 = std::unique_ptr<J>(new J({1, 2}, 1));
+  PJ1.reset(new J({1, 2}, 1));
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PJ1.reset(new J({1, 2}, 1));
+
+  std::unique_ptr<J> PJ2 = std::unique_ptr<J>(new J(E{1, 2}, 1));
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<J> PJ2 = std::unique_ptr<J>(new J(E{1, 2}, 1));
+  PJ2.reset(new J(E{1, 2}, 1));
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PJ2.reset(new J(E{1, 2}, 1));
+
+  std::unique_ptr<J> PJ3 = std::unique_ptr<J>(new J{ {1, 2}, 1 });
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<J> PJ3 = std::unique_ptr<J>(new J{ {1, 2}, 1 });
+  PJ3.reset(new J{ {1, 2}, 1 });
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES:  PJ3.reset(new J{ {1, 2}, 1 });
+
+  std::unique_ptr<J> PJ4 = std::unique_ptr<J>(new J{E{1, 2}, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<J> PJ4 = std::unique_ptr<J>(new J{E{1, 2}, 1});
+  PJ4.reset(new J{E{1, 2}, 1});
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::make_unique instead
+  // CHECK-FIXES: PJ4.reset(new J{E{1, 2}, 1});
+
+  std::unique_ptr<Foo> FF = std::unique_ptr<Foo>(new Foo());
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning:
+  // CHECK-FIXES: std::unique_ptr<Foo> FF = std::make_unique<Foo>();
+  FF.reset(new Foo());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
+  // CHECK-FIXES: FF = std::make_unique<Foo>();
+
+  std::unique_ptr<bar::Bar> BB = std::unique_ptr<bar::Bar>(new bar::Bar());
+  // CHECK-MESSAGES: :[[@LINE-1]]:34: warning:
+  // CHECK-FIXES: std::unique_ptr<bar::Bar> BB = std::make_unique<bar::Bar>();
+  BB.reset(new bar::Bar());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
+  // CHECK-FIXES: BB = std::make_unique<bar::Bar>();
+
+  std::unique_ptr<Foo[]> FFs;
+  FFs.reset(new Foo[5]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+  // CHECK-FIXES: FFs = std::make_unique<Foo[]>(5);
+  FFs.reset(new Foo[5]());
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+  // CHECK-FIXES: FFs = std::make_unique<Foo[]>(5);
+  const int Num = 1;
+  FFs.reset(new Foo[Num]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+  // CHECK-FIXES: FFs = std::make_unique<Foo[]>(Num);
+  int Num2 = 1;
+  FFs.reset(new Foo[Num2]);
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning:
+  // CHECK-FIXES: FFs = std::make_unique<Foo[]>(Num2);
+
+  std::unique_ptr<int[]> FI;
+  FI.reset(new int[5]()); // default initialization.
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning:
+  // CHECK-FIXES: FI = std::make_unique<int[]>(5);
+
+  // The check doesn't give warnings and fixes for cases where the original new
+  // expresion doesn't do any initialization.
+  FI.reset(new int[5]);
+  FI.reset(new int[Num]);
+  FI.reset(new int[Num2]);
+}
+
+void aliases() {
+  typedef std::unique_ptr<int> IntPtr;
+  IntPtr Typedef = IntPtr(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: use std::make_unique instead
+  // CHECK-FIXES: IntPtr Typedef = std::make_unique<int>();
+
+  // We use 'bool' instead of '_Bool'.
+  typedef std::unique_ptr<bool> BoolPtr;
+  BoolPtr BoolType = BoolPtr(new bool);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::make_unique instead
+  // CHECK-FIXES: BoolPtr BoolType = std::make_unique<bool>();
+
+  // We use 'Base' instead of 'struct Base'.
+  typedef std::unique_ptr<Base> BasePtr;
+  BasePtr StructType = BasePtr(new Base);
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: use std::make_unique instead
+// CHECK-FIXES: BasePtr StructType = std::make_unique<Base>();
+
+#define PTR unique_ptr<int>
+  std::unique_ptr<int> Macro = std::PTR(new int);
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
+// CHECK-FIXES: std::unique_ptr<int> Macro = std::make_unique<int>();
+#undef PTR
+
+  std::unique_ptr<int> Using = unique_ptr_<int>(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:32: warning: use std::make_unique instead
+  // CHECK-FIXES: std::unique_ptr<int> Using = std::make_unique<int>();
+}
+
+void whitespaces() {
+  // clang-format off
+  auto Space = std::unique_ptr <int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: use std::make_unique instead
+  // CHECK-FIXES: auto Space = std::make_unique<int>();
+
+  auto Spaces = std  ::    unique_ptr  <int>(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use std::make_unique instead
+  // CHECK-FIXES: auto Spaces = std::make_unique<int>();
+  // clang-format on
+}
+
+void nesting() {
+  auto Nest = std::unique_ptr<std::unique_ptr<int>>(new std::unique_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: use std::make_unique instead
+  // CHECK-FIXES: auto Nest = std::make_unique<std::unique_ptr<int>>(new int);
+  Nest.reset(new std::unique_ptr<int>(new int));
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use std::make_unique instead
+  // CHECK-FIXES: Nest = std::make_unique<std::unique_ptr<int>>(new int);
+  Nest->reset(new int);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use std::make_unique instead
+  // CHECK-FIXES: *Nest = std::make_unique<int>();
+}
+
+void reset() {
+  std::unique_ptr<int> P;
+  P.reset();
+  P.reset(nullptr);
+  P.reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use std::make_unique instead
+  // CHECK-FIXES: P = std::make_unique<int>();
+
+  auto Q = &P;
+  Q->reset(new int());
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: use std::make_unique instead
+  // CHECK-FIXES: *Q = std::make_unique<int>();
+}
+
+#define DEFINE(...) __VA_ARGS__
+template<typename T>
+void g2(std::unique_ptr<Foo> *t) {
+  DEFINE(auto p = std::unique_ptr<Foo>(new Foo); t->reset(new Foo););
+}
+void macro() {
+  std::unique_ptr<Foo> *t;
+  g2<bar::Bar>(t);
+}
+#undef DEFINE
+
+class UniqueFoo : public std::unique_ptr<Foo> {
+ public:
+  void foo() {
+    reset(new Foo);
+    this->reset(new Foo);
+    // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: use std::make_unique instead
+    // CHECK-FIXES: *this = std::make_unique<Foo>();
+    (*this).reset(new Foo);
+    // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: use std::make_unique instead
+    // CHECK-FIXES: (*this) = std::make_unique<Foo>();
+  }
+};
+
+// Ignore statements inside a template instantiation.
+template<typename T>
+void template_fun(T* t) {
+  std::unique_ptr<T> t2 = std::unique_ptr<T>(new T);
+  t2.reset(new T);
+}
+
+void invoke_template() {
+  Foo* foo;
+  template_fun(foo);
+}
+
+void no_fix_for_invalid_new_loc() {
+  // FIXME: Although the code is valid, the end location of `new struct Base` is
+  // invalid. Correct it once https://bugs.llvm.org/show_bug.cgi?id=35952 is
+  // fixed.
+  auto T = std::unique_ptr<Base>(new struct Base);
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: use std::make_unique instead
+  // CHECK-FIXES: auto T = std::unique_ptr<Base>(new struct Base);
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-header.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,9 @@
+// RUN: cp %S/Inputs/modernize-pass-by-value/header.h %T/pass-by-value-header.h
+// RUN: clang-tidy %s -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %T | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
+// RUN: FileCheck -input-file=%T/pass-by-value-header.h %s -check-prefix=CHECK-FIXES
+// FIXME: Make the test work in all language modes.
+
+#include "pass-by-value-header.h"
+// CHECK-MESSAGES: :8:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-FIXES: #include <utility>
+// CHECK-FIXES: A(ThreadId tid) : threadid(std::move(tid)) {}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-macro-header.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-macro-header.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-macro-header.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-macro-header.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,18 @@
+// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -isystem %S/Inputs/Headers
+
+// CHECK-FIXES: #include <utility>
+
+#define HEADER <./a.h>
+#include HEADER
+
+struct A {
+  A(const A &) {}
+  A(A &&) {}
+};
+
+struct B {
+  B(const A &a) : a(a) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-FIXES: B(A a) : a(std::move(a)) {}
+  A a;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-multi-fixes.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-multi-fixes.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-multi-fixes.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value-multi-fixes.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,12 @@
+// RUN: cat %S/Inputs/modernize-pass-by-value/header-with-fix.h > %T/pass-by-value-header-with-fix.h
+// RUN: sed -e 's#//.*$##' %s > %t.cpp
+// RUN: clang-tidy %t.cpp -checks='-*,modernize-pass-by-value' -header-filter='.*' -fix -- -std=c++11 -I %T | FileCheck %s -check-prefix=CHECK-MESSAGES -implicit-check-not="{{warning|error}}:"
+// RUN: FileCheck -input-file=%t.cpp %s -check-prefix=CHECK-FIXES
+// RUN: FileCheck -input-file=%T/pass-by-value-header-with-fix.h %s -check-prefix=CHECK-HEADER-FIXES
+
+#include "pass-by-value-header-with-fix.h"
+// CHECK-HEADER-FIXES: Foo(S s);
+Foo::Foo(const S &s) : s(s) {}
+// CHECK-MESSAGES: :9:10: warning: pass by value and use std::move [modernize-pass-by-value]
+// CHECK-FIXES: #include <utility>
+// CHECK-FIXES: Foo::Foo(S s) : s(std::move(s)) {}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-pass-by-value.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,215 @@
+// RUN: %check_clang_tidy %s modernize-pass-by-value %t -- -- -fno-delayed-template-parsing
+
+namespace {
+// POD types are trivially move constructible.
+struct POD {
+  int a, b, c;
+};
+
+struct Movable {
+  int a, b, c;
+  Movable() = default;
+  Movable(const Movable &) {}
+  Movable(Movable &&) {}
+};
+
+struct NotMovable {
+  NotMovable() = default;
+  NotMovable(const NotMovable &) = default;
+  NotMovable(NotMovable &&) = delete;
+  int a, b, c;
+};
+}
+
+struct A {
+  A(const Movable &M) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move [modernize-pass-by-value]
+  // CHECK-FIXES: A(Movable M) : M(std::move(M)) {}
+  Movable M;
+};
+
+// Test that we aren't modifying other things than a parameter.
+Movable GlobalObj;
+struct B {
+  B(const Movable &M) : M(GlobalObj) {}
+  // CHECK-FIXES: B(const Movable &M) : M(GlobalObj) {}
+  Movable M;
+};
+
+// Test that a parameter with more than one reference to it won't be changed.
+struct C {
+  // Tests extra-reference in body.
+  C(const Movable &M) : M(M) { this->i = M.a; }
+  // CHECK-FIXES: C(const Movable &M) : M(M) { this->i = M.a; }
+
+  // Tests extra-reference in init-list.
+  C(const Movable &M, int) : M(M), i(M.a) {}
+  // CHECK-FIXES: C(const Movable &M, int) : M(M), i(M.a) {}
+  Movable M;
+  int i;
+};
+
+// Test that both declaration and definition are updated.
+struct D {
+  D(const Movable &M);
+  // CHECK-FIXES: D(Movable M);
+  Movable M;
+};
+D::D(const Movable &M) : M(M) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
+// CHECK-FIXES: D::D(Movable M) : M(std::move(M)) {}
+
+// Test with default parameter.
+struct E {
+  E(const Movable &M = Movable()) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: E(Movable M = Movable()) : M(std::move(M)) {}
+  Movable M;
+};
+
+// Test with object that can't be moved.
+struct F {
+  F(const NotMovable &NM) : NM(NM) {}
+  // CHECK-FIXES: F(const NotMovable &NM) : NM(NM) {}
+  NotMovable NM;
+};
+
+// Test unnamed parameter in declaration.
+struct G {
+  G(const Movable &);
+  // CHECK-FIXES: G(Movable );
+  Movable M;
+};
+G::G(const Movable &M) : M(M) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
+// CHECK-FIXES: G::G(Movable M) : M(std::move(M)) {}
+
+// Test parameter with and without qualifier.
+namespace ns_H {
+typedef ::Movable HMovable;
+}
+struct H {
+  H(const ns_H::HMovable &M);
+  // CHECK-FIXES: H(ns_H::HMovable M);
+  ns_H::HMovable M;
+};
+using namespace ns_H;
+H::H(const HMovable &M) : M(M) {}
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: pass by value and use std::move
+// CHECK-FIXES: H(HMovable M) : M(std::move(M)) {}
+
+// Try messing up with macros.
+#define MOVABLE_PARAM(Name) const Movable & Name
+// CHECK-FIXES: #define MOVABLE_PARAM(Name) const Movable & Name
+struct I {
+  I(MOVABLE_PARAM(M)) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: I(MOVABLE_PARAM(M)) : M(M) {}
+  Movable M;
+};
+#undef MOVABLE_PARAM
+
+// Test that templates aren't modified.
+template <typename T> struct J {
+  J(const T &M) : M(M) {}
+  // CHECK-FIXES: J(const T &M) : M(M) {}
+  T M;
+};
+J<Movable> j1(Movable());
+J<NotMovable> j2(NotMovable());
+
+struct K_Movable {
+  K_Movable() = default;
+  K_Movable(const K_Movable &) = default;
+  K_Movable(K_Movable &&o) { dummy = o.dummy; }
+  int dummy;
+};
+
+// Test with movable type with an user defined move constructor.
+struct K {
+  K(const K_Movable &M) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: K(K_Movable M) : M(std::move(M)) {}
+  K_Movable M;
+};
+
+template <typename T> struct L {
+  L(const Movable &M) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: L(Movable M) : M(std::move(M)) {}
+  Movable M;
+};
+L<int> l(Movable());
+
+// Test with a non-instantiated template class.
+template <typename T> struct N {
+  N(const Movable &M) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: N(Movable M) : M(std::move(M)) {}
+
+  Movable M;
+  T A;
+};
+
+// Test with value parameter.
+struct O {
+  O(Movable M) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: O(Movable M) : M(std::move(M)) {}
+  Movable M;
+};
+
+// Test with a const-value parameter.
+struct P {
+  P(const Movable M) : M(M) {}
+  // CHECK-FIXES: P(const Movable M) : M(M) {}
+  Movable M;
+};
+
+// Test with multiples parameters where some need to be changed and some don't.
+// need to.
+struct Q {
+  Q(const Movable &A, const Movable &B, const Movable &C, double D)
+      : A(A), B(B), C(C), D(D) {}
+  // CHECK-MESSAGES: :[[@LINE-2]]:23: warning: pass by value and use std::move
+  // CHECK-MESSAGES: :[[@LINE-3]]:41: warning: pass by value and use std::move
+  // CHECK-FIXES:      Q(const Movable &A, Movable B, Movable C, double D)
+  // CHECK-FIXES:     : A(A), B(std::move(B)), C(std::move(C)), D(D) {}
+  const Movable &A;
+  Movable B;
+  Movable C;
+  double D;
+};
+
+// Test that value-parameters with a nested name specifier are left as-is.
+namespace ns_R {
+typedef ::Movable RMovable;
+}
+struct R {
+  R(ns_R::RMovable M) : M(M) {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: pass by value and use std::move
+  // CHECK-FIXES: R(ns_R::RMovable M) : M(std::move(M)) {}
+  ns_R::RMovable M;
+};
+
+// Test with rvalue parameter.
+struct S {
+  S(Movable &&M) : M(M) {}
+  // CHECK-FIXES: S(Movable &&M) : M(M) {}
+  Movable M;
+};
+
+template <typename T, int N> struct array { T A[N]; };
+
+// Test that types that are trivially copyable will not use std::move. This will
+// cause problems with performance-move-const-arg, as it will revert it.
+struct T {
+  T(array<int, 10> a) : a_(a) {}
+  // CHECK-FIXES: T(array<int, 10> a) : a_(a) {}
+  array<int, 10> a_;
+};
+
+struct U {
+  U(const POD &M) : M(M) {}
+  POD M;
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-delimiter.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-delimiter.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-delimiter.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-delimiter.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,9 @@
+// RUN: %check_clang_tidy %s modernize-raw-string-literal %t -- -config='{CheckOptions: [{key: "modernize-raw-string-literal.DelimiterStem", value: "str"}, {key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}'
+
+char const *const ContainsSentinel{"who\\ops)\""};
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ContainsSentinel{R"str(who\ops)")str"};{{$}}
+
+//char const *const ContainsDelim{"whoops)\")lit\""};
+// CHECK-XMESSAGES: :[[@LINE-1]]:33: warning: {{.*}} can be written as a raw string literal
+// CHECK-XFIXES: {{^}}char const *const ContainsDelim{R"lit1(whoops)")lit")lit1"};{{$}}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-replace-shorter.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-replace-shorter.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-replace-shorter.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal-replace-shorter.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,13 @@
+// RUN: %check_clang_tidy %s modernize-raw-string-literal %t
+
+// Don't replace these, because the raw literal would be longer.
+char const *const JustAQuote("quote:\'");
+char const *const NeedDelimiter("\":)\"");
+
+char const *const ManyQuotes("quotes:\'\'\'\'");
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ManyQuotes(R"(quotes:'''')");{{$}}
+
+char const *const LongOctal("\042\072\051\042");
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const LongOctal(R"lit(":)")lit");{{$}}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-raw-string-literal.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,132 @@
+// RUN: %check_clang_tidy -std=c++11,c++14,c++17 %s modernize-raw-string-literal %t -- -config="{CheckOptions: [{key: modernize-raw-string-literal.ReplaceShorterLiterals, value: 1}]}"
+// FIXME: Fix the checker to work in C++2a mode.
+
+char const *const BackSlash("goink\\frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: escaped string literal can be written as a raw string literal [modernize-raw-string-literal]
+// CHECK-FIXES: {{^}}char const *const BackSlash(R"(goink\frob)");{{$}}
+
+char const *const PlainLiteral("plain literal");
+
+// Non-printable ASCII characters.
+char const *const Nul("goink\\\000");
+char const *const Soh("goink\\\001");
+char const *const Stx("goink\\\002");
+char const *const Etx("goink\\\003");
+char const *const Enq("goink\\\004");
+char const *const Ack("goink\\\005");
+char const *const Bell("goink\\\afrob");
+char const *const BackSpace("goink\\\bfrob");
+char const *const HorizontalTab("goink\\\tfrob");
+char const *const NewLine("goink\nfrob");
+char const *const VerticalTab("goink\\\vfrob");
+char const *const FormFeed("goink\\\ffrob");
+char const *const CarraigeReturn("goink\\\rfrob");
+char const *const So("goink\\\016");
+char const *const Si("goink\\\017");
+char const *const Dle("goink\\\020");
+char const *const Dc1("goink\\\021");
+char const *const Dc2("goink\\\022");
+char const *const Dc3("goink\\\023");
+char const *const Dc4("goink\\\024");
+char const *const Nak("goink\\\025");
+char const *const Syn("goink\\\026");
+char const *const Etb("goink\\\027");
+char const *const Can("goink\\\030");
+char const *const Em("goink\\\031");
+char const *const Sub("goink\\\032");
+char const *const Esc("goink\\\033");
+char const *const Fs("goink\\\034");
+char const *const Gs("goink\\\035");
+char const *const Rs("goink\\\036");
+char const *const Us("goink\\\037");
+char const *const HexNonPrintable("\\\x03");
+char const *const Delete("\\\177");
+char const *const MultibyteSnowman("\xE2\x98\x83");
+// CHECK-FIXES: {{^}}char const *const MultibyteSnowman("\xE2\x98\x83");{{$}}
+
+char const *const TrailingSpace("A line \\with space. \n");
+char const *const TrailingNewLine("A single \\line.\n");
+char const *const AlreadyRaw(R"(foobie\\bletch)");
+char const *const UTF8Literal(u8"foobie\\bletch");
+char const *const UTF8RawLiteral(u8R"(foobie\\bletch)");
+// TODO: enable these tests once all supported compilers
+// support char16_t and char32_t (VS2013 does not)
+// char16_t const *const UTF16Literal(u"foobie\\bletch");
+// char16_t const *const UTF16RawLiteral(uR"(foobie\\bletch)");
+// char32_t const *const UTF32Literal(U"foobie\\bletch");
+// char32_t const *const UTF32RawLiteral(UR"(foobie\\bletch)");
+wchar_t const *const WideLiteral(L"foobie\\bletch");
+wchar_t const *const WideRawLiteral(LR"(foobie\\bletch)");
+
+char const *const SingleQuote("goink\'frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: {{.*}} can be written as a raw string literal
+// CHECK-XFIXES: {{^}}char const *const SingleQuote(R"(goink'frob)");{{$}}
+
+char const *const DoubleQuote("goink\"frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const DoubleQuote(R"(goink"frob)");{{$}}
+
+char const *const QuestionMark("goink\?frob");
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const QuestionMark(R"(goink?frob)");{{$}}
+
+char const *const RegEx("goink\\(one|two\\)\\\\\\?.*\\nfrob");
+// CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const RegEx(R"(goink\(one|two\)\\\?.*\nfrob)");{{$}}
+
+char const *const Path("C:\\Program Files\\Vendor\\Application\\Application.exe");
+// CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const Path(R"(C:\Program Files\Vendor\Application\Application.exe)");{{$}}
+
+char const *const ContainsSentinel("who\\ops)\"");
+// CHECK-MESSAGES: :[[@LINE-1]]:36: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ContainsSentinel(R"lit(who\ops)")lit");{{$}}
+
+char const *const ContainsDelim("whoops)\")lit\"");
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const ContainsDelim(R"lit1(whoops)")lit")lit1");{{$}}
+
+char const *const OctalPrintable("\100\\");
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const OctalPrintable(R"(@\)");{{$}}
+
+char const *const HexPrintable("\x40\\");
+// CHECK-MESSAGES: :[[@LINE-1]]:32: warning: {{.*}} can be written as a raw string literal
+// CHECK-FIXES: {{^}}char const *const HexPrintable(R"(@\)");{{$}}
+
+char const *const prettyFunction(__PRETTY_FUNCTION__);
+char const *const function(__FUNCTION__);
+char const *const func(__func__);
+
+#define TRICK(arg_) #arg_
+char const *const MacroBody = TRICK(foo\\bar);
+
+#define HAT(rabbit_) #rabbit_ "foo\\bar"
+char const *const StringizedMacroArgument = HAT(foo\\bar);
+
+#define SUBST(lit_) lit_
+char const *const MacroArgument = SUBST("foo\\bar");
+// FIXME: We should be able to replace this string literal macro argument
+
+template <typename T>
+void fn(char const *const Arg) {
+  char const *const Str("foo\\bar");
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
+  // CHECK-FIXES: {{^}}  char const *const Str(R"(foo\bar)");{{$}}
+}
+
+template <>
+void fn<int>(char const *const Arg) {
+  char const *const Str("foo\\bar");
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: {{.*}} can be written as a raw string literal
+  // CHECK-FIXES: {{^}}  char const *const Str(R"(foo\bar)");{{$}}
+}
+
+void callFn() {
+  fn<int>("foo\\bar");
+  // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: {{.*}} can be written as a raw string literal
+  // CHECK-FIXES: {{^}}  fn<int>(R"(foo\bar)");{{$}}
+  fn<double>("foo\\bar");
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} can be written as a raw string literal
+  // CHECK-FIXES: {{^}}  fn<double>(R"(foo\bar)");{{$}}
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg-delayed.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg-delayed.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg-delayed.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg-delayed.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,28 @@
+// RUN: %check_clang_tidy %s modernize-redundant-void-arg %t -- -- -fdelayed-template-parsing
+
+int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}}int foo() {{{$}}
+    return 0;
+}
+
+template <class T>
+struct MyFoo {
+  int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}}  int foo() {{{$}}
+    return 0;
+  }
+};
+// Explicit instantiation.
+template class MyFoo<int>;
+
+template <class T>
+struct MyBar {
+  // This declaration isn't instantiated and won't be parsed 'delayed-template-parsing'.
+  int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:11: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}}  int foo() {{{$}}
+    return 0;
+  }
+};

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.c
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.c?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.c (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.c Fri Oct 11 05:05:42 2019
@@ -0,0 +1,58 @@
+// RUN: clang-tidy -checks=-*,modernize-redundant-void-arg %s -- -x c | count 0
+
+#define NULL 0
+
+extern int i;
+
+int foo2() {
+  return 0;
+}
+
+int j = 1;
+
+int foo(void) {
+  return 0;
+}
+
+typedef unsigned int my_uint;
+
+typedef void my_void;
+
+// A function taking void and returning a pointer to function taking void
+// and returning int.
+int (*returns_fn_void_int(void))(void);
+
+typedef int (*returns_fn_void_int_t(void))(void);
+
+int (*returns_fn_void_int(void))(void) {
+  return NULL;
+}
+
+// A function taking void and returning a pointer to a function taking void
+// and returning a pointer to a function taking void and returning void.
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+
+typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void);
+
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void) {
+  return NULL;
+}
+
+void bar() {
+  int i;
+  int *pi = NULL;
+  void *pv = (void *) pi;
+  float f;
+  float *fi;
+  double d;
+  double *pd;
+}
+
+void (*f1)(void);
+void (*f2)(void) = NULL;
+void (*f3)(void) = bar;
+void (*fa)();
+void (*fb)() = NULL;
+void (*fc)() = bar;
+
+typedef void (function_ptr)(void);

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-redundant-void-arg.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,558 @@
+// RUN: %check_clang_tidy %s modernize-redundant-void-arg %t
+
+#define NULL 0
+
+int foo();
+
+void bar();
+
+void bar2();
+
+extern "C" void ecfoo(void);
+
+extern "C" void ecfoo(void) {
+}
+
+extern int i;
+
+int j = 1;
+
+int foo(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+// CHECK-FIXES: {{^}}int foo() {{{$}}
+    return 0;
+}
+
+typedef unsigned int my_uint;
+
+typedef void my_void;
+
+// A function taking void and returning a pointer to function taking void
+// and returning int.
+int (*returns_fn_void_int(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} in function declaration
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in function declaration
+// CHECK-FIXES: {{^}}int (*returns_fn_void_int())();{{$}}
+
+typedef int (*returns_fn_void_int_t(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-2]]:44: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef int (*returns_fn_void_int_t())();{{$}}
+
+// Should work for type aliases as well as typedef.
+using returns_fn_void_int_t2 = int (*(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:39: warning: {{.*}} in type alias
+// CHECK-MESSAGES: :[[@LINE-2]]:46: warning: {{.*}} in type alias
+// CHECK-FIXES: {{^}}using returns_fn_void_int_t2 = int (*())();{{$}}
+
+int (*returns_fn_void_int(void))(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:27: warning: {{.*}} in function definition
+// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}int (*returns_fn_void_int())() {{{$}}
+  return nullptr;
+}
+
+// A function taking void and returning a pointer to a function taking void
+// and returning a pointer to a function taking void and returning void.
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}} in function declaration
+// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: {{.*}} in function declaration
+// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: {{.*}} in function declaration
+// CHECK-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void())())();{{$}}
+
+typedef void (*(*returns_fn_returns_fn_void_void_t(void))(void))(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:52: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-2]]:59: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-3]]:66: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (*(*returns_fn_returns_fn_void_void_t())())();{{$}}
+
+void (*(*returns_fn_returns_fn_void_void(void))(void))(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: {{.*}} in function definition
+// CHECK-MESSAGES: :[[@LINE-2]]:49: warning: {{.*}} in function definition
+// CHECK-MESSAGES: :[[@LINE-3]]:56: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void (*(*returns_fn_returns_fn_void_void())())() {{{$}}
+    return nullptr;
+}
+
+void bar(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void bar() {{{$}}
+}
+
+void op_fn(int i) {
+}
+
+class gronk {
+public:
+  gronk();
+  ~gronk();
+
+    void foo();
+    void bar();
+    void bar2
+        ();
+    void operation(int i) { }
+
+private:
+    int m_i;
+    int *m_pi;
+    float m_f;
+    float *m_pf;
+    double m_d;
+    double *m_pd;
+
+    void (*f1)(void);
+    // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in field declaration
+    // CHECK-FIXES: {{^    }}void (*f1)();{{$}}
+
+  void (*op)(int i);
+
+  void (gronk::*p1)(void);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in field declaration
+  // CHECK-FIXES: {{^  }}void (gronk::*p1)();{{$}}
+
+  int (gronk::*p_mi);
+
+  void (gronk::*p2)(int);
+
+  void (*(*returns_fn_returns_fn_void_void(void))(void))(void);
+  // CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in function declaration
+  // CHECK-MESSAGES: :[[@LINE-2]]:51: warning: {{.*}} in function declaration
+  // CHECK-MESSAGES: :[[@LINE-3]]:58: warning: {{.*}} in function declaration
+  // CHECK-FIXES: {{^}}  void (*(*returns_fn_returns_fn_void_void())())();{{$}}
+
+  void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)(void))(void))(void);
+  // CHECK-MESSAGES: :[[@LINE-1]]:58: warning: {{.*}} in field declaration
+  // CHECK-MESSAGES: :[[@LINE-2]]:65: warning: {{.*}} in field declaration
+  // CHECK-MESSAGES: :[[@LINE-3]]:72: warning: {{.*}} in field declaration
+  // CHECK-FIXES: {{^}}  void (*(*(gronk::*returns_fn_returns_fn_void_void_mem)())())();{{$}}
+};
+
+int i;
+int *pi;
+void *pv = (void *) pi;
+float f;
+float *fi;
+double d;
+double *pd;
+
+void (*f1)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration
+// CHECK-FIXES: {{^}}void (*f1)();{{$}}
+
+void (*f2)(void) = nullptr;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2)() = nullptr;{{$}}
+
+void (*f2b)(void)(nullptr);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2b)()(nullptr);{{$}}
+
+void (*f2c)(void){nullptr};
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2c)(){nullptr};{{$}}
+
+void (*f2d)(void) = NULL;
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2d)() = NULL;{{$}}
+
+void (*f2e)(void)(NULL);
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2e)()(NULL);{{$}}
+
+void (*f2f)(void){NULL};
+// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f2f)(){NULL};{{$}}
+
+void (*f3)(void) = bar;
+// CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (*f3)() = bar;{{$}}
+
+void (*o1)(int i);
+void (*o2)(int i) = nullptr;
+void (*o3)(int i)(nullptr);
+void (*o4)(int i){nullptr};
+void (*o5)(int i) = NULL;
+void (*o6)(int i)(NULL);
+void (*o7)(int i){NULL};
+void (*o8)(int i) = op_fn;
+
+void (*fa)();
+
+void (*fb)() = nullptr;
+
+void (*fc)() = bar;
+
+typedef void (function_ptr)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:29: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (function_ptr)();{{$}}
+
+// intentionally not LLVM style to check preservation of whitesapce
+typedef void (function_ptr2)
+    (
+        void
+    );
+// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef
+// CHECK-FIXES:      {{^typedef void \(function_ptr2\)$}}
+// CHECK-FIXES-NEXT: {{^    \($}}
+// CHECK-FIXES-NEXT: {{^        $}}
+// CHECK-FIXES-NEXT: {{^    \);$}}
+
+// intentionally not LLVM style to check preservation of whitesapce
+typedef
+void
+(
+*
+(
+*
+returns_fn_returns_fn_void_void_t2
+(
+void
+)
+)
+(
+void
+)
+)
+(
+void
+)
+;
+// CHECK-MESSAGES: :[[@LINE-11]]:1: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-8]]:1: warning: {{.*}} in typedef
+// CHECK-MESSAGES: :[[@LINE-5]]:1: warning: {{.*}} in typedef
+// CHECK-FIXES:      {{^typedef$}}
+// CHECK-FIXES-NEXT: {{^void$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NEXT: {{^\*$}}
+// CHECK-FIXES-NEXT: {{^returns_fn_returns_fn_void_void_t2$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT:  {{[^ ]}}
+// CHECK-FIXES:      {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT:  {{[^ ]}}
+// CHECK-FIXES:      {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\)$}}
+// CHECK-FIXES-NEXT: {{^\($}}
+// CHECK-FIXES-NOT:  {{[^ ]}}
+// CHECK-FIXES:      {{^\)$}}
+// CHECK-FIXES-NEXT: {{^;$}}
+
+
+void (gronk::*p1)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration
+// CHECK-FIXES: {{^}}void (gronk::*p1)();{{$}}
+
+void (gronk::*p2)(void) = &gronk::foo;
+// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}} in variable declaration with initializer
+// CHECK-FIXES: {{^}}void (gronk::*p2)() = &gronk::foo;{{$}}
+
+typedef void (gronk::*member_function_ptr)(void);
+// CHECK-MESSAGES: :[[@LINE-1]]:44: warning: {{.*}} in typedef
+// CHECK-FIXES: {{^}}typedef void (gronk::*member_function_ptr)();{{$}}
+
+// intentionally not LLVM style to check preservation of whitesapce
+typedef void (gronk::*member_function_ptr2)
+    (
+        void
+    );
+// CHECK-MESSAGES: :[[@LINE-2]]:9: warning: {{.*}} in typedef
+// CHECK-FIXES:      {{^typedef void \(gronk::\*member_function_ptr2\)$}}
+// CHECK-FIXES-NEXT: {{^    \($}}
+// CHECK-FIXES-NEXT: {{^        $}}
+// CHECK-FIXES-NEXT: {{^    \);$}}
+
+void gronk::foo() {
+  void (*f1)(void) = &::bar;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-FIXES: {{^  }}void (*f1)() = &::bar;{{$}}
+
+  void (*f2)(void);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration
+  // CHECK-FIXES: {{^  }}void (*f2)();{{$}}
+
+  // intentionally not LLVM style to check preservation of whitesapce
+  void (*f3)
+      (
+          void
+      );
+  // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: {{.*}} in variable declaration
+  // CHECK-FIXES:      {{^  }}void (*f3){{$}}
+  // CHECK-FIXES-NEXT: {{^      \($}}
+  // CHECK-FIXES-NEXT: {{^          $}}
+  // CHECK-FIXES-NEXT: {{^      \);$}}
+}
+
+void gronk::bar(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}void gronk::bar() {{{$}}
+  void (gronk::*p3)(void) = &gronk::foo;
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration with initializer
+  // CHECK-FIXES: {{^  }}void (gronk::*p3)() = &gronk::foo;{{$}}
+
+  void (gronk::*p4)(void);
+  // CHECK-MESSAGES: :[[@LINE-1]]:21: warning: {{.*}} in variable declaration
+  // CHECK-FIXES: {{^  }}void (gronk::*p4)();{{$}}
+
+  // intentionally not LLVM style to check preservation of whitesapce
+  void (gronk::*p5)
+      (
+          void
+      );
+  // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: {{.*}} in variable declaration
+  // CHECK-FIXES:      {{^  }}void (gronk::*p5){{$}}
+  // CHECK-FIXES-NEXT: {{^      \($}}
+  // CHECK-FIXES-NExT: {{^          $}}
+  // CHECK-FIXES-NExT: {{^      \);$}}
+}
+
+// intentionally not LLVM style to check preservation of whitesapce
+void gronk::bar2
+  (
+  void
+  )
+// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: {{.*}} in function definition
+// CHECK-FIXES:      {{^void gronk::bar2$}}
+// CHECK-FIXES-NEXT: {{^  \($}}
+// CHECK-FIXES-NEXT: {{^  $}}
+// CHECK-FIXES-NEXT: {{^  \)$}}
+{
+}
+
+gronk::gronk(void)
+// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}gronk::gronk(){{$}}
+  : f1(nullptr),
+  p1(nullptr) {
+}
+
+gronk::~gronk(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}gronk::~gronk() {{{$}}
+}
+
+class nutter {
+public:
+  nutter();
+};
+
+nutter::nutter(void) {
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: {{^}}nutter::nutter() {{{$}}
+  void (*f3)(void) = static_cast<void (*)(void)>(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-MESSAGES: :[[@LINE-2]]:43: warning: {{.*}} in named cast
+  // CHECK-FIXES: void (*f3)() = static_cast<void (*)()>(0);{{$}}
+
+  void (*f4)(void) = (void (*)(void)) 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: {{.*}} in cast expression
+  // CHECK-FIXES: void (*f4)() = (void (*)()) 0;{{$}}
+
+  void (*f5)(void) = reinterpret_cast<void (*)(void)>(0);
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-MESSAGES: :[[@LINE-2]]:48: warning: {{.*}} in named cast
+  // CHECK-FIXES: void (*f5)() = reinterpret_cast<void (*)()>(0);{{$}}
+
+  // intentionally not LLVM style to check preservation of whitesapce
+  void (*f6)(void) = static_cast<void (*)
+      (
+          void
+      )>(0);
+  // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in named cast
+  // CHECK-FIXES:      {{^  }}void (*f6)() = static_cast<void (*){{$}}
+  // CHECK-FIXES-NEXT: {{^      \($}}
+  // CHECK-FIXES-NEXT: {{^          $}}
+  // CHECK-FIXES-NEXT: {{^      }})>(0);{{$}}
+
+  // intentionally not LLVM style to check preservation of whitesapce
+  void (*f7)(void) = (void (*)
+      (
+          void
+      )) 0;
+  // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in cast expression
+  // CHECK-FIXES:      {{^  }}void (*f7)() = (void (*){{$}}
+  // CHECK-FIXES-NEXT: {{^      \($}}
+  // CHECK-FIXES-NEXT: {{^          $}}
+  // CHECK-FIXES-NEXT: {{^      \)\) 0;$}}
+
+  // intentionally not LLVM style to check preservation of whitesapce
+  void (*f8)(void) = reinterpret_cast<void (*)
+      (
+          void
+      )>(0);
+  // CHECK-MESSAGES: :[[@LINE-4]]:14: warning: {{.*}} in variable declaration with initializer
+  // CHECK-MESSAGES: :[[@LINE-3]]:11: warning: {{.*}} in named cast
+  // CHECK-FIXES:      {{^  }}void (*f8)() = reinterpret_cast<void (*){{$}}
+  // CHECK-FIXES-NEXT: {{^      \($}}
+  // CHECK-FIXES-NEXT: {{^          $}}
+  // CHECK-FIXES-NEXT: {{^      \)>\(0\);$}}
+
+  void (*o1)(int) = static_cast<void (*)(int)>(0);
+  void (*o2)(int) = (void (*)(int)) 0;
+  void (*o3)(int) = reinterpret_cast<void (*)(int)>(0);
+}
+
+class generator {
+public:
+  int operator()(void) { return 1; }
+  // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}} in function definition
+  // CHECK-FIXES: {{^  }}int operator()() { return 1; }{{$}}
+};
+
+void test_lambda_functions() {
+  auto lamb_duh = [](void (*fn)(void)) { (*fn)(); };
+  // CHECK-MESSAGES: :[[@LINE-1]]:33: warning: {{.*}} in variable declaration
+  // CHECK-FIXES: {{^  }}auto lamb_duh = [](void (*fn)()) { (*fn)(); };{{$}}
+
+  auto lambda_generator = [](void) { return 1; };
+  // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: {{.*}} in lambda expression
+  // CHECK-FIXES: {{^  }}auto lambda_generator = []() { return 1; };{{$}}
+
+  auto gen2 = []() { return 1; };
+
+  auto gen3 = []{ return 1; };
+
+  auto void_returner = [](void) -> void (*)(void) { return f1; };
+  // CHECK-MESSAGES: [[@LINE-1]]:27: warning: {{.*}} in lambda expression
+  // CHECK-MESSAGES: [[@LINE-2]]:45: warning: {{.*}} in lambda expression
+  // CHECK-FIXES: {{^  }}auto void_returner = []() -> void (*)() { return f1; };{{$}}
+}
+
+#define M(x) x
+
+M(void inmacro(void) {})
+// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: {{.*}} in function definition
+// CHECK-FIXES: M(void inmacro() {})
+
+#define F(A, B)        \
+  struct F_##A##_##B { \
+    F_##A##_##B(void); \
+  };                   \
+  F_##A##_##B::F_##A##_##B(void)
+
+F(Foo, Bar) {
+
+}
+
+struct DefinitionWithNoBody {
+  DefinitionWithNoBody(void) = delete;
+  // CHECK-MESSAGES: :[[@LINE-1]]:24: warning: {{.*}} in function definition
+  // CHECK-FIXES: DefinitionWithNoBody() = delete;
+};
+
+
+
+#define BODY {}
+#define LAMBDA1 [](void){}
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA1 [](){}
+
+#define LAMBDA2 [](void)BODY
+// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA2 []()BODY
+
+#define LAMBDA3(captures, args, body) captures args body
+#define WRAP(...) __VA_ARGS__
+
+#define LAMBDA4 (void)LAMBDA3([],(void),BODY)
+// CHECK-MESSAGES: :[[@LINE-1]]:35: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA4 (void)LAMBDA3([],(),BODY)
+
+#define LAMBDA5 []() -> void (*)(void) {return BODY;}
+// CHECK-MESSAGES: :[[@LINE-1]]:34: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+// CHECK-FIXES: LAMBDA5 []() -> void (*)() {return BODY;}
+void lambda_expression_with_macro_test(){
+  (void)LAMBDA1;
+  (void)LAMBDA2;
+  (void)LAMBDA3([], (void), BODY);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+  // CHECK-FIXES: (void)LAMBDA3([], (), BODY);
+
+  LAMBDA4;
+  LAMBDA5;
+  WRAP((void)WRAP(WRAP(LAMBDA3(WRAP([]), WRAP((void)), WRAP(BODY)))));
+  // CHECK-MESSAGES: :[[@LINE-1]]:48: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+  // CHECK-FIXES: WRAP((void)WRAP(WRAP(LAMBDA3(WRAP([]), WRAP(()), WRAP(BODY)))));
+
+  (void)WRAP([](void) {});
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+  // CHECK-FIXES: (void)WRAP([]() {});
+
+  [](void) BODY;
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: redundant void argument list in lambda expression [modernize-redundant-void-arg]
+  // CHECK-FIXES: []() BODY;
+}
+
+namespace qqq {
+void foo() BODY
+void bar(void) BODY;
+// CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition
+// CHECK-FIXES: void bar() BODY;
+}
+
+struct S_1 {
+  void g_1(void) const {
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+    // CHECK-FIXES: void g_1() const {
+    int a;
+    (void)a;
+  }
+
+  void g_2() const {
+    int a;
+    (void)a;
+  }
+};
+
+template <typename T0>
+struct S_2 {
+  void g_1(void) const {
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+    // CHECK-FIXES: void g_1() const {
+    int a;
+    (void)a;
+  }
+
+  void g_2() const {
+    int a;
+    (void)a;
+  }
+};
+
+template <typename T0>
+struct S_3 {
+  template <typename T1>
+  void g_1(void) const {
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+    // CHECK-FIXES: void g_1() const {
+    int a;
+    (void)a;
+  }
+  template <typename T2>
+  void g_2() const {
+    int a;
+    (void)a;
+  }
+};
+
+template <typename T1>
+void g_3(void) {
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: redundant void argument list in function definition [modernize-redundant-void-arg]
+  // CHECK-FIXES: void g_3() {
+  int a;
+  (void)a;
+}
+
+//Template instantiation
+void f_testTemplate() {
+  S_1();
+  S_2<int>();
+  S_3<int>();
+  g_3<int>();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-auto-ptr.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-auto-ptr.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-auto-ptr.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-auto-ptr.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,303 @@
+// RUN: %check_clang_tidy %s modernize-replace-auto-ptr %t -- -- -I %S/Inputs/modernize-replace-auto-ptr
+
+// CHECK-FIXES: #include <utility>
+
+#include "memory.h"
+
+// Instrumentation for auto_ptr_ref test.
+struct Base {};
+struct Derived : Base {};
+std::auto_ptr<Derived> create_derived_ptr();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated, use unique_ptr instead [modernize-replace-auto-ptr]
+// CHECK-FIXES: std::unique_ptr<Derived> create_derived_ptr();
+
+
+// Test function return values (declaration)
+std::auto_ptr<char> f_5();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
+// CHECK-FIXES: std::unique_ptr<char> f_5()
+
+
+// Test function parameters.
+void f_6(std::auto_ptr<int>);
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
+// CHECK-FIXES: void f_6(std::unique_ptr<int>);
+void f_7(const std::auto_ptr<int> &);
+// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: auto_ptr is deprecated
+// CHECK-FIXES: void f_7(const std::unique_ptr<int> &);
+
+
+// Test on record type fields.
+struct A {
+  std::auto_ptr<int> field;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> field;
+
+  typedef std::auto_ptr<int> int_ptr_type;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: auto_ptr is deprecated
+  // CHECK-FIXES: typedef std::unique_ptr<int> int_ptr_type;
+};
+
+
+// FIXME: Test template WITH instantiation.
+template <typename T> struct B {
+  typedef typename std::auto_ptr<T> created_type;
+  // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: auto_ptr is deprecated
+  // CHECK-FIXES: typedef typename std::unique_ptr<T> created_type;
+
+  created_type create() { return std::auto_ptr<T>(new T()); }
+  // CHECK-MESSAGES: :[[@LINE-1]]:39: warning: auto_ptr is deprecated
+  // CHECK-FIXES: created_type create() { return std::unique_ptr<T>(new T()); }
+};
+
+
+// Test 'using' in a namespace (declaration)
+namespace ns_1 {
+// Test multiple using declarations.
+  using std::auto_ptr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+  // CHECK-FIXES: using std::unique_ptr;
+  using std::auto_ptr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+  // CHECK-FIXES: using std::unique_ptr;
+}
+
+
+namespace ns_2 {
+template <typename T> struct auto_ptr {};
+}
+
+void f_1() {
+  std::auto_ptr<int> a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> a;
+
+  // Check that spaces aren't modified unnecessarily.
+  std:: auto_ptr <int> b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std:: unique_ptr <int> b;
+  std :: auto_ptr < char > c(new char());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std :: unique_ptr < char > c(new char());
+
+  // Test construction from a temporary.
+  std::auto_ptr<char> d = std::auto_ptr<char>();
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<char> d = std::unique_ptr<char>();
+
+  typedef std::auto_ptr<int> int_ptr_t;
+  // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: auto_ptr is deprecated
+  // CHECK-FIXES: typedef std::unique_ptr<int> int_ptr_t;
+  int_ptr_t e(new int());
+
+  // Test pointers.
+  std::auto_ptr<int> *f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> *f;
+
+  // Test 'static' declarations.
+  static std::auto_ptr<int> g;
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
+  // CHECK-FIXES: static std::unique_ptr<int> g;
+
+  // Test with cv-qualifiers.
+  const std::auto_ptr<int> h;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+  // CHECK-FIXES: const std::unique_ptr<int> h;
+  volatile std::auto_ptr<int> i;
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
+  // CHECK-FIXES: volatile std::unique_ptr<int> i;
+  const volatile std::auto_ptr<int> j;
+  // CHECK-MESSAGES: :[[@LINE-1]]:23: warning: auto_ptr is deprecated
+  // CHECK-FIXES: const volatile std::unique_ptr<int> j;
+
+  // Test auto and initializer-list.
+  auto k = std::auto_ptr<int>{};
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
+  // CHECK-FIXES: auto k = std::unique_ptr<int>{};
+  std::auto_ptr<int> l{std::auto_ptr<int>()};
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> l{std::unique_ptr<int>()};
+
+  // Test interlocked auto_ptr.
+  std::auto_ptr<std::auto_ptr<int> > m;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<std::unique_ptr<int> > m;
+
+  // Test temporaries.
+  std::auto_ptr<char>();
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<char>();
+
+  // Test void-specialization.
+  std::auto_ptr<void> n;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<void> n;
+
+  // Test template WITH instantiation (instantiation).
+  B<double> o;
+  std::auto_ptr<double> p(o.create());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<double> p(o.create());
+
+  // Test 'using' in a namespace ("definition").
+  ns_1::auto_ptr<int> q;
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: auto_ptr is deprecated
+  // CHECK-FIXES: ns_1::unique_ptr<int> q;
+
+  // Test construction with an 'auto_ptr_ref'.
+  std::auto_ptr<Base> r(create_derived_ptr());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<Base> r(create_derived_ptr());
+}
+
+// Test without the nested name specifiers.
+void f_2() {
+  using namespace std;
+
+  auto_ptr<int> a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: auto_ptr is deprecated
+  // CHECK-FIXES: unique_ptr<int> a;
+}
+
+// Test using declaration.
+void f_3() {
+  using std::auto_ptr;
+  // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: auto_ptr is deprecated
+  // CHECK-FIXES: using std::unique_ptr;
+
+  auto_ptr<int> a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: auto_ptr is deprecated
+  // CHECK-FIXES: unique_ptr<int> a;
+}
+
+// Test messing-up with macros.
+void f_4() {
+#define MACRO_1 <char>
+  std::auto_ptr MACRO_1 p(new char());
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr MACRO_1 p(new char());
+#define MACRO_2 auto_ptr
+  // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: auto_ptr is deprecated
+  // CHECK-FIXES: #define MACRO_2 unique_ptr
+  std::MACRO_2<int> q;
+#define MACRO_3(Type) std::auto_ptr<Type>
+  // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: auto_ptr is deprecated
+  // CHECK-FIXES: #define MACRO_3(Type) std::unique_ptr<Type>
+  MACRO_3(float)r(new float());
+#define MACRO_4 std::auto_ptr
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: auto_ptr is deprecated
+  // CHECK-FIXES: #define MACRO_4 std::unique_ptr
+  using MACRO_4;
+#undef MACRO_1
+#undef MACRO_2
+#undef MACRO_3
+#undef MACRO_4
+}
+
+// Test function return values (definition).
+std::auto_ptr<char> f_5()
+  // CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<char> f_5()
+{
+  // Test constructor.
+  return std::auto_ptr<char>(new char());
+  // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: auto_ptr is deprecated
+  // CHECK-FIXES: return std::unique_ptr<char>(new char());
+}
+
+// Test that non-std auto_ptr aren't replaced.
+void f_8() {
+  ns_2::auto_ptr<char> a;
+  using namespace ns_2;
+  auto_ptr<int> b;
+}
+
+// Fail to modify when the template is never instantiated.
+//
+// This might not be an issue. If it's never used it doesn't really matter if
+// it's changed or not. If it's a header and one of the source use it, then it
+// will still be changed.
+template <typename X>
+void f() {
+  std::auto_ptr<X> p;
+}
+
+// FIXME: Alias template could be replaced if a matcher existed.
+namespace std {
+template <typename T> using aaaaaaaa = auto_ptr<T>;
+}
+
+// We want to avoid replacing 'aaaaaaaa' by unique_ptr here. It's better to
+// change the type alias directly.
+std::aaaaaaaa<int> d;
+
+
+void takes_ownership_fn(std::auto_ptr<int> x);
+// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: auto_ptr is deprecated
+// CHECK-FIXES: void takes_ownership_fn(std::unique_ptr<int> x);
+
+std::auto_ptr<int> get_by_value();
+// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: auto_ptr is deprecated
+// CHECK-FIXES: std::unique_ptr<int> get_by_value();
+
+class Wrapper {
+ public:
+  std::auto_ptr<int> &get_wrapped();
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+
+ private:
+  std::auto_ptr<int> wrapped;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+};
+
+void f() {
+  std::auto_ptr<int> a, b, c;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> a, b, c;
+  Wrapper wrapper_a, wrapper_b;
+
+  a = b;
+  // CHECK-MESSAGES: :[[@LINE-1]]:7: warning: use std::move to transfer ownership
+  // CHECK-FIXES: a = std::move(b);
+
+  wrapper_a.get_wrapped() = wrapper_b.get_wrapped();
+  // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: use std::move to transfer ownership
+  // CHECK-FIXES: wrapper_a.get_wrapped() = std::move(wrapper_b.get_wrapped());
+
+  // Test that 'std::move()' is inserted when call to the
+  // copy-constructor are made.
+  takes_ownership_fn(c);
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::move to transfer ownership
+  // CHECK-FIXES: takes_ownership_fn(std::move(c));
+  takes_ownership_fn(wrapper_a.get_wrapped());
+  // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: use std::move to transfer ownership
+  // CHECK-FIXES: takes_ownership_fn(std::move(wrapper_a.get_wrapped()));
+
+  std::auto_ptr<int> d[] = { std::auto_ptr<int>(new int(1)),
+                             std::auto_ptr<int>(new int(2)) };
+  // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: auto_ptr is deprecated
+  // CHECK-MESSAGES: :[[@LINE-3]]:35: warning: auto_ptr is deprecated
+  // CHECK-MESSAGES: :[[@LINE-3]]:35: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> d[] = { std::unique_ptr<int>(new int(1)),
+  // CHECK-FIXES-NEXT:                         std::unique_ptr<int>(new int(2)) };
+  std::auto_ptr<int> e = d[0];
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: use std::move to transfer ownership
+  // CHECK: std::unique_ptr<int> e = std::move(d[0]);
+
+  // Test that std::move() is not used when assigning an rvalue
+  std::auto_ptr<int> f;
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> f;
+  f = std::auto_ptr<int>(new int(0));
+  // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: auto_ptr is deprecated
+  // CHECK-NEXT: f = std::unique_ptr<int>(new int(0));
+
+  std::auto_ptr<int> g = get_by_value();
+  // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: auto_ptr is deprecated
+  // CHECK-FIXES: std::unique_ptr<int> g = get_by_value();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-random-shuffle.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-random-shuffle.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-random-shuffle.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-replace-random-shuffle.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,57 @@
+// RUN: %check_clang_tidy %s modernize-replace-random-shuffle %t
+
+//CHECK-FIXES: #include <random>
+
+namespace std {
+template <typename T> struct vec_iterator {
+  T *ptr;
+  vec_iterator operator++(int);
+};
+
+template <typename T> struct vector {
+  typedef vec_iterator<T> iterator;
+
+  iterator begin();
+  iterator end();
+};
+
+template <typename FwIt>
+void random_shuffle(FwIt begin, FwIt end);
+
+template <typename FwIt, typename randomFunc>
+void random_shuffle(FwIt begin, FwIt end, randomFunc& randomfunc);
+
+template <typename FwIt>
+void shuffle(FwIt begin, FwIt end);
+} // namespace std
+
+// Random Func
+int myrandom (int i) { return i;}
+
+using namespace std;
+
+int main() {
+  std::vector<int> vec;
+
+  std::random_shuffle(vec.begin(), vec.end());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' instead
+  // CHECK-FIXES: std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+  std::shuffle(vec.begin(), vec.end());
+
+  random_shuffle(vec.begin(), vec.end());
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' instead
+  // CHECK-FIXES: shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+  
+  std::random_shuffle(vec.begin(), vec.end(), myrandom);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' and an alternative random mechanism instead
+  // CHECK-FIXES: std::shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+  random_shuffle(vec.begin(), vec.end(), myrandom);
+  // CHECK-MESSAGES: [[@LINE-1]]:3: warning: 'std::random_shuffle' has been removed in C++17; use 'std::shuffle' and an alternative random mechanism instead
+  // CHECK-FIXES: shuffle(vec.begin(), vec.end(), std::mt19937(std::random_device()()));
+
+  shuffle(vec.begin(), vec.end());
+
+  return 0;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-return-braced-init-list.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-return-braced-init-list.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-return-braced-init-list.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-return-braced-init-list.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,199 @@
+// RUN: %check_clang_tidy -std=c++14 %s modernize-return-braced-init-list %t
+// FIXME: Fix the checker to work in C++17 mode.
+
+namespace std {
+typedef decltype(sizeof(int)) size_t;
+
+// libc++'s implementation
+template <class _E>
+class initializer_list {
+  const _E *__begin_;
+  size_t __size_;
+
+  initializer_list(const _E *__b, size_t __s)
+      : __begin_(__b),
+        __size_(__s) {}
+
+public:
+  typedef _E value_type;
+  typedef const _E &reference;
+  typedef const _E &const_reference;
+  typedef size_t size_type;
+
+  typedef const _E *iterator;
+  typedef const _E *const_iterator;
+
+  initializer_list() : __begin_(nullptr), __size_(0) {}
+
+  size_t size() const { return __size_; }
+  const _E *begin() const { return __begin_; }
+  const _E *end() const { return __begin_ + __size_; }
+};
+
+template <typename T>
+class vector {
+public:
+  vector(T) {}
+  vector(std::initializer_list<T>) {}
+};
+}
+
+class Bar {};
+
+Bar b0;
+
+class Foo {
+public:
+  Foo(Bar) {}
+  explicit Foo(Bar, unsigned int) {}
+  Foo(unsigned int) {}
+};
+
+class Baz {
+public:
+  Foo m() {
+    Bar bm;
+    return Foo(bm);
+    // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: avoid repeating the return type from the declaration; use a braced initializer list instead [modernize-return-braced-init-list]
+    // CHECK-FIXES: return {bm};
+  }
+};
+
+class Quux : public Foo {
+public:
+  Quux(Bar bar) : Foo(bar) {}
+  Quux(unsigned, unsigned, unsigned k = 0) : Foo(k) {}
+};
+
+Foo f() {
+  Bar b1;
+  return Foo(b1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {b1};
+}
+
+Foo f2() {
+  Bar b2;
+  return {b2};
+}
+
+auto f3() {
+  Bar b3;
+  return Foo(b3);
+}
+
+#define A(b) Foo(b)
+
+Foo f4() {
+  Bar b4;
+  return A(b4);
+}
+
+Foo f5() {
+  Bar b5;
+  return Quux(b5);
+}
+
+Foo f6() {
+  Bar b6;
+  return Foo(b6, 1);
+}
+
+std::vector<int> f7() {
+  int i7 = 1;
+  return std::vector<int>(i7);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+}
+
+Bar f8() {
+  return {};
+}
+
+Bar f9() {
+  return Bar();
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+}
+
+Bar f10() {
+  return Bar{};
+}
+
+Foo f11(Bar b11) {
+  return Foo(b11);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {b11};
+}
+
+Foo f12() {
+  return f11(Bar());
+}
+
+Foo f13() {
+  return Foo(Bar()); // 13
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {Bar()}; // 13
+}
+
+Foo f14() {
+  // FIXME: Type narrowing should not occur!
+  return Foo(-1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {-1};
+}
+
+Foo f15() {
+  return Foo(f10());
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {f10()};
+}
+
+Quux f16() {
+  return Quux(1, 2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {1, 2};
+}
+
+Quux f17() {
+  return Quux(1, 2, 3);
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: avoid repeating the return type
+  // CHECK-FIXES: return {1, 2, 3};
+}
+
+template <typename T>
+T f19() {
+  return T();
+}
+
+Bar i1 = f19<Bar>();
+Baz i2 = f19<Baz>();
+
+template <typename T>
+Foo f20(T t) {
+  return Foo(t);
+}
+
+Foo i3 = f20(b0);
+
+template <typename T>
+class BazT {
+public:
+  T m() {
+    Bar b;
+    return T(b);
+  }
+
+  Foo m2(T t) {
+    return Foo(t);
+  }
+};
+
+BazT<Foo> bazFoo;
+Foo i4 = bazFoo.m();
+Foo i5 = bazFoo.m2(b0);
+
+BazT<Quux> bazQuux;
+Foo i6 = bazQuux.m();
+Foo i7 = bazQuux.m2(b0);
+
+auto v1 = []() { return std::vector<int>({1, 2}); }();
+auto v2 = []() -> std::vector<int> { return std::vector<int>({1, 2}); }();

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-shrink-to-fit.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-shrink-to-fit.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-shrink-to-fit.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-shrink-to-fit.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,87 @@
+// RUN: %check_clang_tidy %s modernize-shrink-to-fit %t
+
+namespace std {
+template <typename T> struct vector { void swap(vector &other); };
+}
+
+void f() {
+  std::vector<int> v;
+
+  std::vector<int>(v).swap(v);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should be used to reduce the capacity of a shrinkable container [modernize-shrink-to-fit]
+  // CHECK-FIXES: {{^  }}v.shrink_to_fit();{{$}}
+
+  std::vector<int> &vref = v;
+  std::vector<int>(vref).swap(vref);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}vref.shrink_to_fit();{{$}}
+
+  std::vector<int> *vptr = &v;
+  std::vector<int>(*vptr).swap(*vptr);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}vptr->shrink_to_fit();{{$}}
+}
+
+struct X {
+  std::vector<int> v;
+  void f() {
+    std::vector<int>(v).swap(v);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should
+    // CHECK-FIXES: {{^    }}v.shrink_to_fit();{{$}}
+
+    std::vector<int> *vptr = &v;
+    std::vector<int>(*vptr).swap(*vptr);
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should
+    // CHECK-FIXES: {{^    }}vptr->shrink_to_fit();{{$}}
+  }
+};
+
+template <typename T> void g() {
+  std::vector<int> v;
+  std::vector<int>(v).swap(v);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}v.shrink_to_fit();{{$}}
+
+  std::vector<T> v2;
+  std::vector<T>(v2).swap(v2);
+  // CHECK-FIXES: {{^  }}std::vector<T>(v2).swap(v2);{{$}}
+}
+
+template <typename T> void g2() {
+  std::vector<int> v;
+  std::vector<int>(v).swap(v);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}v.shrink_to_fit();{{$}}
+
+  T v3;
+  T(v3).swap(v3);
+  // CHECK-FIXES: {{^  }}T(v3).swap(v3);{{$}}
+}
+
+#define COPY_AND_SWAP_INT_VEC(x) std::vector<int>(x).swap(x)
+// CHECK-FIXES: #define COPY_AND_SWAP_INT_VEC(x) std::vector<int>(x).swap(x)
+
+void h() {
+  g<int>();
+  g<double>();
+  g<bool>();
+  g2<std::vector<int>>();
+  std::vector<int> v;
+  COPY_AND_SWAP_INT_VEC(v);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}COPY_AND_SWAP_INT_VEC(v);{{$}}
+}
+
+void PR38315() {
+  typedef std::vector<int> Vector;
+  Vector v;
+  Vector(v).swap(v);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}v.shrink_to_fit();{{$}}
+
+  using Vector2 = std::vector<int>;
+  Vector2 v2;
+  Vector2(v2).swap(v2);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should
+  // CHECK-FIXES: {{^  }}v2.shrink_to_fit();{{$}}
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-unary-static-assert.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-unary-static-assert.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-unary-static-assert.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-unary-static-assert.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy -std=c++17-or-later %s modernize-unary-static-assert %t
+
+#define FOO static_assert(sizeof(a) <= 15, "");
+#define MSG ""
+
+void f_textless(int a) {
+  static_assert(sizeof(a) <= 10, "");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when the string literal is an empty string [modernize-unary-static-assert]
+  // CHECK-FIXES: {{^}}  static_assert(sizeof(a) <= 10 );{{$}}
+  static_assert(sizeof(a) <= 12, L"");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use unary 'static_assert' when
+  // CHECK-FIXES: {{^}}  static_assert(sizeof(a) <= 12 );{{$}}
+  FOO
+  // CHECK-FIXES: {{^}}  FOO{{$}}
+  static_assert(sizeof(a) <= 17, MSG);
+  // CHECK-FIXES: {{^}}  static_assert(sizeof(a) <= 17, MSG);{{$}}
+}
+
+void f_with_tex(int a) {
+  static_assert(sizeof(a) <= 10, "Size of variable a is out of range!");
+}
+
+void f_unary(int a) { static_assert(sizeof(a) <= 10); }
+
+void f_incorrect_assert() { static_assert(""); }

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast-remove-stars.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast-remove-stars.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast-remove-stars.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast-remove-stars.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,233 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: '1'} , {key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN:   -- -frtti
+
+struct A {
+  virtual ~A() {}
+};
+
+struct B : public A {};
+
+struct C {};
+
+void f_static_cast() {
+  long l = 1;
+  int i1 = static_cast<int>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  i1 = static_cast<int>(l);
+
+  const int i2 = static_cast<int>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto  i2 = static_cast<int>(l);
+
+  long long ll = static_cast<long long>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  ll = static_cast<long long>(l);
+  unsigned long long ull = static_cast<unsigned long long>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  ull = static_cast<unsigned long long>(l);
+  unsigned int ui = static_cast<unsigned int>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  ui = static_cast<unsigned int>(l);
+  long double ld = static_cast<long double>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  ld = static_cast<long double>(l);
+
+  A *a = new B();
+  B *b1 = static_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto b1 = static_cast<B *>(a);
+
+  B *const b2 = static_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto const b2 = static_cast<B *>(a);
+
+  const B *b3 = static_cast<const B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto b3 = static_cast<const B *>(a);
+
+  B &b4 = static_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &b4 = static_cast<B &>(*a);
+
+  const B &b5 = static_cast<const B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto  &b5 = static_cast<const B &>(*a);
+
+  B &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+
+  // Don't warn when non-cast involved
+  long double cast = static_cast<long double>(l), noncast = 5;
+
+  // Don't warn when auto is already being used.
+  auto i3 = static_cast<int>(l);
+  auto *b8 = static_cast<B *>(a);
+  auto &b9 = static_cast<B &>(*a);
+}
+
+void f_dynamic_cast() {
+  A *a = new B();
+  B *b1 = dynamic_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto b1 = dynamic_cast<B *>(a);
+
+  B &b2 = dynamic_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &b2 = dynamic_cast<B &>(*a);
+}
+
+void f_reinterpret_cast() {
+  auto *a = new A();
+  C *c1 = reinterpret_cast<C *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto c1 = reinterpret_cast<C *>(a);
+
+  C &c2 = reinterpret_cast<C &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &c2 = reinterpret_cast<C &>(*a);
+}
+
+void f_const_cast() {
+  const A *a1 = new A();
+  A *a2 = const_cast<A *>(a1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto a2 = const_cast<A *>(a1);
+  A &a3 = const_cast<A &>(*a1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &a3 = const_cast<A &>(*a1);
+}
+
+typedef unsigned char xmlChar;
+#define BAD_CAST (xmlChar *)
+
+#define XMLCHAR_CAST(x) (xmlChar *)(x)
+
+#define CAST_IN_MACRO(x)         \
+  do {                           \
+    xmlChar *s = (xmlChar *)(x); \
+  } while (false);
+// CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
+
+void f_cstyle_cast() {
+  auto *a = new A();
+  C *c1 = (C *)a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto c1 = (C *)a;
+
+  C &c2 = (C &)*a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &c2 = (C &)*a;
+
+  xmlChar  *s = BAD_CAST "xml";
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto s = BAD_CAST "xml";
+  xmlChar  *t = XMLCHAR_CAST("xml");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto t = XMLCHAR_CAST("xml");
+  CAST_IN_MACRO("xml");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+}
+
+void f_functional_cast() {
+  long l = 1;
+  int i1 = int(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  i1 = int(l);
+
+  B b;
+  A a = A(b);
+}
+
+class StringRef
+{
+public:
+  StringRef(const char *);
+  const char *begin() const;
+  const char *end() const;
+};
+
+template <typename T, typename U>
+T template_value_cast(const U &u);
+
+template <typename T, typename U>
+T *template_pointer_cast(U *u);
+
+template <typename T, typename U>
+T &template_reference_cast(U &u);
+
+template <typename T, typename U>
+const T *template_const_pointer_cast(const U *u);
+
+template <typename T, typename U>
+const T &template_const_reference_cast(const U &u);
+
+template <typename T>
+T template_value_get(StringRef s);
+
+struct S {
+  template <typename T>
+  const T *template_member_get();
+};
+
+template <typename T>
+T max(T t1, T t2);
+
+void f_template_cast()
+{
+  double d = 0;
+  int i1 = template_value_cast<int>(d);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  i1 = template_value_cast<int>(d);
+
+  A *a = new B();
+  B *b1 = template_value_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto b1 = template_value_cast<B *>(a);
+  B &b2 = template_value_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &b2 = template_value_cast<B &>(*a);
+  B *b3 = template_pointer_cast<B>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto b3 = template_pointer_cast<B>(a);
+  B &b4 = template_reference_cast<B>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto  &b4 = template_reference_cast<B>(*a);
+  const B *b5 = template_const_pointer_cast<B>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto b5 = template_const_pointer_cast<B>(a);
+  const B &b6 = template_const_reference_cast<B>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto  &b6 = template_const_reference_cast<B>(*a);
+  B *b7 = template_value_get<B *>("foo");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto b7 = template_value_get<B *>("foo");
+  B *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto b8 = template_value_get<B *>("foo"), b9 = template_value_get<B *>("bar");
+
+  S s;
+  const B *b10 = s.template_member_get<B>();
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto b10 = s.template_member_get<B>();
+
+  // Don't warn when auto is already being used.
+  auto i2 = template_value_cast<int>(d);
+  auto *i3 = template_value_cast<int *>(d);
+  auto **i4 = template_value_cast<int **>(d);
+  auto &i5 = template_reference_cast<int>(d);
+
+  // Don't warn for implicit template arguments.
+  int i6 = max(i1, i2);
+
+  // Don't warn for mismatched var and initializer types.
+  A *a1 = template_value_cast<B *>(a);
+
+  // Don't warn for mismatched var types.
+  B *b11 = template_value_get<B *>("foo"), b12 = template_value_get<B>("bar");
+
+  // Don't warn for implicit variables.
+  for (auto &c : template_reference_cast<StringRef>(*a)) {
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-cast.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,233 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN:   -- -I %S/Inputs/modernize-use-auto -frtti
+
+struct A {
+  virtual ~A() {}
+};
+
+struct B : public A {};
+
+struct C {};
+
+void f_static_cast() {
+  long l = 1;
+  int i1 = static_cast<int>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto i1 = static_cast<int>(l);
+
+  const int i2 = static_cast<int>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto i2 = static_cast<int>(l);
+
+  long long ll = static_cast<long long>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto ll = static_cast<long long>(l);
+  unsigned long long ull = static_cast<unsigned long long>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto ull = static_cast<unsigned long long>(l);
+  unsigned int ui = static_cast<unsigned int>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto ui = static_cast<unsigned int>(l);
+  long double ld = static_cast<long double>(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto ld = static_cast<long double>(l);
+
+  A *a = new B();
+  B *b1 = static_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *b1 = static_cast<B *>(a);
+
+  B *const b2 = static_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *const b2 = static_cast<B *>(a);
+
+  const B *b3 = static_cast<const B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto *b3 = static_cast<const B *>(a);
+
+  B &b4 = static_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &b4 = static_cast<B &>(*a);
+
+  const B &b5 = static_cast<const B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto &b5 = static_cast<const B &>(*a);
+
+  B &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &b6 = static_cast<B &>(*a), &b7 = static_cast<B &>(*a);
+
+  // Don't warn when non-cast involved
+  long double cast = static_cast<long double>(l), noncast = 5;
+
+  // Don't warn when auto is already being used.
+  auto i3 = static_cast<int>(l);
+  auto *b8 = static_cast<B *>(a);
+  auto &b9 = static_cast<B &>(*a);
+}
+
+void f_dynamic_cast() {
+  A *a = new B();
+  B *b1 = dynamic_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *b1 = dynamic_cast<B *>(a);
+
+  B &b2 = dynamic_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &b2 = dynamic_cast<B &>(*a);
+}
+
+void f_reinterpret_cast() {
+  auto *a = new A();
+  C *c1 = reinterpret_cast<C *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *c1 = reinterpret_cast<C *>(a);
+
+  C &c2 = reinterpret_cast<C &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &c2 = reinterpret_cast<C &>(*a);
+}
+
+void f_const_cast() {
+  const A *a1 = new A();
+  A *a2 = const_cast<A *>(a1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *a2 = const_cast<A *>(a1);
+  A &a3 = const_cast<A &>(*a1);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &a3 = const_cast<A &>(*a1);
+}
+
+typedef unsigned char xmlChar;
+#define BAD_CAST (xmlChar *)
+
+#define XMLCHAR_CAST(x) (xmlChar *)(x)
+
+#define CAST_IN_MACRO(x)         \
+  do {                           \
+    xmlChar *s = (xmlChar *)(x); \
+  } while (false);
+// CHECK-FIXES: xmlChar *s = (xmlChar *)(x);
+
+void f_cstyle_cast() {
+  auto *a = new A();
+  C *c1 = (C *)a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *c1 = (C *)a;
+
+  C &c2 = (C &)*a;
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &c2 = (C &)*a;
+
+  xmlChar *s = BAD_CAST "xml";
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *s = BAD_CAST "xml";
+  xmlChar *t = XMLCHAR_CAST("xml");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *t = XMLCHAR_CAST("xml");
+  CAST_IN_MACRO("xml");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+}
+
+void f_functional_cast() {
+  long l = 1;
+  int i1 = int(l);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name
+  // CHECK-FIXES: auto i1 = int(l);
+
+  B b;
+  A a = A(b);
+}
+
+class StringRef
+{
+public:
+  StringRef(const char *);
+  const char *begin() const;
+  const char *end() const;
+};
+
+template <typename T, typename U>
+T template_value_cast(const U &u);
+
+template <typename T, typename U>
+T *template_pointer_cast(U *u);
+
+template <typename T, typename U>
+T &template_reference_cast(U &u);
+
+template <typename T, typename U>
+const T *template_const_pointer_cast(const U *u);
+
+template <typename T, typename U>
+const T &template_const_reference_cast(const U &u);
+
+template <typename T>
+T template_value_get(StringRef s);
+
+struct S {
+  template <typename T>
+  const T *template_member_get();
+};
+
+template <typename T>
+T max(T t1, T t2);
+
+void f_template_cast()
+{
+  double d = 0;
+  int i1 = template_value_cast<int>(d);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto i1 = template_value_cast<int>(d);
+
+  A *a = new B();
+  B *b1 = template_value_cast<B *>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *b1 = template_value_cast<B *>(a);
+  B &b2 = template_value_cast<B &>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &b2 = template_value_cast<B &>(*a);
+  B *b3 = template_pointer_cast<B>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *b3 = template_pointer_cast<B>(a);
+  B &b4 = template_reference_cast<B>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto &b4 = template_reference_cast<B>(*a);
+  const B *b5 = template_const_pointer_cast<B>(a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto *b5 = template_const_pointer_cast<B>(a);
+  const B &b6 = template_const_reference_cast<B>(*a);
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto &b6 = template_const_reference_cast<B>(*a);
+  B *b7 = template_value_get<B *>("foo");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *b7 = template_value_get<B *>("foo");
+  B *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: auto *b8 = template_value_get<B *>("foo"), *b9 = template_value_get<B *>("bar");
+
+  S s;
+  const B *b10 = s.template_member_get<B>();
+  // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: use auto when initializing with a template cast to avoid duplicating the type name
+  // CHECK-FIXES: const auto *b10 = s.template_member_get<B>();
+
+  // Don't warn when auto is already being used.
+  auto i2 = template_value_cast<int>(d);
+  auto *i3 = template_value_cast<int *>(d);
+  auto **i4 = template_value_cast<int **>(d);
+  auto &i5 = template_reference_cast<int>(d);
+
+  // Don't warn for implicit template arguments.
+  int i6 = max(i1, i2);
+
+  // Don't warn for mismatched var and initializer types.
+  A *a1 = template_value_cast<B *>(a);
+
+  // Don't warn for mismatched var types.
+  B *b11 = template_value_get<B *>("foo"), b12 = template_value_get<B>("bar");
+
+  // Don't warn for implicit variables.
+  for (auto &c : template_reference_cast<StringRef>(*a)) {
+  }
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-iterator.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-iterator.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-iterator.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-iterator.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,320 @@
+// RUN: %check_clang_tidy -std=c++11,c++14 %s modernize-use-auto %t -- -- -I %S/Inputs/modernize-use-auto
+// FIXME: Fix the checker to work in C++17 mode.
+
+#include "containers.h"
+
+void f_array() {
+  std::array<int, 4> C;
+  std::array<int, 4>::iterator ArrayI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators [modernize-use-auto]
+  // CHECK-FIXES: auto ArrayI1 = C.begin();
+
+  std::array<int, 5>::reverse_iterator ArrayI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ArrayI2 = C.rbegin();
+
+  const std::array<int, 3> D;
+  std::array<int, 3>::const_iterator ArrayI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ArrayI3 = D.begin();
+
+  std::array<int, 5>::const_reverse_iterator ArrayI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ArrayI4 = D.rbegin();
+}
+
+void f_deque() {
+  std::deque<int> C;
+  std::deque<int>::iterator DequeI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto DequeI1 = C.begin();
+
+  std::deque<int>::reverse_iterator DequeI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto DequeI2 = C.rbegin();
+
+  const std::deque<int> D;
+  std::deque<int>::const_iterator DequeI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto DequeI3 = D.begin();
+
+  std::deque<int>::const_reverse_iterator DequeI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto DequeI4 = D.rbegin();
+}
+
+void f_forward_list() {
+  std::forward_list<int> C;
+  std::forward_list<int>::iterator FListI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto FListI1 = C.begin();
+
+  const std::forward_list<int> D;
+  std::forward_list<int>::const_iterator FListI2 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto FListI2 = D.begin();
+}
+
+void f_list() {
+  std::list<int> C;
+  std::list<int>::iterator ListI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ListI1 = C.begin();
+  std::list<int>::reverse_iterator ListI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ListI2 = C.rbegin();
+
+  const std::list<int> D;
+  std::list<int>::const_iterator ListI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ListI3 = D.begin();
+  std::list<int>::const_reverse_iterator ListI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto ListI4 = D.rbegin();
+}
+
+void f_vector() {
+  std::vector<int> C;
+  std::vector<int>::iterator VecI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto VecI1 = C.begin();
+
+  std::vector<int>::reverse_iterator VecI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto VecI2 = C.rbegin();
+
+  const std::vector<int> D;
+  std::vector<int>::const_iterator VecI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto VecI3 = D.begin();
+
+  std::vector<int>::const_reverse_iterator VecI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto VecI4 = D.rbegin();
+}
+
+void f_map() {
+  std::map<int, int> C;
+  std::map<int, int>::iterator MapI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MapI1 = C.begin();
+
+  std::map<int, int>::reverse_iterator MapI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MapI2 = C.rbegin();
+
+  const std::map<int, int> D;
+  std::map<int, int>::const_iterator MapI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MapI3 = D.begin();
+
+  std::map<int, int>::const_reverse_iterator MapI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MapI4 = D.rbegin();
+}
+
+void f_multimap() {
+  std::multimap<int, int> C;
+  std::multimap<int, int>::iterator MMapI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MMapI1 = C.begin();
+
+  std::multimap<int, int>::reverse_iterator MMapI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MMapI2 = C.rbegin();
+
+  const std::multimap<int, int> D;
+  std::multimap<int, int>::const_iterator MMapI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MMapI3 = D.begin();
+
+  std::multimap<int, int>::const_reverse_iterator MMapI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MMapI4 = D.rbegin();
+}
+
+void f_set() {
+  std::set<int> C;
+  std::set<int>::iterator SetI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto SetI1 = C.begin();
+
+  std::set<int>::reverse_iterator SetI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto SetI2 = C.rbegin();
+
+  const std::set<int> D;
+  std::set<int>::const_iterator SetI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto SetI3 = D.begin();
+
+  std::set<int>::const_reverse_iterator SetI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto SetI4 = D.rbegin();
+}
+
+void f_multiset() {
+  std::multiset<int> C;
+  std::multiset<int>::iterator MSetI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MSetI1 = C.begin();
+
+  std::multiset<int>::reverse_iterator MSetI2 = C.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MSetI2 = C.rbegin();
+
+  const std::multiset<int> D;
+  std::multiset<int>::const_iterator MSetI3 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MSetI3 = D.begin();
+
+  std::multiset<int>::const_reverse_iterator MSetI4 = D.rbegin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto MSetI4 = D.rbegin();
+}
+
+void f_unordered_map() {
+  std::unordered_map<int, int> C;
+  std::unordered_map<int, int>::iterator UMapI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto UMapI1 = C.begin();
+
+  const std::unordered_map<int, int> D;
+  std::unordered_map<int, int>::const_iterator UMapI2 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto UMapI2 = D.begin();
+}
+
+void f_unordered_multimap() {
+  std::unordered_multimap<int, int> C;
+  std::unordered_multimap<int, int>::iterator UMMapI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto UMMapI1 = C.begin();
+
+  const std::unordered_multimap<int, int> D;
+  std::unordered_multimap<int, int>::const_iterator UMMapI2 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto UMMapI2 = D.begin();
+}
+
+void f_unordered_set() {
+  std::unordered_set<int> C;
+  std::unordered_set<int>::iterator USetI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto USetI1 = C.begin();
+
+  const std::unordered_set<int> D;
+  std::unordered_set<int>::const_iterator USetI2 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto USetI2 = D.begin();
+}
+
+void f_unordered_multiset() {
+  std::unordered_multiset<int> C;
+  std::unordered_multiset<int>::iterator UMSetI1 = C.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto UMSetI1 = C.begin();
+
+  const std::unordered_multiset<int> D;
+  std::unordered_multiset<int>::const_iterator UMSetI2 = D.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto UMSetI2 = D.begin();
+}
+
+typedef std::vector<int>::iterator int_iterator;
+
+std::vector<int> Vec;
+std::unordered_map<int, int> Map;
+
+void sugar() {
+  // Types with more sugar should work. Types with less should not.
+  int_iterator more_sugar = Vec.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto more_sugar = Vec.begin();
+}
+
+void initializer_list() {
+  // Initialization from initializer lists isn't allowed. Using 'auto' would
+  // result in std::initializer_list being deduced for the type.
+  std::unordered_map<int, int>::iterator I{Map.begin()};
+  std::unordered_map<int, int>::iterator I2 = {Map.begin()};
+}
+
+void construction() {
+  // Various forms of construction. Default constructors and constructors with
+  // all-default parameters shouldn't get transformed. Construction from other
+  // types is also not allowed.
+
+  std::unordered_map<int, int>::iterator copy(Map.begin());
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto copy(Map.begin());
+
+  std::unordered_map<int, int>::iterator def;
+  std::unordered_map<int, int>::const_iterator constI;
+
+  // Implicit conversion.
+  std::unordered_map<int, int>::const_iterator constI2 = def;
+  std::unordered_map<int, int>::const_iterator constI3(def);
+
+  // Explicit conversion
+  std::unordered_map<int, int>::const_iterator constI4
+      = std::unordered_map<int, int>::const_iterator(def);
+  // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto constI4
+  // CHECK-FIXES-NEXT: = std::unordered_map<int, int>::const_iterator(def);
+}
+
+void pointer_to_iterator() {
+  int_iterator I = Vec.begin();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto I = Vec.begin();
+
+  // Pointers and references to iterators are not transformed.
+  int_iterator *IPtr = &I;
+  int_iterator &IRef = I;
+}
+
+void loop() {
+  for (std::vector<int>::iterator I = Vec.begin(); I != Vec.end(); ++I) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
+    // CHECK-FIXES: for (auto I = Vec.begin(); I != Vec.end(); ++I)
+  }
+
+  for (int_iterator I = Vec.begin(), E = Vec.end(); I != E; ++I) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
+    // CHECK-FIXES: for (auto I = Vec.begin(), E = Vec.end(); I != E; ++I)
+  }
+
+  std::vector<std::vector<int>::iterator> IterVec;
+  for (std::vector<int>::iterator I : IterVec) {
+    // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: use auto when declaring iterators
+    // CHECK-FIXES: for (auto I : IterVec)
+  }
+}
+
+void cv_qualifiers() {
+  // Make sure references and cv qualifiers don't get removed (i.e. replaced
+  // with just 'auto').
+  const auto & I = Vec.begin();
+  auto && I2 = Vec.begin();
+}
+
+void cleanup() {
+  // Passing a string as an argument to introduce a temporary object that will
+  // create an expression with cleanups.
+  std::map<std::string, int> MapFind;
+  std::map<std::string, int>::iterator I = MapFind.find("foo");
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto I = MapFind.find("foo");
+}
+
+void declaration_lists() {
+  // Declaration lists that match the declaration type with written no-list
+  // initializer are transformed.
+  std::vector<int>::iterator I = Vec.begin(), E = Vec.end();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when declaring iterators
+  // CHECK-FIXES: auto I = Vec.begin(), E = Vec.end();
+
+  // Declaration lists with non-initialized variables should not be transformed.
+  std::vector<int>::iterator J = Vec.begin(), K;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-min-type-name-length.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-min-type-name-length.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-min-type-name-length.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-min-type-name-length.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,85 @@
+// RUN: %check_clang_tidy -check-suffix=0-0 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=0-8 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=1-0 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- -frtti
+// RUN: %check_clang_tidy -check-suffix=1-8 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- -frtti
+
+template <class T> extern T foo();
+template <class T> struct P {  explicit P(T t) : t_(t) {}  T t_;};
+template <class T> P<T> *foo_ptr();
+template <class T> P<T> &foo_ref();
+
+int bar() {
+  {
+    // Lenth(long) = 4
+    long i = static_cast<long>(foo<long>());
+    // CHECK-FIXES-0-0: auto i = {{.*}}
+    // CHECK-FIXES-0-8: long i = {{.*}}
+    // CHECK-FIXES-1-0: auto  i = {{.*}}
+    // CHECK-FIXES-1-8: long i = {{.*}}
+    const long ci = static_cast<long>(foo<const long>());
+    // CHECK-FIXES-0-0: auto ci = {{.*}}
+    // CHECK-FIXES-0-8: long ci = {{.*}}
+    // CHECK-FIXES-1-0: auto  ci = {{.*}}
+    // CHECK-FIXES-1-8: long ci = {{.*}}
+    long *pi = static_cast<long *>(foo<long *>());
+    // CHECK-FIXES-0-0: auto *pi = {{.*}}
+    // CHECK-FIXES-0-8: long *pi = {{.*}}
+    // CHECK-FIXES-1-0: auto pi = {{.*}}
+    // CHECK-FIXES-1-8: long *pi = {{.*}}
+
+    // Length(long       *) is still 5
+    long      *     pi2 = static_cast<long *>(foo<long *>());
+    // CHECK-FIXES-0-0: auto      *     pi2 = {{.*}}
+    // CHECK-FIXES-0-8: long      *     pi2 = {{.*}}
+    // CHECK-FIXES-1-0: auto      pi2 = {{.*}}
+    // CHECK-FIXES-1-8: long      *     pi2 = {{.*}}
+
+    // Length(long **) = 6
+    long **ppi = static_cast<long **>(foo<long **>());
+    // CHECK-FIXES-0-0: auto **ppi = {{.*}}
+    // CHECK-FIXES-0-8: long **ppi = {{.*}}
+    // CHECK-FIXES-1-0: auto ppi = {{.*}}
+    // CHECK-FIXES-1-8: long **ppi = {{.*}}
+  }
+
+  {
+    // Lenth(long int) = 4 + 1 + 3 = 8
+    // Lenth(long        int) is still 8
+    long int i = static_cast<long int>(foo<long int>());
+    // CHECK-FIXES-0-0: auto i = {{.*}}
+    // CHECK-FIXES-0-8: auto i = {{.*}}
+    // CHECK-FIXES-1-0: auto  i = {{.*}}
+    // CHECK-FIXES-1-8: auto  i = {{.*}}
+
+    long int *pi = static_cast<long int *>(foo<long int *>());
+    // CHECK-FIXES-0-0: auto *pi = {{.*}}
+    // CHECK-FIXES-0-8: auto *pi = {{.*}}
+    // CHECK-FIXES-1-0: auto pi = {{.*}}
+    // CHECK-FIXES-1-8: auto pi = {{.*}}
+  }
+
+  // Templates
+  {
+    // Length(P<long>) = 7
+    P<long>& i = static_cast<P<long>&>(foo_ref<long>());
+    // CHECK-FIXES-0-0: auto& i = {{.*}}
+    // CHECK-FIXES-0-8: P<long>& i = {{.*}}
+    // CHECK-FIXES-1-0: auto & i = {{.*}}
+    // CHECK-FIXES-1-8: P<long>& i = {{.*}}
+
+    // Length(P<long*>) = 8
+    P<long*>& pi = static_cast<P<long*> &>(foo_ref<long*>());
+    // CHECK-FIXES-0-0: auto& pi = {{.*}}
+    // CHECK-FIXES-0-8: auto& pi = {{.*}}
+    // CHECK-FIXES-1-0: auto & pi = {{.*}}
+    // CHECK-FIXES-1-8: auto & pi = {{.*}}
+
+    P<long>* pi2 = static_cast<P<long>*>(foo_ptr<long>());
+    // CHECK-FIXES-0-0: auto* pi2 = {{.*}}
+    // CHECK-FIXES-0-8: P<long>* pi2 = {{.*}}
+    // CHECK-FIXES-1-0: auto  pi2 = {{.*}}
+    // CHECK-FIXES-1-8: auto  pi2 = {{.*}}
+  }
+
+  return 1;
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new-remove-stars.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new-remove-stars.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new-remove-stars.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new-remove-stars.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,105 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: '1'}, {key: modernize-use-auto.MinTypeNameLength, value: '0'}]}"
+
+class MyType {};
+
+class MyDerivedType : public MyType {};
+
+// FIXME: the replacement sometimes results in two consecutive spaces after
+// the word 'auto' (due to the presence of spaces at both sides of '*').
+void auto_new() {
+  MyType *a_new = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto a_new = new MyType();
+
+  static MyType *a_static = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+  // CHECK-FIXES: static auto a_static = new MyType();
+
+  MyType *derived = new MyDerivedType();
+
+  void *vd = new MyType();
+
+  // CV-qualifier tests.
+  //
+  // NOTE : the form "type const" is expected here because of a deficiency in
+  // TypeLoc where CV qualifiers are not considered part of the type location
+  // info. That is, all that is being replaced in each case is "MyType *" and
+  // not "MyType * const".
+  static MyType * const d_static = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+  // CHECK-FIXES: static auto  const d_static = new MyType();
+
+  MyType * const a_const = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto  const a_const = new MyType();
+
+  MyType * volatile vol = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto  volatile vol = new MyType();
+
+  struct SType {} *stype = new SType;
+
+  int (**func)(int, int) = new (int(*[5])(int,int));
+
+  int *array = new int[5];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto array = new int[5];
+
+  MyType *ptr(new MyType);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto ptr(new MyType);
+
+  MyType *ptr2{new MyType};
+
+  {
+    // Test for declaration lists.
+    MyType *a = new MyType(), *b = new MyType(), *c = new MyType();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto a = new MyType(), b = new MyType(), c = new MyType();
+
+    // Non-initialized declaration should not be transformed.
+    MyType *d = new MyType(), *e;
+
+    MyType **f = new MyType*(), **g = new MyType*();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto f = new MyType*(), g = new MyType*();
+
+    // Mismatching types in declaration lists should not be transformed.
+    MyType *h = new MyType(), **i = new MyType*();
+
+    // '*' shouldn't be removed in case of mismatching types with multiple
+    // declarations.
+    MyType *j = new MyType(), *k = new MyType(), **l = new MyType*();
+  }
+
+  {
+    // Test for typedefs.
+    typedef int * int_p;
+    // CHECK-FIXES: typedef int * int_p;
+
+    int_p a = new int;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto  a = new int;
+    int_p *b = new int*;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto b = new int*;
+
+    // Test for typedefs in declarations lists.
+    int_p c = new int, d = new int;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto  c = new int, d = new int;
+
+    // Different types should not be transformed.
+    int_p e = new int, *f = new int_p;
+
+    int_p *g = new int*, *h = new int_p;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto g = new int*, h = new int_p;
+  }
+
+  // Don't warn when 'auto' is already being used.
+  auto aut = new MyType();
+  auto *paut = new MyType();
+  const auto *pcaut = new MyType();
+}

Added: clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new.cpp?rev=374540&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/checkers/modernize-use-auto-new.cpp Fri Oct 11 05:05:42 2019
@@ -0,0 +1,110 @@
+// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
+// RUN:   -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '0'}]}" \
+// RUN:   -- -frtti
+
+class MyType {};
+
+class MyDerivedType : public MyType {};
+
+// FIXME: the replacement sometimes results in two consecutive spaces after
+// the word 'auto' (due to the presence of spaces at both sides of '*').
+void auto_new() {
+  MyType *a_new = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto *a_new = new MyType();
+
+  static MyType *a_static = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+  // CHECK-FIXES: static auto *a_static = new MyType();
+
+  long long *ll = new long long();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto *ll = new long long();
+
+  MyType *derived = new MyDerivedType();
+
+  void *vd = new MyType();
+
+  // CV-qualifier tests.
+  //
+  // NOTE : the form "type const" is expected here because of a deficiency in
+  // TypeLoc where CV qualifiers are not considered part of the type location
+  // info. That is, all that is being replaced in each case is "MyType *" and
+  // not "MyType * const".
+  static MyType * const d_static = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: use auto when initializing with new
+  // CHECK-FIXES: static auto * const d_static = new MyType();
+
+  MyType * const a_const = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto * const a_const = new MyType();
+
+  MyType * volatile vol = new MyType();
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto * volatile vol = new MyType();
+
+  struct SType {} *stype = new SType;
+
+  int (**func)(int, int) = new (int(*[5])(int,int));
+
+  int *array = new int[5];
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto *array = new int[5];
+
+  MyType *ptr(new MyType);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with new
+  // CHECK-FIXES: auto *ptr(new MyType);
+
+  MyType *ptr2{new MyType};
+
+  {
+    // Test for declaration lists.
+    MyType *a = new MyType(), *b = new MyType(), *c = new MyType();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto *a = new MyType(), *b = new MyType(), *c = new MyType();
+
+    // Non-initialized declaration should not be transformed.
+    MyType *d = new MyType(), *e;
+
+    MyType **f = new MyType*(), **g = new MyType*();
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto **f = new MyType*(), **g = new MyType*();
+
+    // Mismatching types in declaration lists should not be transformed.
+    MyType *h = new MyType(), **i = new MyType*();
+
+    // '*' shouldn't be removed in case of mismatching types with multiple
+    // declarations.
+    MyType *j = new MyType(), *k = new MyType(), **l = new MyType*();
+  }
+
+  {
+    // Test for typedefs.
+    typedef int * int_p;
+    // CHECK-FIXES: typedef int * int_p;
+
+    int_p a = new int;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto a = new int;
+    int_p *b = new int*;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto *b = new int*;
+
+    // Test for typedefs in declarations lists.
+    int_p c = new int, d = new int;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto c = new int, d = new int;
+
+    // Different types should not be transformed.
+    int_p e = new int, *f = new int_p;
+
+    int_p *g = new int*, *h = new int_p;
+    // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use auto when initializing with new
+    // CHECK-FIXES: auto *g = new int*, *h = new int_p;
+  }
+
+  // Don't warn when 'auto' is already being used.
+  auto aut = new MyType();
+  auto *paut = new MyType();
+  const auto *pcaut = new MyType();
+}




More information about the cfe-commits mailing list