This revision was landed with ongoing or failed builds. This revision was automatically updated to reflect the committed changes. Closed by commit rG5331e1229aa6: [clang][transformer] Fix crash on replacement-less ASTEdit. (authored by courbet).
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D128887/new/ https://reviews.llvm.org/D128887 Files: clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp clang/lib/Tooling/Transformer/RewriteRule.cpp Index: clang/lib/Tooling/Transformer/RewriteRule.cpp =================================================================== --- clang/lib/Tooling/Transformer/RewriteRule.cpp +++ clang/lib/Tooling/Transformer/RewriteRule.cpp @@ -50,17 +50,21 @@ // produces a bad range, whereas the latter will simply ignore A. if (!EditRange) return SmallVector<Edit, 0>(); - auto Replacement = E.Replacement->eval(Result); - if (!Replacement) - return Replacement.takeError(); - auto Metadata = E.Metadata(Result); - if (!Metadata) - return Metadata.takeError(); transformer::Edit T; T.Kind = E.Kind; T.Range = *EditRange; - T.Replacement = std::move(*Replacement); - T.Metadata = std::move(*Metadata); + if (E.Replacement) { + auto Replacement = E.Replacement->eval(Result); + if (!Replacement) + return Replacement.takeError(); + T.Replacement = std::move(*Replacement); + } + if (E.Metadata) { + auto Metadata = E.Metadata(Result); + if (!Metadata) + return Metadata.takeError(); + T.Metadata = std::move(*Metadata); + } Edits.push_back(std::move(T)); } return Edits; Index: clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp =================================================================== --- clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp +++ clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp @@ -90,6 +90,32 @@ EXPECT_EQ(Errors[0].Message.FileOffset, 10U); } +transformer::ASTEdit noReplacementEdit(transformer::RangeSelector Target) { + transformer::ASTEdit E; + E.TargetRange = std::move(Target); + return E; +} + +TEST(TransformerClangTidyCheckTest, EmptyReplacement) { + class DiagOnlyCheck : public TransformerClangTidyCheck { + public: + DiagOnlyCheck(StringRef Name, ClangTidyContext *Context) + : TransformerClangTidyCheck( + makeRule(returnStmt(), edit(noReplacementEdit(node(RootID))), + cat("message")), + Name, Context) {} + }; + std::string Input = "int h() { return 5; }"; + std::vector<ClangTidyError> Errors; + EXPECT_EQ("int h() { }", test::runCheckOnCode<DiagOnlyCheck>(Input, &Errors)); + EXPECT_EQ(Errors.size(), 1U); + EXPECT_EQ(Errors[0].Message.Message, "message"); + EXPECT_THAT(Errors[0].Message.Ranges, testing::IsEmpty()); + + // The diagnostic is anchored to the match, "return 5". + EXPECT_EQ(Errors[0].Message.FileOffset, 10U); +} + TEST(TransformerClangTidyCheckTest, DiagnosticMessageEscaped) { class GiveDiagWithPercentSymbol : public TransformerClangTidyCheck { public:
Index: clang/lib/Tooling/Transformer/RewriteRule.cpp =================================================================== --- clang/lib/Tooling/Transformer/RewriteRule.cpp +++ clang/lib/Tooling/Transformer/RewriteRule.cpp @@ -50,17 +50,21 @@ // produces a bad range, whereas the latter will simply ignore A. if (!EditRange) return SmallVector<Edit, 0>(); - auto Replacement = E.Replacement->eval(Result); - if (!Replacement) - return Replacement.takeError(); - auto Metadata = E.Metadata(Result); - if (!Metadata) - return Metadata.takeError(); transformer::Edit T; T.Kind = E.Kind; T.Range = *EditRange; - T.Replacement = std::move(*Replacement); - T.Metadata = std::move(*Metadata); + if (E.Replacement) { + auto Replacement = E.Replacement->eval(Result); + if (!Replacement) + return Replacement.takeError(); + T.Replacement = std::move(*Replacement); + } + if (E.Metadata) { + auto Metadata = E.Metadata(Result); + if (!Metadata) + return Metadata.takeError(); + T.Metadata = std::move(*Metadata); + } Edits.push_back(std::move(T)); } return Edits; Index: clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp =================================================================== --- clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp +++ clang-tools-extra/unittests/clang-tidy/TransformerClangTidyCheckTest.cpp @@ -90,6 +90,32 @@ EXPECT_EQ(Errors[0].Message.FileOffset, 10U); } +transformer::ASTEdit noReplacementEdit(transformer::RangeSelector Target) { + transformer::ASTEdit E; + E.TargetRange = std::move(Target); + return E; +} + +TEST(TransformerClangTidyCheckTest, EmptyReplacement) { + class DiagOnlyCheck : public TransformerClangTidyCheck { + public: + DiagOnlyCheck(StringRef Name, ClangTidyContext *Context) + : TransformerClangTidyCheck( + makeRule(returnStmt(), edit(noReplacementEdit(node(RootID))), + cat("message")), + Name, Context) {} + }; + std::string Input = "int h() { return 5; }"; + std::vector<ClangTidyError> Errors; + EXPECT_EQ("int h() { }", test::runCheckOnCode<DiagOnlyCheck>(Input, &Errors)); + EXPECT_EQ(Errors.size(), 1U); + EXPECT_EQ(Errors[0].Message.Message, "message"); + EXPECT_THAT(Errors[0].Message.Ranges, testing::IsEmpty()); + + // The diagnostic is anchored to the match, "return 5". + EXPECT_EQ(Errors[0].Message.FileOffset, 10U); +} + TEST(TransformerClangTidyCheckTest, DiagnosticMessageEscaped) { class GiveDiagWithPercentSymbol : public TransformerClangTidyCheck { public:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits