diff options
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 29 | ||||
-rw-r--r-- | test/Parser/cxx-stmt.cpp | 6 |
2 files changed, 28 insertions, 7 deletions
diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index c3595b9e13..9085b8713d 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -1259,18 +1259,32 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { } // Parse Outputs, if present. - if (Tok.is(tok::colon)) { + bool AteExtraColon = false; + if (Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { + // In C++ mode, parse "::" like ": :". + AteExtraColon = Tok.is(tok::coloncolon); ConsumeToken(); - if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) + if (!AteExtraColon && + ParseAsmOperandsOpt(Names, Constraints, Exprs)) return StmtError(); } + unsigned NumOutputs = Names.size(); // Parse Inputs, if present. - if (Tok.is(tok::colon)) { - ConsumeToken(); - if (ParseAsmOperandsOpt(Names, Constraints, Exprs)) + if (AteExtraColon || + Tok.is(tok::colon) || Tok.is(tok::coloncolon)) { + // In C++ mode, parse "::" like ": :". + if (AteExtraColon) + AteExtraColon = false; + else { + AteExtraColon = Tok.is(tok::coloncolon); + ConsumeToken(); + } + + if (!AteExtraColon && + ParseAsmOperandsOpt(Names, Constraints, Exprs)) return StmtError(); } @@ -1281,8 +1295,9 @@ Parser::OwningStmtResult Parser::ParseAsmStatement(bool &msAsm) { unsigned NumInputs = Names.size() - NumOutputs; // Parse the clobbers, if present. - if (Tok.is(tok::colon)) { - ConsumeToken(); + if (AteExtraColon || Tok.is(tok::colon)) { + if (!AteExtraColon) + ConsumeToken(); // Parse the asm-string list for clobbers. while (1) { diff --git a/test/Parser/cxx-stmt.cpp b/test/Parser/cxx-stmt.cpp index 3fd3e256a8..fdd573e6bf 100644 --- a/test/Parser/cxx-stmt.cpp +++ b/test/Parser/cxx-stmt.cpp @@ -52,3 +52,9 @@ void f4() { case Type: i = 7; break; // no error. } } + +// PR5500 +void f5() { + asm volatile ("":: :"memory"); + asm volatile ("": ::"memory"); +} |