[clang-tools-extra] r334829 - [clang-tidy] This patch is a fix for D45405 where spaces were mistakenly considered as a part of a type name. So length("int *") was 5 instead of 3 with RemoveStars=0 or 4 with RemoveStars=1

Zinovy Nis via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 15 06:35:40 PDT 2018


Author: zinovy.nis
Date: Fri Jun 15 06:35:40 2018
New Revision: 334829

URL: http://llvm.org/viewvc/llvm-project?rev=334829&view=rev
Log:
[clang-tidy] This patch is a fix for D45405 where spaces were mistakenly considered as a part of a type name. So length("int *") was 5 instead of 3 with RemoveStars=0 or 4 with RemoveStars=1

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


Modified:
    clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp
    clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst
    clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp

Modified: clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp?rev=334829&r1=334828&r2=334829&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/modernize/UseAutoCheck.cpp Fri Jun 15 06:35:40 2018
@@ -11,6 +11,7 @@
 #include "clang/AST/ASTContext.h"
 #include "clang/ASTMatchers/ASTMatchFinder.h"
 #include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Basic/CharInfo.h"
 #include "clang/Tooling/FixIt.h"
 
 using namespace clang;
@@ -27,6 +28,34 @@ const char DeclWithNewId[] = "decl_new";
 const char DeclWithCastId[] = "decl_cast";
 const char DeclWithTemplateCastId[] = "decl_template";
 
+size_t GetTypeNameLength(bool RemoveStars, StringRef Text) {
+  enum CharType { Space, Alpha, Punctuation };
+  CharType LastChar = Space, BeforeSpace = Punctuation;
+  size_t NumChars = 0;
+  int TemplateTypenameCntr = 0;
+  for (const unsigned char C : Text) {
+    if (C == '<')
+      ++TemplateTypenameCntr;
+    else if (C == '>')
+      --TemplateTypenameCntr;
+    const CharType NextChar =
+        isAlphanumeric(C)
+            ? Alpha
+            : (isWhitespace(C) ||
+               (!RemoveStars && TemplateTypenameCntr == 0 && C == '*'))
+                  ? Space
+                  : Punctuation;
+    if (NextChar != Space) {
+      ++NumChars; // Count the non-space character.
+      if (LastChar == Space && NextChar == Alpha && BeforeSpace == Alpha)
+        ++NumChars; // Count a single space character between two words.
+      BeforeSpace = NextChar;
+    }
+    LastChar = NextChar;
+  }
+  return NumChars;
+}
+
 /// \brief Matches variable declarations that have explicit initializers that
 /// are not initializer lists.
 ///
@@ -419,8 +448,10 @@ void UseAutoCheck::replaceExpr(
   SourceRange Range(Loc.getSourceRange());
 
   if (MinTypeNameLength != 0 &&
-      tooling::fixit::getText(Loc.getSourceRange(), FirstDecl->getASTContext())
-              .size() < MinTypeNameLength)
+      GetTypeNameLength(RemoveStars,
+                        tooling::fixit::getText(Loc.getSourceRange(),
+                                                FirstDecl->getASTContext())) <
+          MinTypeNameLength)
     return;
 
   auto Diag = diag(Range.getBegin(), Message);

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst?rev=334829&r1=334828&r2=334829&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/modernize-use-auto.rst Fri Jun 15 06:35:40 2018
@@ -182,20 +182,37 @@ Options
    If the option is set to non-zero (default `5`), the check will ignore type
    names having a length less than the option value. The option affects
    expressions only, not iterators.
+   Spaces between multi-lexeme type names (``long int``) are considered as one.
+   If ``RemoveStars`` option (see below) is set to non-zero, then ``*s`` in
+   the type are also counted as a part of the type name.
 
 .. code-block:: c++
 
-  // MinTypeNameLength = 0
+  // MinTypeNameLength = 0, RemoveStars=0
 
   int a = static_cast<int>(foo());            // ---> auto a = ...
