poelmanc updated this revision to Diff 225894.
poelmanc added a comment.

Removed the two uses of auto where the type was not an iterator or clear from 
the right-hand-side.


Repository:
  rCTE Clang Tools Extra

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D69238/new/

https://reviews.llvm.org/D69238

Files:
  clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init-msvc.cpp
  
clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp
@@ -1,5 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s readability-redundant-string-init %t
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
 
 namespace std {
 template <typename T>
@@ -104,7 +103,7 @@
   // CHECK-MESSAGES: [[@LINE-1]]:10: warning: redundant string initialization
   // CHECK-FIXES: STRING d;
   DECL_STRING(e, "");
-  // CHECK-MESSAGES: [[@LINE-1]]:15: warning: redundant string initialization
+  // CHECK-MESSAGES: [[@LINE-1]]:1{{[58]}}: warning: redundant string initialization
 
   MyString f = "u";
   STRING g = "u";
Index: clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init-msvc.cpp
===================================================================
--- clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init-msvc.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init-msvc.cpp
@@ -1,5 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11,c++14 %s readability-redundant-string-init %t
-// FIXME: Fix the checker to work in C++17 mode.
+// RUN: %check_clang_tidy %s readability-redundant-string-init %t
 
 namespace std {
 template <typename T>
Index: clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
===================================================================
--- clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
+++ clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp
@@ -57,12 +57,77 @@
       this);
 }
 
+// Returns the SourceRange for the string constructor expression and a bool
+// indicating whether to fix it (by replacing it with just the variable name)
+// or just issue a diagnostic warning. CtorExpr's SourceRange includes:
+//   foo = ""
+//   bar("")
+//   ""    (only in C++17 and later)
+//
+// With -std c++14 or earlier (!LangOps.CPlusPlus17), it was sufficient to
+// return CtorExpr->getSourceRange(). However, starting with c++17, parsing
+// the expression 'std::string Name = ""' results in a CtorExpr whose
+// SourceRange includes just '""' rather than the previous 'Name = ""'.
+//
+// So if the CtorExpr's SourceRange doesn't already start with 'Name', we
+// search leftward for 'Name\b*=\b*' (where \b* represents optional whitespace)
+// and if found, extend the SourceRange to start at 'Name'.
+std::pair<clang::SourceRange, bool>
+CtorSourceRange(const MatchFinder::MatchResult &Result,
+                const clang::NamedDecl *Decl, const clang::Expr *CtorExpr) {
+  const SourceManager &SM = *Result.SourceManager;
+  const StringRef Name = Decl->getName();
+  const int NameLength = Name.size();
+  const SourceLocation CtorStartLoc(CtorExpr->getSourceRange().getBegin());
+  const std::pair<FileID, unsigned> CtorLocInfo = SM.getDecomposedLoc(
+      CtorStartLoc.isMacroID() ? SM.getImmediateMacroCallerLoc(CtorStartLoc)
+                               : CtorStartLoc);
+  const int CtorStartPos = CtorLocInfo.second;
+  const StringRef File = SM.getBufferData(CtorLocInfo.first);
+  const StringRef CtorCheckName = File.substr(CtorStartPos, NameLength);
+  if (CtorCheckName == Name) {
+    // For 'std::string foo("");', CtorExpr is 'foo("")'
+    return std::make_pair(CtorExpr->getSourceRange(), true);
+  }
+  // Scan backwards from CtorStartPos.
+  // If find "Name\b*=\b*", extend CtorExpr SourceRange leftwards to include it.
+  bool FoundEquals = false;
+  for (int Pos = CtorStartPos - 1; Pos >= 0; Pos--) {
+    const char Char = File.data()[Pos];
+    if (Char == '=') {
+      if (FoundEquals) {
+        break; // Only allow one equals sign
+      }
+      FoundEquals = true;
+    } else if (!isWhitespace(Char)) {
+      // First non-whitespace/non-equals char. Check for Name ending with it.
+      const int CheckNameStart = Pos - NameLength + 1;
+      const StringRef CheckName(File.data() + CheckNameStart, NameLength);
+      if (FoundEquals && Name == CheckName) {
+        return std::make_pair(
+            clang::SourceRange(
+                CtorStartLoc.getLocWithOffset(CheckNameStart - CtorStartPos),
+                CtorExpr->getSourceRange().getEnd()),
+            true);
+      } else {
+        break; // Found something other than 'Name\b*=\b*'
+      }
+    }
+  }
+  // We can't find Name\b*=\b* so to be safe warn but don't fix.
+  return std::make_pair(CtorExpr->getSourceRange(), false);
+}
+
 void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *CtorExpr = Result.Nodes.getNodeAs<Expr>("expr");
   const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl");
-  diag(CtorExpr->getExprLoc(), "redundant string initialization")
-      << FixItHint::CreateReplacement(CtorExpr->getSourceRange(),
-                                      Decl->getName());
+  const std::pair<clang::SourceRange, bool> CtorExprRange =
+      CtorSourceRange(Result, Decl, CtorExpr);
+  DiagnosticBuilder Diag =
+      diag(CtorExprRange.first.getBegin(), "redundant string initialization");
+  if (CtorExprRange.second) {
+    Diag << FixItHint::CreateReplacement(CtorExprRange.first, Decl->getName());
+  }
 }
 
 } // namespace readability
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to