diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Parse/ParseDecl.cpp | 3 | ||||
-rw-r--r-- | clang/lib/Parse/ParseObjc.cpp | 9 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 4 | ||||
-rw-r--r-- | clang/test/SemaObjC/crash-on-type-args-protocols.m | 40 |
4 files changed, 54 insertions, 2 deletions
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 71cbc451e1c..1dfa2f4e7c1 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -5877,7 +5877,8 @@ bool Parser::isFunctionDeclaratorIdentifierList() { // To handle this, we check to see if the token after the first // identifier is a "," or ")". Only then do we parse it as an // identifier list. - && (NextToken().is(tok::comma) || NextToken().is(tok::r_paren)); + && (!Tok.is(tok::eof) && + (NextToken().is(tok::comma) || NextToken().is(tok::r_paren))); } /// ParseFunctionDeclaratorIdentifierList - While parsing a function declarator diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index b5569950020..ecf8ae8dffc 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -344,9 +344,11 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, protocols, protocolLocs, EndProtoLoc, /*consumeLastToken=*/true, /*warnOnIncompleteProtocols=*/true); + if (Tok.is(tok::eof)) + return nullptr; } } - + // Next, we need to check for any protocol references. if (LAngleLoc.isValid()) { if (!ProtocolIdents.empty()) { @@ -1814,6 +1816,8 @@ void Parser::parseObjCTypeArgsAndProtocolQualifiers( protocolRAngleLoc, consumeLastToken, /*warnOnIncompleteProtocols=*/false); + if (Tok.is(tok::eof)) // Nothing else to do here... + return; // An Objective-C object pointer followed by type arguments // can then be followed again by a set of protocol references, e.g., @@ -1862,6 +1866,9 @@ TypeResult Parser::parseObjCTypeArgsAndProtocolQualifiers( protocols, protocolLocs, protocolRAngleLoc, consumeLastToken); + if (Tok.is(tok::eof)) + return true; // Invalid type result. + // Compute the location of the last token. if (consumeLastToken) endLoc = PrevTokLocation; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 8cc97e5f0d7..78eba62695d 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -1539,6 +1539,8 @@ Parser::TryAnnotateName(bool IsAddressOfOperand, NewEndLoc); if (NewType.isUsable()) Ty = NewType.get(); + else if (Tok.is(tok::eof)) // Nothing to do here, bail out... + return ANK_Error; } Tok.setKind(tok::annot_typename); @@ -1770,6 +1772,8 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(bool EnteringContext, NewEndLoc); if (NewType.isUsable()) Ty = NewType.get(); + else if (Tok.is(tok::eof)) // Nothing to do here, bail out... + return false; } // This is a typename. Replace the current token in-place with an diff --git a/clang/test/SemaObjC/crash-on-type-args-protocols.m b/clang/test/SemaObjC/crash-on-type-args-protocols.m new file mode 100644 index 00000000000..f7d847851fa --- /dev/null +++ b/clang/test/SemaObjC/crash-on-type-args-protocols.m @@ -0,0 +1,40 @@ +// RUN: %clang_cc1 -DFIRST -fsyntax-only -verify %s +// RUN: %clang_cc1 -DSECOND -fsyntax-only -verify %s +// RUN: %clang_cc1 -DTHIRD -fsyntax-only -verify %s +// RUN: %clang_cc1 -DFOURTH -fsyntax-only -verify %s + +@protocol P; +@interface NSObject +@end +@protocol X +@end +@interface X : NSObject <X> +@end + +@class A; + +#ifdef FIRST +id<X> F1(id<[P> v) { // expected-error {{expected a type}} // expected-error {{use of undeclared identifier 'P'}} // expected-error {{use of undeclared identifier 'v'}} // expected-note {{to match this '('}} + return 0; +} +#endif + +#ifdef SECOND +id<X> F2(id<P[X> v) { // expected-error {{unknown type name 'P'}} // expected-error {{unexpected interface name 'X': expected expression}} // expected-error {{use of undeclared identifier 'v'}} // expected-note {{to match this '('}} + return 0; +} +#endif + +#ifdef THIRD +id<X> F3(id<P, P *[> v) { // expected-error {{unknown type name 'P'}} // expected-error {{expected expression}} // expected-error {{use of undeclared identifier 'v'}} // expected-note {{to match this '('}} + return 0; +} +#endif + +#ifdef FOURTH +id<X> F4(id<P, P *(> v { // expected-error {{unknown type name 'P'}} // expected-error {{expected ')'}} // expected-note {{to match this '('}} // expected-note {{to match this '('}} + return 0; +} +#endif + +// expected-error {{expected '>'}} // expected-error {{expected parameter declarator}} // expected-error {{expected ')'}} // expected-error {{expected function body after function declarator}} |