diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index 5f939fc354a3..6cbb68e9ddc1 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -1920,30 +1920,33 @@ ExprResult Parser::ParseMSAsmIdentifier(llvm::SmallVectorImpl &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(); diff --git a/clang/test/Sema/ms-inline-asm.c b/clang/test/Sema/ms-inline-asm.c index 69f234e5e9ae..83b80294ff95 100644 --- a/clang/test/Sema/ms-inline-asm.c +++ b/clang/test/Sema/ms-inline-asm.c @@ -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 + } +}