danielmarjamaki created this revision.
Herald added a subscriber: mgorny.

I propose this new readability checker.


Repository:
  rL LLVM

https://reviews.llvm.org/D32346

Files:
  clang-tidy/readability/CMakeLists.txt
  clang-tidy/readability/ReadabilityTidyModule.cpp
  clang-tidy/readability/StrlenArgumentCheck.cpp
  clang-tidy/readability/StrlenArgumentCheck.h
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/checks/readability-strlen-argument.rst
  test/clang-tidy/readability-strlen-argument.cpp

Index: test/clang-tidy/readability-strlen-argument.cpp
===================================================================
--- test/clang-tidy/readability-strlen-argument.cpp
+++ test/clang-tidy/readability-strlen-argument.cpp
@@ -0,0 +1,25 @@
+// RUN: %check_clang_tidy %s readability-strlen-argument %t
+
+typedef __typeof(sizeof(int)) size_t;
+size_t strlen(const char *s);
+
+void warn1(const char *Str) {
+  int X;
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:18: warning: strlen() argument has pointer addition, it is recommended to subtract the result instead. [readability-strlen-argument]
+  X = strlen(Str + 10);
+  // CHECK-FIXES: {{^}}  X = (strlen(Str) - 10);{{$}}
+
+  // CHECK-MESSAGES: :[[@LINE+1]]:17: warning: strlen() argument has pointer addition, it is recommended to subtract the result instead. [readability-strlen-argument]
+  X = strlen(10 + Str);
+}
+
+struct S {
+  char *P;
+};
+void warn2(const struct S &Par) {
+  int X;
+  // CHECK-MESSAGES: :[[@LINE+1]]:20: warning: strlen() argument has pointer addition, it is recommended to subtract the result instead. [readability-strlen-argument]
+  X = strlen(Par.P + 10);
+  // CHECK-FIXES: {{^}}  X = (strlen(Par.P) - 10);{{$}}
+}
Index: docs/clang-tidy/checks/readability-strlen-argument.rst
===================================================================
--- docs/clang-tidy/checks/readability-strlen-argument.rst
+++ docs/clang-tidy/checks/readability-strlen-argument.rst
@@ -0,0 +1,18 @@
+.. title:: clang-tidy - readability-strlen-argument
+
+readability-strlen-argument
+===========================
+
+This checker will detect addition in strlen() argument. Example code:
+
+.. code-block:: c++
+
+    strlen(str + 10)
+
+With -fix that becomes:
+
+.. code-block:: c++
+
+    (strlen(str) - 10)
+
+For readability it is considered better to subtract the result outside the strlen().
Index: docs/clang-tidy/checks/list.rst
===================================================================
--- docs/clang-tidy/checks/list.rst
+++ docs/clang-tidy/checks/list.rst
@@ -169,4 +169,5 @@
    readability-redundant-string-init
    readability-simplify-boolean-expr
    readability-static-definition-in-anonymous-namespace
+   readability-strlen-argument
    readability-uniqueptr-delete-release
Index: clang-tidy/readability/StrlenArgumentCheck.h
===================================================================
--- clang-tidy/readability/StrlenArgumentCheck.h
+++ clang-tidy/readability/StrlenArgumentCheck.h
@@ -0,0 +1,35 @@
+//===--- StrlenArgumentCheck.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_READABILITY_STRLEN_ARGUMENT_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STRLEN_ARGUMENT_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+/// Detect pointer addition in strlen() argument.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability-strlen-argument.html
+class StrlenArgumentCheck : public ClangTidyCheck {
+public:
+  StrlenArgumentCheck(StringRef Name, ClangTidyContext *Context)
+      : ClangTidyCheck(Name, Context) {}
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+};
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_STRLEN_ARGUMENT_H
Index: clang-tidy/readability/StrlenArgumentCheck.cpp
===================================================================
--- clang-tidy/readability/StrlenArgumentCheck.cpp
+++ clang-tidy/readability/StrlenArgumentCheck.cpp
@@ -0,0 +1,48 @@
+//===--- StrlenArgumentCheck.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 "StrlenArgumentCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace readability {
+
+void StrlenArgumentCheck::registerMatchers(MatchFinder *Finder) {
+  Finder->addMatcher(
+      callExpr(callee(functionDecl(hasName("strlen"))),
+               hasAnyArgument(ignoringParenImpCasts(
+                   binaryOperator(hasOperatorName("+")).bind("B"))))
+          .bind("CE"),
+      this);
+}
+
+void StrlenArgumentCheck::check(const MatchFinder::MatchResult &Result) {
+  const auto *B = Result.Nodes.getNodeAs<BinaryOperator>("B");
+  const auto *CE = Result.Nodes.getNodeAs<CallExpr>("CE");
+  auto D =
+      diag(B->getExprLoc(), "strlen() argument has pointer addition, it is "
+                            "recommended to subtract the result instead.");
+  if (!B->getRHS()->getType()->isAnyPointerType()) {
+    SourceLocation LHSEndLoc = Lexer::getLocForEndOfToken(
+        B->getLHS()->getLocEnd(), 0, *Result.SourceManager, getLangOpts());
+    D << FixItHint::CreateInsertion(LHSEndLoc, ")")
+      << FixItHint::CreateInsertion(CE->getLocStart(), "(")
+      << FixItHint::CreateReplacement(
+             SourceRange(B->getExprLoc(), B->getExprLoc()), "-");
+  }
+}
+
+} // namespace readability
+} // namespace tidy
+} // namespace clang
Index: clang-tidy/readability/ReadabilityTidyModule.cpp
===================================================================
--- clang-tidy/readability/ReadabilityTidyModule.cpp
+++ clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -33,6 +33,7 @@
 #include "RedundantStringInitCheck.h"
 #include "SimplifyBooleanExprCheck.h"
 #include "StaticDefinitionInAnonymousNamespaceCheck.h"
+#include "StrlenArgumentCheck.h"
 #include "UniqueptrDeleteReleaseCheck.h"
 
 namespace clang {
@@ -72,6 +73,8 @@
         "readability-redundant-member-init");
     CheckFactories.registerCheck<StaticDefinitionInAnonymousNamespaceCheck>(
         "readability-static-definition-in-anonymous-namespace");
+    CheckFactories.registerCheck<StrlenArgumentCheck>(
+        "readability-strlen-argument");
     CheckFactories.registerCheck<readability::NamedParameterCheck>(
         "readability-named-parameter");
     CheckFactories.registerCheck<NonConstParameterCheck>(
Index: clang-tidy/readability/CMakeLists.txt
===================================================================
--- clang-tidy/readability/CMakeLists.txt
+++ clang-tidy/readability/CMakeLists.txt
@@ -26,6 +26,7 @@
   RedundantStringInitCheck.cpp
   SimplifyBooleanExprCheck.cpp
   StaticDefinitionInAnonymousNamespaceCheck.cpp
+  StrlenArgumentCheck.cpp
   UniqueptrDeleteReleaseCheck.cpp
 
   LINK_LIBS
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to