From: Argyrios Kyrtzidis Date: Sat, 17 Dec 2011 04:13:18 +0000 (+0000) Subject: After late parsing an objc method, make sure there are no leftover cached tokens, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a24195aaf71cee202f92ea4bad50358f3d0b701f;p=clang After late parsing an objc method, make sure there are no leftover cached tokens, because the memory associated with them is going to get released. We also don't want them to affect later parsing. (We do the same for C++ inline methods.) The underlying cause for the leftover tokens is going to be addressed in the next commit. Couldn't get a test case for the crash though. rdar://10583033. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@146814 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 5ac1d6c331..56d5c57c05 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -2564,7 +2564,10 @@ ExprResult Parser::ParseObjCSelectorExpression(SourceLocation AtLoc) { } Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) { - + + // Save the current token position. + SourceLocation OrigLoc = Tok.getLocation(); + assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!"); // Append the current token at the end of the new token stream so that it // doesn't get lost. @@ -2603,5 +2606,19 @@ Decl *Parser::ParseLexedObjCMethodDefs(LexedMethod &LM) { // Leave the function body scope. BodyScope.Exit(); - return Actions.ActOnFinishFunctionBody(MDecl, FnBody.take()); + MDecl = Actions.ActOnFinishFunctionBody(MDecl, FnBody.take()); + + if (Tok.getLocation() != OrigLoc) { + // Due to parsing error, we either went over the cached tokens or + // there are still cached tokens left. If it's the latter case skip the + // leftover tokens. + // Since this is an uncommon situation that should be avoided, use the + // expensive isBeforeInTranslationUnit call. + if (PP.getSourceManager().isBeforeInTranslationUnit(Tok.getLocation(), + OrigLoc)) + while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof)) + ConsumeAnyToken(); + } + + return MDecl; }