summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/ScriptParser.cpp39
-rw-r--r--lld/test/ELF/linkerscript/operators.test8
2 files changed, 27 insertions, 20 deletions
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index b89dfea4246..28efd384bf5 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -98,6 +98,7 @@ private:
uint64_t readMemoryAssignment(StringRef, StringRef, StringRef);
std::pair<uint32_t, uint32_t> readMemoryAttributes();
+ Expr combine(StringRef Op, Expr L, Expr R);
Expr readExpr();
Expr readExpr1(Expr Lhs, int MinPrec);
StringRef readParenLiteral();
@@ -157,20 +158,6 @@ static ExprValue sub(ExprValue A, ExprValue B) {
return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc};
}
-static ExprValue div(ExprValue A, ExprValue B) {
- if (uint64_t BV = B.getValue())
- return A.getValue() / BV;
- error("division by zero");
- return 0;
-}
-
-static ExprValue mod(ExprValue A, ExprValue B) {
- if (uint64_t BV = B.getValue())
- return A.getValue() % BV;
- error("modulo by zero");
- return 0;
-}
-
static ExprValue bitAnd(ExprValue A, ExprValue B) {
moveAbsRight(A, B);
return {A.Sec, A.ForceAbsolute,
@@ -809,17 +796,31 @@ Expr ScriptParser::readExpr() {
return E;
}
-static Expr combine(StringRef Op, Expr L, Expr R) {
+Expr ScriptParser::combine(StringRef Op, Expr L, Expr R) {
if (Op == "+")
return [=] { return add(L(), R()); };
if (Op == "-")
return [=] { return sub(L(), R()); };
if (Op == "*")
return [=] { return L().getValue() * R().getValue(); };
- if (Op == "/")
- return [=] { return div(L(), R()); };
- if (Op == "%")
- return [=] { return mod(L(), R()); };
+ if (Op == "/") {
+ std::string Loc = getCurrentLocation();
+ return [=]() -> uint64_t {
+ if (uint64_t RV = R().getValue())
+ return L().getValue() / RV;
+ error(Loc + ": division by zero");
+ return (uint64_t)0;
+ };
+ }
+ if (Op == "%") {
+ std::string Loc = getCurrentLocation();
+ return [=]() -> uint64_t {
+ if (uint64_t RV = R().getValue())
+ return L().getValue() % RV;
+ error(Loc + ": modulo by zero");
+ return (uint64_t)0;
+ };
+ }
if (Op == "<<")
return [=] { return L().getValue() << R().getValue(); };
if (Op == ">>")
diff --git a/lld/test/ELF/linkerscript/operators.test b/lld/test/ELF/linkerscript/operators.test
index a5189fa1d4a..fa6e7eeb4ca 100644
--- a/lld/test/ELF/linkerscript/operators.test
+++ b/lld/test/ELF/linkerscript/operators.test
@@ -91,7 +91,13 @@ SECTIONS {
# RUN: echo "SECTIONS { . = 1 / 0; }" > %t.script
# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
# RUN: FileCheck --check-prefix=DIVZERO %s
-# DIVZERO: division by zero
+# DIVZERO: {{.*}}.script:1: division by zero
+
+## Mod by zero error.
+# RUN: echo "SECTIONS { . = 1 % 0; }" > %t.script
+# RUN: not ld.lld %t --script %t.script -o %t2 2>&1 | \
+# RUN: FileCheck --check-prefix=MODZERO %s
+# MODZERO: {{.*}}.script:1: modulo by zero
## Broken ternary operator expression.
# RUN: echo "SECTIONS { . = 1 ? 2; }" > %t.script
OpenPOWER on IntegriCloud