jbcoe created this revision.
jbcoe added reviewers: aaron.ballman, alexfh.
jbcoe added a subscriber: cfe-commits.
jbcoe set the repository for this revision to rL LLVM.

Find instances where a string_view is constructed from a temporary string and 
replace the string_view with a string.

Repository:
  rL LLVM

http://reviews.llvm.org/D17772

Files:
  clang-tidy/misc/CMakeLists.txt
  clang-tidy/misc/MiscTidyModule.cpp
  clang-tidy/misc/StringViewOfTemporaryCheck.cpp
  clang-tidy/misc/StringViewOfTemporaryCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/misc-string_view-of-temporary.rst
  test/clang-tidy/misc-string_view-of-temporary.cpp

Index: test/clang-tidy/misc-string_view-of-temporary.cpp
===================================================================
--- /dev/null
+++ test/clang-tidy/misc-string_view-of-temporary.cpp
@@ -0,0 +1,33 @@
+// RUN: %check_clang_tidy %s misc-string_view-of-temporary %t
+
+namespace std {
+inline namespace implementation {
+class string {
+public:
+  string(const char *);
+};
+
+class string_view {
+public:
+  string_view(const string &);
+  string_view(const char*);
+};
+}
+}
+
+using std::string;
+using std::string_view;
+
+string f();
+void g(string_view);
+void h()
+{
+  string_view sv(f());
+// CHECK-MESSAGES: :[[@LINE-1]]:15: warning: string_view 'sv' is constructed from a temporary string [misc-string_view-of-temporary]
+// CHECK-FIXES: std::string sv(f());
+  g(f());
+  auto s = f();
+  string_view sv2(s);
+  string_view sv3("char[] construction");
+}
+
Index: docs/clang-tidy/checks/misc-string_view-of-temporary.rst
===================================================================
--- /dev/null
+++ docs/clang-tidy/checks/misc-string_view-of-temporary.rst
@@ -0,0 +1,25 @@
+.. title:: clang-tidy - misc-string_view-of-temporary
+
+misc-string_view-of-temporary
+=============================
+
+Find non-temporary ``string_view``s constructed from temporary strings and
+replace them with ``std::string``s.
+
+The following construction of a ``string_view`` constructs a view of a
+temporary object: 
+
+.. code:: c++
+
+  std::string f();
+
+  std::string_view s(f());
+
+The fix replaces the ``std::string_view`` with an ``std::string``:
+
+.. code:: c++
+
+  std::string f();
+
+  std::string s(f());
+
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -65,6 +65,7 @@
    misc-sizeof-container
    misc-static-assert
    misc-string-integer-assignment
+   misc-string_view-of-temporary
    misc-suspicious-semicolon
    misc-swapped-arguments
    misc-throw-by-value-catch-by-reference
Index: clang-tidy/misc/StringViewOfTemporaryCheck.h
===================================================================
--- /dev/null
+++ clang-tidy/misc/StringViewOfTemporaryCheck.h
@@ -0,0 +1,35 @@
+//===--- String_viewOfTemporaryCheck.h - clang-tidy--------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STRING_VIEW_OF_TEMPORARY_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STRING_VIEW_OF_TEMPORARY_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// Find non-temporary string_views constructed from temporary strings.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-string_view-of-temporary.html
+class String_viewOfTemporaryCheck : public ClangTidyCheck {
+public:
+  String_viewOfTemporaryCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_STRING_VIEW_OF_TEMPORARY_H
Index: clang-tidy/misc/StringViewOfTemporaryCheck.cpp
===================================================================
--- /dev/null
+++ clang-tidy/misc/StringViewOfTemporaryCheck.cpp
@@ -0,0 +1,55 @@
+//===--- StringViewOfTemporaryCheck.cpp - clang-tidy----------------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "StringViewOfTemporaryCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+namespace {
+
+AST_MATCHER(RecordDecl, isStdString) {
+  return Node.isInStdNamespace() && (Node.getName() == "string");
+}
+
+AST_MATCHER(RecordDecl, isStdStringView) {
+  return Node.isInStdNamespace() && (Node.getName() == "string_view");
+}
+
+} // end namespace
+
+void String_viewOfTemporaryCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      varDecl(has(cxxConstructExpr(hasDescendant(materializeTemporaryExpr(
+                  hasType(recordDecl(isStdString())))))),
+              hasType(recordDecl(isStdStringView())))
+          .bind("sv-temp"),
+      this);
+}
+
+void String_viewOfTemporaryCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *MatchedDecl = Result.Nodes.getNodeAs<VarDecl>("sv-temp");
+
+  const auto TypeLoc =
+      MatchedDecl->getTypeSourceInfo()->getTypeLoc().getSourceRange();
+
+  diag(MatchedDecl->getLocation(),
+       "string_view %0 is constructed from a temporary string")
+      << MatchedDecl << FixItHint::CreateReplacement(TypeLoc, "std::string");
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/misc/MiscTidyModule.cpp
===================================================================
--- clang-tidy/misc/MiscTidyModule.cpp
+++ clang-tidy/misc/MiscTidyModule.cpp
@@ -30,6 +30,7 @@
 #include "SizeofContainerCheck.h"
 #include "StaticAssertCheck.h"
 #include "StringIntegerAssignmentCheck.h"
+#include "StringViewOfTemporaryCheck.h"
 #include "SuspiciousSemicolonCheck.h"
 #include "SwappedArgumentsCheck.h"
 #include "ThrowByValueCatchByReferenceCheck.h"
@@ -85,6 +86,8 @@
         "misc-static-assert");
     CheckFactories.registerCheck<StringIntegerAssignmentCheck>(
         "misc-string-integer-assignment");
+    CheckFactories.registerCheck<String_viewOfTemporaryCheck>(
+        "misc-string_view-of-temporary");
     CheckFactories.registerCheck<SuspiciousSemicolonCheck>(
         "misc-suspicious-semicolon");
     CheckFactories.registerCheck<SwappedArgumentsCheck>(
Index: clang-tidy/misc/CMakeLists.txt
===================================================================
--- clang-tidy/misc/CMakeLists.txt
+++ clang-tidy/misc/CMakeLists.txt
@@ -22,6 +22,7 @@
   SizeofContainerCheck.cpp
   StaticAssertCheck.cpp
   StringIntegerAssignmentCheck.cpp
+  StringViewOfTemporaryCheck.cpp
   SuspiciousSemicolonCheck.cpp
   SwappedArgumentsCheck.cpp
   ThrowByValueCatchByReferenceCheck.cpp
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to