[cfe-commits] r74264 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseExprCXX.cpp lib/Parse/ParseTemplate.cpp lib/Parse/Parser.cpp test/SemaCXX/nested-name-spec.cpp

Chris Lattner sabre at nondot.org
Thu Jun 25 21:27:48 PDT 2009


Author: lattner
Date: Thu Jun 25 23:27:47 2009
New Revision: 74264

URL: http://llvm.org/viewvc/llvm-project?rev=74264&view=rev
Log:
fix PR4452, a crash on invalid.  The error recovery is still terrible in this case
but at least we don't crash :)

Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseExprCXX.cpp
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/test/SemaCXX/nested-name-spec.cpp

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=74264&r1=74263&r2=74264&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Jun 25 23:27:47 2009
@@ -1193,7 +1193,7 @@
                                TemplateArgLocationList &TemplateArgLocations,
                                         SourceLocation &RAngleLoc);
 
-  void AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+  bool AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                const CXXScopeSpec *SS,
                                SourceLocation TemplateKWLoc = SourceLocation(),
                                bool AllowTypeAnnotation = true);

Modified: cfe/trunk/lib/Parse/ParseExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseExprCXX.cpp?rev=74264&r1=74263&r2=74264&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseExprCXX.cpp (original)
+++ cfe/trunk/lib/Parse/ParseExprCXX.cpp Thu Jun 25 23:27:47 2009
@@ -85,8 +85,10 @@
         = Actions.ActOnDependentTemplateName(TemplateKWLoc,
                                              *Tok.getIdentifierInfo(),
                                              Tok.getLocation(), SS);
-      AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
-                              &SS, TemplateKWLoc, false);
+      if (AnnotateTemplateIdToken(Template, TNK_Dependent_template_name,
+                                  &SS, TemplateKWLoc, false))
+        break;
+      
       continue;
     }
     
@@ -179,7 +181,9 @@
         // because some clients (e.g., the parsing of class template
         // specializations) still want to see the original template-id
         // token.
-        AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(), false);
+        if (AnnotateTemplateIdToken(Template, TNK, &SS, SourceLocation(),
+                                    false))
+          break;
         continue;
       }
     }

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=74264&r1=74263&r2=74264&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Thu Jun 25 23:27:47 2009
@@ -621,7 +621,11 @@
 /// replaced with a type annotation token. Otherwise, the
 /// simple-template-id is always replaced with a template-id
 /// annotation token.
-void Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
+///
+/// If an unrecoverable parse error occurs and no annotation token can be
+/// formed, this function returns true.
+///
+bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
                                      const CXXScopeSpec *SS, 
                                      SourceLocation TemplateKWLoc,
                                      bool AllowTypeAnnotation) {
@@ -644,14 +648,19 @@
                                                   TemplateArgIsType,
                                                   TemplateArgLocations,
                                                   RAngleLoc);
+  
+  if (Invalid) {
+    // If we failed to parse the template ID but skipped ahead to a >, we're not
+    // going to be able to form a token annotation.  Eat the '>' if present.
+    if (Tok.is(tok::greater))
+      ConsumeToken();
+    return true;
+  }
 
   ASTTemplateArgsPtr TemplateArgsPtr(Actions, TemplateArgs.data(),
                                      TemplateArgIsType.data(),
                                      TemplateArgs.size());
 
-  if (Invalid) // FIXME: How to recover from a broken template-id?
-    return; 
-
   // Build the annotation token.
   if (TNK == TNK_Type_template && AllowTypeAnnotation) {
     Action::TypeResult Type 
@@ -659,8 +668,13 @@
                                     LAngleLoc, TemplateArgsPtr,
                                     &TemplateArgLocations[0],
                                     RAngleLoc);
-    if (Type.isInvalid()) // FIXME: better recovery?
-      return;
+    if (Type.isInvalid()) {
+      // If we failed to parse the template ID but skipped ahead to a >, we're not
+      // going to be able to form a token annotation.  Eat the '>' if present.
+      if (Tok.is(tok::greater))
+        ConsumeToken();
+      return true;
+    }
 
     Tok.setKind(tok::annot_typename);
     Tok.setAnnotationValue(Type.get());
@@ -705,6 +719,7 @@
   // In case the tokens were cached, have Preprocessor replace them with the
   // annotation token.
   PP.AnnotateCachedTokens(Tok);
+  return false;
 }
 
 /// \brief Replaces a template-id annotation token with a type

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=74264&r1=74263&r2=74264&view=diff

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Jun 25 23:27:47 2009
@@ -839,7 +839,8 @@
 /// specifier, and another one to get the actual type inside
 /// ParseDeclarationSpecifiers).
 ///
-/// This returns true if the token was annotated.
+/// This returns true if the token was annotated or an unrecoverable error
+/// occurs.
 /// 
 /// Note that this routine emits an error if you call it with ::new or ::delete
 /// as the current tokens, so only call it in contexts where these are invalid.
@@ -934,7 +935,12 @@
       if (TemplateNameKind TNK 
             = Actions.isTemplateName(*Tok.getIdentifierInfo(),
                                      CurScope, Template, &SS))
-        AnnotateTemplateIdToken(Template, TNK, &SS);
+        if (AnnotateTemplateIdToken(Template, TNK, &SS)) {
+          // If an unrecoverable error occurred, we need to return true here,
+          // because the token stream is in a damaged state.  We may not return
+          // a valid identifier.
+          return Tok.isNot(tok::identifier);
+        }
     }
 
     // The current token, which is either an identifier or a
@@ -978,7 +984,8 @@
 
 /// TryAnnotateScopeToken - Like TryAnnotateTypeOrScopeToken but only
 /// annotates C++ scope specifiers and template-ids.  This returns
-/// true if the token was annotated.
+/// true if the token was annotated or there was an error that could not be
+/// recovered from.
 /// 
 /// Note that this routine emits an error if you call it with ::new or ::delete
 /// as the current tokens, so only call it in contexts where these are invalid.

Modified: cfe/trunk/test/SemaCXX/nested-name-spec.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/nested-name-spec.cpp?rev=74264&r1=74263&r2=74264&view=diff

==============================================================================
--- cfe/trunk/test/SemaCXX/nested-name-spec.cpp (original)
+++ cfe/trunk/test/SemaCXX/nested-name-spec.cpp Thu Jun 25 23:27:47 2009
@@ -171,3 +171,27 @@
 X::X() : a(5) { } // expected-error{{use of undeclared identifier 'X'}} \
       // expected-error{{C++ requires a type specifier for all declarations}} \
       // expected-error{{only constructors take base initializers}}
+
+
+
+
+namespace somens {
+  struct a { };
+}
+
+template <typename T>
+class foo {
+};
+
+
+// PR4452
+// FIXME: This error recovery sucks.
+foo<somens:a> a2;  // expected-error {{unexpected namespace name 'somens': expected expression}} \
+expected-error {{C++ requires a type specifier for all declarations}}
+
+// FIXME: This is bogus, there is no int here!
+somens::a a3 = a2; // expected-error {{cannot initialize 'a3' with an lvalue of type 'int'}}
+
+
+
+





More information about the cfe-commits mailing list