r345990 - [analyzer] Put llvm.Conventions back in alpha

Kristof Umann via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 2 09:02:10 PDT 2018


Author: szelethus
Date: Fri Nov  2 09:02:10 2018
New Revision: 345990

URL: http://llvm.org/viewvc/llvm-project?rev=345990&view=rev
Log:
[analyzer] Put llvm.Conventions back in alpha

Interestingly, this many year old (when I last looked I remember 2010ish)
checker was committed without any tests, so I thought I'd implement them, but I
was shocked to see how I barely managed to get it working. The code is severely
outdated, I'm not even sure it has ever been used, so I'd propose to move it
back into alpha, and possibly even remove it.

Differential Revision: https://reviews.llvm.org/D53856

Added:
    cfe/trunk/test/Analysis/llvm-conventions.cpp
Modified:
    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/temporaries.cpp
    cfe/trunk/www/analyzer/alpha_checks.html

Modified: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td Fri Nov  2 09:02:10 2018
@@ -83,6 +83,7 @@ def LocalizabilityOptIn : Package<"local
 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 @@ let ParentPackage = MPI in {
 //===----------------------------------------------------------------------===//
 
 def LLVMConventionsChecker : Checker<"Conventions">,
-  InPackage<LLVM>,
+  InPackage<LLVMAlpha>,
   HelpText<"Check code for LLVM codebase conventions">,
   DescFile<"LLVMConventionsChecker.cpp">;
 

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp Fri Nov  2 09:02:10 2018
@@ -32,8 +32,7 @@ static bool IsLLVMStringRef(QualType T)
   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

Modified: cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h (original)
+++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-cxx.h Fri Nov  2 09:02:10 2018
@@ -12,6 +12,13 @@ typedef __typeof__((char*)0-(char*)0) pt
 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 @@ namespace std {
     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();

Modified: cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp (original)
+++ cfe/trunk/test/Analysis/diagnostics/explicit-suppression.cpp Fri Nov  2 09:02:10 2018
@@ -19,6 +19,6 @@ class C {
 void testCopyNull(C *I, C *E) {
   std::copy(I, E, (C *)0);
 #ifndef SUPPRESSED
-  // expected-warning at ../Inputs/system-header-simulator-cxx.h:627 {{Called C++ object pointer is null}}
+  // expected-warning at ../Inputs/system-header-simulator-cxx.h:668 {{Called C++ object pointer is null}}
 #endif
 }

Modified: cfe/trunk/test/Analysis/inner-pointer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/inner-pointer.cpp?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/inner-pointer.cpp (original)
+++ cfe/trunk/test/Analysis/inner-pointer.cpp Fri Nov  2 09:02:10 2018
@@ -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);
 

Added: cfe/trunk/test/Analysis/llvm-conventions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/llvm-conventions.cpp?rev=345990&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/llvm-conventions.cpp (added)
+++ cfe/trunk/test/Analysis/llvm-conventions.cpp Fri Nov  2 09:02:10 2018
@@ -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

Modified: cfe/trunk/test/Analysis/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temporaries.cpp?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temporaries.cpp (original)
+++ cfe/trunk/test/Analysis/temporaries.cpp Fri Nov  2 09:02:10 2018
@@ -9,7 +9,7 @@ extern bool clang_analyzer_eval(bool);
 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) {}

Modified: cfe/trunk/www/analyzer/alpha_checks.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/analyzer/alpha_checks.html?rev=345990&r1=345989&r2=345990&view=diff
==============================================================================
--- cfe/trunk/www/analyzer/alpha_checks.html (original)
+++ cfe/trunk/www/analyzer/alpha_checks.html Fri Nov  2 09:02:10 2018
@@ -27,6 +27,7 @@ Patches welcome!
 <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 @@ void test(id x) {
 </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">




More information about the cfe-commits mailing list