aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp36
1 files changed, 32 insertions, 4 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index e78d16056460..bc5f562d9589 100644
--- a/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/contrib/llvm-project/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -263,8 +263,7 @@ private:
return 0;
SmallVector<ICToken, 16> OperandStack;
- for (unsigned i = 0, e = PostfixStack.size(); i != e; ++i) {
- ICToken Op = PostfixStack[i];
+ for (const ICToken &Op : PostfixStack) {
if (Op.first == IC_IMM || Op.first == IC_REGISTER) {
OperandStack.push_back(Op);
} else if (isUnaryOperator(Op.first)) {
@@ -1731,8 +1730,8 @@ bool X86AsmParser::VerifyAndAdjustOperands(OperandVector &OrigOperands,
OrigOperands.pop_back();
}
// OrigOperands.append(FinalOperands.begin(), FinalOperands.end());
- for (unsigned int i = 0; i < FinalOperands.size(); ++i)
- OrigOperands.push_back(std::move(FinalOperands[i]));
+ for (auto &Op : FinalOperands)
+ OrigOperands.push_back(std::move(Op));
return false;
}
@@ -3062,6 +3061,35 @@ bool X86AsmParser::ParseMemOperand(unsigned SegReg, const MCExpr *Disp,
ErrMsg))
return Error(BaseLoc, ErrMsg);
+ // If the displacement is a constant, check overflows. For 64-bit addressing,
+ // gas requires isInt<32> and otherwise reports an error. For others, gas
+ // reports a warning and allows a wider range. E.g. gas allows
+ // [-0xffffffff,0xffffffff] for 32-bit addressing (e.g. Linux kernel uses
+ // `leal -__PAGE_OFFSET(%ecx),%esp` where __PAGE_OFFSET is 0xc0000000).
+ if (BaseReg || IndexReg) {
+ if (auto CE = dyn_cast<MCConstantExpr>(Disp)) {
+ auto Imm = CE->getValue();
+ bool Is64 = X86MCRegisterClasses[X86::GR64RegClassID].contains(BaseReg) ||
+ X86MCRegisterClasses[X86::GR64RegClassID].contains(IndexReg);
+ bool Is16 = X86MCRegisterClasses[X86::GR16RegClassID].contains(BaseReg);
+ if (Is64) {
+ if (!isInt<32>(Imm))
+ return Error(BaseLoc, "displacement " + Twine(Imm) +
+ " is not within [-2147483648, 2147483647]");
+ } else if (!Is16) {
+ if (!isUInt<32>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
+ Warning(BaseLoc, "displacement " + Twine(Imm) +
+ " shortened to 32-bit signed " +
+ Twine(static_cast<int32_t>(Imm)));
+ }
+ } else if (!isUInt<16>(Imm < 0 ? -uint64_t(Imm) : uint64_t(Imm))) {
+ Warning(BaseLoc, "displacement " + Twine(Imm) +
+ " shortened to 16-bit signed " +
+ Twine(static_cast<int16_t>(Imm)));
+ }
+ }
+ }
+
if (SegReg || BaseReg || IndexReg)
Operands.push_back(X86Operand::CreateMem(getPointerWidth(), SegReg, Disp,
BaseReg, IndexReg, Scale, StartLoc,