diff options
-rw-r--r-- | include/clang/AST/CommentParser.h | 5 | ||||
-rw-r--r-- | lib/AST/CommentParser.cpp | 29 | ||||
-rw-r--r-- | test/Analysis/temp-obj-dtors-cfg-output.cpp | 1 | ||||
-rw-r--r-- | test/Sema/warn-documentation.cpp | 28 |
4 files changed, 57 insertions, 6 deletions
diff --git a/include/clang/AST/CommentParser.h b/include/clang/AST/CommentParser.h index 5f6e0c56e2..8bf629b45e 100644 --- a/include/clang/AST/CommentParser.h +++ b/include/clang/AST/CommentParser.h @@ -86,6 +86,11 @@ class Parser { Tok = Toks[0]; } + bool isTokBlockCommand() { + return Tok.is(tok::command) && + Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand; + } + public: Parser(Lexer &L, Sema &S, llvm::BumpPtrAllocator &Allocator, const SourceManager &SourceMgr, DiagnosticsEngine &Diags, diff --git a/lib/AST/CommentParser.cpp b/lib/AST/CommentParser.cpp index a7ba013efc..5f45125bdc 100644 --- a/lib/AST/CommentParser.cpp +++ b/lib/AST/CommentParser.cpp @@ -329,8 +329,7 @@ BlockCommandComment *Parser::parseBlockCommand() { } consumeToken(); - if (Tok.is(tok::command) && - Traits.getCommandInfo(Tok.getCommandID())->IsBlockCommand) { + if (isTokBlockCommand()) { // Block command ahead. We can't nest block commands, so pretend that this // command has an empty argument. ParagraphComment *Paragraph = S.actOnParagraphComment( @@ -362,10 +361,28 @@ BlockCommandComment *Parser::parseBlockCommand() { Retokenizer.putBackLeftoverTokens(); } - BlockContentComment *Block = parseParagraphOrBlockCommand(); - // Since we have checked for a block command, we should have parsed a - // paragraph. - ParagraphComment *Paragraph = cast<ParagraphComment>(Block); + // If there's a block command ahead, we will attach an empty paragraph to + // this command. + bool EmptyParagraph = false; + if (isTokBlockCommand()) + EmptyParagraph = true; + else if (Tok.is(tok::newline)) { + Token PrevTok = Tok; + consumeToken(); + EmptyParagraph = isTokBlockCommand(); + putBack(PrevTok); + } + + ParagraphComment *Paragraph; + if (EmptyParagraph) + Paragraph = S.actOnParagraphComment(ArrayRef<InlineContentComment *>()); + else { + BlockContentComment *Block = parseParagraphOrBlockCommand(); + // Since we have checked for a block command, we should have parsed a + // paragraph. + Paragraph = cast<ParagraphComment>(Block); + } + if (IsParam) { S.actOnParamCommandFinish(PC, Paragraph); return PC; diff --git a/test/Analysis/temp-obj-dtors-cfg-output.cpp b/test/Analysis/temp-obj-dtors-cfg-output.cpp index df9d906c98..c8844754be 100644 --- a/test/Analysis/temp-obj-dtors-cfg-output.cpp +++ b/test/Analysis/temp-obj-dtors-cfg-output.cpp @@ -1,6 +1,7 @@ // RUN: rm -f %t // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCFG -analyzer-config cfg-temporary-dtors=true %s > %t 2>&1 // RUN: FileCheck --input-file=%t %s +// XPASS: * class A { public: diff --git a/test/Sema/warn-documentation.cpp b/test/Sema/warn-documentation.cpp index 5678fd94cb..6a6b8dd599 100644 --- a/test/Sema/warn-documentation.cpp +++ b/test/Sema/warn-documentation.cpp @@ -836,3 +836,31 @@ typedef const struct test_nocrash7 * test_nocrash8; /// aaa \unknown aaa \unknown aaa int test_nocrash9; + +// We used to crash on this. PR15068 + +// expected-warning@+2 {{empty paragraph passed to '\param' command}} +// expected-warning@+2 {{empty paragraph passed to '\param' command}} +///@param x +///@param y +int test_nocrash10(int x, int y); + +// expected-warning@+2 {{empty paragraph passed to '\param' command}} expected-warning@+2 {{parameter 'x' not found in the function declaration}} +// expected-warning@+2 {{empty paragraph passed to '\param' command}} expected-warning@+2 {{parameter 'y' not found in the function declaration}} +///@param x +///@param y +int test_nocrash11(); + +// expected-warning@+3 {{empty paragraph passed to '\param' command}} expected-warning@+3 {{parameter 'x' not found in the function declaration}} +// expected-warning@+3 {{empty paragraph passed to '\param' command}} expected-warning@+3 {{parameter 'y' not found in the function declaration}} +/** +@param x +@param y +**/ +int test_nocrash12(); + +// expected-warning@+2 {{empty paragraph passed to '\param' command}} +// expected-warning@+1 {{empty paragraph passed to '\param' command}} +///@param x@param y +int test_nocrash13(int x, int y); + |