[PATCH] D69238: Fix clang-tidy readability-redundant-string-init for c++17/c++2a
Conrad Poelman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 8 21:50:46 PST 2019
poelmanc added a comment.
In D69238#1739627 <https://reviews.llvm.org/D69238#1739627>, @NoQ wrote:
> Clang's `-ast-dump` <https://clang.llvm.org/docs/IntroductionToTheClangAST.html>.
Wow. That makes this so much easier... Thank you so much!
Looking at the AST showed that the `CXXConstructExpr`s that `readability-redundant-string-init` previously relied upon for `SourceRange` were being elided in C++17/2a, but that `VarDecl`s consistently held all the right info across all C++ modes. So I completely rewrote this patch to get the `SourceRange` from the `VarDecl`. All tests pass.
In case anyone cares or for posterity, what follows are a bunch of probably unnecessary details.
I made a super minimal readability-redundant-string-init.cpp:
namespace std {
struct string {
string();
string(const char *);
};
}
void f() {
std::string a = "", b = "foo", c, d(""), e("bar");
}
Running `clang -Xclang -ast-dump -std=c++11 readability-redundant-string-init.cpp` yields:
`-FunctionDecl 0x27a33bfd610 <line:8:1, line:10:1> line:8:6 f 'void ()'
`-CompoundStmt 0x27a33bf6c78 <col:10, line:10:1>
`-DeclStmt 0x27a33bf6c60 <line:9:3, col:52>
|-VarDecl 0x27a33bfd788 <col:3, col:19> col:15 a 'std::string':'std::string' cinit
| `-ExprWithCleanups 0x27a33bfddd0 <col:15, col:19> 'std::string':'std::string'
| `-CXXConstructExpr 0x27a33bfdda0 <col:15, col:19> 'std::string':'std::string' 'void (std::string &&) noexcept' elidable
| `-MaterializeTemporaryExpr 0x27a33bfdd48 <col:19> 'std::string':'std::string' xvalue
| `-ImplicitCastExpr 0x27a33bfdc20 <col:19> 'std::string':'std::string' <ConstructorConversion>
| `-CXXConstructExpr 0x27a33bfdbf0 <col:19> 'std::string':'std::string' 'void (const char *)'
| `-ImplicitCastExpr 0x27a33bfdbd8 <col:19> 'const char *' <ArrayToPointerDecay>
| `-StringLiteral 0x27a33bfd868 <col:19> 'const char [1]' lvalue ""
|-VarDecl 0x27a33bfde08 <col:3, col:27> col:23 b 'std::string':'std::string' cinit
| `-ExprWithCleanups 0x27a33bfdfb0 <col:23, col:27> 'std::string':'std::string'
| `-CXXConstructExpr 0x27a33bfdf80 <col:23, col:27> 'std::string':'std::string' 'void (std::string &&) noexcept' elidable
| `-MaterializeTemporaryExpr 0x27a33bfdf68 <col:27> 'std::string':'std::string' xvalue
| `-ImplicitCastExpr 0x27a33bfdf50 <col:27> 'std::string':'std::string' <ConstructorConversion>
| `-CXXConstructExpr 0x27a33bfdf20 <col:27> 'std::string':'std::string' 'void (const char *)'
| `-ImplicitCastExpr 0x27a33bfdf08 <col:27> 'const char *' <ArrayToPointerDecay>
| `-StringLiteral 0x27a33bfdee8 <col:27> 'const char [4]' lvalue "foo"
|-VarDecl 0x27a33bfdfe8 <col:3, col:34> col:34 c 'std::string':'std::string' callinit
| `-CXXConstructExpr 0x27a33bfe050 <col:34> 'std::string':'std::string' 'void ()'
|-VarDecl 0x27a33bfe098 <col:3, col:41> col:37 d 'std::string':'std::string' callinit
| `-CXXConstructExpr 0x27a33bf6af0 <col:37, col:41> 'std::string':'std::string' 'void (const char *)'
| `-ImplicitCastExpr 0x27a33bf6ad8 <col:39> 'const char *' <ArrayToPointerDecay>
| `-StringLiteral 0x27a33bf6aa0 <col:39> 'const char [1]' lvalue ""
`-VarDecl 0x27a33bf6b40 <col:3, col:51> col:44 e 'std::string':'std::string' callinit
`-CXXConstructExpr 0x27a33bf6c00 <col:44, col:51> 'std::string':'std::string' 'void (const char *)'
`-ImplicitCastExpr 0x27a33bf6be8 <col:46> 'const char *' <ArrayToPointerDecay>
`-StringLiteral 0x27a33bf6ba8 <col:46> 'const char [4]' lvalue "bar"
With -std=c++11, all of the outer `CXXConstructExpr` have the correct range to replace with just the variable names, which explains why all is fine with C++11.
Then running `clang -Xclang -ast-dump -std=c++17 readability-redundant-string-init.cpp` yields:
`-FunctionDecl 0x2b8e6ac96b0 <line:8:1, line:10:1> line:8:6 f 'void ()'
`-CompoundStmt 0x2b8e6acc608 <col:10, line:10:1>
`-DeclStmt 0x2b8e6acc5f0 <line:9:3, col:52>
|-VarDecl 0x2b8e6ac9828 <col:3, col:19> col:15 a 'std::string':'std::string' cinit
| `-ImplicitCastExpr 0x2b8e6ac9cc0 <col:19> 'std::string':'std::string' <ConstructorConversion>
| `-CXXConstructExpr 0x2b8e6ac9c90 <col:19> 'std::string':'std::string' 'void (const char *)'
| `-ImplicitCastExpr 0x2b8e6ac9c78 <col:19> 'const char *' <ArrayToPointerDecay>
| `-StringLiteral 0x2b8e6ac9908 <col:19> 'const char [1]' lvalue ""
|-VarDecl 0x2b8e6ac9e08 <col:3, col:27> col:23 b 'std::string':'std::string' cinit
| `-ImplicitCastExpr 0x2b8e6ac9f50 <col:27> 'std::string':'std::string' <ConstructorConversion>
| `-CXXConstructExpr 0x2b8e6ac9f20 <col:27> 'std::string':'std::string' 'void (const char *)'
| `-ImplicitCastExpr 0x2b8e6ac9f08 <col:27> 'const char *' <ArrayToPointerDecay>
| `-StringLiteral 0x2b8e6ac9ee8 <col:27> 'const char [4]' lvalue "foo"
|-VarDecl 0x2b8e6ac9f88 <col:3, col:34> col:34 c 'std::string':'std::string' callinit
| `-CXXConstructExpr 0x2b8e6ac9ff0 <col:34> 'std::string':'std::string' 'void ()'
|-VarDecl 0x2b8e6aca038 <col:3, col:41> col:37 d 'std::string':'std::string' callinit
| `-CXXConstructExpr 0x2b8e6aca0f0 <col:37, col:41> 'std::string':'std::string' 'void (const char *)'
| `-ImplicitCastExpr 0x2b8e6aca0d8 <col:39> 'const char *' <ArrayToPointerDecay>
| `-StringLiteral 0x2b8e6aca0a0 <col:39> 'const char [1]' lvalue ""
`-VarDecl 0x2b8e6acc4d0 <col:3, col:51> col:44 e 'std::string':'std::string' callinit
`-CXXConstructExpr 0x2b8e6acc590 <col:44, col:51> 'std::string':'std::string' 'void (const char *)'
`-ImplicitCastExpr 0x2b8e6acc578 <col:46> 'const char *' <ArrayToPointerDecay>
`-StringLiteral 0x2b8e6acc538 <col:46> 'const char [4]' lvalue "bar"
With -std=c++17 the two elidable `CXXConstructExpr` are gone, and the previously nested `CXXConstructExpr` that remain have too-short ranges, which explains the C++17 failure.
Fortunately this dump showed that VarDecl contained all the information needed to obtain the //right// ranges. From
VarDecl 0xfffffffffff <col:Begin, col:End> col:Loc var_name 'std::string':'std::string' cinit
we extract `SourceRange(Loc,End)` and everything works fine across C++ modes.
Repository:
rCTE Clang Tools Extra
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D69238/new/
https://reviews.llvm.org/D69238
More information about the cfe-commits
mailing list