-  bool b = new bool;                          // ---> auto b = ...
+  // length(bool *) = 4
+  bool *b = new bool;                         // ---> auto *b = ...
   unsigned c = static_cast<unsigned>(foo());  // ---> auto c = ...
 
-  // MinTypeNameLength = 8
+  // MinTypeNameLength = 5, RemoveStars=0
 
-  int a = static_cast<int>(foo());            // ---> int  a = ...
-  bool b = new bool;                          // ---> bool b = ...
-  unsigned c = static_cast<unsigned>(foo());  // ---> auto c = ...
+  int a = static_cast<int>(foo());                 // ---> int  a = ...
+  bool b = static_cast<bool>(foo());               // ---> bool b = ...
+  bool *pb = static_cast<bool*>(foo());            // ---> bool *pb = ...
+  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...
+  // length(long <on-or-more-spaces> int) = 8
+  long int d = static_cast<long int>(foo());       // ---> auto d = ...
+
+  // MinTypeNameLength = 5, RemoveStars=1
+
+  int a = static_cast<int>(foo());                 // ---> int  a = ...
+  // length(int * * ) = 5
+  int **pa = static_cast<int**>(foo());            // ---> auto pa = ...
+  bool b = static_cast<bool>(foo());               // ---> bool b = ...
+  bool *pb = static_cast<bool*>(foo());            // ---> auto pb = ...
+  unsigned c = static_cast<unsigned>(foo());       // ---> auto c = ...
+  long int d = static_cast<long int>(foo());       // ---> auto d = ...
 
 .. option:: RemoveStars
 

