Index: lld/trunk/ELF/ScriptParser.cpp =================================================================== --- lld/trunk/ELF/ScriptParser.cpp +++ lld/trunk/ELF/ScriptParser.cpp @@ -98,6 +98,7 @@ uint64_t readMemoryAssignment(StringRef, StringRef, StringRef); std::pair readMemoryAttributes(); + Expr combine(StringRef Op, Expr L, Expr R); Expr readExpr(); Expr readExpr1(Expr Lhs, int MinPrec); StringRef readParenLiteral(); @@ -157,20 +158,6 @@ 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 @@ 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 == ">>") Index: lld/trunk/test/ELF/linkerscript/operators.test =================================================================== --- lld/trunk/test/ELF/linkerscript/operators.test +++ lld/trunk/test/ELF/linkerscript/operators.test @@ -91,7 +91,13 @@ # 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