]> granicus.if.org Git - clang/commitdiff
MS inline asm: When LLVM called back to Clang to parse a name and do name
authorDmitri Gribenko <gribozavr@gmail.com>
Tue, 3 Dec 2013 00:48:09 +0000 (00:48 +0000)
committerDmitri Gribenko <gribozavr@gmail.com>
Tue, 3 Dec 2013 00:48:09 +0000 (00:48 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@196182 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseStmt.cpp
test/Sema/ms-inline-asm.c

index 5f939fc354a312274432f442dfdc2a7ba1412379..6cbb68e9ddc1dd67611119a70899c795c16054f9 100644 (file)
@@ -1920,30 +1920,33 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl<Token> &LineToks,
                                     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();
index 69f234e5e9ae077e226506dcc9694030873bd532..83b80294ff95cf8c33096edf7f3ee64bd1a36417 100644 (file)
@@ -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@+2 {{expected identifier}}
+  __asm {
+    and ecx, ~15
+  }
+
+  int x = 0;
+  // expected-error@+3 {{expected identifier}}
+  __asm {
+    and ecx, x
+    and ecx, ~15
+  }
+}