[cfe-commits] r54340 - in /cfe/trunk: include/clang/Parse/Parser.h lib/Parse/ParseObjc.cpp lib/Parse/Parser.cpp test/SemaObjC/invalid-code.m

Chris Lattner sabre at nondot.org
Mon Aug 4 23:19:10 PDT 2008


Author: lattner
Date: Tue Aug  5 01:19:09 2008
New Revision: 54340

URL: http://llvm.org/viewvc/llvm-project?rev=54340&view=rev
Log:
Fix rdar://6124613 a crash on invalid code.

Added:
    cfe/trunk/test/SemaObjC/invalid-code.m
Modified:
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/Parse/ParseObjc.cpp
    cfe/trunk/lib/Parse/Parser.cpp

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

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Tue Aug  5 01:19:09 2008
@@ -244,12 +244,12 @@
   //===--------------------------------------------------------------------===//
   // Diagnostic Emission and Error recovery.
     
-  void Diag(SourceLocation Loc, unsigned DiagID,
+  bool Diag(SourceLocation Loc, unsigned DiagID,
             const std::string &Msg = std::string());
-  void Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R);
-  void Diag(const Token &Tok, unsigned DiagID,
+  bool Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R);
+  bool Diag(const Token &Tok, unsigned DiagID,
             const std::string &M = std::string()) {
-    Diag(Tok.getLocation(), DiagID, M);
+    return Diag(Tok.getLocation(), DiagID, M);
   }
   
   /// SkipUntil - Read tokens until we get to the specified token, then consume

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

==============================================================================
--- cfe/trunk/lib/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/lib/Parse/ParseObjc.cpp Tue Aug  5 01:19:09 2008
@@ -1337,26 +1337,24 @@
 }
 
 Parser::ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) {
-
   switch (Tok.getKind()) {
   case tok::string_literal:    // primary-expression: string-literal
   case tok::wide_string_literal:
     return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
   default:
-    break;
-  }
-  
-  switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
-  case tok::objc_encode:
-    return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
-  case tok::objc_protocol:
-    return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
-  case tok::objc_selector:
-    return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
-  default:
-    Diag(AtLoc, diag::err_unexpected_at);
-    SkipUntil(tok::semi);
-    return true;
+    if (Tok.getIdentifierInfo() == 0)
+      return Diag(AtLoc, diag::err_unexpected_at);
+      
+    switch (Tok.getIdentifierInfo()->getObjCKeywordID()) {
+    case tok::objc_encode:
+      return ParsePostfixExpressionSuffix(ParseObjCEncodeExpression(AtLoc));
+    case tok::objc_protocol:
+      return ParsePostfixExpressionSuffix(ParseObjCProtocolExpression(AtLoc));
+    case tok::objc_selector:
+      return ParsePostfixExpressionSuffix(ParseObjCSelectorExpression(AtLoc));
+    default:
+      return Diag(AtLoc, diag::err_unexpected_at);
+    }
   }
 }
 
@@ -1380,10 +1378,10 @@
 
   ExprResult Res = ParseAssignmentExpression();
   if (Res.isInvalid) {
-    Diag(Tok, diag::err_invalid_receiver_to_message);
     SkipUntil(tok::r_square);
     return Res;
   }
+  
   return ParseObjCMessageExpressionBody(LBracLoc, 0, Res.Val);
 }
   
@@ -1426,16 +1424,24 @@
 
       if (Tok.isNot(tok::colon)) {
         Diag(Tok, diag::err_expected_colon);
-        SkipUntil(tok::semi);
+        // We must manually skip to a ']', otherwise the expression skipper will
+        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+        // the enclosing expression.
+        SkipUntil(tok::r_square);
         return true;
       }
+      
       ConsumeToken(); // Eat the ':'.
       ///  Parse the expression after ':' 
       ExprResult Res = ParseAssignmentExpression();
       if (Res.isInvalid) {
-        SkipUntil(tok::identifier);
+        // We must manually skip to a ']', otherwise the expression skipper will
+        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+        // the enclosing expression.
+        SkipUntil(tok::r_square);
         return Res;
       }
+      
       // We have a valid expression.
       KeyExprs.push_back(Res.Val);
       
@@ -1451,23 +1457,35 @@
       ///  Parse the expression after ',' 
       ExprResult Res = ParseAssignmentExpression();
       if (Res.isInvalid) {
-        SkipUntil(tok::identifier);
+        // We must manually skip to a ']', otherwise the expression skipper will
+        // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+        // the enclosing expression.
+        SkipUntil(tok::r_square);
         return Res;
       }
