diff options
| author | Alex Lorenz <arphaman@gmail.com> | 2016-12-01 12:14:38 +0000 |
|---|---|---|
| committer | Alex Lorenz <arphaman@gmail.com> | 2016-12-01 12:14:38 +0000 |
| commit | a589abc35346747b10f55bcf6a839fab8d5f9e62 (patch) | |
| tree | a3e912fd5338716d405d668fab5b38ccf9d4a5fd /clang | |
| parent | 947650e99d60452259cc3b9601a11bca588972ec (diff) | |
| download | bcm5719-llvm-a589abc35346747b10f55bcf6a839fab8d5f9e62.tar.gz bcm5719-llvm-a589abc35346747b10f55bcf6a839fab8d5f9e62.zip | |
[ObjC] Avoid a @try/@finally/@autoreleasepool fixit when parsing an expression
This patch ensures that the typo fixit for the @try/@finally/@autoreleasepool {}
directive is shown only when we're parsing an actual statement where such
directives can actually be present.
rdar://19669565
Differential Revision: https://reviews.llvm.org/D26916
llvm-svn: 288334
Diffstat (limited to 'clang')
| -rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 7 | ||||
| -rw-r--r-- | clang/test/Parser/objc-at-directive-fixit.m | 28 |
2 files changed, 34 insertions, 1 deletions
diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 42081a29ad9..81761bf8d2d 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -2773,6 +2773,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { return Actions.ActOnNullStmt(Tok.getLocation()); } + ExprStatementTokLoc = AtLoc; ExprResult Res(ParseExpressionWithLeadingAt(AtLoc)); if (Res.isInvalid()) { // If the expression is invalid, skip ahead to the next semicolon. Not @@ -2869,7 +2870,11 @@ ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { return ParseAvailabilityCheckExpr(AtLoc); default: { const char *str = nullptr; - if (GetLookAheadToken(1).is(tok::l_brace)) { + // Only provide the @try/@finally/@autoreleasepool fixit when we're sure + // that this is a proper statement where such directives could actually + // occur. + if (GetLookAheadToken(1).is(tok::l_brace) && + ExprStatementTokLoc == AtLoc) { char ch = Tok.getIdentifierInfo()->getNameStart()[0]; str = ch == 't' ? "try" diff --git a/clang/test/Parser/objc-at-directive-fixit.m b/clang/test/Parser/objc-at-directive-fixit.m new file mode 100644 index 00000000000..dcf695d3aaa --- /dev/null +++ b/clang/test/Parser/objc-at-directive-fixit.m @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.10.0 -verify -fobjc-exceptions %s +// RUN: not %clang_cc1 -fsyntax-only -triple x86_64-apple-macosx10.10.0 -fdiagnostics-parseable-fixits -fobjc-exceptions %s 2>&1 | FileCheck %s + +// rdar://19669565 + +void bar(int x); + +void f() { + @try { } + @finally { } + @autoreleasepool { } + + // Provide a fixit when we are parsing a standalone statement + @tr { }; // expected-error {{unexpected '@' in program}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:6}:"try" + @finaly { }; // expected-error {{unexpected '@' in program}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:10}:"finally" + @autorelpool { }; // expected-error {{unexpected '@' in program}} + // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:4-[[@LINE-1]]:15}:"autoreleasepool" + + // Ensure that no fixit is given when parsing expressions + // CHECK-NOT: fix-it + id thing = @autoreleasepool { }; // expected-error {{unexpected '@' in program}} + (void)@tr { }; // expected-error {{unexpected '@' in program}} + bar(@final { }); // expected-error {{unexpected '@' in program}} + for(@auto;;) { } // expected-error {{unexpected '@' in program}} + [@try]; // expected-error {{unexpected '@' in program}} +} |

