[Parser][ObjC] Use an artificial EOF token while parsing lexed ObjC methods

This change avoid a crash that occurred when skipping to EOF while parsing an
ObjC interface/implementation.

rdar://31963299

Differential Revision: https://reviews.llvm.org/D34185

llvm-svn: 305719
This commit is contained in:
Alex Lorenz 2017-06-19 17:53:21 +00:00
parent 02e5d2a6cb
commit 812012f3c9
3 changed files with 53 additions and 1 deletions

View File

@ -3627,6 +3627,14 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
SourceLocation OrigLoc = Tok.getLocation();
assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
// Store an artificial EOF token to ensure that we don't run off the end of
// the method's body when we come to parse it.
Token Eof;
Eof.startToken();
Eof.setKind(tok::eof);
Eof.setEofData(MCDecl);
Eof.setLocation(OrigLoc);
LM.Toks.push_back(Eof);
// Append the current token at the end of the new token stream so that it
// doesn't get lost.
LM.Toks.push_back(Tok);
@ -3658,7 +3666,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
Actions.ActOnDefaultCtorInitializers(MCDecl);
ParseFunctionStatementBody(MCDecl, BodyScope);
}
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
@ -3670,4 +3678,6 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
ConsumeAnyToken();
}
// Clean up the remaining EOF token.
ConsumeAnyToken();
}

View File

@ -0,0 +1,21 @@
// RUN: %clang_cc1 -verify -Wno-objc-root-class %s
@interface ClassA
- (void)fileExistsAtPath:(int)x;
@end
@interface ClassB
@end
@implementation ClassB // expected-note {{implementation started here}}
- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}}
mgr fileExistsAtPath:0
} // expected-error {{expected ']'}}
@implementation ClassC // expected-error {{missing '@end'}} // expected-error {{expected '}'}} // expected-warning {{cannot find interface declaration for 'ClassC'}}
@end

View File

@ -0,0 +1,21 @@
// RUN: %clang_cc1 -verify -Wno-objc-root-class %s
@interface ClassA
- (void)fileExistsAtPath:(int)x;
@end
@interface ClassB
@end
@implementation ClassB // expected-note {{implementation started here}}
- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}}
mgr fileExistsAtPath:0
} // expected-error {{expected ']'}}
@interface ClassC // expected-error {{missing '@end'}} // expected-error {{expected '}'}}
@end