diff --git a/clang/include/clang/AST/CommentLexer.h b/clang/include/clang/AST/CommentLexer.h index 99b95d340497..f2636973ff27 100644 --- a/clang/include/clang/AST/CommentLexer.h +++ b/clang/include/clang/AST/CommentLexer.h @@ -34,8 +34,8 @@ enum TokenKind { eof, newline, text, - unknown_command, - command, + unknown_command, // Command that does not have an ID. + command, // Command with an ID. verbatim_block_begin, verbatim_block_line, verbatim_block_end, diff --git a/clang/include/clang/AST/CommentSema.h b/clang/include/clang/AST/CommentSema.h index 5ebf5f0afac7..c913d28daeff 100644 --- a/clang/include/clang/AST/CommentSema.h +++ b/clang/include/clang/AST/CommentSema.h @@ -139,7 +139,11 @@ public: InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name); + StringRef CommandName); + + InlineContentComment *actOnUnknownCommand(SourceLocation LocBegin, + SourceLocation LocEnd, + unsigned CommandID); TextComment *actOnText(SourceLocation LocBegin, SourceLocation LocEnd, diff --git a/clang/lib/AST/CommentCommandTraits.cpp b/clang/lib/AST/CommentCommandTraits.cpp index ba0aa9ae12ef..e7e40fd1090f 100644 --- a/clang/lib/AST/CommentCommandTraits.cpp +++ b/clang/lib/AST/CommentCommandTraits.cpp @@ -40,6 +40,7 @@ const CommandInfo *CommandTraits::registerUnknownCommand(StringRef CommandName) CommandInfo *Info = new (Allocator) CommandInfo(); Info->Name = Name; Info->ID = NextID++; + Info->IsUnknownCommand = true; RegisteredCommands.push_back(Info); diff --git a/clang/lib/AST/CommentParser.cpp b/clang/lib/AST/CommentParser.cpp index f6acd9645fb5..d053dc0f1800 100644 --- a/clang/lib/AST/CommentParser.cpp +++ b/clang/lib/AST/CommentParser.cpp @@ -554,6 +554,13 @@ BlockContentComment *Parser::parseParagraphOrBlockCommand() { return parseBlockCommand(); break; // Block command ahead, finish this parapgaph. } + if (Info->IsUnknownCommand) { + Content.push_back(S.actOnUnknownCommand(Tok.getLocation(), + Tok.getEndLocation(), + Info->getID())); + consumeToken(); + continue; + } assert(Info->IsInlineCommand); Content.push_back(parseInlineCommand()); continue; diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp index e57dac71044d..477717f735ef 100644 --- a/clang/lib/AST/CommentSema.cpp +++ b/clang/lib/AST/CommentSema.cpp @@ -272,9 +272,15 @@ InlineCommandComment *Sema::actOnInlineCommand(SourceLocation CommandLocBegin, InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, SourceLocation LocEnd, - StringRef Name) { + StringRef CommandName) { + unsigned CommandID = Traits.registerUnknownCommand(CommandName)->getID(); + return actOnUnknownCommand(LocBegin, LocEnd, CommandID); +} + +InlineContentComment *Sema::actOnUnknownCommand(SourceLocation LocBegin, + SourceLocation LocEnd, + unsigned CommandID) { ArrayRef Args; - unsigned CommandID = Traits.registerUnknownCommand(Name)->getID(); return new (Allocator) InlineCommandComment( LocBegin, LocEnd, CommandID, InlineCommandComment::RenderNormal, diff --git a/clang/test/Sema/warn-documentation.cpp b/clang/test/Sema/warn-documentation.cpp index 80880d453a4f..28544e0a81b1 100644 --- a/clang/test/Sema/warn-documentation.cpp +++ b/clang/test/Sema/warn-documentation.cpp @@ -761,3 +761,8 @@ inline void test_nocrash6() */ typedef const struct test_nocrash7 * test_nocrash8; +// We used to crash on this. + +/// aaa \unknown aaa \unknown aaa +int test_nocrash9; +