r281383 - [SemaObjC] Be more strict while parsing type arguments and protocols
Bruno Cardoso Lopes via cfe-commits
cfe-commits at lists.llvm.org
Tue Sep 13 13:04:36 PDT 2016
Author: bruno
Date: Tue Sep 13 15:04:35 2016
New Revision: 281383
URL: http://llvm.org/viewvc/llvm-project?rev=281383&view=rev
Log:
[SemaObjC] Be more strict while parsing type arguments and protocols
Fix a crash-on-invalid.
When parsing type arguments and protocols,
parseObjCTypeArgsOrProtocolQualifiers() calls ParseTypeName(), which tries to
find matching tokens for '[', '(', etc whenever they appear among potential
type names. If unmatched, ParseTypeName() yields a tok::eof token stream. This
leads to crashes since the parsing at this point is not expected to go beyond
the param list closing '>'.
Fix that by properly handling tok::eof in
parseObjCTypeArgsOrProtocolQualifiers() callers.
Differential Revision: https://reviews.llvm.org/D23852
rdar://problem/25063557
Added:
cfe/trunk/test/SemaObjC/crash-on-type-args-protocols.m
Modified:
cfe/trunk/lib/Parse/ParseDecl.cpp
cfe/trunk/lib/Parse/ParseObjc.cpp
cfe/trunk/lib/Parse/Parser.cpp
Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=281383&r1=281382&r2=281383&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Tue Sep 13 15:04:35 2016
@@ -5877,7 +5877,8 @@ bool Parser::isFunctionDeclaratorIdentif
// 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
Modified: cfe/trunk/lib/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=281383&r1=281382&r2=281383&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Sep 13 15:04:35 2016
@@ -344,9 +344,11 @@ Decl *Parser::ParseObjCAtInterfaceDeclar
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::parseObjCTypeArgsAndProtoco
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::parseObjCTypeArgsAndP
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;
Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=281383&r1=281382&r2=281383&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Sep 13 15:04:35 2016
@@ -1539,6 +1539,8 @@ Parser::TryAnnotateName(bool IsAddressOf
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::TryAnnotateTypeOrScopeToken
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
Added: cfe/trunk/test/SemaObjC/crash-on-type-args-protocols.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/crash-on-type-args-protocols.m?rev=281383&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/crash-on-type-args-protocols.m (added)
+++ cfe/trunk/test/SemaObjC/crash-on-type-args-protocols.m Tue Sep 13 15:04:35 2016
@@ -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
+
+ at protocol P;
+ at interface NSObject
+ at end
+ at protocol X
+ at end
+ at interface X : NSObject <X>
+ at end
+
+ at 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}}
More information about the cfe-commits
mailing list