diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2020-01-17 20:45:01 +0000 |
commit | 706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch) | |
tree | 4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp | |
parent | 7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff) |
Notes
Diffstat (limited to 'llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp')
-rw-r--r-- | llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp index 93c4ce4b5ccc..607266d552a6 100644 --- a/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp +++ b/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp @@ -1304,14 +1304,23 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal, if (getParser().parseExpression(Expr)) return MatchOperand_NoMatch; + auto isOutOfRangeConstant = [&](const MCExpr *E) -> bool { + if (auto *CE = dyn_cast<MCConstantExpr>(E)) { + int64_t Value = CE->getValue(); + if ((Value & 1) || Value < MinVal || Value > MaxVal) + return true; + } + return false; + }; + // For consistency with the GNU assembler, treat immediates as offsets // from ".". if (auto *CE = dyn_cast<MCConstantExpr>(Expr)) { - int64_t Value = CE->getValue(); - if ((Value & 1) || Value < MinVal || Value > MaxVal) { + if (isOutOfRangeConstant(CE)) { Error(StartLoc, "offset out of range"); return MatchOperand_ParseFail; } + int64_t Value = CE->getValue(); MCSymbol *Sym = Ctx.createTempSymbol(); Out.EmitLabel(Sym); const MCExpr *Base = MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, @@ -1319,6 +1328,15 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal, Expr = Value == 0 ? Base : MCBinaryExpr::createAdd(Base, Expr, Ctx); } + // For consistency with the GNU assembler, conservatively assume that a + // constant offset must by itself be within the given size range. + if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) + if (isOutOfRangeConstant(BE->getLHS()) || + isOutOfRangeConstant(BE->getRHS())) { + Error(StartLoc, "offset out of range"); + return MatchOperand_ParseFail; + } + // Optionally match :tls_gdcall: or :tls_ldcall: followed by a TLS symbol. const MCExpr *Sym = nullptr; if (AllowTLS && getLexer().is(AsmToken::Colon)) { @@ -1371,6 +1389,6 @@ SystemZAsmParser::parsePCRel(OperandVector &Operands, int64_t MinVal, } // Force static initialization. -extern "C" void LLVMInitializeSystemZAsmParser() { +extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSystemZAsmParser() { RegisterMCAsmParser<SystemZAsmParser> X(getTheSystemZTarget()); } |