Index: test/clang-tidy/arg-comments.cpp =================================================================== --- test/clang-tidy/arg-comments.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-argument-comment %t -// REQUIRES: shell - -// FIXME: clang-tidy should provide a -verify mode to make writing these checks -// easier and more accurate. - -void ffff(int xxxx, int yyyy); - -void f(int x, int y); -void g() { - // CHECK-MESSAGES: [[@LINE+4]]:5: warning: argument name 'y' in comment does not match parameter name 'x' - // CHECK-MESSAGES: :[[@LINE-3]]:12: note: 'x' declared here - // CHECK-MESSAGES: [[@LINE+2]]:14: warning: argument name 'z' in comment does not match parameter name 'y' - // CHECK-MESSAGES: :[[@LINE-5]]:19: note: 'y' declared here - f(/*y=*/0, /*z=*/0); -} - -struct Closure {}; - -template -Closure *NewCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; } - -template -Closure *NewPermanentCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; } - -void h() { - (void)NewCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22); - (void)NewPermanentCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22); -} - -template -void variadic(Args&&... args); - -template -void variadic2(int zzz, Args&&... args); - -void templates() { - variadic(/*xxx=*/0, /*yyy=*/1); - variadic2(/*zzZ=*/0, /*xxx=*/1, /*yyy=*/2); - // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument name 'zzZ' in comment does not match parameter name 'zzz' -} Index: test/clang-tidy/google-explicit-constructor.cpp =================================================================== --- test/clang-tidy/google-explicit-constructor.cpp +++ /dev/null @@ -1,127 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-explicit-constructor %t -// REQUIRES: shell - -namespace std { - typedef decltype(sizeof(int)) size_t; - - // libc++'s implementation - template - 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 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 explicit [google-explicit-constructor] - // CHECK-FIXES: {{^ }}explicit A(int x1) {} - - A(double x2, double y = 3.14) {} - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors - // CHECK-FIXES: {{^ }}explicit A(double x2, double y = 3.14) {} -}; - -struct B { - B(std::initializer_list list1) {} - B(const std::initializer_list &list2) {} - B(std::initializer_list &&list3) {} - - explicit B(::std::initializer_list list4) {} - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor] - // CHECK-FIXES: {{^ }}B(::std::initializer_list list4) {} - - explicit B(const ::std::initializer_list &list5) {} - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor - // CHECK-FIXES: {{^ }}B(const ::std::initializer_list &list5) {} - - explicit B(::std::initializer_list &&list6) {} - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor - // CHECK-FIXES: {{^ }}B(::std::initializer_list &&list6) {} -}; - -using namespace std; - -struct C { - C(initializer_list list1) {} - C(const initializer_list &list2) {} - C(initializer_list &&list3) {} -}; - -template -struct C2 { - C2(initializer_list list1) {} - C2(const initializer_list &list2) {} - C2(initializer_list &&list3) {} - - explicit C2(initializer_list list4) {} - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor - // CHECK-FIXES: {{^ }}C2(initializer_list list4) {} -}; - -template -struct C3 { - C3(initializer_list list1) {} - C3(const std::initializer_list &list2) {} - C3(::std::initializer_list &&list3) {} - - template - C3(initializer_list list3) {} -}; - -struct D { - template - explicit D(T t) {} -}; - -template -struct E { - E(T *pt) {} - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors - // CHECK-FIXES: {{^ }}explicit E(T *pt) {} - template - E(U *pu) {} - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors - // CHECK-FIXES: {{^ }}explicit E(U *pu) {} - - explicit E(T t) {} - template - explicit E(U u) {} -}; - -void f(std::initializer_list list) { - D d(list); - E e(list); - E e2(list); -} Index: test/clang-tidy/google-explicit-make-pair.cpp =================================================================== --- test/clang-tidy/google-explicit-make-pair.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-build-explicit-make-pair %t -// REQUIRES: shell - -namespace std { -template -struct pair { - pair(T1 x, T2 y) {} -}; - -template -pair make_pair(T1 x, T2 y) { - return pair(x, y); -} -} - -template -void templ(T a, T b) { - std::make_pair(a, b); - std::make_pair(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 -int t(); - -void test(int i) { - std::make_pair(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(i, i); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly -// CHECK-FIXES: std::pair(i, i) - - std::make_pair(i, i); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly -// CHECK-FIXES: std::pair(i, i) - -#define M std::make_pair(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(i, i); -// CHECK-FIXES-NEXT: M - - templ(i, i); - templ(1U, 2U); - - std::make_pair(i, 1); // no-warning - std::make_pair(t, 1); -} Index: test/clang-tidy/google-member-string-references.cpp =================================================================== --- test/clang-tidy/google-member-string-references.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-runtime-member-string-references %t -// REQUIRES: shell - -namespace std { -template - class basic_string {}; - -typedef basic_string string; -} - -class string {}; - - -struct A { - const std::string &s; -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: const string& members are dangerous. It is much better to use alternatives, such as pointers or simple constants. [google-runtime-member-string-references] -}; - -struct B { - std::string &s; -}; - -struct C { - const std::string s; -}; - -template -struct D { - D(); - const T &s; - const std::string &s2; -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: const string& members are dangerous. -}; - -D d; - -struct AA { - const string &s; -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: const string& members are dangerous. -}; - -struct BB { - string &s; -}; - -struct CC { - const string s; -}; - -D dd; Index: test/clang-tidy/google-memset-zero-length.cpp =================================================================== --- test/clang-tidy/google-memset-zero-length.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-runtime-memset %t -// REQUIRES: shell - -void *memset(void *, int, __SIZE_TYPE__); - -namespace std { - using ::memset; -} - -template -void memtmpl() { - memset(0, sizeof(int), i); - memset(0, sizeof(T), sizeof(T)); - memset(0, sizeof(T), 0); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: memset(0, 0, sizeof(T)); - memset(0, sizeof(int), 0); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: memset(0, 0, sizeof(int)); -} - -void foo(void *a, int xsize, int ysize) { - memset(a, sizeof(int), 0); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: memset(a, 0, sizeof(int)); -#define M memset(a, sizeof(int), 0); - M -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: #define M memset(a, sizeof(int), 0); - ::memset(a, xsize * - ysize, 0); -// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: ::memset(a, 0, xsize * -// CHECK-FIXES-NEXT: ysize); - std::memset(a, sizeof(int), 0x00); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: std::memset(a, 0x00, sizeof(int)); - - const int v = 0; - memset(a, sizeof(int), v); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: memset(a, v, sizeof(int)); - - memset(a, sizeof(int), v + v); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument -// CHECK-FIXES: memset(a, v + v, sizeof(int)); - - memset(a, sizeof(int), v + 1); - - memset(a, -1, sizeof(int)); - memset(a, 0xcd, 1); - memset(a, v, 0); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero -// CHECK-FIXES: memset(a, v, 0); - - memset(a, -1, v); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero -// CHECK-FIXES: memset(a, -1, v); - - memtmpl<0, int>(); -} Index: test/clang-tidy/google-module.cpp =================================================================== --- test/clang-tidy/google-module.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// 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'}} Index: test/clang-tidy/google-namespaces.cpp =================================================================== --- test/clang-tidy/google-namespaces.cpp +++ /dev/null @@ -1,8 +0,0 @@ -// 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. - -using namespace spaaaace; -// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives. Use using-declarations instead. - -using spaaaace::core; // no-warning Index: test/clang-tidy/google-overloaded-unary-and.cpp =================================================================== --- test/clang-tidy/google-overloaded-unary-and.cpp +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-runtime-operator %t -// REQUIRES: shell - -struct Foo { - void *operator&(); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator&, it is dangerous. [google-runtime-operator] -}; - -template -struct TFoo { - T *operator&(); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator& -}; - -TFoo 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); Index: test/clang-tidy/google-readability-casting.c =================================================================== --- test/clang-tidy/google-readability-casting.c +++ /dev/null @@ -1,9 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-readability-casting %t -- -x c -// REQUIRES: shell - -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; -} Index: test/clang-tidy/google-readability-casting.cpp =================================================================== --- test/clang-tidy/google-readability-casting.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-readability-casting %t -// REQUIRES: shell - -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: possibly redundant cast between typedefs of the same type [google-readability-casting] - // CHECK-FIXES: {{^}} (Typedef2)t1; - (const char*)t1; - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast {{.*}} - // CHECK-FIXES: {{^}} (const char*)t1; - (Typedef1)cpc; - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast {{.*}} - // CHECK-FIXES: {{^}} (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(cpc); - - char *pc2 = (char*)(cpc + 33); - // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}. Use const_cast {{.*}} - // CHECK-FIXES: char *pc2 = const_cast(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(crc); - - char &rc2 = (char&)*cpc; - // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}. Use const_cast {{.*}} - // CHECK-FIXES: char &rc2 = const_cast(*cpc); - - char ** const* const* ppcpcpc; - char ****ppppc = (char****)ppcpcpc; - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}}. Use const_cast {{.*}} - // CHECK-FIXES: char ****ppppc = const_cast(ppcpcpc); - - char ***pppc = (char***)*(ppcpcpc); - // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}. Use const_cast {{.*}} - // CHECK-FIXES: char ***pppc = const_cast(*(ppcpcpc)); - - char ***pppc2 = (char***)(*ppcpcpc); - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}. Use const_cast {{.*}} - // CHECK-FIXES: char ***pppc2 = const_cast(*ppcpcpc); - - char *pc5 = (char*)(const char*)(cpv); - // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}. Use const_cast {{.*}} - // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}}. Use reinterpret_cast {{.*}} - // CHECK-FIXES: char *pc5 = const_cast(reinterpret_cast(cpv)); - - int b1 = (int)b; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}. Use static_cast {{.*}} - // CHECK-FIXES: int b1 = static_cast(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 reinterpret_cast {{.*}} - // CHECK-FIXES: const char *pc3 = reinterpret_cast(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(Enum1); - - Enum e = (Enum)b1; - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}. Use static_cast {{.*}} - // CHECK-FIXES: Enum e = static_cast(b1); - - // CHECK-MESSAGES-NOT: warning: - int b2 = int(b); - int b3 = static_cast(b); - int b4 = b; - double aa = a; - (void)b2; - return (void)g(); -} - -template -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 -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().f(1, 42); - TemplateStruct().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 -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 {}; Index: test/clang-tidy/google-readability-function.cpp =================================================================== --- test/clang-tidy/google-readability-function.cpp +++ /dev/null @@ -1,130 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-readability-function %t -// REQUIRES: shell - -void Method(char *) { /* */ } -// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: all parameters should be named in a function -// CHECK-FIXES: void Method(char * /*unused*/) { /* */ } -void Method2(char *) {} -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function -// CHECK-FIXES: void Method2(char * /*unused*/) {} -void Method3(char *, void *) {} -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function -// CHECK-FIXES: void Method3(char * /*unused*/, void * /*unused*/) {} -void Method4(char *, int /*unused*/) {} -// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function -// CHECK-FIXES: void Method4(char * /*unused*/, int /*unused*/) {} -void operator delete[](void *) throw() {} -// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: all parameters should be named in a function -// CHECK-FIXES: void operator delete[](void * /*unused*/) throw() {} -int Method5(int) { return 0; } -// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: all parameters should be named in a function -// CHECK-FIXES: int Method5(int /*unused*/) { return 0; } -void Method6(void (*)(void *)) {} -// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: all parameters should be named in a function -// CHECK-FIXES: void Method6(void (* /*unused*/)(void *)) {} -template void Method7(T) {} -// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: all parameters should be named in a function -// CHECK-FIXES: template void Method7(T /*unused*/) {} - -// Don't warn in macros. -#define M void MethodM(int) {} -M - -void operator delete(void *x) throw() {} -void Method7(char * /*x*/) {} -void Method8(char *x) {} -typedef void (*TypeM)(int x); -void operator delete[](void *x) throw(); -void operator delete[](void * /*x*/) throw(); - -struct X { - X operator++(int) {} - X operator--(int) {} - - X(X&) = delete; - X &operator=(X&) = default; - - const int &i; -}; - -void (*Func1)(void *); -void Func2(void (*func)(void *)) {} -template void Func3() {} - -template -struct Y { - void foo(T) {} -// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: all parameters should be named in a function -// CHECK-FIXES: void foo(T /*unused*/) {} -}; - -Y y; -Y z; - -struct Base { - virtual void foo(bool notThisOne); - virtual void foo(int argname); -}; - -struct Derived : public Base { - void foo(int); -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function -// CHECK-FIXES: void foo(int /*argname*/); -}; - -void FDef(int); -// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: all parameters should be named in a function -// CHECK-FIXES: void FDef(int /*n*/); -void FDef(int n) {} - -void FDef2(int, int); -// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function -// CHECK-FIXES: void FDef2(int /*n*/, int /*unused*/); -void FDef2(int n, int) {} -// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: all parameters should be named in a function -// CHECK-FIXES: void FDef2(int n, int /*unused*/) {} - -void FNoDef(int); - -class Z {}; - -Z &operator++(Z&) {} -// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function -// CHECK-FIXES: Z &operator++(Z& /*unused*/) {} - -Z &operator++(Z&, int) {} -// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function -// CHECK-FIXES: Z &operator++(Z& /*unused*/, int) {} - -Z &operator--(Z&) {} -// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function -// CHECK-FIXES: Z &operator--(Z& /*unused*/) {} - -Z &operator--(Z&, int) {} -// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function -// CHECK-FIXES: Z &operator--(Z& /*unused*/, int) {} - -namespace testing { -namespace internal { -class IgnoredValue { - public: - template - IgnoredValue(const T& /* ignored */) {} -}; -} -typedef internal::IgnoredValue Unused; -} - -using ::testing::Unused; - -void MockFunction(Unused, int q, Unused) { - ++q; - ++q; - ++q; -} - -namespace std { -typedef decltype(nullptr) nullptr_t; -} - -void f(std::nullptr_t) {} Index: test/clang-tidy/google-readability-namespace-comments.cpp =================================================================== --- test/clang-tidy/google-readability-namespace-comments.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-readability-namespace-comments %t -// REQUIRES: shell - -namespace n1 { -namespace n2 { - - - - - -// CHECK-MESSAGES: :[[@LINE+4]]:2: 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+3]]: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 - - -namespace short1 { -namespace short2 { -// Namespaces covering 10 lines or fewer are exempt from this rule. - - - - - -} -} Index: test/clang-tidy/google-readability-todo.cpp =================================================================== --- test/clang-tidy/google-readability-todo.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-readability-todo %t -config="{User: 'some user'}" -- -// REQUIRES: shell - -// 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 Index: test/clang-tidy/google-runtime-int.c =================================================================== --- test/clang-tidy/google-runtime-int.c +++ /dev/null @@ -1,27 +0,0 @@ -// 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; -} Index: test/clang-tidy/google-runtime-int.cpp =================================================================== --- test/clang-tidy/google-runtime-int.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s google-runtime-int %t -// REQUIRES: shell - -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 -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(); -// CHECK-MESSAGES: [[@LINE-1]]:8: warning: consider replacing 'short' with 'int16' -} - -void p(unsigned short port); - -void qux() { - short port; -// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'short' with 'int16' -} Index: test/clang-tidy/google/explicit-constructor.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/explicit-constructor.cpp @@ -0,0 +1,127 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-explicit-constructor %t +// REQUIRES: shell + +namespace std { + typedef decltype(sizeof(int)) size_t; + + // libc++'s implementation + template + 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 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 explicit [google-explicit-constructor] + // CHECK-FIXES: {{^ }}explicit A(int x1) {} + + A(double x2, double y = 3.14) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors + // CHECK-FIXES: {{^ }}explicit A(double x2, double y = 3.14) {} +}; + +struct B { + B(std::initializer_list list1) {} + B(const std::initializer_list &list2) {} + B(std::initializer_list &&list3) {} + + explicit B(::std::initializer_list list4) {} + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor should not be declared explicit [google-explicit-constructor] + // CHECK-FIXES: {{^ }}B(::std::initializer_list list4) {} + + explicit B(const ::std::initializer_list &list5) {} + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor + // CHECK-FIXES: {{^ }}B(const ::std::initializer_list &list5) {} + + explicit B(::std::initializer_list &&list6) {} + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor + // CHECK-FIXES: {{^ }}B(::std::initializer_list &&list6) {} +}; + +using namespace std; + +struct C { + C(initializer_list list1) {} + C(const initializer_list &list2) {} + C(initializer_list &&list3) {} +}; + +template +struct C2 { + C2(initializer_list list1) {} + C2(const initializer_list &list2) {} + C2(initializer_list &&list3) {} + + explicit C2(initializer_list list4) {} + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: initializer-list constructor + // CHECK-FIXES: {{^ }}C2(initializer_list list4) {} +}; + +template +struct C3 { + C3(initializer_list list1) {} + C3(const std::initializer_list &list2) {} + C3(::std::initializer_list &&list3) {} + + template + C3(initializer_list list3) {} +}; + +struct D { + template + explicit D(T t) {} +}; + +template +struct E { + E(T *pt) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors + // CHECK-FIXES: {{^ }}explicit E(T *pt) {} + template + E(U *pu) {} + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: single-argument constructors + // CHECK-FIXES: {{^ }}explicit E(U *pu) {} + + explicit E(T t) {} + template + explicit E(U u) {} +}; + +void f(std::initializer_list list) { + D d(list); + E e(list); + E e2(list); +} Index: test/clang-tidy/google/explicit-make-pair.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/explicit-make-pair.cpp @@ -0,0 +1,52 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-build-explicit-make-pair %t +// REQUIRES: shell + +namespace std { +template +struct pair { + pair(T1 x, T2 y) {} +}; + +template +pair make_pair(T1 x, T2 y) { + return pair(x, y); +} +} + +template +void templ(T a, T b) { + std::make_pair(a, b); + std::make_pair(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 +int t(); + +void test(int i) { + std::make_pair(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(i, i); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly +// CHECK-FIXES: std::pair(i, i) + + std::make_pair(i, i); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: for C++11-compatibility, use pair directly +// CHECK-FIXES: std::pair(i, i) + +#define M std::make_pair(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(i, i); +// CHECK-FIXES-NEXT: M + + templ(i, i); + templ(1U, 2U); + + std::make_pair(i, 1); // no-warning + std::make_pair(t, 1); +} Index: test/clang-tidy/google/google-module.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/google-module.cpp @@ -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'}} Index: test/clang-tidy/google/member-string-references.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/member-string-references.cpp @@ -0,0 +1,50 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-runtime-member-string-references %t +// REQUIRES: shell + +namespace std { +template + class basic_string {}; + +typedef basic_string string; +} + +class string {}; + + +struct A { + const std::string &s; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: const string& members are dangerous. It is much better to use alternatives, such as pointers or simple constants. [google-runtime-member-string-references] +}; + +struct B { + std::string &s; +}; + +struct C { + const std::string s; +}; + +template +struct D { + D(); + const T &s; + const std::string &s2; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: const string& members are dangerous. +}; + +D d; + +struct AA { + const string &s; +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: const string& members are dangerous. +}; + +struct BB { + string &s; +}; + +struct CC { + const string s; +}; + +D dd; Index: test/clang-tidy/google/memset-zero-length.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/memset-zero-length.cpp @@ -0,0 +1,61 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-runtime-memset %t +// REQUIRES: shell + +void *memset(void *, int, __SIZE_TYPE__); + +namespace std { + using ::memset; +} + +template +void memtmpl() { + memset(0, sizeof(int), i); + memset(0, sizeof(T), sizeof(T)); + memset(0, sizeof(T), 0); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: memset(0, 0, sizeof(T)); + memset(0, sizeof(int), 0); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: memset(0, 0, sizeof(int)); +} + +void foo(void *a, int xsize, int ysize) { + memset(a, sizeof(int), 0); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: memset(a, 0, sizeof(int)); +#define M memset(a, sizeof(int), 0); + M +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: #define M memset(a, sizeof(int), 0); + ::memset(a, xsize * + ysize, 0); +// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: ::memset(a, 0, xsize * +// CHECK-FIXES-NEXT: ysize); + std::memset(a, sizeof(int), 0x00); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: std::memset(a, 0x00, sizeof(int)); + + const int v = 0; + memset(a, sizeof(int), v); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: memset(a, v, sizeof(int)); + + memset(a, sizeof(int), v + v); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero, potentially swapped argument +// CHECK-FIXES: memset(a, v + v, sizeof(int)); + + memset(a, sizeof(int), v + 1); + + memset(a, -1, sizeof(int)); + memset(a, 0xcd, 1); + memset(a, v, 0); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero +// CHECK-FIXES: memset(a, v, 0); + + memset(a, -1, v); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: memset of size zero +// CHECK-FIXES: memset(a, -1, v); + + memtmpl<0, int>(); +} Index: test/clang-tidy/google/namespace.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/namespace.cpp @@ -0,0 +1,8 @@ +// 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. + +using namespace spaaaace; +// CHECK: :[[@LINE-1]]:1: warning: do not use namespace using-directives. Use using-declarations instead. + +using spaaaace::core; // no-warning Index: test/clang-tidy/google/overloaded-unary-and.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/overloaded-unary-and.cpp @@ -0,0 +1,26 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-runtime-operator %t +// REQUIRES: shell + +struct Foo { + void *operator&(); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator&, it is dangerous. [google-runtime-operator] +}; + +template +struct TFoo { + T *operator&(); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: do not overload unary operator& +}; + +TFoo 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); Index: test/clang-tidy/google/readability-casting.c =================================================================== --- /dev/null +++ test/clang-tidy/google/readability-casting.c @@ -0,0 +1,9 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-readability-casting %t -- -x c +// REQUIRES: shell + +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; +} Index: test/clang-tidy/google/readability-casting.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/readability-casting.cpp @@ -0,0 +1,151 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-readability-casting %t +// REQUIRES: shell + +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: possibly redundant cast between typedefs of the same type [google-readability-casting] + // CHECK-FIXES: {{^}} (Typedef2)t1; + (const char*)t1; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast {{.*}} + // CHECK-FIXES: {{^}} (const char*)t1; + (Typedef1)cpc; + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: possibly redundant cast {{.*}} + // CHECK-FIXES: {{^}} (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(cpc); + + char *pc2 = (char*)(cpc + 33); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}. Use const_cast {{.*}} + // CHECK-FIXES: char *pc2 = const_cast(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(crc); + + char &rc2 = (char&)*cpc; + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}. Use const_cast {{.*}} + // CHECK-FIXES: char &rc2 = const_cast(*cpc); + + char ** const* const* ppcpcpc; + char ****ppppc = (char****)ppcpcpc; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: {{.*}}. Use const_cast {{.*}} + // CHECK-FIXES: char ****ppppc = const_cast(ppcpcpc); + + char ***pppc = (char***)*(ppcpcpc); + // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: {{.*}}. Use const_cast {{.*}} + // CHECK-FIXES: char ***pppc = const_cast(*(ppcpcpc)); + + char ***pppc2 = (char***)(*ppcpcpc); + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: {{.*}}. Use const_cast {{.*}} + // CHECK-FIXES: char ***pppc2 = const_cast(*ppcpcpc); + + char *pc5 = (char*)(const char*)(cpv); + // CHECK-MESSAGES: :[[@LINE-1]]:15: warning: {{.*}}. Use const_cast {{.*}} + // CHECK-MESSAGES: :[[@LINE-2]]:22: warning: {{.*}}. Use reinterpret_cast {{.*}} + // CHECK-FIXES: char *pc5 = const_cast(reinterpret_cast(cpv)); + + int b1 = (int)b; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}. Use static_cast {{.*}} + // CHECK-FIXES: int b1 = static_cast(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 reinterpret_cast {{.*}} + // CHECK-FIXES: const char *pc3 = reinterpret_cast(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(Enum1); + + Enum e = (Enum)b1; + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: {{.*}}. Use static_cast {{.*}} + // CHECK-FIXES: Enum e = static_cast(b1); + + // CHECK-MESSAGES-NOT: warning: + int b2 = int(b); + int b3 = static_cast(b); + int b4 = b; + double aa = a; + (void)b2; + return (void)g(); +} + +template +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 +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().f(1, 42); + TemplateStruct().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 +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 {}; Index: test/clang-tidy/google/readability-function.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/readability-function.cpp @@ -0,0 +1,130 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-readability-function %t +// REQUIRES: shell + +void Method(char *) { /* */ } +// CHECK-MESSAGES: :[[@LINE-1]]:19: warning: all parameters should be named in a function +// CHECK-FIXES: void Method(char * /*unused*/) { /* */ } +void Method2(char *) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function +// CHECK-FIXES: void Method2(char * /*unused*/) {} +void Method3(char *, void *) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function +// CHECK-FIXES: void Method3(char * /*unused*/, void * /*unused*/) {} +void Method4(char *, int /*unused*/) {} +// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: all parameters should be named in a function +// CHECK-FIXES: void Method4(char * /*unused*/, int /*unused*/) {} +void operator delete[](void *) throw() {} +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: all parameters should be named in a function +// CHECK-FIXES: void operator delete[](void * /*unused*/) throw() {} +int Method5(int) { return 0; } +// CHECK-MESSAGES: :[[@LINE-1]]:16: warning: all parameters should be named in a function +// CHECK-FIXES: int Method5(int /*unused*/) { return 0; } +void Method6(void (*)(void *)) {} +// CHECK-MESSAGES: :[[@LINE-1]]:21: warning: all parameters should be named in a function +// CHECK-FIXES: void Method6(void (* /*unused*/)(void *)) {} +template void Method7(T) {} +// CHECK-MESSAGES: :[[@LINE-1]]:37: warning: all parameters should be named in a function +// CHECK-FIXES: template void Method7(T /*unused*/) {} + +// Don't warn in macros. +#define M void MethodM(int) {} +M + +void operator delete(void *x) throw() {} +void Method7(char * /*x*/) {} +void Method8(char *x) {} +typedef void (*TypeM)(int x); +void operator delete[](void *x) throw(); +void operator delete[](void * /*x*/) throw(); + +struct X { + X operator++(int) {} + X operator--(int) {} + + X(X&) = delete; + X &operator=(X&) = default; + + const int &i; +}; + +void (*Func1)(void *); +void Func2(void (*func)(void *)) {} +template void Func3() {} + +template +struct Y { + void foo(T) {} +// CHECK-MESSAGES: :[[@LINE-1]]:13: warning: all parameters should be named in a function +// CHECK-FIXES: void foo(T /*unused*/) {} +}; + +Y y; +Y z; + +struct Base { + virtual void foo(bool notThisOne); + virtual void foo(int argname); +}; + +struct Derived : public Base { + void foo(int); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function +// CHECK-FIXES: void foo(int /*argname*/); +}; + +void FDef(int); +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: all parameters should be named in a function +// CHECK-FIXES: void FDef(int /*n*/); +void FDef(int n) {} + +void FDef2(int, int); +// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: all parameters should be named in a function +// CHECK-FIXES: void FDef2(int /*n*/, int /*unused*/); +void FDef2(int n, int) {} +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: all parameters should be named in a function +// CHECK-FIXES: void FDef2(int n, int /*unused*/) {} + +void FNoDef(int); + +class Z {}; + +Z &operator++(Z&) {} +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function +// CHECK-FIXES: Z &operator++(Z& /*unused*/) {} + +Z &operator++(Z&, int) {} +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function +// CHECK-FIXES: Z &operator++(Z& /*unused*/, int) {} + +Z &operator--(Z&) {} +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function +// CHECK-FIXES: Z &operator--(Z& /*unused*/) {} + +Z &operator--(Z&, int) {} +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: all parameters should be named in a function +// CHECK-FIXES: Z &operator--(Z& /*unused*/, int) {} + +namespace testing { +namespace internal { +class IgnoredValue { + public: + template + IgnoredValue(const T& /* ignored */) {} +}; +} +typedef internal::IgnoredValue Unused; +} + +using ::testing::Unused; + +void MockFunction(Unused, int q, Unused) { + ++q; + ++q; + ++q; +} + +namespace std { +typedef decltype(nullptr) nullptr_t; +} + +void f(std::nullptr_t) {} Index: test/clang-tidy/google/readability-namespace-comments.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/readability-namespace-comments.cpp @@ -0,0 +1,30 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-readability-namespace-comments %t +// REQUIRES: shell + +namespace n1 { +namespace n2 { + + + + + +// CHECK-MESSAGES: :[[@LINE+4]]:2: 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+3]]: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 + + +namespace short1 { +namespace short2 { +// Namespaces covering 10 lines or fewer are exempt from this rule. + + + + + +} +} Index: test/clang-tidy/google/readability-todo.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/readability-todo.cpp @@ -0,0 +1,27 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-readability-todo %t -config="{User: 'some user'}" -- +// REQUIRES: shell + +// 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 Index: test/clang-tidy/google/runtime-int.c =================================================================== --- /dev/null +++ test/clang-tidy/google/runtime-int.c @@ -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; +} Index: test/clang-tidy/google/runtime-int.cpp =================================================================== --- /dev/null +++ test/clang-tidy/google/runtime-int.cpp @@ -0,0 +1,60 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s google-runtime-int %t +// REQUIRES: shell + +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 +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(); +// CHECK-MESSAGES: [[@LINE-1]]:8: warning: consider replacing 'short' with 'int16' +} + +void p(unsigned short port); + +void qux() { + short port; +// CHECK-MESSAGES: [[@LINE-1]]:3: warning: consider replacing 'short' with 'int16' +} Index: test/clang-tidy/llvm-include-order.cpp =================================================================== --- test/clang-tidy/llvm-include-order.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s llvm-include-order %t -- -isystem %S/Inputs/Headers -// REQUIRES: shell - -// FIXME: Investigating. -// XFAIL: win32 - -// CHECK-MESSAGES: [[@LINE+2]]:1: warning: #includes are not sorted properly -#include "j.h" -#include "gtest/foo.h" -#include "i.h" -#include -#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 - -#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" Index: test/clang-tidy/llvm-twine-local.cpp =================================================================== --- test/clang-tidy/llvm-twine-local.cpp +++ /dev/null @@ -1,33 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s llvm-twine-local %t -// REQUIRES: shell - -namespace llvm { -class Twine { -public: - Twine(const char *); - Twine(int); - 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"; -} Index: test/clang-tidy/llvm/include-order.cpp =================================================================== --- /dev/null +++ test/clang-tidy/llvm/include-order.cpp @@ -0,0 +1,41 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s llvm-include-order %t -- -isystem %S/../Inputs/Headers +// REQUIRES: shell + +// FIXME: Investigating. +// XFAIL: win32 + +// CHECK-MESSAGES: [[@LINE+2]]:1: warning: #includes are not sorted properly +#include "j.h" +#include "gtest/foo.h" +#include "i.h" +#include +#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 + +#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" Index: test/clang-tidy/llvm/twine-local.cpp =================================================================== --- /dev/null +++ test/clang-tidy/llvm/twine-local.cpp @@ -0,0 +1,33 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s llvm-twine-local %t +// REQUIRES: shell + +namespace llvm { +class Twine { +public: + Twine(const char *); + Twine(int); + 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"; +} Index: test/clang-tidy/misc-assign-operator-signature.cpp =================================================================== --- test/clang-tidy/misc-assign-operator-signature.cpp +++ /dev/null @@ -1,52 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-assign-operator-signature %t -// REQUIRES: shell - -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 BadReturn { - void operator=(const BadReturn&); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturn&' [misc-assign-operator-signature] - const BadReturn& operator=(BadReturn&&); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad -}; -struct BadReturn2 { - BadReturn2&& operator=(const BadReturn2&); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad - int operator=(BadReturn2&&); - // 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 &); -}; Index: test/clang-tidy/misc-bool-pointer-implicit-conversion.cpp =================================================================== --- test/clang-tidy/misc-bool-pointer-implicit-conversion.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-bool-pointer-implicit-conversion %t -// REQUIRES: shell - -bool *SomeFunction(); -void SomeOtherFunction(bool*); -bool F(); -void G(bool); - - -template -void t(T b) { - if (b) { - } -} - -void foo() { - bool *b = SomeFunction(); - if (b) { -// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: dubious check of 'bool *' against 'nullptr' -// CHECK-FIXES: if (*b) { - } - - if (F() && b) { -// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: dubious check of 'bool *' against 'nullptr' -// CHECK-FIXES: if (F() && *b) { - } - - // TODO: warn here. - if (b) { - G(b); - } - -#define TESTMACRO if (b || F()) - - TESTMACRO { - } - - t(b); - - if (!b) { - // no-warning - } - - if (SomeFunction()) { - // no-warning - } - - bool *c = SomeFunction(); - if (c) { - (void)c; - (void)*c; // no-warning - } - - if (c) { - *c = true; // no-warning - } - - if (c) { - c[0] = false; // no-warning - } - - if (c) { - SomeOtherFunction(c); // no-warning - } - - if (c) { - delete[] c; // no-warning - } - - if (c) { - *(c) = false; // no-warning - } - - struct { - bool *b; - } d = { SomeFunction() }; - - if (d.b) - (void)*d.b; // no-warning - -#define CHECK(b) if (b) {} - CHECK(c) -} Index: test/clang-tidy/misc-inaccurate-erase.cpp =================================================================== --- test/clang-tidy/misc-inaccurate-erase.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-inaccurate-erase %t -// REQUIRES: shell - -namespace std { -template struct vec_iterator { - T *ptr; - vec_iterator operator++(int); -}; - -template struct vector { - typedef vec_iterator iterator; - - iterator begin(); - iterator end(); - - void erase(iterator); - void erase(iterator, iterator); -}; - -template -FwIt remove(FwIt begin, FwIt end, const T &val); - -template -FwIt remove_if(FwIt begin, FwIt end, Func f); - -template FwIt unique(FwIt begin, FwIt end); - -template struct unique_ptr {}; -} // namespace std - -struct custom_iter {}; -struct custom_container { - void erase(...); - custom_iter begin(); - custom_iter end(); -}; - -template void g() { - T t; - t.erase(std::remove(t.begin(), t.end(), 10)); - // CHECK-FIXES: {{^ }}t.erase(std::remove(t.begin(), t.end(), 10));{{$}} - - std::vector v; - v.erase(remove(v.begin(), v.end(), 10)); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one - // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}} -} - -#define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y)) -// CHECK-FIXES: #define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y)) - -int main() { - std::vector v; - - v.erase(remove(v.begin(), v.end(), 10)); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one item even when multiple items should be removed [misc-inaccurate-erase] - // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}} - v.erase(remove(v.begin(), v.end(), 20), v.end()); - - // Fix is not trivial. - auto it = v.end(); - v.erase(remove(v.begin(), it, 10)); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one - // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), it, 10));{{$}} - - g>(); - g(); - - ERASE(v, 15); - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: this call will remove at most one - // CHECK-FIXES: {{^ }}ERASE(v, 15);{{$}} - - std::vector> vupi; - auto iter = vupi.begin(); - vupi.erase(iter++); - // CHECK-FIXES: {{^ }}vupi.erase(iter++);{{$}} -} Index: test/clang-tidy/misc-inefficient-algorithm.cpp =================================================================== --- test/clang-tidy/misc-inefficient-algorithm.cpp +++ /dev/null @@ -1,133 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-inefficient-algorithm %t -// REQUIRES: shell - -namespace std { -template struct less { - bool operator()(const T &lhs, const T &rhs) { return lhs < rhs; } -}; - -template struct greater { - bool operator()(const T &lhs, const T &rhs) { return lhs > rhs; } -}; - -struct iterator_type {}; - -template > struct set { - typedef iterator_type iterator; - iterator find(const K &k); - unsigned count(const K &k); - - iterator begin(); - iterator end(); - iterator begin() const; - iterator end() const; -}; - -struct other_iterator_type {}; - -template > struct map { - typedef other_iterator_type iterator; - iterator find(const K &k); - unsigned count(const K &k); - - iterator begin(); - iterator end(); - iterator begin() const; - iterator end() const; -}; - -template struct unordered_set : set {}; - -template > struct multiset : set {}; - -template FwIt find(FwIt, FwIt, const K &); - -template -FwIt find(FwIt, FwIt, const K &, Cmp); - -template FwIt find_if(FwIt, FwIt, Pred); - -template FwIt count(FwIt, FwIt, const K &); - -template FwIt lower_bound(FwIt, FwIt, const K &); - -template -FwIt lower_bound(FwIt, FwIt, const K &, Ord); -} - -#define FIND_IN_SET(x) find(x.begin(), x.end(), 10) -// CHECK-FIXES: #define FIND_IN_SET(x) find(x.begin(), x.end(), 10) - -template void f(const T &t) { - std::set s; - find(s.begin(), s.end(), 46); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}s.find(46);{{$}} - - find(t.begin(), t.end(), 46); - // CHECK-FIXES: {{^ }}find(t.begin(), t.end(), 46);{{$}} -} - -int main() { - std::set s; - auto it = std::find(s.begin(), s.end(), 43); - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: this STL algorithm call should be replaced with a container method [misc-inefficient-algorithm] - // CHECK-FIXES: {{^ }}auto it = s.find(43);{{$}} - auto c = count(s.begin(), s.end(), 43); - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}auto c = s.count(43);{{$}} - it = find_if(s.begin(), s.end(), [](int) { return false; }); - - std::multiset ms; - find(ms.begin(), ms.end(), 46); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}ms.find(46);{{$}} - - const std::multiset &msref = ms; - find(msref.begin(), msref.end(), 46); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}msref.find(46);{{$}} - - std::multiset *msptr = &ms; - find(msptr->begin(), msptr->end(), 46); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}msptr->find(46);{{$}} - - it = std::find(s.begin(), s.end(), 43, std::greater()); - // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: different comparers used in the algorithm and the container [misc-inefficient-algorithm] - - FIND_IN_SET(s); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}FIND_IN_SET(s);{{$}} - - f(s); - - std::unordered_set us; - lower_bound(us.begin(), us.end(), 10); - // CHECK-FIXES: {{^ }}lower_bound(us.begin(), us.end(), 10);{{$}} - find(us.begin(), us.end(), 10); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}us.find(10);{{$}} - - std::map intmap; - find(intmap.begin(), intmap.end(), 46); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}find(intmap.begin(), intmap.end(), 46);{{$}} -} - -struct Value { - int value; -}; - -struct Ordering { - bool operator()(const Value &lhs, const Value &rhs) const { - return lhs.value < rhs.value; - } - bool operator()(int lhs, const Value &rhs) const { return lhs < rhs.value; } -}; - -void g(std::set container, int value) { - lower_bound(container.begin(), container.end(), value, Ordering()); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be - // CHECK-FIXES: {{^ }}lower_bound(container.begin(), container.end(), value, Ordering());{{$}} -} Index: test/clang-tidy/misc-swapped-arguments.cpp =================================================================== --- test/clang-tidy/misc-swapped-arguments.cpp +++ /dev/null @@ -1,44 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-swapped-arguments %t -// REQUIRES: shell - -void F(int, double); - -int SomeFunction(); - -template -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. -// In macro, don't emit fixits. -// CHECK-FIXES: F(b, M(Some, Function)); - -#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 -} Index: test/clang-tidy/misc-undelegated-constructor.cpp =================================================================== --- test/clang-tidy/misc-undelegated-constructor.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-undelegated-constructor %t -// REQUIRES: shell - -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 [misc-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 -struct TDerived : public Base { - TDerived() { Base(); } -}; - -TDerived t; Index: test/clang-tidy/misc-uniqueptr-reset-release.cpp =================================================================== --- test/clang-tidy/misc-uniqueptr-reset-release.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-uniqueptr-reset-release %t -// REQUIRES: shell - -namespace std { -template -struct unique_ptr { - unique_ptr(); - explicit unique_ptr(T *); - template - unique_ptr(unique_ptr &&); - void reset(T *); - T *release(); -}; -} // namespace std - -struct Foo {}; -struct Bar : Foo {}; - -std::unique_ptr Create(); -std::unique_ptr &Look(); -std::unique_ptr *Get(); - -void f() { - std::unique_ptr a, b; - std::unique_ptr c; - std::unique_ptr *x = &a; - std::unique_ptr *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 ptr1 = std::move(ptr2) - // 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()); -} - Index: test/clang-tidy/misc-unused-raii.cpp =================================================================== --- test/clang-tidy/misc-unused-raii.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-unused-raii %t -// REQUIRES: shell - -struct Foo { - Foo(); - Foo(int); - Foo(int, int); - ~Foo(); -}; - -struct Bar { - Bar(); - Foo f; -}; - -template -void qux() { - T(42); -} - -template -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(23); -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object? -// CHECK-FIXES: TFoo give_me_a_name(23); - - Bar(); - f(); - qux(); - -#define M Foo(); - M - - { - Foo(); - } - Foo(); -} Index: test/clang-tidy/misc-use-override-cxx98.cpp =================================================================== --- test/clang-tidy/misc-use-override-cxx98.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-use-override %t -- -std=c++98 -// REQUIRES: shell - -struct Base { - virtual ~Base() {} - virtual void a(); - virtual void b(); -}; - -struct SimpleCases : public Base { -public: - virtual ~SimpleCases(); - // CHECK-FIXES: {{^}} virtual ~SimpleCases(); - - void a(); - // CHECK-FIXES: {{^}} void a(); - - virtual void b(); - // CHECK-FIXES: {{^}} virtual void b(); -}; Index: test/clang-tidy/misc-use-override.cpp =================================================================== --- test/clang-tidy/misc-use-override.cpp +++ /dev/null @@ -1,247 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s misc-use-override %t -// REQUIRES: shell - -#define ABSTRACT = 0 - -#define OVERRIDE override -#define VIRTUAL virtual -#define NOT_VIRTUAL -#define NOT_OVERRIDE - -#define MUST_USE_RESULT __attribute__((warn_unused_result)) -#define UNUSED __attribute__((unused)) - -struct MUST_USE_RESULT MustUseResultObject {}; - -struct Base { - virtual ~Base() {} - virtual void a(); - virtual void b(); - virtual void c(); - virtual void d(); - virtual void d2(); - virtual void e() = 0; - virtual void f() = 0; - virtual void g() = 0; - - virtual void j() const; - virtual MustUseResultObject k(); - virtual bool l() MUST_USE_RESULT UNUSED; - virtual bool n() MUST_USE_RESULT UNUSED; - - virtual void m(); - virtual void m2(); - virtual void o() __attribute__((unused)); -}; - -struct SimpleCases : public Base { -public: - virtual ~SimpleCases(); - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' - // CHECK-FIXES: {{^}} ~SimpleCases() override; - - void a(); - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this - // CHECK-FIXES: {{^}} void a() override; - - void b() override; - // CHECK-MESSAGES-NOT: warning: - // CHECK-FIXES: {{^}} void b() override; - - virtual void c(); - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void c() override; - - virtual void d() override; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override' - // CHECK-FIXES: {{^}} void d() override; - - virtual void d2() final; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final' - // CHECK-FIXES: {{^}} void d2() final; - - virtual void e() = 0; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void e() override = 0; - - virtual void f()=0; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void f()override =0; - - virtual void g() ABSTRACT; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void g() override ABSTRACT; - - virtual void j() const; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void j() const override; - - virtual MustUseResultObject k(); // Has an implicit attribute. - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using - // CHECK-FIXES: {{^}} MustUseResultObject k() override; - - virtual bool l() MUST_USE_RESULT UNUSED; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED; - - virtual bool n() UNUSED MUST_USE_RESULT; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} bool n() override UNUSED MUST_USE_RESULT; - - void m() override final; - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final' - // CHECK-FIXES: {{^}} void m() final; - - virtual void m2() override final; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final' - // CHECK-FIXES: {{^}} void m2() final; - - virtual void o() __attribute__((unused)); - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void o() override __attribute__((unused)); -}; - -// CHECK-MESSAGES-NOT: warning: - -void SimpleCases::c() {} -// CHECK-FIXES: {{^}}void SimpleCases::c() {} - -SimpleCases::~SimpleCases() {} -// CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {} - -struct DefaultedDestructor : public Base { - DefaultedDestructor() {} - virtual ~DefaultedDestructor() = default; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using - // CHECK-FIXES: {{^}} ~DefaultedDestructor() override = default; -}; - -struct FinalSpecified : public Base { -public: - virtual ~FinalSpecified() final; - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final' - // CHECK-FIXES: {{^}} ~FinalSpecified() final; - - void b() final; - // CHECK-MESSAGES-NOT: warning: - // CHECK-FIXES: {{^}} void b() final; - - virtual void d() final; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant - // CHECK-FIXES: {{^}} void d() final; - - virtual void e() final = 0; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant - // CHECK-FIXES: {{^}} void e() final = 0; - - virtual void j() const final; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant - // CHECK-FIXES: {{^}} void j() const final; - - virtual bool l() final MUST_USE_RESULT UNUSED; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant - // CHECK-FIXES: {{^}} bool l() final MUST_USE_RESULT UNUSED; -}; - -struct InlineDefinitions : public Base { -public: - virtual ~InlineDefinitions() {} - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using - // CHECK-FIXES: {{^}} ~InlineDefinitions() override {} - - void a() {} - // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this - // CHECK-FIXES: {{^}} void a() override {} - - void b() override {} - // CHECK-MESSAGES-NOT: warning: - // CHECK-FIXES: {{^}} void b() override {} - - virtual void c() {} - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void c() override {} - - virtual void d() override {} - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant - // CHECK-FIXES: {{^}} void d() override {} - - virtual void j() const {} - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void j() const override {} - - virtual MustUseResultObject k() {} // Has an implicit attribute. - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using - // CHECK-FIXES: {{^}} MustUseResultObject k() override {} - - virtual bool l() MUST_USE_RESULT UNUSED {} - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED {} -}; - -struct Macros : public Base { - // Tests for 'virtual' and 'override' being defined through macros. Basically - // give up for now. - NOT_VIRTUAL void a() NOT_OVERRIDE; - // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this - // CHECK-FIXES: {{^}} NOT_VIRTUAL void a() override NOT_OVERRIDE; - - VIRTUAL void b() NOT_OVERRIDE; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} VIRTUAL void b() override NOT_OVERRIDE; - - NOT_VIRTUAL void c() OVERRIDE; - // CHECK-MESSAGES-NOT: warning: - // CHECK-FIXES: {{^}} NOT_VIRTUAL void c() OVERRIDE; - - VIRTUAL void d() OVERRIDE; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant - // CHECK-FIXES: {{^}} VIRTUAL void d() OVERRIDE; - -#define FUNC(return_type, name) return_type name() - FUNC(void, e); - // CHECK-FIXES: {{^}} FUNC(void, e); - -#define F virtual void f(); - F - // CHECK-FIXES: {{^}} F - - VIRTUAL void g() OVERRIDE final; - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant - // CHECK-FIXES: {{^}} VIRTUAL void g() final; -}; - -// Tests for templates. -template struct TemplateBase { - virtual void f(T t); -}; - -template struct DerivedFromTemplate : public TemplateBase { - virtual void f(T t); - // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using - // CHECK-FIXES: {{^}} void f(T t) override; -}; -void f() { DerivedFromTemplate().f(2); } - -template -struct UnusedMemberInstantiation : public C { - virtual ~UnusedMemberInstantiation() {} - // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using - // CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {} -}; -struct IntantiateWithoutUse : public UnusedMemberInstantiation {}; - -struct Base2 { - virtual ~Base2() {} - virtual void a(); -}; - -// The OverrideAttr isn't propagated to specializations in all cases. Make sure -// we don't add "override" a second time. -template -struct MembersOfSpecializations : public Base2 { - void a() override; - // CHECK-MESSAGES-NOT: warning: - // CHECK-FIXES: {{^}} void a() override; -}; -template <> void MembersOfSpecializations<3>::a() {} -void ff() { MembersOfSpecializations<3>().a(); }; Index: test/clang-tidy/misc/arg-comments.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/arg-comments.cpp @@ -0,0 +1,41 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-argument-comment %t +// REQUIRES: shell + +// FIXME: clang-tidy should provide a -verify mode to make writing these checks +// easier and more accurate. + +void ffff(int xxxx, int yyyy); + +void f(int x, int y); +void g() { + // CHECK-MESSAGES: [[@LINE+4]]:5: warning: argument name 'y' in comment does not match parameter name 'x' + // CHECK-MESSAGES: :[[@LINE-3]]:12: note: 'x' declared here + // CHECK-MESSAGES: [[@LINE+2]]:14: warning: argument name 'z' in comment does not match parameter name 'y' + // CHECK-MESSAGES: :[[@LINE-5]]:19: note: 'y' declared here + f(/*y=*/0, /*z=*/0); +} + +struct Closure {}; + +template +Closure *NewCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; } + +template +Closure *NewPermanentCallback(void (*f)(T1, T2), T1 arg1, T2 arg2) { return nullptr; } + +void h() { + (void)NewCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22); + (void)NewPermanentCallback(&ffff, /*xxxx=*/11, /*yyyy=*/22); +} + +template +void variadic(Args&&... args); + +template +void variadic2(int zzz, Args&&... args); + +void templates() { + variadic(/*xxx=*/0, /*yyy=*/1); + variadic2(/*zzZ=*/0, /*xxx=*/1, /*yyy=*/2); + // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument name 'zzZ' in comment does not match parameter name 'zzz' +} Index: test/clang-tidy/misc/assign-operator-signature.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/assign-operator-signature.cpp @@ -0,0 +1,52 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-assign-operator-signature %t +// REQUIRES: shell + +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 BadReturn { + void operator=(const BadReturn&); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'BadReturn&' [misc-assign-operator-signature] + const BadReturn& operator=(BadReturn&&); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad +}; +struct BadReturn2 { + BadReturn2&& operator=(const BadReturn2&); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: operator=() should return 'Bad + int operator=(BadReturn2&&); + // 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 &); +}; Index: test/clang-tidy/misc/bool-pointer-implicit-conversion.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/bool-pointer-implicit-conversion.cpp @@ -0,0 +1,83 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-bool-pointer-implicit-conversion %t +// REQUIRES: shell + +bool *SomeFunction(); +void SomeOtherFunction(bool*); +bool F(); +void G(bool); + + +template +void t(T b) { + if (b) { + } +} + +void foo() { + bool *b = SomeFunction(); + if (b) { +// CHECK-MESSAGES: :[[@LINE-1]]:7: warning: dubious check of 'bool *' against 'nullptr' +// CHECK-FIXES: if (*b) { + } + + if (F() && b) { +// CHECK-MESSAGES: :[[@LINE-1]]:14: warning: dubious check of 'bool *' against 'nullptr' +// CHECK-FIXES: if (F() && *b) { + } + + // TODO: warn here. + if (b) { + G(b); + } + +#define TESTMACRO if (b || F()) + + TESTMACRO { + } + + t(b); + + if (!b) { + // no-warning + } + + if (SomeFunction()) { + // no-warning + } + + bool *c = SomeFunction(); + if (c) { + (void)c; + (void)*c; // no-warning + } + + if (c) { + *c = true; // no-warning + } + + if (c) { + c[0] = false; // no-warning + } + + if (c) { + SomeOtherFunction(c); // no-warning + } + + if (c) { + delete[] c; // no-warning + } + + if (c) { + *(c) = false; // no-warning + } + + struct { + bool *b; + } d = { SomeFunction() }; + + if (d.b) + (void)*d.b; // no-warning + +#define CHECK(b) if (b) {} + CHECK(c) +} Index: test/clang-tidy/misc/inaccurate-erase.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/inaccurate-erase.cpp @@ -0,0 +1,77 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-inaccurate-erase %t +// REQUIRES: shell + +namespace std { +template struct vec_iterator { + T *ptr; + vec_iterator operator++(int); +}; + +template struct vector { + typedef vec_iterator iterator; + + iterator begin(); + iterator end(); + + void erase(iterator); + void erase(iterator, iterator); +}; + +template +FwIt remove(FwIt begin, FwIt end, const T &val); + +template +FwIt remove_if(FwIt begin, FwIt end, Func f); + +template FwIt unique(FwIt begin, FwIt end); + +template struct unique_ptr {}; +} // namespace std + +struct custom_iter {}; +struct custom_container { + void erase(...); + custom_iter begin(); + custom_iter end(); +}; + +template void g() { + T t; + t.erase(std::remove(t.begin(), t.end(), 10)); + // CHECK-FIXES: {{^ }}t.erase(std::remove(t.begin(), t.end(), 10));{{$}} + + std::vector v; + v.erase(remove(v.begin(), v.end(), 10)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one + // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}} +} + +#define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y)) +// CHECK-FIXES: #define ERASE(x, y) x.erase(remove(x.begin(), x.end(), y)) + +int main() { + std::vector v; + + v.erase(remove(v.begin(), v.end(), 10)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one item even when multiple items should be removed [misc-inaccurate-erase] + // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), v.end(), 10), v.end());{{$}} + v.erase(remove(v.begin(), v.end(), 20), v.end()); + + // Fix is not trivial. + auto it = v.end(); + v.erase(remove(v.begin(), it, 10)); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this call will remove at most one + // CHECK-FIXES: {{^ }}v.erase(remove(v.begin(), it, 10));{{$}} + + g>(); + g(); + + ERASE(v, 15); + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: this call will remove at most one + // CHECK-FIXES: {{^ }}ERASE(v, 15);{{$}} + + std::vector> vupi; + auto iter = vupi.begin(); + vupi.erase(iter++); + // CHECK-FIXES: {{^ }}vupi.erase(iter++);{{$}} +} Index: test/clang-tidy/misc/inefficient-algorithm.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/inefficient-algorithm.cpp @@ -0,0 +1,133 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-inefficient-algorithm %t +// REQUIRES: shell + +namespace std { +template struct less { + bool operator()(const T &lhs, const T &rhs) { return lhs < rhs; } +}; + +template struct greater { + bool operator()(const T &lhs, const T &rhs) { return lhs > rhs; } +}; + +struct iterator_type {}; + +template > struct set { + typedef iterator_type iterator; + iterator find(const K &k); + unsigned count(const K &k); + + iterator begin(); + iterator end(); + iterator begin() const; + iterator end() const; +}; + +struct other_iterator_type {}; + +template > struct map { + typedef other_iterator_type iterator; + iterator find(const K &k); + unsigned count(const K &k); + + iterator begin(); + iterator end(); + iterator begin() const; + iterator end() const; +}; + +template struct unordered_set : set {}; + +template > struct multiset : set {}; + +template FwIt find(FwIt, FwIt, const K &); + +template +FwIt find(FwIt, FwIt, const K &, Cmp); + +template FwIt find_if(FwIt, FwIt, Pred); + +template FwIt count(FwIt, FwIt, const K &); + +template FwIt lower_bound(FwIt, FwIt, const K &); + +template +FwIt lower_bound(FwIt, FwIt, const K &, Ord); +} + +#define FIND_IN_SET(x) find(x.begin(), x.end(), 10) +// CHECK-FIXES: #define FIND_IN_SET(x) find(x.begin(), x.end(), 10) + +template void f(const T &t) { + std::set s; + find(s.begin(), s.end(), 46); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}s.find(46);{{$}} + + find(t.begin(), t.end(), 46); + // CHECK-FIXES: {{^ }}find(t.begin(), t.end(), 46);{{$}} +} + +int main() { + std::set s; + auto it = std::find(s.begin(), s.end(), 43); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: this STL algorithm call should be replaced with a container method [misc-inefficient-algorithm] + // CHECK-FIXES: {{^ }}auto it = s.find(43);{{$}} + auto c = count(s.begin(), s.end(), 43); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}auto c = s.count(43);{{$}} + it = find_if(s.begin(), s.end(), [](int) { return false; }); + + std::multiset ms; + find(ms.begin(), ms.end(), 46); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}ms.find(46);{{$}} + + const std::multiset &msref = ms; + find(msref.begin(), msref.end(), 46); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}msref.find(46);{{$}} + + std::multiset *msptr = &ms; + find(msptr->begin(), msptr->end(), 46); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}msptr->find(46);{{$}} + + it = std::find(s.begin(), s.end(), 43, std::greater()); + // CHECK-MESSAGES: :[[@LINE-1]]:42: warning: different comparers used in the algorithm and the container [misc-inefficient-algorithm] + + FIND_IN_SET(s); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}FIND_IN_SET(s);{{$}} + + f(s); + + std::unordered_set us; + lower_bound(us.begin(), us.end(), 10); + // CHECK-FIXES: {{^ }}lower_bound(us.begin(), us.end(), 10);{{$}} + find(us.begin(), us.end(), 10); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}us.find(10);{{$}} + + std::map intmap; + find(intmap.begin(), intmap.end(), 46); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}find(intmap.begin(), intmap.end(), 46);{{$}} +} + +struct Value { + int value; +}; + +struct Ordering { + bool operator()(const Value &lhs, const Value &rhs) const { + return lhs.value < rhs.value; + } + bool operator()(int lhs, const Value &rhs) const { return lhs < rhs.value; } +}; + +void g(std::set container, int value) { + lower_bound(container.begin(), container.end(), value, Ordering()); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this STL algorithm call should be + // CHECK-FIXES: {{^ }}lower_bound(container.begin(), container.end(), value, Ordering());{{$}} +} Index: test/clang-tidy/misc/swapped-arguments.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/swapped-arguments.cpp @@ -0,0 +1,44 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-swapped-arguments %t +// REQUIRES: shell + +void F(int, double); + +int SomeFunction(); + +template +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. +// In macro, don't emit fixits. +// CHECK-FIXES: F(b, M(Some, Function)); + +#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 +} Index: test/clang-tidy/misc/undelegated-constructor.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/undelegated-constructor.cpp @@ -0,0 +1,55 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-undelegated-constructor %t +// REQUIRES: shell + +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 [misc-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 +struct TDerived : public Base { + TDerived() { Base(); } +}; + +TDerived t; Index: test/clang-tidy/misc/uniqueptr-reset-release.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/uniqueptr-reset-release.cpp @@ -0,0 +1,48 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-uniqueptr-reset-release %t +// REQUIRES: shell + +namespace std { +template +struct unique_ptr { + unique_ptr(); + explicit unique_ptr(T *); + template + unique_ptr(unique_ptr &&); + void reset(T *); + T *release(); +}; +} // namespace std + +struct Foo {}; +struct Bar : Foo {}; + +std::unique_ptr Create(); +std::unique_ptr &Look(); +std::unique_ptr *Get(); + +void f() { + std::unique_ptr a, b; + std::unique_ptr c; + std::unique_ptr *x = &a; + std::unique_ptr *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 ptr1 = std::move(ptr2) + // 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()); +} + Index: test/clang-tidy/misc/unused-raii.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/unused-raii.cpp @@ -0,0 +1,61 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-unused-raii %t +// REQUIRES: shell + +struct Foo { + Foo(); + Foo(int); + Foo(int, int); + ~Foo(); +}; + +struct Bar { + Bar(); + Foo f; +}; + +template +void qux() { + T(42); +} + +template +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(23); +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after creation; did you mean to name the object? +// CHECK-FIXES: TFoo give_me_a_name(23); + + Bar(); + f(); + qux(); + +#define M Foo(); + M + + { + Foo(); + } + Foo(); +} Index: test/clang-tidy/misc/use-override-cxx98.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/use-override-cxx98.cpp @@ -0,0 +1,20 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-use-override %t -- -std=c++98 +// REQUIRES: shell + +struct Base { + virtual ~Base() {} + virtual void a(); + virtual void b(); +}; + +struct SimpleCases : public Base { +public: + virtual ~SimpleCases(); + // CHECK-FIXES: {{^}} virtual ~SimpleCases(); + + void a(); + // CHECK-FIXES: {{^}} void a(); + + virtual void b(); + // CHECK-FIXES: {{^}} virtual void b(); +}; Index: test/clang-tidy/misc/use-override.cpp =================================================================== --- /dev/null +++ test/clang-tidy/misc/use-override.cpp @@ -0,0 +1,247 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s misc-use-override %t +// REQUIRES: shell + +#define ABSTRACT = 0 + +#define OVERRIDE override +#define VIRTUAL virtual +#define NOT_VIRTUAL +#define NOT_OVERRIDE + +#define MUST_USE_RESULT __attribute__((warn_unused_result)) +#define UNUSED __attribute__((unused)) + +struct MUST_USE_RESULT MustUseResultObject {}; + +struct Base { + virtual ~Base() {} + virtual void a(); + virtual void b(); + virtual void c(); + virtual void d(); + virtual void d2(); + virtual void e() = 0; + virtual void f() = 0; + virtual void g() = 0; + + virtual void j() const; + virtual MustUseResultObject k(); + virtual bool l() MUST_USE_RESULT UNUSED; + virtual bool n() MUST_USE_RESULT UNUSED; + + virtual void m(); + virtual void m2(); + virtual void o() __attribute__((unused)); +}; + +struct SimpleCases : public Base { +public: + virtual ~SimpleCases(); + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using 'override' or (rarely) 'final' instead of 'virtual' + // CHECK-FIXES: {{^}} ~SimpleCases() override; + + void a(); + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this + // CHECK-FIXES: {{^}} void a() override; + + void b() override; + // CHECK-MESSAGES-NOT: warning: + // CHECK-FIXES: {{^}} void b() override; + + virtual void c(); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void c() override; + + virtual void d() override; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'override' + // CHECK-FIXES: {{^}} void d() override; + + virtual void d2() final; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant since the function is already declared 'final' + // CHECK-FIXES: {{^}} void d2() final; + + virtual void e() = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void e() override = 0; + + virtual void f()=0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void f()override =0; + + virtual void g() ABSTRACT; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void g() override ABSTRACT; + + virtual void j() const; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void j() const override; + + virtual MustUseResultObject k(); // Has an implicit attribute. + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using + // CHECK-FIXES: {{^}} MustUseResultObject k() override; + + virtual bool l() MUST_USE_RESULT UNUSED; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED; + + virtual bool n() UNUSED MUST_USE_RESULT; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} bool n() override UNUSED MUST_USE_RESULT; + + void m() override final; + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: 'override' is redundant since the function is already declared 'final' + // CHECK-FIXES: {{^}} void m() final; + + virtual void m2() override final; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant since the function is already declared 'final' + // CHECK-FIXES: {{^}} void m2() final; + + virtual void o() __attribute__((unused)); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void o() override __attribute__((unused)); +}; + +// CHECK-MESSAGES-NOT: warning: + +void SimpleCases::c() {} +// CHECK-FIXES: {{^}}void SimpleCases::c() {} + +SimpleCases::~SimpleCases() {} +// CHECK-FIXES: {{^}}SimpleCases::~SimpleCases() {} + +struct DefaultedDestructor : public Base { + DefaultedDestructor() {} + virtual ~DefaultedDestructor() = default; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using + // CHECK-FIXES: {{^}} ~DefaultedDestructor() override = default; +}; + +struct FinalSpecified : public Base { +public: + virtual ~FinalSpecified() final; + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: 'virtual' is redundant since the function is already declared 'final' + // CHECK-FIXES: {{^}} ~FinalSpecified() final; + + void b() final; + // CHECK-MESSAGES-NOT: warning: + // CHECK-FIXES: {{^}} void b() final; + + virtual void d() final; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant + // CHECK-FIXES: {{^}} void d() final; + + virtual void e() final = 0; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant + // CHECK-FIXES: {{^}} void e() final = 0; + + virtual void j() const final; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant + // CHECK-FIXES: {{^}} void j() const final; + + virtual bool l() final MUST_USE_RESULT UNUSED; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant + // CHECK-FIXES: {{^}} bool l() final MUST_USE_RESULT UNUSED; +}; + +struct InlineDefinitions : public Base { +public: + virtual ~InlineDefinitions() {} + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using + // CHECK-FIXES: {{^}} ~InlineDefinitions() override {} + + void a() {} + // CHECK-MESSAGES: :[[@LINE-1]]:8: warning: annotate this + // CHECK-FIXES: {{^}} void a() override {} + + void b() override {} + // CHECK-MESSAGES-NOT: warning: + // CHECK-FIXES: {{^}} void b() override {} + + virtual void c() {} + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void c() override {} + + virtual void d() override {} + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant + // CHECK-FIXES: {{^}} void d() override {} + + virtual void j() const {} + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void j() const override {} + + virtual MustUseResultObject k() {} // Has an implicit attribute. + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: prefer using + // CHECK-FIXES: {{^}} MustUseResultObject k() override {} + + virtual bool l() MUST_USE_RESULT UNUSED {} + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} bool l() override MUST_USE_RESULT UNUSED {} +}; + +struct Macros : public Base { + // Tests for 'virtual' and 'override' being defined through macros. Basically + // give up for now. + NOT_VIRTUAL void a() NOT_OVERRIDE; + // CHECK-MESSAGES: :[[@LINE-1]]:20: warning: annotate this + // CHECK-FIXES: {{^}} NOT_VIRTUAL void a() override NOT_OVERRIDE; + + VIRTUAL void b() NOT_OVERRIDE; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} VIRTUAL void b() override NOT_OVERRIDE; + + NOT_VIRTUAL void c() OVERRIDE; + // CHECK-MESSAGES-NOT: warning: + // CHECK-FIXES: {{^}} NOT_VIRTUAL void c() OVERRIDE; + + VIRTUAL void d() OVERRIDE; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' is redundant + // CHECK-FIXES: {{^}} VIRTUAL void d() OVERRIDE; + +#define FUNC(return_type, name) return_type name() + FUNC(void, e); + // CHECK-FIXES: {{^}} FUNC(void, e); + +#define F virtual void f(); + F + // CHECK-FIXES: {{^}} F + + VIRTUAL void g() OVERRIDE final; + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: 'virtual' and 'override' are redundant + // CHECK-FIXES: {{^}} VIRTUAL void g() final; +}; + +// Tests for templates. +template struct TemplateBase { + virtual void f(T t); +}; + +template struct DerivedFromTemplate : public TemplateBase { + virtual void f(T t); + // CHECK-MESSAGES: :[[@LINE-1]]:16: warning: prefer using + // CHECK-FIXES: {{^}} void f(T t) override; +}; +void f() { DerivedFromTemplate().f(2); } + +template +struct UnusedMemberInstantiation : public C { + virtual ~UnusedMemberInstantiation() {} + // CHECK-MESSAGES: :[[@LINE-1]]:11: warning: prefer using + // CHECK-FIXES: {{^}} ~UnusedMemberInstantiation() override {} +}; +struct IntantiateWithoutUse : public UnusedMemberInstantiation {}; + +struct Base2 { + virtual ~Base2() {} + virtual void a(); +}; + +// The OverrideAttr isn't propagated to specializations in all cases. Make sure +// we don't add "override" a second time. +template +struct MembersOfSpecializations : public Base2 { + void a() override; + // CHECK-MESSAGES-NOT: warning: + // CHECK-FIXES: {{^}} void a() override; +}; +template <> void MembersOfSpecializations<3>::a() {} +void ff() { MembersOfSpecializations<3>().a(); }; Index: test/clang-tidy/readability-braces-around-statements-few-lines.cpp =================================================================== --- test/clang-tidy/readability-braces-around-statements-few-lines.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-braces-around-statements %t -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 4}]}" -- -// REQUIRES: shell - -void do_something(const char *) {} - -bool cond(const char *) { - return false; -} - -void test() { - if (cond("if1") /*comment*/) do_something("same-line"); - - if (cond("if2")) - do_something("single-line"); - - if (cond("if3") /*comment*/) - // some comment - do_something("three" - "lines"); - - if (cond("if4") /*comment*/) - // some comment - do_something("many" - "many" - "many" - "many" - "lines"); - // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if4") /*comment*/) { - // CHECK-FIXES: } -} Index: test/clang-tidy/readability-braces-around-statements-same-line.cpp =================================================================== --- test/clang-tidy/readability-braces-around-statements-same-line.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-braces-around-statements %t -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 1}]}" -- -// REQUIRES: shell - -void do_something(const char *) {} - -bool cond(const char *) { - return false; -} - -void test() { - if (cond("if1") /*comment*/) do_something("same-line"); - - if (cond("if2")) - do_something("single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if2")) { - // CHECK-FIXES: } - - if (cond("if3") /*comment*/) - // some comment - do_something("three" - "lines"); - // CHECK-MESSAGES: :[[@LINE-4]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if3") /*comment*/) { - // CHECK-FIXES: } - - if (cond("if4") /*comment*/) - // some comment - do_something("many" - "many" - "many" - "many" - "lines"); - // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if4") /*comment*/) { - // CHECK-FIXES: } -} Index: test/clang-tidy/readability-braces-around-statements-single-line.cpp =================================================================== --- test/clang-tidy/readability-braces-around-statements-single-line.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-braces-around-statements %t -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 2}]}" -- -// REQUIRES: shell - -void do_something(const char *) {} - -bool cond(const char *) { - return false; -} - -void test() { - if (cond("if1") /*comment*/) do_something("same-line"); - - if (cond("if2")) - do_something("single-line"); - - if (cond("if3") /*comment*/) - // some comment - do_something("three" - "lines"); - // CHECK-MESSAGES: :[[@LINE-4]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if3") /*comment*/) { - // CHECK-FIXES: } - - if (cond("if4") /*comment*/) - // some comment - do_something("many" - "many" - "many" - "many" - "lines"); - // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if4") /*comment*/) { - // CHECK-FIXES: } -} Index: test/clang-tidy/readability-braces-around-statements.cpp =================================================================== --- test/clang-tidy/readability-braces-around-statements.cpp +++ /dev/null @@ -1,174 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-braces-around-statements %t -// REQUIRES: shell - -void do_something(const char *) {} - -bool cond(const char *) { - return false; -} - -#define EMPTY_MACRO -#define EMPTY_MACRO_FUN() - -void test() { - if (cond("if0") /*comment*/) do_something("same-line"); - // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if0") /*comment*/) { do_something("same-line"); - // CHECK-FIXES: } - - if (cond("if0.1")) - do_something("single-line"); - // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if0.1")) { - // CHECK-FIXES: } - - if (cond("if1") /*comment*/) - // some comment - do_something("if1"); - // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if1") /*comment*/) { - // CHECK-FIXES: } - if (cond("if2")) { - do_something("if2"); - } - if (cond("if3")) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if3")) { - // CHECK-FIXES: } - - if (cond("if-else1")) - do_something("if-else1"); - // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: statement should be inside braces - // CHECK-FIXES: if (cond("if-else1")) { - // CHECK-FIXES: } else { - else - do_something("if-else1 else"); - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces - // CHECK-FIXES: } - if (cond("if-else2")) { - do_something("if-else2"); - } else { - do_something("if-else2 else"); - } - - if (cond("if-else if-else1")) - do_something("if"); - // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: statement should be inside braces - // CHECK-FIXES: } else if (cond("else if1")) { - else if (cond("else if1")) - do_something("else if"); - // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: statement should be inside braces - else - do_something("else"); - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces - // CHECK-FIXES: } - if (cond("if-else if-else2")) { - do_something("if"); - } else if (cond("else if2")) { - do_something("else if"); - } else { - do_something("else"); - } - - for (;;) - do_something("for"); - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces - // CHECK-FIXES: for (;;) { - // CHECK-FIXES: } - for (;;) { - do_something("for"); - } - for (;;) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces - // CHECK-FIXES: for (;;) { - // CHECK-FIXES: } - - int arr[4] = {1, 2, 3, 4}; - for (int a : arr) - do_something("for-range"); - // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces - // CHECK-FIXES: for (int a : arr) { - // CHECK-FIXES: } - for (int a : arr) { - do_something("for-range"); - } - for (int a : arr) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces - // CHECK-FIXES: for (int a : arr) { - // CHECK-FIXES: } - - while (cond("while1")) - do_something("while"); - // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces - // CHECK-FIXES: while (cond("while1")) { - // CHECK-FIXES: } - while (cond("while2")) { - do_something("while"); - } - while (false) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: statement should be inside braces - // CHECK-FIXES: while (false) { - // CHECK-FIXES: } - - do - do_something("do1"); - while (cond("do1")); - // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces - // CHECK-FIXES: do { - // CHECK-FIXES: } while (cond("do1")); - do { - do_something("do2"); - } while (cond("do2")); - - do - ; - while (false); - // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces - // CHECK-FIXES: do { - // CHECK-FIXES: } while (false); - - if (cond("ifif1")) - // comment - if (cond("ifif2")) - // comment - /*comment*/ ; // comment - // CHECK-MESSAGES: :[[@LINE-5]]:21: warning: statement should be inside braces - // CHECK-MESSAGES: :[[@LINE-4]]:23: warning: statement should be inside braces - // CHECK-FIXES: if (cond("ifif1")) { - // CHECK-FIXES: if (cond("ifif2")) { - // CHECK-FIXES: } - // CHECK-FIXES-NEXT: } - - if (cond("ifif3")) - // comment - if (cond("ifif4")) { - // comment - /*comment*/; // comment - } - // CHECK-MESSAGES: :[[@LINE-6]]:21: warning: statement should be inside braces - // CHECK-FIXES: if (cond("ifif3")) { - // CHECK-FIXES: } - - if (cond("ifif5")) - ; /* multi-line - comment */ - // CHECK-MESSAGES: :[[@LINE-3]]:21: warning: statement should be inside braces - // CHECK-FIXES: if (cond("ifif5")) { - // CHECK-FIXES: }/* multi-line - - if (1) while (2) if (3) for (;;) do ; while(false) /**/;/**/ - // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should be inside braces - // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces - // CHECK-MESSAGES: :[[@LINE-3]]:26: warning: statement should be inside braces - // CHECK-MESSAGES: :[[@LINE-4]]:35: warning: statement should be inside braces - // CHECK-MESSAGES: :[[@LINE-5]]:38: warning: statement should be inside braces - // CHECK-FIXES: if (1) { while (2) { if (3) { for (;;) { do { ; } while(false) /**/;/**/ - // CHECK-FIXES-NEXT: } - // CHECK-FIXES-NEXT: } - // CHECK-FIXES-NEXT: } - // CHECK-FIXES-NEXT: } -} Index: test/clang-tidy/readability-container-size-empty.cpp =================================================================== --- test/clang-tidy/readability-container-size-empty.cpp +++ /dev/null @@ -1,106 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-container-size-empty %t -// REQUIRES: shell - -namespace std { -template struct vector { - vector() {} - int size() const {} - bool empty() const {} -}; -} - -int main() { - std::vector vect; - if (vect.size() == 0) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used to check for emptiness instead of 'size'. [readability-container-size-empty] - // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} - if (vect.size() != 0) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - if (0 == vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} - if (0 != vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - if (vect.size() > 0) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - if (0 < vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - if (vect.size() < 1) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} - if (1 > vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} - if (vect.size() >= 1) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - if (1 <= vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - if (!vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} - if (vect.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} - - if (vect.empty()) - ; - - const std::vector vect2; - if (vect2.size() != 0) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!vect2.empty()){{$}} - - std::vector *vect3 = new std::vector(); - if (vect3->size() == 0) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}} - - delete vect3; - - const std::vector &vect4 = vect2; - if (vect4.size() == 0) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (vect4.empty()){{$}} -} - -#define CHECKSIZE(x) if (x.size()) -// CHECK-FIXES: #define CHECKSIZE(x) if (x.size()) - -template void f() { - std::vector v; - if (v.size()) - ; - // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used - // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} - // CHECK-FIXES-NEXT: ; - CHECKSIZE(v); - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: The 'empty' method should be used - // CHECK-MESSAGES: CHECKSIZE(v); -} - -void g() { - f(); - f(); - f(); -} Index: test/clang-tidy/readability-else-after-return.cpp =================================================================== --- test/clang-tidy/readability-else-after-return.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-else-after-return %t -// REQUIRES: shell - -void f(int a) { - if (a > 0) - return; - else // comment -// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: don't use else after return -// CHECK-FIXES: {{^}} // comment - return; - - if (a > 0) { - return; - } else { // comment -// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: don't use else after return -// CHECK-FIXES: } // comment - return; - } - - if (a > 0) { - f(0); - if (a > 10) - return; - } else { - return; - } -} - Index: test/clang-tidy/readability-function-size.cpp =================================================================== --- test/clang-tidy/readability-function-size.cpp +++ /dev/null @@ -1,55 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-function-size %t -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}]}' -- -std=c++11 -// REQUIRES: shell - -void foo1() { -} - -void foo2() {;} -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'foo2' exceeds recommended size/complexity thresholds [readability-function-size] -// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 1 statements (threshold 0) - -void foo3() { -; - -} -// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'foo3' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) -// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 1 statements (threshold 0) - -void foo4(int i) { if (i) {} else; {} -} -// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: function 'foo4' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-3]]:6: note: 1 lines including whitespace and comments (threshold 0) -// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 3 statements (threshold 0) -// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 branches (threshold 0) - -void foo5(int i) {for(;i;)while(i) -do;while(i); -} -// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'foo5' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0) -// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 7 statements (threshold 0) -// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 3 branches (threshold 0) - -template T foo6(T i) {return i; -} -int x = foo6(0); -// CHECK-MESSAGES: :[[@LINE-3]]:25: warning: function 'foo6' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-4]]:25: note: 1 lines including whitespace and comments (threshold 0) -// CHECK-MESSAGES: :[[@LINE-5]]:25: note: 1 statements (threshold 0) - -void bar1() { [](){;;;;;;;;;;;if(1){}}(); - - -} -// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'bar1' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) -// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 14 statements (threshold 0) -// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 1 branches (threshold 0) - -void bar2() { class A { void barx() {;;} }; } -// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'bar2' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 3 statements (threshold 0) -// -// CHECK-MESSAGES: :[[@LINE-4]]:30: warning: function 'barx' exceeds recommended size/complexity -// CHECK-MESSAGES: :[[@LINE-5]]:30: note: 2 statements (threshold 0) Index: test/clang-tidy/readability-redundant-smartptr-get.cpp =================================================================== --- test/clang-tidy/readability-redundant-smartptr-get.cpp +++ /dev/null @@ -1,129 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-redundant-smartptr-get %t -// REQUIRES: shell - -#define NULL __null - -namespace std { - -template -struct unique_ptr { - T& operator*() const; - T* operator->() const; - T* get() const; -}; - -template -struct shared_ptr { - T& operator*() const; - T* operator->() const; - T* get() const; -}; - -} // namespace std - -struct Bar { - void Do(); - void ConstDo() const; -}; -struct BarPtr { - Bar* operator->(); - Bar& operator*(); - Bar* get(); -}; -struct int_ptr { - int* get(); - int* operator->(); - int& operator*(); -}; - -struct Fail1 { - Bar* get(); -}; -struct Fail2 { - Bar* get(); - int* operator->(); - int& operator*(); -}; - -void Positive() { - BarPtr u; - // CHECK-FIXES: BarPtr u; - BarPtr().get()->Do(); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Redundant get() call on smart pointer. [readability-redundant-smartptr-get] - // CHECK-MESSAGES: BarPtr().get()->Do(); - // CHECK-FIXES: BarPtr()->Do(); - - u.get()->ConstDo(); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: u.get()->ConstDo(); - // CHECK-FIXES: u->ConstDo(); - - Bar& b = *BarPtr().get(); - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: Bar& b = *BarPtr().get(); - // CHECK-FIXES: Bar& b = *BarPtr(); - - Bar& b2 = *std::unique_ptr().get(); - // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: Bar& b2 = *std::unique_ptr().get(); - // CHECK-FIXES: Bar& b2 = *std::unique_ptr(); - - (*BarPtr().get()).ConstDo(); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: (*BarPtr().get()).ConstDo(); - // CHECK-FIXES: (*BarPtr()).ConstDo(); - - (*std::unique_ptr().get()).ConstDo(); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: (*std::unique_ptr().get()).ConstDo(); - // CHECK-FIXES: (*std::unique_ptr()).ConstDo(); - - std::unique_ptr* up; - (*up->get()).Do(); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: (*up->get()).Do(); - // CHECK-FIXES: (**up).Do(); - - int_ptr ip; - int i = *ip.get(); - // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: int i = *ip.get(); - // CHECK-FIXES: int i = *ip; - - std::unique_ptr uu; - std::shared_ptr *ss; - bool bb = uu.get() == nullptr; - // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: uu.get() == nullptr; - // CHECK-FIXES: bool bb = uu == nullptr; - - bb = nullptr != ss->get(); - // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: Redundant get() call on smart pointer. - // CHECK-MESSAGES: nullptr != ss->get(); - // CHECK-FIXES: bb = nullptr != *ss; -} - -void Negative() { - struct NegPtr { - int* get(); - int* operator->() { - return &*this->get(); - } - int& operator*() { - return *get(); - } - }; - - std::unique_ptr* u; - u->get()->Do(); - - Fail1().get()->Do(); - Fail2().get()->Do(); - const Bar& b = *Fail1().get(); - (*Fail2().get()).Do(); - - int_ptr ip; - bool bb = std::unique_ptr().get() == NULL; - bb = ip.get() == nullptr; - bb = u->get() == NULL; -} Index: test/clang-tidy/readability-shrink-to-fit.cpp =================================================================== --- test/clang-tidy/readability-shrink-to-fit.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// RUN: $(dirname %s)/check_clang_tidy.sh %s readability-shrink-to-fit %t -// REQUIRES: shell - -namespace std { -template struct vector { void swap(vector &other); }; -} - -void f() { - std::vector v; - - std::vector(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 [readability-shrink-to-fit] - // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}} - - std::vector &vref = v; - std::vector(vref).swap(vref); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should - // CHECK-FIXES: {{^ }}vref.shrink_to_fit();{{$}} - - std::vector *vptr = &v; - std::vector(*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 v; - void f() { - std::vector(v).swap(v); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should - // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}} - - std::vector *vptr = &v; - std::vector(*vptr).swap(*vptr); - // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should - // CHECK-FIXES: {{^ }}vptr->shrink_to_fit();{{$}} - } -}; - -template void g() { - std::vector v; - std::vector(v).swap(v); - // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should - // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}} - - std::vector v2; - std::vector(v2).swap(v2); - // CHECK-FIXES: {{^ }}std::vector(v2).swap(v2);{{$}} -} - -template void g2() { - std::vector v; - std::vector(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(x).swap(x) -// CHECK-FIXES: #define COPY_AND_SWAP_INT_VEC(x) std::vector(x).swap(x) - -void h() { - g(); - g(); - g(); - g2>(); - std::vector 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);{{$}} -} - Index: test/clang-tidy/readability/braces-around-statements-few-lines.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/braces-around-statements-few-lines.cpp @@ -0,0 +1,31 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-braces-around-statements %t -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 4}]}" -- +// REQUIRES: shell + +void do_something(const char *) {} + +bool cond(const char *) { + return false; +} + +void test() { + if (cond("if1") /*comment*/) do_something("same-line"); + + if (cond("if2")) + do_something("single-line"); + + if (cond("if3") /*comment*/) + // some comment + do_something("three" + "lines"); + + if (cond("if4") /*comment*/) + // some comment + do_something("many" + "many" + "many" + "many" + "lines"); + // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if4") /*comment*/) { + // CHECK-FIXES: } +} Index: test/clang-tidy/readability/braces-around-statements-same-line.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/braces-around-statements-same-line.cpp @@ -0,0 +1,37 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-braces-around-statements %t -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 1}]}" -- +// REQUIRES: shell + +void do_something(const char *) {} + +bool cond(const char *) { + return false; +} + +void test() { + if (cond("if1") /*comment*/) do_something("same-line"); + + if (cond("if2")) + do_something("single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if2")) { + // CHECK-FIXES: } + + if (cond("if3") /*comment*/) + // some comment + do_something("three" + "lines"); + // CHECK-MESSAGES: :[[@LINE-4]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if3") /*comment*/) { + // CHECK-FIXES: } + + if (cond("if4") /*comment*/) + // some comment + do_something("many" + "many" + "many" + "many" + "lines"); + // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if4") /*comment*/) { + // CHECK-FIXES: } +} Index: test/clang-tidy/readability/braces-around-statements-single-line.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/braces-around-statements-single-line.cpp @@ -0,0 +1,34 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-braces-around-statements %t -config="{CheckOptions: [{key: readability-braces-around-statements.ShortStatementLines, value: 2}]}" -- +// REQUIRES: shell + +void do_something(const char *) {} + +bool cond(const char *) { + return false; +} + +void test() { + if (cond("if1") /*comment*/) do_something("same-line"); + + if (cond("if2")) + do_something("single-line"); + + if (cond("if3") /*comment*/) + // some comment + do_something("three" + "lines"); + // CHECK-MESSAGES: :[[@LINE-4]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if3") /*comment*/) { + // CHECK-FIXES: } + + if (cond("if4") /*comment*/) + // some comment + do_something("many" + "many" + "many" + "many" + "lines"); + // CHECK-MESSAGES: :[[@LINE-7]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if4") /*comment*/) { + // CHECK-FIXES: } +} Index: test/clang-tidy/readability/braces-around-statements.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/braces-around-statements.cpp @@ -0,0 +1,174 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-braces-around-statements %t +// REQUIRES: shell + +void do_something(const char *) {} + +bool cond(const char *) { + return false; +} + +#define EMPTY_MACRO +#define EMPTY_MACRO_FUN() + +void test() { + if (cond("if0") /*comment*/) do_something("same-line"); + // CHECK-MESSAGES: :[[@LINE-1]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if0") /*comment*/) { do_something("same-line"); + // CHECK-FIXES: } + + if (cond("if0.1")) + do_something("single-line"); + // CHECK-MESSAGES: :[[@LINE-2]]:21: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if0.1")) { + // CHECK-FIXES: } + + if (cond("if1") /*comment*/) + // some comment + do_something("if1"); + // CHECK-MESSAGES: :[[@LINE-3]]:31: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if1") /*comment*/) { + // CHECK-FIXES: } + if (cond("if2")) { + do_something("if2"); + } + if (cond("if3")) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if3")) { + // CHECK-FIXES: } + + if (cond("if-else1")) + do_something("if-else1"); + // CHECK-MESSAGES: :[[@LINE-2]]:24: warning: statement should be inside braces + // CHECK-FIXES: if (cond("if-else1")) { + // CHECK-FIXES: } else { + else + do_something("if-else1 else"); + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces + // CHECK-FIXES: } + if (cond("if-else2")) { + do_something("if-else2"); + } else { + do_something("if-else2 else"); + } + + if (cond("if-else if-else1")) + do_something("if"); + // CHECK-MESSAGES: :[[@LINE-2]]:32: warning: statement should be inside braces + // CHECK-FIXES: } else if (cond("else if1")) { + else if (cond("else if1")) + do_something("else if"); + // CHECK-MESSAGES: :[[@LINE-2]]:29: warning: statement should be inside braces + else + do_something("else"); + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: statement should be inside braces + // CHECK-FIXES: } + if (cond("if-else if-else2")) { + do_something("if"); + } else if (cond("else if2")) { + do_something("else if"); + } else { + do_something("else"); + } + + for (;;) + do_something("for"); + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces + // CHECK-FIXES: for (;;) { + // CHECK-FIXES: } + for (;;) { + do_something("for"); + } + for (;;) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: statement should be inside braces + // CHECK-FIXES: for (;;) { + // CHECK-FIXES: } + + int arr[4] = {1, 2, 3, 4}; + for (int a : arr) + do_something("for-range"); + // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces + // CHECK-FIXES: for (int a : arr) { + // CHECK-FIXES: } + for (int a : arr) { + do_something("for-range"); + } + for (int a : arr) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:20: warning: statement should be inside braces + // CHECK-FIXES: for (int a : arr) { + // CHECK-FIXES: } + + while (cond("while1")) + do_something("while"); + // CHECK-MESSAGES: :[[@LINE-2]]:25: warning: statement should be inside braces + // CHECK-FIXES: while (cond("while1")) { + // CHECK-FIXES: } + while (cond("while2")) { + do_something("while"); + } + while (false) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:16: warning: statement should be inside braces + // CHECK-FIXES: while (false) { + // CHECK-FIXES: } + + do + do_something("do1"); + while (cond("do1")); + // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces + // CHECK-FIXES: do { + // CHECK-FIXES: } while (cond("do1")); + do { + do_something("do2"); + } while (cond("do2")); + + do + ; + while (false); + // CHECK-MESSAGES: :[[@LINE-3]]:5: warning: statement should be inside braces + // CHECK-FIXES: do { + // CHECK-FIXES: } while (false); + + if (cond("ifif1")) + // comment + if (cond("ifif2")) + // comment + /*comment*/ ; // comment + // CHECK-MESSAGES: :[[@LINE-5]]:21: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-4]]:23: warning: statement should be inside braces + // CHECK-FIXES: if (cond("ifif1")) { + // CHECK-FIXES: if (cond("ifif2")) { + // CHECK-FIXES: } + // CHECK-FIXES-NEXT: } + + if (cond("ifif3")) + // comment + if (cond("ifif4")) { + // comment + /*comment*/; // comment + } + // CHECK-MESSAGES: :[[@LINE-6]]:21: warning: statement should be inside braces + // CHECK-FIXES: if (cond("ifif3")) { + // CHECK-FIXES: } + + if (cond("ifif5")) + ; /* multi-line + comment */ + // CHECK-MESSAGES: :[[@LINE-3]]:21: warning: statement should be inside braces + // CHECK-FIXES: if (cond("ifif5")) { + // CHECK-FIXES: }/* multi-line + + if (1) while (2) if (3) for (;;) do ; while(false) /**/;/**/ + // CHECK-MESSAGES: :[[@LINE-1]]:9: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-2]]:19: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-3]]:26: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-4]]:35: warning: statement should be inside braces + // CHECK-MESSAGES: :[[@LINE-5]]:38: warning: statement should be inside braces + // CHECK-FIXES: if (1) { while (2) { if (3) { for (;;) { do { ; } while(false) /**/;/**/ + // CHECK-FIXES-NEXT: } + // CHECK-FIXES-NEXT: } + // CHECK-FIXES-NEXT: } + // CHECK-FIXES-NEXT: } +} Index: test/clang-tidy/readability/container-size-empty.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/container-size-empty.cpp @@ -0,0 +1,106 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-container-size-empty %t +// REQUIRES: shell + +namespace std { +template struct vector { + vector() {} + int size() const {} + bool empty() const {} +}; +} + +int main() { + std::vector vect; + if (vect.size() == 0) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used to check for emptiness instead of 'size'. [readability-container-size-empty] + // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} + if (vect.size() != 0) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + if (0 == vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} + if (0 != vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + if (vect.size() > 0) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + if (0 < vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + if (vect.size() < 1) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} + if (1 > vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:11: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} + if (vect.size() >= 1) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + if (1 <= vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:12: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + if (!vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:8: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (vect.empty()){{$}} + if (vect.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect.empty()){{$}} + + if (vect.empty()) + ; + + const std::vector vect2; + if (vect2.size() != 0) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!vect2.empty()){{$}} + + std::vector *vect3 = new std::vector(); + if (vect3->size() == 0) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (vect3->empty()){{$}} + + delete vect3; + + const std::vector &vect4 = vect2; + if (vect4.size() == 0) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (vect4.empty()){{$}} +} + +#define CHECKSIZE(x) if (x.size()) +// CHECK-FIXES: #define CHECKSIZE(x) if (x.size()) + +template void f() { + std::vector v; + if (v.size()) + ; + // CHECK-MESSAGES: :[[@LINE-2]]:7: warning: The 'empty' method should be used + // CHECK-FIXES: {{^ }}if (!v.empty()){{$}} + // CHECK-FIXES-NEXT: ; + CHECKSIZE(v); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: The 'empty' method should be used + // CHECK-MESSAGES: CHECKSIZE(v); +} + +void g() { + f(); + f(); + f(); +} Index: test/clang-tidy/readability/else-after-return.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/else-after-return.cpp @@ -0,0 +1,28 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-else-after-return %t +// REQUIRES: shell + +void f(int a) { + if (a > 0) + return; + else // comment +// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: don't use else after return +// CHECK-FIXES: {{^}} // comment + return; + + if (a > 0) { + return; + } else { // comment +// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: don't use else after return +// CHECK-FIXES: } // comment + return; + } + + if (a > 0) { + f(0); + if (a > 10) + return; + } else { + return; + } +} + Index: test/clang-tidy/readability/function-size.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/function-size.cpp @@ -0,0 +1,55 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-function-size %t -config='{CheckOptions: [{key: readability-function-size.LineThreshold, value: 0}, {key: readability-function-size.StatementThreshold, value: 0}, {key: readability-function-size.BranchThreshold, value: 0}]}' -- -std=c++11 +// REQUIRES: shell + +void foo1() { +} + +void foo2() {;} +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'foo2' exceeds recommended size/complexity thresholds [readability-function-size] +// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 1 statements (threshold 0) + +void foo3() { +; + +} +// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'foo3' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 1 statements (threshold 0) + +void foo4(int i) { if (i) {} else; {} +} +// CHECK-MESSAGES: :[[@LINE-2]]:6: warning: function 'foo4' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-3]]:6: note: 1 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 3 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 1 branches (threshold 0) + +void foo5(int i) {for(;i;)while(i) +do;while(i); +} +// CHECK-MESSAGES: :[[@LINE-3]]:6: warning: function 'foo5' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-4]]:6: note: 2 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 7 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 3 branches (threshold 0) + +template T foo6(T i) {return i; +} +int x = foo6(0); +// CHECK-MESSAGES: :[[@LINE-3]]:25: warning: function 'foo6' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-4]]:25: note: 1 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-5]]:25: note: 1 statements (threshold 0) + +void bar1() { [](){;;;;;;;;;;;if(1){}}(); + + +} +// CHECK-MESSAGES: :[[@LINE-4]]:6: warning: function 'bar1' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-5]]:6: note: 3 lines including whitespace and comments (threshold 0) +// CHECK-MESSAGES: :[[@LINE-6]]:6: note: 14 statements (threshold 0) +// CHECK-MESSAGES: :[[@LINE-7]]:6: note: 1 branches (threshold 0) + +void bar2() { class A { void barx() {;;} }; } +// CHECK-MESSAGES: :[[@LINE-1]]:6: warning: function 'bar2' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-2]]:6: note: 3 statements (threshold 0) +// +// CHECK-MESSAGES: :[[@LINE-4]]:30: warning: function 'barx' exceeds recommended size/complexity +// CHECK-MESSAGES: :[[@LINE-5]]:30: note: 2 statements (threshold 0) Index: test/clang-tidy/readability/redundant-smartptr-get.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/redundant-smartptr-get.cpp @@ -0,0 +1,129 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-redundant-smartptr-get %t +// REQUIRES: shell + +#define NULL __null + +namespace std { + +template +struct unique_ptr { + T& operator*() const; + T* operator->() const; + T* get() const; +}; + +template +struct shared_ptr { + T& operator*() const; + T* operator->() const; + T* get() const; +}; + +} // namespace std + +struct Bar { + void Do(); + void ConstDo() const; +}; +struct BarPtr { + Bar* operator->(); + Bar& operator*(); + Bar* get(); +}; +struct int_ptr { + int* get(); + int* operator->(); + int& operator*(); +}; + +struct Fail1 { + Bar* get(); +}; +struct Fail2 { + Bar* get(); + int* operator->(); + int& operator*(); +}; + +void Positive() { + BarPtr u; + // CHECK-FIXES: BarPtr u; + BarPtr().get()->Do(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Redundant get() call on smart pointer. [readability-redundant-smartptr-get] + // CHECK-MESSAGES: BarPtr().get()->Do(); + // CHECK-FIXES: BarPtr()->Do(); + + u.get()->ConstDo(); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: u.get()->ConstDo(); + // CHECK-FIXES: u->ConstDo(); + + Bar& b = *BarPtr().get(); + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: Bar& b = *BarPtr().get(); + // CHECK-FIXES: Bar& b = *BarPtr(); + + Bar& b2 = *std::unique_ptr().get(); + // CHECK-MESSAGES: :[[@LINE-1]]:14: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: Bar& b2 = *std::unique_ptr().get(); + // CHECK-FIXES: Bar& b2 = *std::unique_ptr(); + + (*BarPtr().get()).ConstDo(); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: (*BarPtr().get()).ConstDo(); + // CHECK-FIXES: (*BarPtr()).ConstDo(); + + (*std::unique_ptr().get()).ConstDo(); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: (*std::unique_ptr().get()).ConstDo(); + // CHECK-FIXES: (*std::unique_ptr()).ConstDo(); + + std::unique_ptr* up; + (*up->get()).Do(); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: (*up->get()).Do(); + // CHECK-FIXES: (**up).Do(); + + int_ptr ip; + int i = *ip.get(); + // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: int i = *ip.get(); + // CHECK-FIXES: int i = *ip; + + std::unique_ptr uu; + std::shared_ptr *ss; + bool bb = uu.get() == nullptr; + // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: uu.get() == nullptr; + // CHECK-FIXES: bool bb = uu == nullptr; + + bb = nullptr != ss->get(); + // CHECK-MESSAGES: :[[@LINE-1]]:19: warning: Redundant get() call on smart pointer. + // CHECK-MESSAGES: nullptr != ss->get(); + // CHECK-FIXES: bb = nullptr != *ss; +} + +void Negative() { + struct NegPtr { + int* get(); + int* operator->() { + return &*this->get(); + } + int& operator*() { + return *get(); + } + }; + + std::unique_ptr* u; + u->get()->Do(); + + Fail1().get()->Do(); + Fail2().get()->Do(); + const Bar& b = *Fail1().get(); + (*Fail2().get()).Do(); + + int_ptr ip; + bool bb = std::unique_ptr().get() == NULL; + bb = ip.get() == nullptr; + bb = u->get() == NULL; +} Index: test/clang-tidy/readability/shrink-to-fit.cpp =================================================================== --- /dev/null +++ test/clang-tidy/readability/shrink-to-fit.cpp @@ -0,0 +1,75 @@ +// RUN: $(dirname %s)/../check_clang_tidy.sh %s readability-shrink-to-fit %t +// REQUIRES: shell + +namespace std { +template struct vector { void swap(vector &other); }; +} + +void f() { + std::vector v; + + std::vector(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 [readability-shrink-to-fit] + // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}} + + std::vector &vref = v; + std::vector(vref).swap(vref); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should + // CHECK-FIXES: {{^ }}vref.shrink_to_fit();{{$}} + + std::vector *vptr = &v; + std::vector(*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 v; + void f() { + std::vector(v).swap(v); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should + // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}} + + std::vector *vptr = &v; + std::vector(*vptr).swap(*vptr); + // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: the shrink_to_fit method should + // CHECK-FIXES: {{^ }}vptr->shrink_to_fit();{{$}} + } +}; + +template void g() { + std::vector v; + std::vector(v).swap(v); + // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: the shrink_to_fit method should + // CHECK-FIXES: {{^ }}v.shrink_to_fit();{{$}} + + std::vector v2; + std::vector(v2).swap(v2); + // CHECK-FIXES: {{^ }}std::vector(v2).swap(v2);{{$}} +} + +template void g2() { + std::vector v; + std::vector(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(x).swap(x) +// CHECK-FIXES: #define COPY_AND_SWAP_INT_VEC(x) std::vector(x).swap(x) + +void h() { + g(); + g(); + g(); + g2>(); + std::vector 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);{{$}} +} +