This patch fixes a Clang crash that happens when an Objective-C source code contains an @interface/@implementation declaration that follows unterminated @implementation declaration that contains a method with a message send that doesn't have the ']'. The crash happens because the @interface/@implementation parsing methods encounter an unexpected EOF that is caused by parser's attempt to recover from the missing ']' by skipping to the next ']'/';' (it reaches EOF instead since these tokens are not present).
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
This patch fixes the crash and that is fine, but the users might find the last error ("expected '}'" at the end of the file) confusing. This seems to happen because Parser::ParseLexedObjCMethodDefs consumes all tokens in the file until it sees the EOF after consuming all the cached tokens of LexedMethod.
I wonder whether we can insert a fake EOF token to prevent ParseLexedObjCMethodDefs from going all the way to the end, just like ParseCXXNonStaticMemberInitialize does. Do you think that would work or would it be too hackish?
I think that it would probably work quite well. I've thought about fixing it while working on a patch as well, but didn't realize that we could just inject EOF into the token stream. I will update this patch with this kind of handling then.
Use the 'Eof' token to make sure that the "expected '}'" error is presented not at the end of the file, but at the start of the @interface/@implementation.
lib/Parse/ParseObjc.cpp | ||
---|---|---|
220 ↗ | (On Diff #102718) | Do you need this check here (and below)? |
3674 ↗ | (On Diff #102718) | I think you want to clean up the EOF token after the code below which skips the leftover tokens, regardless of whether Tok is EOF. You can do it unconditionally since Tok.getLocation() == OrigLoc and you know the token is the EOF inserted above. |
Thanks, LGTM.
lib/Parse/ParseObjc.cpp | ||
---|---|---|
3636 ↗ | (On Diff #103013) | You can use OrigLoc instead of calling Tok.getLocation(). |