Modified: clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp?rev=334829&r1=334828&r2=334829&view=diff
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp (original)
+++ clang-tools-extra/trunk/test/clang-tidy/modernize-use-auto-min-type-name-length.cpp Fri Jun 15 06:35:40 2018
@@ -1,30 +1,85 @@
-// RUN: %check_clang_tidy %s modernize-use-auto %t -- \
-// RUN:   -config="{CheckOptions: [{key: modernize-use-auto.MinTypeNameLength, value: '5'}]}" \
-// RUN:   -- -std=c++11 -frtti
-
-extern int foo();
-
-using VeryVeryVeryLongTypeName = int;
+// RUN: %check_clang_tidy -check-suffix=0-0 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- --std=c++11 -frtti
+// RUN: %check_clang_tidy -check-suffix=0-8 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 0}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- --std=c++11 -frtti
+// RUN: %check_clang_tidy -check-suffix=1-0 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 0}]}" -- --std=c++11 -frtti
+// RUN: %check_clang_tidy -check-suffix=1-8 %s modernize-use-auto %t  -- -config="{CheckOptions: [{key: modernize-use-auto.RemoveStars, value: 1}, {key: modernize-use-auto.MinTypeNameLength, value: 8}]}" -- --std=c++11 -frtti
+
+template <class T> extern T foo();
+template <class T> struct P {  explicit P(T t) : t_(t) {}  T t_;};
+template <class T> P<T> *foo_ptr();
+template <class T> P<T> &foo_ref();
 
 int bar() {
-  int a = static_cast<VeryVeryVeryLongTypeName>(foo());
-  // strlen('int') = 4 <  5, so skip it,
-  // even strlen('VeryVeryVeryLongTypeName') > 5.
-
-  unsigned b = static_cast<unsigned>(foo());
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
-  // CHECK-FIXES: auto b = static_cast<unsigned>(foo());
-
-  bool c = static_cast<bool>(foo());
-  // strlen('bool') = 4 <  5, so skip it.
-
-  const bool c1 = static_cast<const bool>(foo());
-  // strlen('bool') = 4 <  5, so skip it, even there's a 'const'.
-
-  unsigned long long ull = static_cast<unsigned long long>(foo());
-  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use auto when initializing with a cast to avoid duplicating the type name [modernize-use-auto]
-  // CHECK-FIXES: auto ull = static_cast<unsigned long long>(foo());
+  {
+    // Lenth(long) = 4
+    long i = static_cast<long>(foo<long>());
+    // CHECK-FIXES-0-0: auto i = {{.*}}
+    // CHECK-FIXES-0-8: long i = {{.*}}
+    // CHECK-FIXES-1-0: auto  i = {{.*}}
+    // CHECK-FIXES-1-8: long i = {{.*}}
+    const long ci = static_cast<long>(foo<const long>());
+    // CHECK-FIXES-0-0: auto ci = {{.*}}
+    // CHECK-FIXES-0-8: long ci = {{.*}}
+    // CHECK-FIXES-1-0: auto  ci = {{.*}}
+    // CHECK-FIXES-1-8: long ci = {{.*}}
+    long *pi = static_cast<long *>(foo<long *>());
+    // CHECK-FIXES-0-0: auto *pi = {{.*}}
+    // CHECK-FIXES-0-8: long *pi = {{.*}}
+    // CHECK-FIXES-1-0: auto pi = {{.*}}
+    // CHECK-FIXES-1-8: long *pi = {{.*}}
+
+    // Length(long       *) is still 5
+    long      *     pi2 = static_cast<long *>(foo<long *>());
+    // CHECK-FIXES-0-0: auto      *     pi2 = {{.*}}
+    // CHECK-FIXES-0-8: long      *     pi2 = {{.*}}
+    // CHECK-FIXES-1-0: auto      pi2 = {{.*}}
+    // CHECK-FIXES-1-8: long      *     pi2 = {{.*}}
+
+    // Length(long **) = 6
+    long **ppi = static_cast<long **>(foo<long **>());
+    // CHECK-FIXES-0-0: auto **ppi = {{.*}}
+    // CHECK-FIXES-0-8: long **ppi = {{.*}}
+    // CHECK-FIXES-1-0: auto ppi = {{.*}}
+    // CHECK-FIXES-1-8: long **ppi = {{.*}}
+  }
+
+  {
+    // Lenth(long int) = 4 + 1 + 3 = 8
+    // Lenth(long        int) is still 8
+    long int i = static_cast<long int>(foo<long int>());
+    // CHECK-FIXES-0-0: auto i = {{.*}}
+    // CHECK-FIXES-0-8: auto i = {{.*}}
+    // CHECK-FIXES-1-0: auto  i = {{.*}}
+    // CHECK-FIXES-1-8: auto  i = {{.*}}
+
+    long int *pi = static_cast<long int *>(foo<long int *>());
+    // CHECK-FIXES-0-0: auto *pi = {{.*}}
+    // CHECK-FIXES-0-8: auto *pi = {{.*}}
+    // CHECK-FIXES-1-0: auto pi = {{.*}}
+    // CHECK-FIXES-1-8: auto pi = {{.*}}
+  }
+
+  // Templates
+  {
+    // Length(P<long>) = 7
+    P<long>& i = static_cast<P<long>&>(foo_ref<long>());
+    // CHECK-FIXES-0-0: auto& i = {{.*}}
+    // CHECK-FIXES-0-8: P<long>& i = {{.*}}
+    // CHECK-FIXES-1-0: auto & i = {{.*}}
+    // CHECK-FIXES-1-8: P<long>& i = {{.*}}
+
+    // Length(P<long*>) = 8
+    P<long*>& pi = static_cast<P<long*> &>(foo_ref<long*>());
+    // CHECK-FIXES-0-0: auto& pi = {{.*}}
+    // CHECK-FIXES-0-8: auto& pi = {{.*}}
+    // CHECK-FIXES-1-0: auto & pi = {{.*}}
+    // CHECK-FIXES-1-8: auto & pi = {{.*}}
+
+    P<long>* pi2 = static_cast<P<long>*>(foo_ptr<long>());
+    // CHECK-FIXES-0-0: auto* pi2 = {{.*}}
+    // CHECK-FIXES-0-8: P<long>* pi2 = {{.*}}
+    // CHECK-FIXES-1-0: auto  pi2 = {{.*}}
+    // CHECK-FIXES-1-8: auto  pi2 = {{.*}}
+  }
 
   return 1;
 }
-




More information about the cfe-commits mailing list