[PATCH] D23852: [SemaObjC] Fix crash while parsing type arguments and protocols

Bruno Cardoso Lopes via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 24 13:56:59 PDT 2016


bruno created this revision.
bruno added a reviewer: doug.gregor.
bruno added subscribers: cfe-commits, manmanren.

Fix a crash-on-invalid.

When parsing type arguments and protocols, ParseTypeName() 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 '>'.

ParseTypeName() can parse a variety combination of names, making this
case complicated to handle by looking tokens ahead. Fix the issue by
doing temptive parsing in the remaining type arg list, and revert the
token state in case tok::eof is reached.

rdar://problem/25063557

https://reviews.llvm.org/D23852

Files:
  lib/Parse/ParseObjc.cpp
  test/SemaObjC/crash-on-type-args-protocols.m

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
+
+ 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-error {{expected '>'}} // expected-error {{expected ')'}} // expected-note {{to match this '('}}
+  return 0;
+}
+
+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-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<X> F3(id<P, P *[> 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<X> F4(id<P, P *(> 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}}
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,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D23852.69166.patch
Type: text/x-patch
Size: 2812 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160824/1df73aa1/attachment-0001.bin>


More information about the cfe-commits mailing list