diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index bdcdd7966eb..a4741270c7a 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -2071,20 +2071,22 @@ bool ARMAsmParser::ParseInstruction(StringRef Name, SMLoc NameLoc, bool CanAcceptCarrySet, CanAcceptPredicationCode; GetMnemonicAcceptInfo(Head, CanAcceptCarrySet, CanAcceptPredicationCode); + // If we had a carry-set on an instruction that can't do that, issue an + // error. + if (!CanAcceptCarrySet && CarrySetting) { + Parser.EatToEndOfStatement(); + return Error(NameLoc, "instruction '" + Head + + "' can not set flags, but 's' suffix specified"); + } + // Add the carry setting operand, if necessary. // // FIXME: It would be awesome if we could somehow invent a location such that // match errors on this operand would print a nice diagnostic about how the // 's' character in the mnemonic resulted in a CCOut operand. - if (CanAcceptCarrySet) { + if (CanAcceptCarrySet) Operands.push_back(ARMOperand::CreateCCOut(CarrySetting ? ARM::CPSR : 0, NameLoc)); - } else { - // This mnemonic can't ever accept a carry set, but the user wrote one (or - // misspelled another mnemonic). - - // FIXME: Issue a nice error. - } // Add the predication code operand, if necessary. if (CanAcceptPredicationCode) { diff --git a/test/MC/ARM/diagnostics.s b/test/MC/ARM/diagnostics.s index 7a9d85e9449..4537a0ff6df 100644 --- a/test/MC/ARM/diagnostics.s +++ b/test/MC/ARM/diagnostics.s @@ -3,6 +3,12 @@ @ Check for various assembly diagnostic messages on invalid input. +@ 's' bit on an instruction that can't accept it. + mlss r1, r2, r3, r4 +@ CHECK-ERRORS: error: instruction 'mls' can not set flags, +@ CHECK-ERRORS: but 's' suffix specified + + @ Out of range shift immediate values. adc r1, r2, r3, lsl #invalid adc r4, r5, r6, lsl #-1