]> granicus.if.org Git - clang/commitdiff
Comment parsing: don't crash while parsing \deprecated in a standalone comment
authorDmitri Gribenko <gribozavr@gmail.com>
Mon, 27 Jan 2014 17:55:43 +0000 (17:55 +0000)
committerDmitri Gribenko <gribozavr@gmail.com>
Mon, 27 Jan 2014 17:55:43 +0000 (17:55 +0000)
(comment without a decl).

I think this can not happen during normal compilation with -Wdocumentation,
only while using Clang APIs to parse comments outside of a source file.

Based on a patch by Olivier Goffart.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@200230 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/CommentSema.cpp
unittests/AST/CommentParser.cpp

index 450325f91dcb041ce7de50ed16a7ce9a9e45f9d5..0ae00820fde6df6c9f27fa1216e02e2033cadddf 100644 (file)
@@ -68,8 +68,12 @@ void Sema::actOnBlockCommandFinish(BlockCommandComment *Command,
   Command->setParagraph(Paragraph);
   checkBlockCommandEmptyParagraph(Command);
   checkBlockCommandDuplicate(Command);
-  checkReturnsCommand(Command);
-  checkDeprecatedCommand(Command);
+  if (ThisDeclInfo) {
+    // These checks only make sense if the comment is attached to a
+    // declaration.
+    checkReturnsCommand(Command);
+    checkDeprecatedCommand(Command);
+  }
 }
 
 ParamCommandComment *Sema::actOnParamCommandStart(
@@ -558,6 +562,9 @@ void Sema::checkBlockCommandEmptyParagraph(BlockCommandComment *Command) {
 void Sema::checkReturnsCommand(const BlockCommandComment *Command) {
   if (!Traits.getCommandInfo(Command->getCommandID())->IsReturnsCommand)
     return;
+
+  assert(ThisDeclInfo && "should not call this check on a bare comment");
+
   if (isFunctionDecl()) {
     if (ThisDeclInfo->ReturnType->isVoidType()) {
       unsigned DiagKind;
@@ -636,6 +643,8 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) {
   if (!Traits.getCommandInfo(Command->getCommandID())->IsDeprecatedCommand)
     return;
 
+  assert(ThisDeclInfo && "should not call this check on a bare comment");
+
   const Decl *D = ThisDeclInfo->CommentDecl;
   if (!D)
     return;
index f75c636e01dd6ee2320369f9fedac10d7dbce3b5..c72aef107f511a6bbcaa9eb3e6ce87c711c36fd4 100644 (file)
@@ -1420,6 +1420,26 @@ TEST_F(CommentParserTest, VerbatimLine2) {
   }
 }
 
+TEST_F(CommentParserTest, Deprecated) {
+  const char *Sources[] = {
+    "/** @deprecated*/",
+    "/// @deprecated\n"
+  };
+
+  for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
+    FullComment *FC = parseString(Sources[i]);
+    ASSERT_TRUE(HasChildCount(FC, 2));
+
+    ASSERT_TRUE(HasParagraphCommentAt(FC, 0, " "));
+    {
+      BlockCommandComment *BCC;
+      ParagraphComment *PC;
+      ASSERT_TRUE(HasBlockCommandAt(FC, Traits, 1, BCC, "deprecated", PC));
+      ASSERT_TRUE(HasChildCount(PC, 0));
+    }
+  }
+}
+
 } // unnamed namespace
 
 } // end namespace comments