diff --git a/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp b/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp --- a/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/abseil-string-find-str-contains.cpp @@ -239,16 +239,12 @@ asv.find('c') == absl::string_view::npos; } -#define COMPARE_MACRO(x, y) ((x) == (y)) -#define FIND_MACRO(x, y) ((x).find(y)) -#define FIND_COMPARE_MACRO(x, y, z) ((x).find(y) == (z)) - -// Confirms that it does not match when a macro is involved. -void no_macros() { - std::string s; - COMPARE_MACRO(s.find("a"), std::string::npos); - FIND_MACRO(s, "a") == std::string::npos; - FIND_COMPARE_MACRO(s, "a", std::string::npos); +#define FOO(a, b, c, d) ((a).find(b) == std::string::npos ? (c) : (d)) + +// Confirms that it does not match when a macro would be "torn" by the fix. +void no_tearing_macros() { + std::string h = "helo"; + FOO(h, "x", 5, 6); } // Confirms that it does not match when the pos parameter is non-zero. diff --git a/clang/lib/Tooling/Transformer/Stencil.cpp b/clang/lib/Tooling/Transformer/Stencil.cpp --- a/clang/lib/Tooling/Transformer/Stencil.cpp +++ b/clang/lib/Tooling/Transformer/Stencil.cpp @@ -12,6 +12,7 @@ #include "clang/AST/Expr.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/ASTMatchers/ASTMatchers.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Lex/Lexer.h" #include "clang/Tooling/Transformer/SourceCode.h" #include "clang/Tooling/Transformer/SourceCodeBuilders.h" @@ -226,12 +227,14 @@ Error evalData(const SelectorData &Data, const MatchFinder::MatchResult &Match, std::string *Result) { - auto Range = Data.Selector(Match); - if (!Range) - return Range.takeError(); - if (auto Err = tooling::validateEditRange(*Range, *Match.SourceManager)) + auto RawRange = Data.Selector(Match); + if (!RawRange) + return RawRange.takeError(); + CharSourceRange Range = Lexer::makeFileCharRange( + *RawRange, *Match.SourceManager, Match.Context->getLangOpts()); + if (auto Err = tooling::validateEditRange(Range, *Match.SourceManager)) return Err; - *Result += tooling::getText(*Range, *Match.Context); + *Result += tooling::getText(Range, *Match.Context); return Error::success(); } diff --git a/clang/unittests/Tooling/StencilTest.cpp b/clang/unittests/Tooling/StencilTest.cpp --- a/clang/unittests/Tooling/StencilTest.cpp +++ b/clang/unittests/Tooling/StencilTest.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/Transformer/Stencil.h" +#include "clang/AST/ASTTypeTraits.h" #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/Tooling/FixIt.h" #include "clang/Tooling/Tooling.h" @@ -373,6 +374,48 @@ testExpr(Id, "3;", run(SimpleFn), "Bound"); } +TEST_F(StencilTest, CatOfMacroRangeSucceeds) { + StringRef Snippet = R"cpp( +#define MACRO 3.77 + double foo(double d); + foo(MACRO);)cpp"; + + auto StmtMatch = + matchStmt(Snippet, callExpr(callee(functionDecl(hasName("foo"))), + argumentCountIs(1), + hasArgument(0, expr().bind("arg")))); + ASSERT_TRUE(StmtMatch); + Stencil S = cat(node("arg")); + EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("MACRO")); +} + +TEST_F(StencilTest, CatOfMacroArgRangeSucceeds) { + StringRef Snippet = R"cpp( +#define MACRO(a, b) a + b + MACRO(2, 3);)cpp"; + + auto StmtMatch = + matchStmt(Snippet, binaryOperator(hasRHS(expr().bind("rhs")))); + ASSERT_TRUE(StmtMatch); + Stencil S = cat(node("rhs")); + EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("3")); +} + +TEST_F(StencilTest, CatOfMacroArgSubRangeSucceeds) { + StringRef Snippet = R"cpp( +#define MACRO(a, b) a + b + int foo(int); + MACRO(2, foo(3));)cpp"; + + auto StmtMatch = matchStmt( + Snippet, binaryOperator(hasRHS(callExpr( + callee(functionDecl(hasName("foo"))), argumentCountIs(1), + hasArgument(0, expr().bind("arg")))))); + ASSERT_TRUE(StmtMatch); + Stencil S = cat(node("arg")); + EXPECT_THAT_EXPECTED(S->eval(StmtMatch->Result), HasValue("3")); +} + TEST_F(StencilTest, CatOfInvalidRangeFails) { StringRef Snippet = R"cpp( #define MACRO (3.77)