Skip to content

Commit

Permalink
[ObjC] Avoid a @try/@finally/@autoreleasepool fixit when parsing an e…
Browse files Browse the repository at this point in the history
…xpression

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
  • Loading branch information
hyp committed Dec 1, 2016
1 parent 947650e commit a589abc
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
7 changes: 6 additions & 1 deletion clang/lib/Parse/ParseObjc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
28 changes: 28 additions & 0 deletions clang/test/Parser/objc-at-directive-fixit.m
Original file line number Diff line number Diff line change
@@ -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}}
}

0 comments on commit a589abc

Please sign in to comment.