diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index d78908dee8768414c4ba7b29531f1a0800b2e742..4c24d2b391daac0e7d5c8e5f9ca9339a0bec30b9 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1687,8 +1687,6 @@ void CodeGenFunction::EmitMSAsmStmt(const MSAsmStmt &S) { if (!CGM.getCodeGenOpts().EmitMicrosoftInlineAsm) return; - assert (S.isSimple() && "CodeGen can only handle simple MSAsmStmts."); - std::vector Args; std::vector ArgTypes; std::string Constraints; diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp index 96ccd7574fe323a62bc98c86e9ea8ab68ef4ecb8..a4a7a4127768902295f2a91d1110599303e05fa3 100644 --- a/clang/lib/Sema/SemaStmtAsm.cpp +++ b/clang/lib/Sema/SemaStmtAsm.cpp @@ -338,6 +338,20 @@ static StringRef getSpelling(Sema &SemaRef, Token AsmTok) { return Asm; } +static bool bailOnMSAsm(std::vector Piece) { + for (unsigned i = 0, e = Piece.size(); i != e; ++i) + if (isMSAsmKeyword(Piece[i])) + return true; + return false; +} + +static bool bailOnMSAsm(std::vector > Pieces) { + for (unsigned i = 0, e = Pieces.size(); i != e; ++i) + if (bailOnMSAsm(Pieces[i])) + return true; + return false; +} + static bool isSimpleMSAsm(std::vector &Pieces, const TargetInfo &TI) { if (isMSAsmKeyword(Pieces[0])) @@ -401,6 +415,12 @@ static std::string buildMSAsmString(Sema &SemaRef, return Res.c_str(); } +#define DEF_SIMPLE_MSASM \ + MSAsmStmt *NS = \ + new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, \ + /*IsVolatile*/ true, AsmToks, Inputs, Outputs, \ + AsmString, Clobbers, EndLoc); + StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SourceLocation LBraceLoc, ArrayRef AsmToks, @@ -415,10 +435,7 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, // Empty asm statements don't need to instantiate the AsmParser, etc. if (AsmToks.empty()) { StringRef AsmString; - MSAsmStmt *NS = - new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, - /*IsVolatile*/ true, AsmToks, Inputs, Outputs, - AsmString, Clobbers, EndLoc); + DEF_SIMPLE_MSASM; return Owned(NS); } @@ -437,14 +454,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, IsSimple = isSimpleMSAsm(Pieces[i], Context.getTargetInfo()); } - // AsmParser doesn't fully support non-simple asm statements. - if (!IsSimple) { - MSAsmStmt *NS = - new (Context) MSAsmStmt(Context, AsmLoc, LBraceLoc, /*IsSimple*/ true, - /*IsVolatile*/ true, AsmToks, Inputs, Outputs, - AsmString, Clobbers, EndLoc); - return Owned(NS); - } + // AsmParser doesn't fully support these asm statements. + if (bailOnMSAsm(Pieces)) { DEF_SIMPLE_MSASM; return Owned(NS); } // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); @@ -497,7 +508,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, SmallVector Operands; bool HadError = TargetParser->ParseInstruction(Opcode.str(), IDLoc, Operands); - assert (!HadError && "Unexpected error parsing instruction"); + // If we had an error parsing the operands, fail gracefully. + if (HadError) { DEF_SIMPLE_MSASM; return Owned(NS); } // Match the MCInstr. unsigned ErrorInfo; @@ -505,8 +517,8 @@ StmtResult Sema::ActOnMSAsmStmt(SourceLocation AsmLoc, HadError = TargetParser->MatchInstruction(IDLoc, Operands, Instrs, ErrorInfo, /*matchingInlineAsm*/ true); - assert (!HadError && "Unexpected error matching instruction"); - assert ((Instrs.size() == 1) && "Expected only a single instruction."); + // If we had an error parsing the operands, fail gracefully. + if (HadError) { DEF_SIMPLE_MSASM; return Owned(NS); } // Get the instruction descriptor. llvm::MCInst Inst = Instrs[0]; diff --git a/clang/test/CodeGen/ms-inline-asm.c b/clang/test/CodeGen/ms-inline-asm.c index 7680e3efa96216d473eef4704ecbec028cf4fd99..bd9fe53554b5a144bcf4c55a2261a3ed0d86da18 100644 --- a/clang/test/CodeGen/ms-inline-asm.c +++ b/clang/test/CodeGen/ms-inline-asm.c @@ -88,7 +88,7 @@ unsigned t10(void) { // CHECK: [[I:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: [[J:%[a-zA-Z0-9]+]] = alloca i32, align 4 // CHECK: store i32 1, i32* [[I]], align 4 -// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect +// CHECK: call void asm sideeffect "mov eax, i\0Amov j, eax", "~{eax},~{dirflag},~{fpsr},~{flags}"() nounwind ia_nsdialect // CHECK: [[RET:%[a-zA-Z0-9]+]] = load i32* [[J]], align 4 // CHECK: ret i32 [[RET]] }