[lld] 2a89356 - [ELF] Add till and rewrite while (... consume("}"))
Fangrui Song via llvm-commits
llvm-commits at lists.llvm.org
Fri Jul 26 17:13:41 PDT 2024
Author: Fangrui Song
Date: 2024-07-26T17:13:37-07:00
New Revision: 2a89356d64a274f7171b45d8b7b05b6315a6f627
URL: https://github.com/llvm/llvm-project/commit/2a89356d64a274f7171b45d8b7b05b6315a6f627
DIFF: https://github.com/llvm/llvm-project/commit/2a89356d64a274f7171b45d8b7b05b6315a6f627.diff
LOG: [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.
Added:
Modified:
lld/ELF/ScriptLexer.cpp
lld/ELF/ScriptLexer.h
lld/ELF/ScriptParser.cpp
lld/test/ELF/linkerscript/phdrs.s
lld/test/ELF/linkerscript/sections.s
Removed:
################################################################################
diff --git a/lld/ELF/ScriptLexer.cpp b/lld/ELF/ScriptLexer.cpp
index d3a1586332f99..51282dba53c83 100644
--- a/lld/ELF/ScriptLexer.cpp
+++ b/lld/ELF/ScriptLexer.cpp
@@ -234,6 +234,17 @@ void ScriptLexer::expect(StringRef expect) {
}
}
+ScriptLexer::Token ScriptLexer::till(StringRef tok) {
+ StringRef str = next();
+ if (str == tok)
+ return {};
+ if (!atEOF())
+ return {str};
+ prevTok = {};
+ setError("unexpected EOF");
+ return {};
+}
+
// Returns true if S encloses T.
static bool encloses(StringRef s, StringRef t) {
return s.bytes_begin() <= t.bytes_begin() && t.bytes_end() <= s.bytes_end();
diff --git a/lld/ELF/ScriptLexer.h b/lld/ELF/ScriptLexer.h
index 7651908d60200..bc2b5fee618f7 100644
--- a/lld/ELF/ScriptLexer.h
+++ b/lld/ELF/ScriptLexer.h
@@ -32,6 +32,12 @@ class ScriptLexer {
Buffer curBuf;
SmallVector<Buffer, 0> buffers;
+ struct Token {
+ StringRef str;
+ explicit operator bool() const { return !str.empty(); }
+ operator StringRef() const { return str; }
+ };
+
// The token before the last next().
StringRef prevTok;
// Rules for what is a token are
diff erent when we are in an expression.
@@ -54,6 +60,7 @@ class ScriptLexer {
void skip();
bool consume(StringRef tok);
void expect(StringRef expect);
+ Token till(StringRef tok);
std::string getCurrentLocation();
MemoryBufferRef getCurrentMB();
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index 7303bb564afad..bdfa106090ca5 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -527,10 +527,9 @@ void ScriptParser::readOutputFormat() {
void ScriptParser::readPhdrs() {
expect("{");
-
- while (!errorCount() && !consume("}")) {
+ while (auto tok = till("}")) {
PhdrsCommand cmd;
- cmd.name = next();
+ cmd.name = tok;
cmd.type = readPhdrType();
while (!errorCount() && !consume(";")) {
@@ -626,15 +625,14 @@ SmallVector<SectionCommand *, 0> ScriptParser::readOverlay() {
void ScriptParser::readOverwriteSections() {
expect("{");
- while (!errorCount() && !consume("}"))
- script->overwriteSections.push_back(readOutputSectionDescription(next()));
+ while (auto tok = till("}"))
+ script->overwriteSections.push_back(readOutputSectionDescription(tok));
}
void ScriptParser::readSections() {
expect("{");
SmallVector<SectionCommand *, 0> v;
- while (!errorCount() && !consume("}")) {
- StringRef tok = next();
+ while (auto tok = till("}")) {
if (tok == "OVERLAY") {
for (SectionCommand *cmd : readOverlay())
v.push_back(cmd);
@@ -1005,8 +1003,7 @@ OutputDesc *ScriptParser::readOutputSectionDescription(StringRef outSec) {
osec->constraint = ConstraintKind::ReadWrite;
expect("{");
- while (!errorCount() && !consume("}")) {
- StringRef tok = next();
+ while (auto tok = till("}")) {
if (tok == ";") {
// Empty commands are allowed. Do nothing here.
} else if (SymbolAssignment *assign = readAssignment(tok)) {
@@ -1806,8 +1803,7 @@ Expr ScriptParser::readMemoryAssignment(StringRef s1, StringRef s2,
// MEMORY { name [(attr)] : ORIGIN = origin, LENGTH = len ... }
void ScriptParser::readMemory() {
expect("{");
- while (!errorCount() && !consume("}")) {
- StringRef tok = next();
+ while (auto tok = till("}")) {
if (tok == "INCLUDE") {
readInclude();
continue;
diff --git a/lld/test/ELF/linkerscript/phdrs.s b/lld/test/ELF/linkerscript/phdrs.s
index 18307bcf36675..9768c4ccdbacb 100644
--- a/lld/test/ELF/linkerscript/phdrs.s
+++ b/lld/test/ELF/linkerscript/phdrs.s
@@ -101,7 +101,8 @@ PHDRS { text PT_FOO FOOHDR; }
PHDRS { text PT_LOAD ;
# RUN: not ld.lld -T unclosed.lds a.o 2>&1 | FileCheck --check-prefix=UNCLOSED %s
-# UNCLOSED:error: unclosed.lds:1: invalid program header type:
+# UNCLOSED:error: unclosed.lds:1: unexpected EOF
+# UNCLOSED-NOT:{{.}}
#--- a.s
.global _start
diff --git a/lld/test/ELF/linkerscript/sections.s b/lld/test/ELF/linkerscript/sections.s
index 0453a12ceb147..dbedd12a9129e 100644
--- a/lld/test/ELF/linkerscript/sections.s
+++ b/lld/test/ELF/linkerscript/sections.s
@@ -103,7 +103,8 @@ SECTIONS {
.text : { *(.text) }
# RUN: not ld.lld -T unclosed.lds a.o 2>&1 | FileCheck --check-prefix=UNCLOSED %s
-# UNCLOSED: error: unclosed.lds:1: malformed number:
+# UNCLOSED:error: unclosed.lds:1: unexpected EOF
+# UNCLOSED-NOT:{{.}}
#--- unclosed-out.lds
SECTIONS {
More information about the llvm-commits
mailing list