arphaman created this revision.
arphaman added reviewers: manmanren, bruno.
arphaman added a subscriber: cfe-commits.
arphaman set the repository for this revision to rL LLVM.
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.
Repository:
rL LLVM
https://reviews.llvm.org/D26916
Files:
lib/Parse/ParseObjc.cpp
test/Parser/objc-at-directive-fixit.m
Index: test/Parser/objc-at-directive-fixit.m
===================================================================
--- /dev/null
+++ 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}}
+}
Index: lib/Parse/ParseObjc.cpp
===================================================================
--- lib/Parse/ParseObjc.cpp
+++ lib/Parse/ParseObjc.cpp
@@ -2773,6 +2773,7 @@
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 @@
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"
Index: test/Parser/objc-at-directive-fixit.m
===================================================================
--- /dev/null
+++ 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}}
+}
Index: lib/Parse/ParseObjc.cpp
===================================================================
--- lib/Parse/ParseObjc.cpp
+++ lib/Parse/ParseObjc.cpp
@@ -2773,6 +2773,7 @@
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 @@
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"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits