aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
committerDimitry Andric <dim@FreeBSD.org>2020-01-17 20:45:01 +0000
commit706b4fc47bbc608932d3b491ae19a3b9cde9497b (patch)
tree4adf86a776049cbf7f69a1929c4babcbbef925eb /llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp
parent7cc9cf2bf09f069cb2dd947ead05d0b54301fb71 (diff)
Notes
Diffstat (limited to 'llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp')
-rw-r--r--llvm/lib/Target/SystemZ/AsmParser/SystemZAsmParser.cpp24
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());
}