Skip to content

Commit 1315f4e

Browse files
author
Mitchell Balan
committed
[clang-tidy] Fix readability-redundant-string-init for c++17/c++2a
Summary: `readability-redundant-string-init` was one of several clang-tidy checks documented as failing for C++17. (The failure mode in C++17 is that it changes `std::string Name = ""`; to `std::string Name = Name;`, which actually compiles but crashes at run-time.) Analyzing the AST with `clang -Xclang -ast-dump` showed that the outer `CXXConstructExprs` that previously held the correct SourceRange were being elided in C++17/2a, but the containing `VarDecl` expressions still had all the relevant information. So this patch changes the fix to get its source ranges from `VarDecl`. It adds one test `std::string g = "u", h = "", i = "uuu", j = "", k;` to confirm proper warnings and fixit replacements in a single `DeclStmt` where some strings require replacement and others don't. The readability-redundant-string-init.cpp and readability-redundant-string-init-msvc.cpp tests now pass for C++11/14/17/2a. Reviewers: gribozavr, etienneb, alexfh, hokein, aaron.ballman, gribozavr2 Patch by: poelmanc Subscribers: NoQ, MyDeveloperDay, Eugene.Zelenko, dylanmckay, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D69238
1 parent f8901af commit 1315f4e

File tree

3 files changed

+18
-9
lines changed

3 files changed

+18
-9
lines changed

clang-tools-extra/clang-tidy/readability/RedundantStringInitCheck.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
7373
namedDecl(
7474
varDecl(
7575
hasType(hasUnqualifiedDesugaredType(recordType(
76-
hasDeclaration(cxxRecordDecl(hasName("basic_string")))))),
76+
hasDeclaration(cxxRecordDecl(hasStringTypeName))))),
7777
hasInitializer(expr(ignoringImplicit(anyOf(
7878
EmptyStringCtorExpr, EmptyStringCtorExprWithTemporaries)))))
7979
.bind("vardecl"),
@@ -82,11 +82,12 @@ void RedundantStringInitCheck::registerMatchers(MatchFinder *Finder) {
8282
}
8383

8484
void RedundantStringInitCheck::check(const MatchFinder::MatchResult &Result) {
85-
const auto *CtorExpr = Result.Nodes.getNodeAs<Expr>("expr");
86-
const auto *Decl = Result.Nodes.getNodeAs<NamedDecl>("decl");
87-
diag(CtorExpr->getExprLoc(), "redundant string initialization")
88-
<< FixItHint::CreateReplacement(CtorExpr->getSourceRange(),
89-
Decl->getName());
85+
const auto *VDecl = Result.Nodes.getNodeAs<VarDecl>("vardecl");
86+
// VarDecl's getSourceRange() spans 'string foo = ""' or 'string bar("")'.
87+
// So start at getLocation() to span just 'foo = ""' or 'bar("")'.
88+
SourceRange ReplaceRange(VDecl->getLocation(), VDecl->getEndLoc());
89+
diag(VDecl->getLocation(), "redundant string initialization")
90+
<< FixItHint::CreateReplacement(ReplaceRange, VDecl->getName());
9091
}
9192

9293
} // namespace readability

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
// RUN: %check_clang_tidy -std=c++11,c++14 %s readability-redundant-string-init %t
2-
// FIXME: Fix the checker to work in C++17 mode.
1+
// RUN: %check_clang_tidy %s readability-redundant-string-init %t
32

43
namespace std {
54
template <typename T>

clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-init.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
// RUN: %check_clang_tidy -std=c++11,c++14 %s readability-redundant-string-init %t
1+
// RUN: %check_clang_tidy -std=c++11,c++14 %s readability-redundant-string-init %t \
2+
// RUN: -config="{CheckOptions: \
3+
// RUN: [{key: readability-redundant-string-init.StringNames, \
4+
// RUN: value: '::std::basic_string;our::TestString'}] \
5+
// RUN: }"
26
// FIXME: Fix the checker to work in C++17 mode.
37

48
namespace std {
@@ -131,6 +135,11 @@ void k() {
131135
// CHECK-FIXES: std::string a, b, c;
132136

133137
std::string d = "u", e = "u", f = "u";
138+
139+
std::string g = "u", h = "", i = "uuu", j = "", k;
140+
// CHECK-MESSAGES: [[@LINE-1]]:24: warning: redundant string initialization
141+
// CHECK-MESSAGES: [[@LINE-2]]:43: warning: redundant string initialization
142+
// CHECK-FIXES: std::string g = "u", h, i = "uuu", j, k;
134143
}
135144

136145
// These cases should not generate warnings.

0 commit comments

Comments
 (0)