bruno updated the summary for this revision.
bruno updated this revision to Diff 69456.
bruno added a comment.

Updated patch and changed approach after Doug's comment.


https://reviews.llvm.org/D23852

Files:
  lib/Parse/ParseDecl.cpp
  lib/Parse/ParseObjc.cpp
  lib/Parse/Parser.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,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}}
Index: lib/Parse/Parser.cpp
===================================================================
--- lib/Parse/Parser.cpp
+++ lib/Parse/Parser.cpp
@@ -1513,6 +1513,8 @@
                                                    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);
@@ -1744,6 +1746,8 @@
                                                    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
Index: lib/Parse/ParseObjc.cpp
===================================================================
--- lib/Parse/ParseObjc.cpp
+++ lib/Parse/ParseObjc.cpp
@@ -344,9 +344,11 @@
           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 @@
                                         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 @@
                                          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;
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -5861,7 +5861,8 @@
          // 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
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to