Index: lib/Parse/ParseObjc.cpp =================================================================== --- lib/Parse/ParseObjc.cpp +++ lib/Parse/ParseObjc.cpp @@ -1740,6 +1740,10 @@ } } + // ParseTypeName() can advance the token stream up to tok::eof when there's + // an umatched token (e.g. "["). Restore the state in case this happens. + TentativeParsingAction TPA(*this); + // Continue parsing type-names. do { Token CurTypeTok = Tok; @@ -1763,6 +1767,11 @@ } } while (TryConsumeToken(tok::comma)); + if (Tok.is(tok::eof)) + TPA.Revert(); + else + TPA.Commit(); + // Diagnose the mix between type args and protocols. if (foundProtocolId && foundValidTypeId) Actions.DiagnoseTypeArgsAndProtocols(foundProtocolId, foundProtocolSrcLoc, Index: test/SemaObjC/crash-on-type-args-protocols.m =================================================================== --- /dev/null +++ test/SemaObjC/crash-on-type-args-protocols.m @@ -0,0 +1,37 @@ +// RUN: %clang_cc1 -DFIRST -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSECOND -fsyntax-only -verify %s +// RUN: %clang_cc1 -DTHIRD -fsyntax-only -verify %s + +@protocol P; +@interface NSObject +@end +@protocol X +@end +@interface X : NSObject +@end + +@class A; + +#ifdef FIRST +id F1(id<[P> v) { // expected-error {{expected a type}} // expected-error {{use of undeclared identifier 'P'}} // expected-error {{use of undeclared identifier 'v'}} // expected-error {{expected '>'}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} + return 0; +} + +id F2(id v) { // expected-error {{unknown type name 'P'}} // expected-error {{unexpected interface name 'X': expected expression}} // expected-error {{use of undeclared identifier 'v'}} // expected-error {{expected '>'}} // expected-error {{unexpected interface name 'X': expected expression}} // expected-error {{use of undeclared identifier 'v'}} // expected-note {{to match this '('}} + return 0; +} +#endif + +#ifdef SECOND +id F3(id v) { // expected-error {{unknown type name 'P'}} // expected-error {{expected expression}} // expected-error {{use of undeclared identifier 'v'}} // expected-error {{expected '>'}} // expected-error {{expected expression}} // expected-error {{use of undeclared identifier 'v'}} // expected-note {{to match this '('}} + return 0; +} +#endif + +#ifdef THIRD +id F4(id v { // expected-error {{unknown type name 'P'}} // expected-error {{expected ')'}} // expected-error {{expected '>'}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} // expected-note {{to match this '('}} // expected-note {{to match this '('}} + return 0; +} +#endif + + // expected-error {{expected ')'}} // expected-error {{expected function body after function declarator}}