Index: ELF/ScriptParser.cpp =================================================================== --- ELF/ScriptParser.cpp +++ 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,17 +158,17 @@ return {A.Sec, false, A.getSectionOffset() - B.getValue(), A.Loc}; } -static ExprValue div(ExprValue A, ExprValue B) { +static ExprValue div(ExprValue A, ExprValue B, std::string Loc) { if (uint64_t BV = B.getValue()) return A.getValue() / BV; - error("division by zero"); + error(Loc + ": division by zero"); return 0; } -static ExprValue mod(ExprValue A, ExprValue B) { +static ExprValue mod(ExprValue A, ExprValue B, std::string Loc) { if (uint64_t BV = B.getValue()) return A.getValue() % BV; - error("modulo by zero"); + error(Loc + ": modulo by zero"); return 0; } @@ -805,17 +806,21 @@ 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 [=] { return div(L(), R(), Loc); }; + } + if (Op == "%") { + std::string Loc = getCurrentLocation(); + return [=] { return mod(L(), R(), Loc); }; + } if (Op == "<<") return [=] { return L().getValue() << R().getValue(); }; if (Op == ">>") Index: test/ELF/linkerscript/operators.test =================================================================== --- test/ELF/linkerscript/operators.test +++ 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