+      
       // We have a valid expression.
       KeyExprs.push_back(Res.Val);
     }
   } else if (!selIdent) {
     Diag(Tok, diag::err_expected_ident); // missing selector name.
-    SkipUntil(tok::semi);
+    
+    // We must manually skip to a ']', otherwise the expression skipper will
+    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+    // the enclosing expression.
+    SkipUntil(tok::r_square);
     return true;
   }
   
   if (Tok.isNot(tok::r_square)) {
     Diag(Tok, diag::err_expected_rsquare);
-    SkipUntil(tok::semi);
+    // We must manually skip to a ']', otherwise the expression skipper will
+    // stop at the ']' when it skips to the ';'.  We want it to skip beyond
+    // the enclosing expression.
+    SkipUntil(tok::r_square);
     return true;
   }
+  
   SourceLocation RBracLoc = ConsumeBracket(); // consume ']'
   
   unsigned nKeys = KeyIdents.size();
@@ -1527,10 +1545,8 @@
   
   SourceLocation EncLoc = ConsumeToken();
   
-  if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after, "@encode");
-    return true;
-  }
+  if (Tok.isNot(tok::l_paren))
+    return Diag(Tok, diag::err_expected_lparen_after, "@encode");
    
   SourceLocation LParenLoc = ConsumeParen();
   
@@ -1549,17 +1565,14 @@
 {
   SourceLocation ProtoLoc = ConsumeToken();
   
-  if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after, "@protocol");
-    return true;
-  }
+  if (Tok.isNot(tok::l_paren))
+    return Diag(Tok, diag::err_expected_lparen_after, "@protocol");
   
   SourceLocation LParenLoc = ConsumeParen();
   
-  if (Tok.isNot(tok::identifier)) {
-    Diag(Tok, diag::err_expected_ident);
-    return true;
-  }
+  if (Tok.isNot(tok::identifier))
+    return Diag(Tok, diag::err_expected_ident);
+  
   IdentifierInfo *protocolId = Tok.getIdentifierInfo();
   ConsumeToken();
   
@@ -1575,27 +1588,23 @@
 {
   SourceLocation SelectorLoc = ConsumeToken();
   
-  if (Tok.isNot(tok::l_paren)) {
-    Diag(Tok, diag::err_expected_lparen_after, "@selector");
-    return 0;
-  }
+  if (Tok.isNot(tok::l_paren))
+    return Diag(Tok, diag::err_expected_lparen_after, "@selector");
   
   llvm::SmallVector<IdentifierInfo *, 12> KeyIdents;
   SourceLocation LParenLoc = ConsumeParen();
   SourceLocation sLoc;
   IdentifierInfo *SelIdent = ParseObjCSelector(sLoc);
-  if (!SelIdent && Tok.isNot(tok::colon)) {
-    Diag(Tok, diag::err_expected_ident); // missing selector name.
-    return 0;
-  }
+  if (!SelIdent && Tok.isNot(tok::colon))
+    return Diag(Tok, diag::err_expected_ident); // missing selector name.
+  
   KeyIdents.push_back(SelIdent);
   unsigned nColons = 0;
   if (Tok.isNot(tok::r_paren)) {
     while (1) {
-      if (Tok.isNot(tok::colon)) {
-        Diag(Tok, diag::err_expected_colon);
-        break;
-      }
+      if (Tok.isNot(tok::colon))
+        return Diag(Tok, diag::err_expected_colon);
+      
       nColons++;
       ConsumeToken(); // Eat the ':'.
       if (Tok.is(tok::r_paren))

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

==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Tue Aug  5 01:19:09 2008
@@ -31,14 +31,16 @@
 Action::~Action() {}
 
 
-void Parser::Diag(SourceLocation Loc, unsigned DiagID,
+bool Parser::Diag(SourceLocation Loc, unsigned DiagID,
                   const std::string &Msg) {
   Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, &Msg, 1);
+  return true;
 }
 
-void Parser::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R) {
+bool Parser::Diag(SourceLocation Loc, unsigned DiagID, const SourceRange &R) {
   Diags.Report(FullSourceLoc(Loc,PP.getSourceManager()), DiagID, 0, 0,
                &R, 1);
+  return true;
 }
 
 

Added: cfe/trunk/test/SemaObjC/invalid-code.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/invalid-code.m?rev=54340&view=auto

==============================================================================
--- cfe/trunk/test/SemaObjC/invalid-code.m (added)
+++ cfe/trunk/test/SemaObjC/invalid-code.m Tue Aug  5 01:19:09 2008
@@ -0,0 +1,7 @@
+// RUN: clang %s -fsyntax-only -verify
+
+// rdar://6124613
+void test1() {
+  void *p = @1; // expected-error {{unexpected '@' in program}}
+}
+





More information about the cfe-commits mailing list