Skip to content

Commit 2a89356

Browse files
committed
[ELF] Add till and rewrite while (... consume("}"))
After #100493, the idiom `while (!errorCount() && !consume("}"))` could lead to inaccurate diagnostics or dead loops. Introduce till to change the code pattern.
1 parent c901b73 commit 2a89356

File tree

5 files changed

+29
-13
lines changed

5 files changed

+29
-13
lines changed

lld/ELF/ScriptLexer.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,17 @@ void ScriptLexer::expect(StringRef expect) {
234234
}
235235
}
236236

237+
ScriptLexer::Token ScriptLexer::till(StringRef tok) {
238+
StringRef str = next();
239+
if (str == tok)
240+
return {};
241+
if (!atEOF())
242+
return {str};
243+
prevTok = {};
244+
setError("unexpected EOF");
245+
return {};
246+
}
247+
237248
// Returns true if S encloses T.
238249
static bool encloses(StringRef s, StringRef t) {
239250
return s.bytes_begin() <= t.bytes_begin() && t.bytes_end() <= s.bytes_end();

lld/ELF/ScriptLexer.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@ class ScriptLexer {
3232
Buffer curBuf;
3333
SmallVector<Buffer, 0> buffers;
3434

35+
struct Token {
36+
StringRef str;
37+
explicit operator bool() const { return !str.empty(); }
38+
operator StringRef() const { return str; }
39+
};
40+
3541
// The token before the last next().
3642
StringRef prevTok;
3743
// Rules for what is a token are different when we are in an expression.
@@ -54,6 +60,7 @@ class ScriptLexer {
5460
void skip();
5561
bool consume(StringRef tok);
5662
void expect(StringRef expect);
63+
Token till(StringRef tok);
5764
std::string getCurrentLocation();
5865
MemoryBufferRef getCurrentMB();
5966

lld/ELF/ScriptParser.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -527,10 +527,9 @@ void ScriptParser::readOutputFormat() {
527527

528528
void ScriptParser::readPhdrs() {
529529
expect("{");
530-
531-
while (!errorCount() && !consume("}")) {
530+
while (auto tok = till("}")) {
532531
PhdrsCommand cmd;
533-
cmd.name = next();
532+
cmd.name = tok;
534533
cmd.type = readPhdrType();
535534

536535
while (!errorCount() && !consume(";")) {
@@ -626,15 +625,14 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
626625

627626
void ScriptParser::readOverwriteSections() {
628627
expect("{");
629-
while (!errorCount() && !consume("}"))
630-
script->overwriteSections.push_back(readOutputSectionDescription(next()));
628+
while (auto tok = till("}"))
629+
script->overwriteSections.push_back(readOutputSectionDescription(tok));
631630
}
632631

633632
void ScriptParser::readSections() {
634633
expect("{");
635634
SmallVector<SectionCommand *, 0> v;
636-
while (!errorCount() && !consume("}")) {
637-
StringRef tok = next();
635+
while (auto tok = till("}")) {
638636
if (tok == "OVERLAY") {
639637
for (SectionCommand *cmd : readOverlay())
640638
v.push_back(cmd);
@@ -1005,8 +1003,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
10051003
osec->constraint = ConstraintKind::ReadWrite;
10061004
expect("{");
10071005

1008-
while (!errorCount() && !consume("}")) {
1009-
StringRef tok = next();
1006+
while (auto tok = till("}")) {
10101007
if (tok == ";") {
10111008
// Empty commands are allowed. Do nothing here.
10121009
} else if (SymbolAssignment *assign = readAssignment(tok)) {
@@ -1806,8 +1803,7 @@ Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
18061803
// MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
18071804
void ScriptParser::readMemory() {
18081805
expect("{");
1809-
while (!errorCount() && !consume("}")) {
1810-
StringRef tok = next();
1806+
while (auto tok = till("}")) {
18111807
if (tok == "INCLUDE") {
18121808
readInclude();
18131809
continue;

lld/test/ELF/linkerscript/phdrs.s

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ PHDRS { text PT_FOO FOOHDR; }
101101
PHDRS { text PT_LOAD ;
102102

103103
# RUN: not ld.lld -T unclosed.lds a.o 2>&1 | FileCheck --check-prefix=UNCLOSED %s
104-
# UNCLOSED:error: unclosed.lds:1: invalid program header type:
104+
# UNCLOSED:error: unclosed.lds:1: unexpected EOF
105+
# UNCLOSED-NOT:{{.}}
105106

106107
#--- a.s
107108
.global _start

lld/test/ELF/linkerscript/sections.s

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,8 @@ SECTIONS {
103103
.text : { *(.text) }
104104

105105
# RUN: not ld.lld -T unclosed.lds a.o 2>&1 | FileCheck --check-prefix=UNCLOSED %s
106-
# UNCLOSED: error: unclosed.lds:1: malformed number:
106+
# UNCLOSED:error: unclosed.lds:1: unexpected EOF
107+
# UNCLOSED-NOT:{{.}}
107108

108109
#--- unclosed-out.lds
109110
SECTIONS {

0 commit comments

Comments
 (0)