From 9f08f49929324ec6863e81b22a43fb2e8575b433 Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Fri, 20 Jul 2012 20:18:53 +0000 Subject: [PATCH] Fix PR13411: Comment parsing: failed assertion on unterminated verbatim block. The assertion was wrong in case we have a verbatim block without a closing command. Also add tests for closing command name in a verbatim block, since now it can be empty in such cases. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@160568 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/CommentParser.cpp | 15 ++++--- test/Sema/warn-documentation.cpp | 6 +++ unittests/AST/CommentParser.cpp | 73 +++++++++++++++++++++++++------- 3 files changed, 74 insertions(+), 20 deletions(-) diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp index d4b9708778..6b7e0ab49d 100644 --- a/lib/AST/CommentParser.cpp +++ b/lib/AST/CommentParser.cpp @@ -378,11 +378,16 @@ VerbatimBlockComment *Parser::parseVerbatimBlock() { Lines.push_back(Line); } - assert(Tok.is(tok::verbatim_block_end)); - VB = S.actOnVerbatimBlockFinish(VB, Tok.getLocation(), - Tok.getVerbatimBlockName(), - copyArray(llvm::makeArrayRef(Lines))); - consumeToken(); + if (Tok.is(tok::verbatim_block_end)) { + VB = S.actOnVerbatimBlockFinish(VB, Tok.getLocation(), + Tok.getVerbatimBlockName(), + copyArray(llvm::makeArrayRef(Lines))); + consumeToken(); + } else { + // Unterminated \\verbatim block + VB = S.actOnVerbatimBlockFinish(VB, SourceLocation(), "", + copyArray(llvm::makeArrayRef(Lines))); + } return VB; } diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index aec914a7cd..69e12b5097 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -276,3 +276,9 @@ namespace test_attach24 { } } +// PR13411, reduced. We used to crash on this. +/** + * @code Aaa. + */ +void test_nocrash1(int); + diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp index 5f91947f0b..2c2175070c 100644 --- a/unittests/AST/CommentParser.cpp +++ b/unittests/AST/CommentParser.cpp @@ -388,7 +388,8 @@ struct NoAttrs {}; ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, size_t Idx, VerbatimBlockComment *&VBC, - StringRef Name) { + StringRef Name, + StringRef CloseName) { ::testing::AssertionResult AR = GetChildAt(C, Idx, VBC); if (!AR) return AR; @@ -399,17 +400,27 @@ struct NoAttrs {}; << "VerbatimBlockComment has name \"" << ActualName.str() << "\", " "expected \"" << Name.str() << "\""; + StringRef ActualCloseName = VBC->getCloseName(); + if (ActualCloseName != CloseName) + return ::testing::AssertionFailure() + << "VerbatimBlockComment has closing command name \"" + << ActualCloseName.str() << "\", " + "expected \"" << CloseName.str() << "\""; + return ::testing::AssertionSuccess(); } struct NoLines {}; +struct Lines {}; ::testing::AssertionResult HasVerbatimBlockAt(const Comment *C, size_t Idx, VerbatimBlockComment *&VBC, StringRef Name, + StringRef CloseName, NoLines) { - ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name); + ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name, + CloseName); if (!AR) return AR; @@ -425,8 +436,11 @@ struct NoLines {}; size_t Idx, VerbatimBlockComment *&VBC, StringRef Name, + StringRef CloseName, + Lines, StringRef Line0) { - ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name); + ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name, + CloseName); if (!AR) return AR; @@ -448,9 +462,12 @@ struct NoLines {}; size_t Idx, VerbatimBlockComment *&VBC, StringRef Name, + StringRef CloseName, + Lines, StringRef Line0, StringRef Line1) { - ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name); + ::testing::AssertionResult AR = HasVerbatimBlockAt(C, Idx, VBC, Name, + CloseName); if (!AR) return AR; @@ -994,7 +1011,8 @@ TEST_F(CommentParserTest, VerbatimBlock1) { } { VerbatimBlockComment *VCC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VCC, "verbatim", NoLines())); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VCC, "verbatim", "endverbatim", + NoLines())); } } @@ -1013,11 +1031,32 @@ TEST_F(CommentParserTest, VerbatimBlock2) { } { VerbatimBlockComment *VBC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", " Aaa ")); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim", + Lines(), " Aaa ")); } } TEST_F(CommentParserTest, VerbatimBlock3) { + const char *Source = "// \\verbatim Aaa\n"; + + FullComment *FC = parseString(Source); + ASSERT_TRUE(HasChildCount(FC, 2)); + + { + ParagraphComment *PC; + ASSERT_TRUE(GetChildAt(FC, 0, PC)); + + ASSERT_TRUE(HasChildCount(PC, 1)); + ASSERT_TRUE(HasTextAt(PC, 0, " ")); + } + { + VerbatimBlockComment *VBC; + ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "", + Lines(), " Aaa")); + } +} + +TEST_F(CommentParserTest, VerbatimBlock4) { const char *Source = "//\\verbatim\n" "//\\endverbatim\n"; @@ -1027,11 +1066,12 @@ TEST_F(CommentParserTest, VerbatimBlock3) { { VerbatimBlockComment *VBC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", NoLines())); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim", + NoLines())); } } -TEST_F(CommentParserTest, VerbatimBlock4) { +TEST_F(CommentParserTest, VerbatimBlock5) { const char *Sources[] = { "//\\verbatim\n" "// Aaa\n" @@ -1048,12 +1088,13 @@ TEST_F(CommentParserTest, VerbatimBlock4) { { VerbatimBlockComment *VBC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", " Aaa")); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 0, VBC, "verbatim", "endverbatim", + Lines(), " Aaa")); } } } -TEST_F(CommentParserTest, VerbatimBlock5) { +TEST_F(CommentParserTest, VerbatimBlock6) { const char *Sources[] = { "// \\verbatim\n" "// Aaa\n" @@ -1077,12 +1118,13 @@ TEST_F(CommentParserTest, VerbatimBlock5) { } { VerbatimBlockComment *VBC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", " Aaa")); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim", + Lines(), " Aaa")); } } } -TEST_F(CommentParserTest, VerbatimBlock6) { +TEST_F(CommentParserTest, VerbatimBlock7) { const char *Sources[] = { "// \\verbatim\n" "// Aaa\n" @@ -1108,12 +1150,13 @@ TEST_F(CommentParserTest, VerbatimBlock6) { } { VerbatimBlockComment *VBC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", " Aaa", " Bbb")); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim", + Lines(), " Aaa", " Bbb")); } } } -TEST_F(CommentParserTest, VerbatimBlock7) { +TEST_F(CommentParserTest, VerbatimBlock8) { const char *Sources[] = { "// \\verbatim\n" "// Aaa\n" @@ -1140,7 +1183,7 @@ TEST_F(CommentParserTest, VerbatimBlock7) { } { VerbatimBlockComment *VBC; - ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim")); + ASSERT_TRUE(HasVerbatimBlockAt(FC, 1, VBC, "verbatim", "endverbatim")); ASSERT_EQ(3U, VBC->getNumLines()); ASSERT_EQ(" Aaa", VBC->getText(0)); ASSERT_EQ("", VBC->getText(1)); -- 2.50.1