[clang-tools-extra] 3807079 - [clang-tidy] Fix crash in readability-redundant-string-cstr
Nathan James via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 31 05:27:39 PDT 2020
Author: Nathan James
Date: 2020-03-31T13:27:32+01:00
New Revision: 3807079d705fe04c5c3bde8f848ec922b5771f15
URL: https://github.com/llvm/llvm-project/commit/3807079d705fe04c5c3bde8f848ec922b5771f15
DIFF: https://github.com/llvm/llvm-project/commit/3807079d705fe04c5c3bde8f848ec922b5771f15.diff
LOG: [clang-tidy] Fix crash in readability-redundant-string-cstr
Summary: Addresses [[ https://bugs.llvm.org/show_bug.cgi?id=45286 | clang-tidy-11: Crash in DynTypedMatcher::matches during readability-redundant-string-cstr check ]]
Reviewers: aaron.ballman, alexfh, gribozavr2
Reviewed By: gribozavr2
Subscribers: xazax.hun, cfe-commits
Tags: #clang, #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D76761
Added:
Modified:
clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
index 8975f294373c..e41cdfcc08d8 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantStringCStrCheck.cpp
@@ -61,53 +61,8 @@ formatDereference(const ast_matchers::MatchFinder::MatchResult &Result,
return (llvm::Twine("*") + Text).str();
}
-// Trying to get CallExpr in which CxxConstructExpr is called.
-static const clang::CallExpr *
-tryGetCallExprAncestorForCxxConstructExpr(const Expr *TheExpr,
- ASTContext &Context) {
- // We skip nodes such as CXXBindTemporaryExpr, MaterializeTemporaryExpr.
- for (ast_type_traits::DynTypedNode DynParent : Context.getParents(*TheExpr)) {
- if (const auto *Parent = DynParent.get<Expr>()) {
- if (const auto *TheCallExpr = dyn_cast<CallExpr>(Parent))
- return TheCallExpr;
-
- if (const clang::CallExpr *TheCallExpr =
- tryGetCallExprAncestorForCxxConstructExpr(Parent, Context))
- return TheCallExpr;
- }
- }
-
- return nullptr;
-}
-
-// Check that ParamDecl of CallExprDecl has rvalue type.
-static bool checkParamDeclOfAncestorCallExprHasRValueRefType(
- const Expr *TheCxxConstructExpr, ASTContext &Context) {
- if (const clang::CallExpr *TheCallExpr =
- tryGetCallExprAncestorForCxxConstructExpr(TheCxxConstructExpr,
- Context)) {
- for (unsigned i = 0; i < TheCallExpr->getNumArgs(); ++i) {
- const Expr *Arg = TheCallExpr->getArg(i);
- if (Arg->getSourceRange() == TheCxxConstructExpr->getSourceRange()) {
- if (const auto *TheCallExprFuncProto =
- TheCallExpr->getCallee()
- ->getType()
- ->getPointeeType()
- ->getAs<FunctionProtoType>()) {
- if (TheCallExprFuncProto->getParamType(i)->isRValueReferenceType())
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-AST_MATCHER(CXXConstructExpr,
- matchedParamDeclOfAncestorCallExprHasRValueRefType) {
- return checkParamDeclOfAncestorCallExprHasRValueRefType(
- &Node, Finder->getASTContext());
+AST_MATCHER(MaterializeTemporaryExpr, isBoundToLValue) {
+ return Node.isBoundToLvalueReference();
}
} // end namespace
@@ -141,11 +96,11 @@ void RedundantStringCStrCheck::registerMatchers(
// Detect redundant 'c_str()' calls through a string constructor.
// If CxxConstructExpr is the part of some CallExpr we need to
// check that matched ParamDecl of the ancestor CallExpr is not rvalue.
- Finder->addMatcher(
- cxxConstructExpr(
- StringConstructorExpr, hasArgument(0, StringCStrCallExpr),
- unless(matchedParamDeclOfAncestorCallExprHasRValueRefType())),
- this);
+ Finder->addMatcher(cxxConstructExpr(StringConstructorExpr,
+ hasArgument(0, StringCStrCallExpr),
+ unless(hasParent(materializeTemporaryExpr(
+ unless(isBoundToLValue()))))),
+ this);
// Detect: 's == str.c_str()' -> 's == str'
Finder->addMatcher(
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp
index 1773dc57a8d8..2561b81805bd 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-string-cstr.cpp
@@ -220,3 +220,27 @@ void m1(std::string&&) {
m1tp m1p2 = m1;
m1p2(s.c_str());
}
+
+namespace PR45286 {
+struct Foo {
+ void func(const std::string &) {}
+ void func2(std::string &&) {}
+};
+
+void bar() {
+ std::string Str{"aaa"};
+ Foo Foo;
+ Foo.func(Str.c_str());
+ // CHECK-MESSAGES: :[[@LINE-1]]:12: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}Foo.func(Str);{{$}}
+
+ // Ensure it doesn't transform Binding to r values
+ Foo.func2(Str.c_str());
+
+ // Ensure its not confused by parens
+ Foo.func((Str.c_str()));
+ // CHECK-MESSAGES: :[[@LINE-1]]:13: warning: redundant call to 'c_str' [readability-redundant-string-cstr]
+ // CHECK-FIXES: {{^ }}Foo.func((Str));{{$}}
+ Foo.func2((Str.c_str()));
+}
+} // namespace PR45286
More information about the cfe-commits
mailing list