forked from OSchip/llvm-project
[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:
parent
02e5d2a6cb
commit
812012f3c9
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
|
@ -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
|
Loading…
Reference in New Issue