Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -470,6 +470,11 @@ return; } + if (auto *Cmd = dyn_cast(&Base)) { + Cmd->Expression(0); + return; + } + // It handles single input section description command, // calculates and assigns the offsets for each section and also // updates the output section size. @@ -1420,7 +1425,12 @@ Cmd->Commands.emplace_back(Assignment); else if (BytesDataCommand *Data = readBytesDataCommand(Tok)) Cmd->Commands.emplace_back(Data); - else if (Tok == "FILL") + else if (Tok == "ASSERT") { + Cmd->Commands.emplace_back(new AssertCommand(readAssert())); + // GNU LD expects an "ASSERT" statement to end with a ";" in + // this context. + expect(";"); + } else if (Tok == "FILL") Cmd->Filler = readFill(); else if (Tok == "SORT") readSort(); Index: test/ELF/linkerscript/assert.s =================================================================== --- test/ELF/linkerscript/assert.s +++ test/ELF/linkerscript/assert.s @@ -38,5 +38,27 @@ # RUN: echo "ASSERT(SIZEOF(.foo) == 8, \"true\");" > %t5.script # RUN: ld.lld -shared -o %t5 --script %t5.script %t1.o # RUN: llvm-readobj %t5 > /dev/null + +## Test assertions inside of output section decriptions. +## NOTE: Assertions in this context always end in a semicolon. + +# RUN: echo "SECTIONS { \ +# RUN: .foo : { \ +# RUN: *(.foo) \ +# RUN: ASSERT(SIZEOF(.foo) == 8, \"true\"); \ +# RUN: } \ +# RUN: }" > %t6.script +# RUN: ld.lld -shared -o %t6 --script %t6.script %t1.o +# RUN: llvm-readobj %t6 > /dev/null + +# RUN: echo "SECTIONS { \ +# RUN: .foo : { \ +# RUN: ASSERT(1, \"true\") \ +# RUN: } \ +# RUN: }" > %t7.script +# RUN: not ld.lld -shared -o %t7 --script %t7.script %t1.o > %t.log 2>&1 +# RUN: FileCheck %s -check-prefix=CHECK-SEMI < %t.log +# CHECK-SEMI: error: {{.*}}.script:1: ; expected, but got } + .section .foo, "a" .quad 0