This revision was automatically updated to reflect the committed changes. Closed by commit rL345990: [analyzer] Put llvm.Conventions back in alpha (authored by Szelethus, committed by ). Herald added a subscriber: llvm-commits.
Changed prior to commit: https://reviews.llvm.org/D53856?vs=172253&id=172379#toc Repository: rC Clang https://reviews.llvm.org/D53856 Files: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp cfe/trunk/test/Analysis/inner-pointer.cpp cfe/trunk/test/Analysis/llvm-conventions.cpp cfe/trunk/test/Analysis/temporaries.cpp cfe/trunk/www/analyzer/alpha_checks.html
Index: cfe/trunk/www/analyzer/alpha_checks.html =================================================================== --- cfe/trunk/www/analyzer/alpha_checks.html +++ cfe/trunk/www/analyzer/alpha_checks.html @@ -27,6 +27,7 @@ <li><a href="#clone_alpha_checkers">Clone Alpha Checkers</a></li> <li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li> <li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li> +<li><a href="#llvm_alpha_checkers">LLVM Checkers</a></li> <li><a href="#valist_alpha_checkers">Variable Argument Alpha Checkers</a></li> <li><a href="#deadcode_alpha_checkers">Dead Code Alpha Checkers</a></li> <li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li> @@ -583,6 +584,31 @@ </pre></div></div></td></tr> </tbody></table> +<!-- =========================== llvm alpha =========================== --> +<h3 id="llvm_alpha_checkers">LLVM Checkers</h3> +<table class="checkers"> +<colgroup><col class="namedescr"><col class="example"></colgroup> +<thead><tr><td>Name, Description</td><td>Example</td></tr></thead> + +<tbody> +<tr><td><div class="namedescr expandable"><span class="name"> +alpha.llvm.Conventions</span><span class="lang"> +(C)</span><div class="descr"> +Check code for LLVM codebase conventions: +<ul> + <li>A <code>StringRef</code> should not be bound to a temporary std::string + whose lifetime is shorter than the <code>StringRef</code>'s.</li> + <li>Clang AST nodes should not have fields that can allocate memory.</li> +</ul> +</div></div></td> +<td><div class="exampleContainer expandable"> +<div class="example"><pre> +<!-- TODO: Add examples, as currently it's hard to get this checker working. --> +</pre></div></div></td></tr> + +</tbody></table> + + <!-- ============================== OS X alpha ============================== --> <h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3> <table class="checkers"> Index: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td =================================================================== --- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -83,6 +83,7 @@ def MPI : Package<"mpi">, InPackage<OptIn>; def LLVM : Package<"llvm">; +def LLVMAlpha : Package<"llvm">, InPackage<Alpha>, Hidden; // The APIModeling package is for checkers that model APIs and don't perform // any diagnostics. These checkers are always turned on; this package is @@ -730,7 +731,7 @@ //===----------------------------------------------------------------------===// def LLVMConventionsChecker : Checker<"Conventions">, - InPackage<LLVM>, + InPackage<LLVMAlpha>, HelpText<"Check code for LLVM codebase conventions">, DescFile<"LLVMConventionsChecker.cpp">; Index: cfe/trunk/test/Analysis/llvm-conventions.cpp =================================================================== --- cfe/trunk/test/Analysis/llvm-conventions.cpp +++ cfe/trunk/test/Analysis/llvm-conventions.cpp @@ -0,0 +1,226 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.llvm.Conventions \ +// RUN: -std=c++14 -verify %s + +#include "Inputs/system-header-simulator-cxx.h" + +//===----------------------------------------------------------------------===// +// Forward declarations for StringRef tests. +//===----------------------------------------------------------------------===// + +using size_t = unsigned long; +using size_type = size_t; + +namespace std { + +template <class T> +struct numeric_limits { const static bool is_signed; }; + +} // end of namespace std + +namespace llvm { + +template <class T> +struct iterator_range; + +template <class Func> +struct function_ref; + +struct hash_code; + +template <class T> +struct SmallVectorImpl; + +struct APInt; + +class StringRef { +public: + static const size_t npos = ~size_t(0); + using iterator = const char *; + using const_iterator = const char *; + using size_type = size_t; + + /*implicit*/ StringRef() = default; + StringRef(std::nullptr_t) = delete; + /*implicit*/ StringRef(const char *Str); + /*implicit*/ constexpr StringRef(const char *data, size_t length); + /*implicit*/ StringRef(const std::string &Str); + + static StringRef withNullAsEmpty(const char *data); + iterator begin() const; + iterator end() const; + const unsigned char *bytes_begin() const; + const unsigned char *bytes_end() const; + iterator_range<const unsigned char *> bytes() const; + const char *data() const; + bool empty() const; + size_t size() const; + char front() const; + char back() const; + template <typename Allocator> + StringRef copy(Allocator &A) const; + bool equals(StringRef RHS) const; + bool equals_lower(StringRef RHS) const; + int compare(StringRef RHS) const; + int compare_lower(StringRef RHS) const; + int compare_numeric(StringRef RHS) const; + unsigned edit_distance(StringRef Other, bool AllowReplacements = true, + unsigned MaxEditDistance = 0) const; + std::string str() const; + char operator[](size_t Index) const; + template <typename T> + typename std::enable_if<std::is_same<T, std::string>::value, + StringRef>::type & + operator=(T &&Str) = delete; + operator std::string() const; + bool startswith(StringRef Prefix) const; + bool startswith_lower(StringRef Prefix) const; + bool endswith(StringRef Suffix) const; + bool endswith_lower(StringRef Suffix) const; + size_t find(char C, size_t From = 0) const; + size_t find_lower(char C, size_t From = 0) const; + size_t find_if(function_ref<bool(char)> F, size_t From = 0) const; + size_t find_if_not(function_ref<bool(char)> F, size_t From = 0) const; + size_t find(StringRef Str, size_t From = 0) const; + size_t find_lower(StringRef Str, size_t From = 0) const; + size_t rfind(char C, size_t From = npos) const; + size_t rfind_lower(char C, size_t From = npos) const; + size_t rfind(StringRef Str) const; + size_t rfind_lower(StringRef Str) const; + size_t find_first_of(char C, size_t From = 0) const; + size_t find_first_of(StringRef Chars, size_t From = 0) const; + size_t find_first_not_of(char C, size_t From = 0) const; + size_t find_first_not_of(StringRef Chars, size_t From = 0) const; + size_t find_last_of(char C, size_t From = npos) const; + size_t find_last_of(StringRef Chars, size_t From = npos) const; + size_t find_last_not_of(char C, size_t From = npos) const; + size_t find_last_not_of(StringRef Chars, size_t From = npos) const; + bool contains(StringRef Other) const; + bool contains(char C) const; + bool contains_lower(StringRef Other) const; + bool contains_lower(char C) const; + size_t count(char C) const; + size_t count(StringRef Str) const; + template <typename T> + typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type + getAsInteger(unsigned Radix, T &Result) const; + template <typename T> + typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type + getAsInteger(unsigned Radix, T &Result) const; + template <typename T> + typename std::enable_if<std::numeric_limits<T>::is_signed, bool>::type + consumeInteger(unsigned Radix, T &Result); + template <typename T> + typename std::enable_if<!std::numeric_limits<T>::is_signed, bool>::type + consumeInteger(unsigned Radix, T &Result); + bool getAsInteger(unsigned Radix, APInt &Result) const; + bool getAsDouble(double &Result, bool AllowInexact = true) const; + std::string lower() const; + std::string upper() const; + StringRef substr(size_t Start, size_t N = npos) const; + StringRef take_front(size_t N = 1) const; + StringRef take_back(size_t N = 1) const; + StringRef take_while(function_ref<bool(char)> F) const; + StringRef take_until(function_ref<bool(char)> F) const; + StringRef drop_front(size_t N = 1) const; + StringRef drop_back(size_t N = 1) const; + StringRef drop_while(function_ref<bool(char)> F) const; + StringRef drop_until(function_ref<bool(char)> F) const; + bool consume_front(StringRef Prefix); + bool consume_back(StringRef Suffix); + StringRef slice(size_t Start, size_t End) const; + std::pair<StringRef, StringRef> split(char Separator) const; + std::pair<StringRef, StringRef> split(StringRef Separator) const; + std::pair<StringRef, StringRef> rsplit(StringRef Separator) const; + void split(SmallVectorImpl<StringRef> &A, + StringRef Separator, int MaxSplit = -1, + bool KeepEmpty = true) const; + void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1, + bool KeepEmpty = true) const; + std::pair<StringRef, StringRef> rsplit(char Separator) const; + StringRef ltrim(char Char) const; + StringRef ltrim(StringRef Chars = " \t\n\v\f\r") const; + StringRef rtrim(char Char) const; + StringRef rtrim(StringRef Chars = " \t\n\v\f\r") const; + StringRef trim(char Char) const; + StringRef trim(StringRef Chars = " \t\n\v\f\r") const; +}; + +inline bool operator==(StringRef LHS, StringRef RHS); +inline bool operator!=(StringRef LHS, StringRef RHS); +inline bool operator<(StringRef LHS, StringRef RHS); +inline bool operator<=(StringRef LHS, StringRef RHS); +inline bool operator>(StringRef LHS, StringRef RHS); +inline bool operator>=(StringRef LHS, StringRef RHS); +inline std::string &operator+=(std::string &buffer, StringRef string); +hash_code hash_value(StringRef S); +template <typename T> struct isPodLike; +template <> struct isPodLike<StringRef> { static const bool value = true; }; + +} // end of namespace llvm + +//===----------------------------------------------------------------------===// +// Tests for StringRef. +//===----------------------------------------------------------------------===// + +void temporarayStringToStringRefAssignmentTest() { + // TODO: Emit a warning. + llvm::StringRef Ref = std::string("Yimmy yummy test."); +} + +void assigningStringToStringRefWithLongerLifetimeTest() { + llvm::StringRef Ref; + { + // TODO: Emit a warning. + std::string TmpStr("This is a fine string."); + Ref = TmpStr; + } +} + +std::string getTemporaryString() { + return "One two three."; +} + +void assigningTempStringFromFunctionToStringRefTest() { + // TODO: Emit a warning. + llvm::StringRef Ref = getTemporaryString(); +} + +//===----------------------------------------------------------------------===// +// Forward declaration for Clang AST nodes. +//===----------------------------------------------------------------------===// + +namespace llvm { + +template <class T, int Size> +struct SmallVector {}; + +} // end of namespace llvm + +namespace clang { + +struct Type; +struct Decl; +struct Stmt; +struct Attr; + +} // end of namespace clang + +//===----------------------------------------------------------------------===// +// Tests for Clang AST nodes. +//===----------------------------------------------------------------------===// + +namespace clang { + +struct Type { + std::string str; // expected-warning{{AST class 'Type' has a field 'str' that allocates heap memory (type std::string)}} +}; + +} // end of namespace clang + +namespace clang { + +struct Decl { + llvm::SmallVector<int, 5> Vec; // expected-warning{{AST class 'Decl' has a field 'Vec' that allocates heap memory (type llvm::SmallVector<int, 5>)}} +}; + +} // end of namespace clang Index: cfe/trunk/test/Analysis/inner-pointer.cpp =================================================================== --- cfe/trunk/test/Analysis/inner-pointer.cpp +++ cfe/trunk/test/Analysis/inner-pointer.cpp @@ -1,43 +1,9 @@ -//RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer %s -analyzer-output=text -verify +// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.InnerPointer \ +// RUN: %s -analyzer-output=text -verify +#include "Inputs/system-header-simulator-cxx.h" namespace std { -typedef int size_type; - -template <typename CharT> -class basic_string { -public: - basic_string(); - basic_string(const CharT *s); - - ~basic_string(); - void clear(); - - basic_string &operator=(const basic_string &str); - basic_string &operator+=(const basic_string &str); - - const CharT *c_str() const; - const CharT *data() const; - CharT *data(); - - basic_string &append(size_type count, CharT ch); - basic_string &assign(size_type count, CharT ch); - basic_string &erase(size_type index, size_type count); - basic_string &insert(size_type index, size_type count, CharT ch); - basic_string &replace(size_type pos, size_type count, const basic_string &str); - void pop_back(); - void push_back(CharT ch); - void reserve(size_type new_cap); - void resize(size_type count); - void shrink_to_fit(); - void swap(basic_string &other); -}; - -typedef basic_string<char> string; -typedef basic_string<wchar_t> wstring; -typedef basic_string<char16_t> u16string; -typedef basic_string<char32_t> u32string; - template <typename T> void func_ref(T &a); Index: cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h =================================================================== --- cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h +++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h @@ -12,6 +12,13 @@ void *memmove(void *s1, const void *s2, size_t n); namespace std { + typedef size_t size_type; +#if __cplusplus >= 201103L + using nullptr_t = decltype(nullptr); +#endif +} + +namespace std { struct input_iterator_tag { }; struct output_iterator_tag { }; struct forward_iterator_tag : public input_iterator_tag { }; @@ -517,6 +524,42 @@ const T& front() const { return *begin(); } }; + template <typename CharT> + class basic_string { + public: + basic_string(); + basic_string(const CharT *s); + + ~basic_string(); + void clear(); + + basic_string &operator=(const basic_string &str); + basic_string &operator+=(const basic_string &str); + + const CharT *c_str() const; + const CharT *data() const; + CharT *data(); + + basic_string &append(size_type count, CharT ch); + basic_string &assign(size_type count, CharT ch); + basic_string &erase(size_type index, size_type count); + basic_string &insert(size_type index, size_type count, CharT ch); + basic_string &replace(size_type pos, size_type count, const basic_string &str); + void pop_back(); + void push_back(CharT ch); + void reserve(size_type new_cap); + void resize(size_type count); + void shrink_to_fit(); + void swap(basic_string &other); + }; + + typedef basic_string<char> string; + typedef basic_string<wchar_t> wstring; +#if __cplusplus >= 201103L + typedef basic_string<char16_t> u16string; + typedef basic_string<char32_t> u32string; +#endif + class exception { public: exception() throw(); Index: cfe/trunk/test/Analysis/temporaries.cpp =================================================================== --- cfe/trunk/test/Analysis/temporaries.cpp +++ cfe/trunk/test/Analysis/temporaries.cpp @@ -9,7 +9,7 @@ extern bool clang_analyzer_warnIfReached(); void clang_analyzer_checkInlined(bool); -#include "Inputs/system-header-simulator-cxx.h"; +#include "Inputs/system-header-simulator-cxx.h" struct Trivial { Trivial(int x) : value(x) {} Index: cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp =================================================================== --- cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp +++ cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp @@ -19,6 +19,6 @@ void testCopyNull(C *I, C *E) { std::copy(I, E, (C *)0); #ifndef SUPPRESSED - // expected-warning@../Inputs/system-header-simulator-cxx.h:627 {{Called C++ object pointer is null}} + // expected-warning@../Inputs/system-header-simulator-cxx.h:668 {{Called C++ object pointer is null}} #endif } Index: cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp @@ -32,8 +32,7 @@ if (!RT) return false; - return StringRef(QualType(RT, 0).getAsString()) == - "class StringRef"; + return StringRef(QualType(RT, 0).getAsString()) == "class StringRef"; } /// Check whether the declaration is semantically inside the top-level
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits