Skip to content

Commit 812012f

Browse files
committedJun 19, 2017
[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
1 parent 02e5d2a commit 812012f

File tree

3 files changed

+53
-1
lines changed

3 files changed

+53
-1
lines changed
 

Diff for: ‎clang/lib/Parse/ParseObjc.cpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -3627,6 +3627,14 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
36273627
SourceLocation OrigLoc = Tok.getLocation();
36283628

36293629
assert(!LM.Toks.empty() && "ParseLexedObjCMethodDef - Empty body!");
3630+
// Store an artificial EOF token to ensure that we don't run off the end of
3631+
// the method's body when we come to parse it.
3632+
Token Eof;
3633+
Eof.startToken();
3634+
Eof.setKind(tok::eof);
3635+
Eof.setEofData(MCDecl);
3636+
Eof.setLocation(OrigLoc);
3637+
LM.Toks.push_back(Eof);
36303638
// Append the current token at the end of the new token stream so that it
36313639
// doesn't get lost.
36323640
LM.Toks.push_back(Tok);
@@ -3658,7 +3666,7 @@ void Parser::ParseLexedObjCMethodDefs(LexedMethod &LM, bool parseMethod) {
36583666
Actions.ActOnDefaultCtorInitializers(MCDecl);
36593667
ParseFunctionStatementBody(MCDecl, BodyScope);
36603668
}
3661-
3669+
36623670
if (Tok.getLocation() != OrigLoc) {
36633671
// Due to parsing error, we either went over the cached tokens or
36643672
// 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) {
36703678
while (Tok.getLocation() != OrigLoc && Tok.isNot(tok::eof))
36713679
ConsumeAnyToken();
36723680
}
3681+
// Clean up the remaining EOF token.
3682+
ConsumeAnyToken();
36733683
}

Diff for: ‎clang/test/Parser/objc-at-implementation-eof-crash.m

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -verify -Wno-objc-root-class %s
2+
3+
@interface ClassA
4+
5+
- (void)fileExistsAtPath:(int)x;
6+
7+
@end
8+
9+
@interface ClassB
10+
11+
@end
12+
13+
@implementation ClassB // expected-note {{implementation started here}}
14+
15+
- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}}
16+
mgr fileExistsAtPath:0
17+
} // expected-error {{expected ']'}}
18+
19+
@implementation ClassC // expected-error {{missing '@end'}} // expected-error {{expected '}'}} // expected-warning {{cannot find interface declaration for 'ClassC'}}
20+
21+
@end

Diff for: ‎clang/test/Parser/objc-at-interface-eof-crash.m

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -verify -Wno-objc-root-class %s
2+
3+
@interface ClassA
4+
5+
- (void)fileExistsAtPath:(int)x;
6+
7+
@end
8+
9+
@interface ClassB
10+
11+
@end
12+
13+
@implementation ClassB // expected-note {{implementation started here}}
14+
15+
- (void) method:(ClassA *)mgr { // expected-note {{to match this '{'}}
16+
mgr fileExistsAtPath:0
17+
} // expected-error {{expected ']'}}
18+
19+
@interface ClassC // expected-error {{missing '@end'}} // expected-error {{expected '}'}}
20+
21+
@end

0 commit comments

Comments
 (0)
Please sign in to comment.