From be3fc61859fc4d92ef3295a376c56b5a1218c89f Mon Sep 17 00:00:00 2001 From: Rangi <35663410+Rangi42@users.noreply.github.com> Date: Mon, 6 Jul 2026 14:01:40 -0400 Subject: [PATCH] Fix included linker scripts with no newline at EOF (#2011) --- src/link/lexer.cpp | 27 +++++++++------------- test/link/linkerscript-no-newline-eof.asm | 2 ++ test/link/linkerscript-no-newline-eof.inc | 1 + test/link/linkerscript-no-newline-eof.link | 2 ++ test/link/linkerscript-no-newline-eof.out | 3 +++ 5 files changed, 19 insertions(+), 16 deletions(-) create mode 100644 test/link/linkerscript-no-newline-eof.asm create mode 100644 test/link/linkerscript-no-newline-eof.inc create mode 100644 test/link/linkerscript-no-newline-eof.link create mode 100644 test/link/linkerscript-no-newline-eof.out diff --git a/src/link/lexer.cpp b/src/link/lexer.cpp index 47f16b49..8d4fac74 100644 --- a/src/link/lexer.cpp +++ b/src/link/lexer.cpp @@ -24,8 +24,9 @@ struct LexerStackEntry { std::filebuf file; std::string path; uint32_t lineNo; + bool atEof; - explicit LexerStackEntry(std::string &&path_) : file(), path(path_), lineNo(1) {} + explicit LexerStackEntry(std::string &&path_) : file(), path(path_), lineNo(1), atEof(false) {} }; static std::vector lexerStack; @@ -65,24 +66,18 @@ void lexer_IncLineNo() { yy::parser::symbol_type yylex(); // Forward declaration for `yywrap` static yy::parser::symbol_type yywrap() { - static bool atEof = false; - if (lexerStack.size() != 1) { - if (!atEof) { - // Inject a newline at EOF to simplify parsing. - atEof = true; - return yy::parser::make_newline(); - } - lexerStack.pop_back(); - // Increment the line number *after* an INCLUDE has finished. - ++lexerStack.back().lineNo; - return yylex(); - } - if (!atEof) { + if (LexerStackEntry &context = lexerStack.back(); !context.atEof) { // Inject a newline at EOF to simplify parsing. - atEof = true; + context.atEof = true; return yy::parser::make_newline(); } - return yy::parser::make_YYEOF(); + if (lexerStack.size() == 1) { + return yy::parser::make_YYEOF(); + } + lexerStack.pop_back(); + // Increment the line number *after* an INCLUDE has finished. + ++lexerStack.back().lineNo; + return yylex(); } static std::string readKeyword(int initial) { diff --git a/test/link/linkerscript-no-newline-eof.asm b/test/link/linkerscript-no-newline-eof.asm new file mode 100644 index 00000000..d41460ca --- /dev/null +++ b/test/link/linkerscript-no-newline-eof.asm @@ -0,0 +1,2 @@ +section "test", rom0[1337] +label:: dw label diff --git a/test/link/linkerscript-no-newline-eof.inc b/test/link/linkerscript-no-newline-eof.inc new file mode 100644 index 00000000..3c52026b --- /dev/null +++ b/test/link/linkerscript-no-newline-eof.inc @@ -0,0 +1 @@ +rom0 ; no newline after this \ No newline at end of file diff --git a/test/link/linkerscript-no-newline-eof.link b/test/link/linkerscript-no-newline-eof.link new file mode 100644 index 00000000..d85e282a --- /dev/null +++ b/test/link/linkerscript-no-newline-eof.link @@ -0,0 +1,2 @@ +include "linkerscript-no-newline-eof.inc" + "test" ; no newline after this \ No newline at end of file diff --git a/test/link/linkerscript-no-newline-eof.out b/test/link/linkerscript-no-newline-eof.out new file mode 100644 index 00000000..d48a07a1 --- /dev/null +++ b/test/link/linkerscript-no-newline-eof.out @@ -0,0 +1,3 @@ +error: The linker script assigns section "test" to address $0000, but it was already at $0539 + at linkerscript-no-newline-eof.link(2) +Linking failed with 1 error