diff --git a/tools/clang-tidy/config.yaml b/tools/clang-tidy/config.yaml --- a/tools/clang-tidy/config.yaml +++ b/tools/clang-tidy/config.yaml @@ -1,87 +1,95 @@ --- target: obj-x86_64-pc-linux-gnu # It is used by 'mach static-analysis' and 'mozreview static-analysis bot' # in order to have consistency across the used checkers. # All the clang checks used by the static-analysis tools. platforms: + - linux64 - macosx64 - - linux64 + - win32 - win64 - - win32 clang_checkers: - name: -* publish: !!bool no - name: bugprone-argument-comment - name: bugprone-assert-side-effect - name: bugprone-bool-pointer-implicit-conversion - name: bugprone-forward-declaration-namespace - name: bugprone-macro-repeated-side-effects - name: bugprone-string-constructor - name: bugprone-string-integer-assignment - name: bugprone-suspicious-memset-usage - name: bugprone-suspicious-missing-comma - name: bugprone-suspicious-semicolon - name: bugprone-swapped-arguments - name: bugprone-unused-raii - name: clang-analyzer-cplusplus.NewDelete - name: clang-analyzer-cplusplus.NewDeleteLeaks - name: clang-analyzer-deadcode.DeadStores - name: clang-analyzer-security.FloatLoopCounter + - name: clang-analyzer-security.insecureAPI.bcmp + - name: clang-analyzer-security.insecureAPI.bcopy + - name: clang-analyzer-security.insecureAPI.bzero - name: clang-analyzer-security.insecureAPI.getpw # We don't add clang-analyzer-security.insecureAPI.gets here; it's deprecated. - name: clang-analyzer-security.insecureAPI.mkstemp - name: clang-analyzer-security.insecureAPI.mktemp - name: clang-analyzer-security.insecureAPI.rand publish: !!bool no - name: clang-analyzer-security.insecureAPI.strcpy publish: !!bool no - name: clang-analyzer-security.insecureAPI.UncheckedReturn - name: clang-analyzer-security.insecureAPI.vfork - name: clang-analyzer-unix.Malloc - name: clang-analyzer-unix.cstring.BadSizeArg - name: clang-analyzer-unix.cstring.NullArg - name: misc-unused-alias-decls - name: misc-unused-using-decls - name: modernize-avoid-bind restricted-platforms: - win32 - win64 - name: modernize-loop-convert - name: modernize-raw-string-literal - name: modernize-redundant-void-arg publish: !!bool no - name: modernize-shrink-to-fit - name: modernize-use-auto # Controversial, see bug 1371052. publish: !!bool no - name: modernize-use-bool-literals - name: modernize-use-equals-default - name: modernize-use-equals-delete - name: modernize-use-nullptr - name: modernize-use-override # Too noisy because of the way how we implement NS_IMETHOD. See Bug 1420366. publish: !!bool no - name: mozilla-* - name: performance-faster-string-find - name: performance-for-range-copy - # Only available from clang tidy 6.0. We are currently using 5.0 - # - name: performance-implicit-conversion-in-loop + - name: performance-implicit-conversion-in-loop + - name: performance-inefficient-algorithm + restricted-platforms: + - linux64 + - macosx64 - name: performance-inefficient-string-concatenation - name: performance-inefficient-vector-operation + - name: performance-move-const-arg + - name: performance-move-constructor-init + - name: performance-noexcept-move-constructor - name: performance-type-promotion-in-math-fn - name: performance-unnecessary-copy-initialization - name: performance-unnecessary-value-param - name: readability-container-size-empty - name: readability-else-after-return - name: readability-misleading-indentation - name: readability-redundant-control-flow - name: readability-redundant-smartptr-get publish: !!bool no - name: readability-redundant-string-cstr - name: readability-redundant-string-init + - name: readability-static-accessed-through-instance - name: readability-uniqueptr-delete-release -# Only available from clang tidy 6.0. We are currently using 5.0 -# - name: readability-static-accessed-through-instance # Third party files from mozilla-central third_party: tools/rewriting/ThirdPartyPaths.txt diff --git a/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcmp.cpp b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcmp.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcmp.cpp @@ -0,0 +1,5 @@ +#include "structures.h" + +int test_bcmp(void *a, void *b, size_t n) { + return bcmp(a, b, n); +} diff --git a/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcmp.json b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcmp.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcmp.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"The bcmp() function is obsoleted by memcmp()\", \"clang-analyzer-security.insecureAPI.bcmp\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcopy.cpp b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcopy.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcopy.cpp @@ -0,0 +1,5 @@ +#include "structures.h" + +void test_bcopy(void *a, void *b, size_t n) { + bcopy(a, b, n); +} diff --git a/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcopy.json b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcopy.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bcopy.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"The bcopy() function is obsoleted by memcpy() or memmove()\", \"clang-analyzer-security.insecureAPI.bcopy\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bzero.cpp b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bzero.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bzero.cpp @@ -0,0 +1,6 @@ +#include "structures.h" + +void test_bzero(void *a, size_t n) { + bzero(a, n); +} + diff --git a/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bzero.json b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bzero.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/clang-analyzer-security.insecureAPI.bzero.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"The bzero() function is obsoleted by memset()\", \"clang-analyzer-security.insecureAPI.bzero\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/performance-implicit-conversion-in-loop.cpp b/tools/clang-tidy/test/performance-implicit-conversion-in-loop.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-implicit-conversion-in-loop.cpp @@ -0,0 +1,43 @@ +// Iterator returning by value. +template +struct Iterator { + void operator++(); + T operator*(); + bool operator!=(const Iterator& other); +}; + +// The template argument is an iterator type, and a view is an object you can +// run a for loop on. +template +struct View { + T begin(); + T end(); +}; + +// With this class, the implicit conversion is a call to the (implicit) +// constructor of the class. +template +class ImplicitWrapper { + public: + // Implicit! + ImplicitWrapper(const T& t); +}; + +template +class OperatorWrapper { + public: + OperatorWrapper() = delete; +}; + +struct SimpleClass { + int foo; + operator OperatorWrapper(); +}; + +typedef View> SimpleView; + +void ImplicitSimpleClassIterator() { + for (const ImplicitWrapper& foo : SimpleView()) {} + for (const ImplicitWrapper foo : SimpleView()) {} + for (ImplicitWrapper foo : SimpleView()) {} +} diff --git a/tools/clang-tidy/test/performance-implicit-conversion-in-loop.json b/tools/clang-tidy/test/performance-implicit-conversion-in-loop.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-implicit-conversion-in-loop.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"the type of the loop variable 'foo' is different from the one returned by the iterator and generates an implicit conversion; you can either change the type to the matching one ('const SimpleClass &' but 'const auto&' is always a valid option) or remove the reference to make it explicit that you are creating a new value\", \"performance-implicit-conversion-in-loop\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/performance-inefficient-algorithm.cpp b/tools/clang-tidy/test/performance-inefficient-algorithm.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-inefficient-algorithm.cpp @@ -0,0 +1,30 @@ +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; +}; + +template +FwIt find(FwIt, FwIt end, const K &) { return end; } +} + +template void f(const T &t) { + std::set s; + find(s.begin(), s.end(), 46); +} diff --git a/tools/clang-tidy/test/performance-inefficient-algorithm.json b/tools/clang-tidy/test/performance-inefficient-algorithm.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-inefficient-algorithm.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"this STL algorithm call should be replaced with a container method\", \"performance-inefficient-algorithm\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/performance-move-const-arg.cpp b/tools/clang-tidy/test/performance-move-const-arg.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-move-const-arg.cpp @@ -0,0 +1,22 @@ +namespace std { +template +struct remove_reference { + typedef _Tp type; +}; + +template +constexpr typename std::remove_reference<_Tp>::type &&move(_Tp &&__t) { + return static_cast::type &&>(__t); +} +} // namespace std + +struct TriviallyCopyable { + int i; +}; + +void f(TriviallyCopyable) {} + +void g() { + TriviallyCopyable obj; + f(std::move(obj)); +} diff --git a/tools/clang-tidy/test/performance-move-const-arg.json b/tools/clang-tidy/test/performance-move-const-arg.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-move-const-arg.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"std::move of the variable 'obj' of the trivially-copyable type 'TriviallyCopyable' has no effect; remove std::move()\", \"performance-move-const-arg\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/performance-move-constructor-init.cpp b/tools/clang-tidy/test/performance-move-constructor-init.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-move-constructor-init.cpp @@ -0,0 +1,11 @@ +struct B { + B() {} + B(const B&) {} + B(B &&) {} +}; + +struct D : B { + D() : B() {} + D(const D &RHS) : B(RHS) {} + D(D &&RHS) : B(RHS) {} +}; diff --git a/tools/clang-tidy/test/performance-move-constructor-init.json b/tools/clang-tidy/test/performance-move-constructor-init.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-move-constructor-init.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"move constructor initializes base class by calling a copy constructor\", \"performance-move-constructor-init\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/performance-noexcept-move-constructor.cpp b/tools/clang-tidy/test/performance-noexcept-move-constructor.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-noexcept-move-constructor.cpp @@ -0,0 +1,4 @@ +class A { + A(A &&); + A &operator=(A &&); +}; diff --git a/tools/clang-tidy/test/performance-noexcept-move-constructor.json b/tools/clang-tidy/test/performance-noexcept-move-constructor.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/performance-noexcept-move-constructor.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"move constructors should be marked noexcept\", \"performance-noexcept-move-constructor\"], [\"warning\", \"move assignment operators should be marked noexcept\", \"performance-noexcept-move-constructor\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/readability-static-accessed-through-instance.cpp b/tools/clang-tidy/test/readability-static-accessed-through-instance.cpp new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/readability-static-accessed-through-instance.cpp @@ -0,0 +1,11 @@ +struct C { + static int x; +}; + +int C::x = 0; + +// Expressions with side effects +C &f(int, int, int, int); +void g() { + f(1, 2, 3, 4).x; +} diff --git a/tools/clang-tidy/test/readability-static-accessed-through-instance.json b/tools/clang-tidy/test/readability-static-accessed-through-instance.json new file mode 100644 --- /dev/null +++ b/tools/clang-tidy/test/readability-static-accessed-through-instance.json @@ -0,0 +1,1 @@ +"[[\"warning\", \"static member accessed through instance\", \"readability-static-accessed-through-instance\"]]" \ No newline at end of file diff --git a/tools/clang-tidy/test/structures.h b/tools/clang-tidy/test/structures.h --- a/tools/clang-tidy/test/structures.h +++ b/tools/clang-tidy/test/structures.h @@ -1,104 +1,108 @@ // Proxy file in order to define generic data types, to avoid binding with system headers typedef __SIZE_TYPE__ size_t; namespace std { typedef size_t size_t; template class vector { public: typedef T* iterator; typedef const T* const_iterator; typedef T& reference; typedef const T& const_reference; typedef size_t size_type; explicit vector(); explicit vector(size_type n); void swap(vector &other); void push_back(const T& val); template void emplace_back(Args &&... args); void reserve(size_t n); void resize(size_t n); size_t size(); const_reference operator[] (size_type) const; reference operator[] (size_type); const_iterator begin() const; const_iterator end() const; }; template class basic_string { public: typedef basic_string _Type; basic_string() {} basic_string(const T *p); basic_string(const T *p, size_t count); basic_string(size_t count, char ch); ~basic_string() {} size_t size() const; bool empty() const; size_t find (const char* s, size_t pos = 0) const; const T *c_str() const; _Type& assign(const T *s); basic_string &operator=(T ch); basic_string *operator+=(const basic_string &) {} friend basic_string operator+(const basic_string &, const basic_string &) {} }; typedef basic_string string; typedef basic_string wstring; string to_string(int value); template struct default_delete {}; template > class unique_ptr { public: unique_ptr(); ~unique_ptr(); explicit unique_ptr(T*); template unique_ptr(unique_ptr&&); T* release(); }; template class bind_rt {}; template bind_rt bind(Fp &&, Arguments &&...); } typedef unsigned int uid_t; typedef unsigned int pid_t; +int bcmp(void *, void *, size_t); +void bcopy(void *, void *, size_t); +void bzero(void *, size_t); + int getpw(uid_t uid, char *buf); int setuid(uid_t uid); int mkstemp(char *tmpl); char *mktemp(char *tmpl); pid_t vfork(void); int abort() { return 0; } #define assert(x) \ if (!(x)) \ (void)abort() size_t strlen(const char *s); char *strncat(char *s1, const char *s2, size_t); void free(void *ptr); void *malloc(size_t size); void *memset(void *b, int c, size_t len);