r196182 - MS inline asm: When LLVM called back to Clang to parse a name and do name

Dmitri Gribenko gribozavr at gmail.com
Mon Dec 2 16:48:09 PST 2013


Author: gribozavr
Date: Mon Dec  2 18:48:09 2013
New Revision: 196182

URL: http://llvm.org/viewvc/llvm-project?rev=196182&view=rev
Log:
MS inline asm: When LLVM called back to Clang to parse a name and do name
lookup, if parsing failed, we did not restore the lexer state properly, and
eventually crashed.  This change ensures that we always consume all the tokens
from the new token stream we started to parse the name from inline asm.

Modified:
    cfe/trunk/lib/Parse/ParseStmt.cpp
    cfe/trunk/test/Sema/ms-inline-asm.c

Modified: cfe/trunk/lib/Parse/ParseStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=196182&r1=196181&r2=196182&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseStmt.cpp (original)
+++ cfe/trunk/lib/Parse/ParseStmt.cpp Mon Dec  2 18:48:09 2013
@@ -1920,30 +1920,33 @@ ExprResult Parser::ParseMSAsmIdentifier(
                                     TemplateKWLoc,
                                     Id);
 
-  // If we've run into the poison token we inserted before, or there
-  // was a parsing error, then claim the entire line.
-  if (Invalid || Tok.is(EndOfStream)) {
-    NumLineToksConsumed = LineToks.size() - 2;
-
-    // Otherwise, claim up to the start of the next token.
+  // Figure out how many tokens we are into LineToks.
+  unsigned LineIndex = 0;
+  if (Tok.is(EndOfStream)) {
+    LineIndex = LineToks.size() - 2;
   } else {
-    // Figure out how many tokens we are into LineToks.
-    unsigned LineIndex = 0;
     while (LineToks[LineIndex].getLocation() != Tok.getLocation()) {
       LineIndex++;
       assert(LineIndex < LineToks.size() - 2); // we added two extra tokens
     }
+  }
 
+  // If we've run into the poison token we inserted before, or there
+  // was a parsing error, then claim the entire line.
+  if (Invalid || Tok.is(EndOfStream)) {
+    NumLineToksConsumed = LineToks.size() - 2;
+  } else {
+    // Otherwise, claim up to the start of the next token.
     NumLineToksConsumed = LineIndex;
   }
-      
-  // Finally, restore the old parsing state by consuming all the
-  // tokens we staged before, implicitly killing off the
-  // token-lexer we pushed.
-  for (unsigned n = LineToks.size() - 2 - NumLineToksConsumed; n != 0; --n) {
+
+  // Finally, restore the old parsing state by consuming all the tokens we
+  // staged before, implicitly killing off the token-lexer we pushed.
+  for (unsigned i = 0, e = LineToks.size() - LineIndex - 2; i != e; ++i) {
     ConsumeAnyToken();
   }
-  ConsumeToken(EndOfStream);
+  assert(Tok.is(EndOfStream));
+  ConsumeToken();
 
   // Leave LineToks in its original state.
   LineToks.pop_back();

Modified: cfe/trunk/test/Sema/ms-inline-asm.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/ms-inline-asm.c?rev=196182&r1=196181&r2=196182&view=diff
==============================================================================
--- cfe/trunk/test/Sema/ms-inline-asm.c (original)
+++ cfe/trunk/test/Sema/ms-inline-asm.c Mon Dec  2 18:48:09 2013
@@ -32,3 +32,21 @@ void f() {
     mov eax, TYPE bar // expected-error {{unable to lookup expression}}
   }
 }
+
+void rdar15318432(void) {
+  // We used to crash on this.  When LLVM called back to Clang to parse a name
+  // and do name lookup, if parsing failed, we did not restore the lexer state
+  // properly.
+
+  // expected-error at +2 {{expected identifier}}
+  __asm {
+    and ecx, ~15
+  }
+
+  int x = 0;
+  // expected-error at +3 {{expected identifier}}
+  __asm {
+    and ecx, x
+    and ecx, ~15
+  }
+}





More information about the cfe-commits mailing list