From 25c41e0814bdc8bcab7722bb4108c5ab4f8eaaef Mon Sep 17 00:00:00 2001 From: Rangi Date: Sat, 17 Apr 2021 12:44:24 -0400 Subject: [PATCH] Fix expansions that start from the end of another expansion Do not free an expansion until its offset is *past* its size. This means potentially freeing a nested stack of expansions all at once. Fixes #696 --- src/asm/lexer.c | 10 ++- test/asm/equs-newline.err | 1 + test/asm/equs-recursion.asm | 6 +- test/asm/interpolation-recursion.asm | 6 +- test/asm/interpolation-recursion.err | 130 +++++++++++++-------------- test/asm/rst.asm | 8 +- test/asm/test.sh | 1 + test/asm/unique-id.err | 8 ++ test/link/rst.asm | 8 +- 9 files changed, 88 insertions(+), 90 deletions(-) diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 4f23187e7e..6fd5e79747 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -736,7 +736,9 @@ static char const *readMacroArg(char name) static int peekInternal(uint8_t distance) { for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) { - assert(exp->offset < exp->size); + assert(exp->offset <= exp->size); + if (exp->offset == exp->size) + continue; if (distance < exp->size - exp->offset) return exp->contents.unowned[exp->offset + distance]; distance -= exp->size - exp->offset; @@ -870,16 +872,18 @@ static void shiftChar(void) lexerState->macroArgScanDistance--; +restart: if (lexerState->expansions) { /* Advance within the current expansion */ - assert(lexerState->expansions->offset < lexerState->expansions->size); + assert(lexerState->expansions->offset <= lexerState->expansions->size); lexerState->expansions->offset++; - if (lexerState->expansions->offset == lexerState->expansions->size) { + if (lexerState->expansions->offset > lexerState->expansions->size) { /* When an expansion is done, free it and move up to its parent */ struct Expansion *exp = lexerState->expansions; lexerState->expansions = lexerState->expansions->parent; freeExpansion(exp); + goto restart; } } else { /* Advance within the file contents */ diff --git a/test/asm/equs-newline.err b/test/asm/equs-newline.err index 04ceb7beb2..3208a80aa4 100644 --- a/test/asm/equs-newline.err +++ b/test/asm/equs-newline.err @@ -3,5 +3,6 @@ warning: equs-newline.asm(3): [-Wuser] while expanding symbol "ACT" warning: equs-newline.asm(3): [-Wuser] Second +while expanding symbol "ACT" warning: equs-newline.asm(4): [-Wuser] Third diff --git a/test/asm/equs-recursion.asm b/test/asm/equs-recursion.asm index 3aae90530b..9ca7c997cc 100644 --- a/test/asm/equs-recursion.asm +++ b/test/asm/equs-recursion.asm @@ -1,6 +1,2 @@ -recurse EQUS "recurse " +recurse EQUS "recurse" recurse - -; FIXME: also handle the following: -; recurse EQUS "recurse" -; recurse diff --git a/test/asm/interpolation-recursion.asm b/test/asm/interpolation-recursion.asm index f522b1e8c3..a1e2ba5c46 100644 --- a/test/asm/interpolation-recursion.asm +++ b/test/asm/interpolation-recursion.asm @@ -1,6 +1,2 @@ -recurse EQUS "\{recurse\} " +recurse EQUS "\{recurse\}" {recurse} - -; FIXME: also handle the following: -; recurse EQUS "\{recurse\}" -; {recurse} diff --git a/test/asm/interpolation-recursion.err b/test/asm/interpolation-recursion.err index 3597573d1b..50fd075e7f 100644 --- a/test/asm/interpolation-recursion.err +++ b/test/asm/interpolation-recursion.err @@ -1,67 +1,67 @@ FATAL: interpolation-recursion.asm(2): Recursion limit (64) exceeded -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " -while expanding symbol "{recurse} " +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" +while expanding symbol "{recurse}" diff --git a/test/asm/rst.asm b/test/asm/rst.asm index 09dafe843d..e42683cb31 100644 --- a/test/asm/rst.asm +++ b/test/asm/rst.asm @@ -16,12 +16,8 @@ SECTION "calls", ROM0[0] defRST: MACRO -; FIXME: This is required, otherwise the lexer does not paste the two tokens -ADDR equs "$\1" -SECTION "rst\1", ROM0[ADDR] - -rst\1: - PURGE ADDR + SECTION "rst\1", ROM0[$\1] + rst\1: ENDM defRST 00 defRST 08 diff --git a/test/asm/test.sh b/test/asm/test.sh index 7056cf2b0f..90b02add8b 100755 --- a/test/asm/test.sh +++ b/test/asm/test.sh @@ -62,6 +62,7 @@ EOF cat > quote\"file.err < unique-id.asm::m(4): [-Wuser] _u1 +while expanding symbol "warn_unique" warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser] _u2 +while expanding symbol "warn_unique" warning: unique-id.asm(12) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser] _u3 +while expanding symbol "warn_unique" warning: unique-id.asm(12) -> unique-id.asm::m(8): [-Wuser] _u1 +while expanding symbol "warn_unique" warning: unique-id.asm(14) -> unique-id.asm::m(4): [-Wuser] _u4 +while expanding symbol "warn_unique" warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~1(6): [-Wuser] _u5 +while expanding symbol "warn_unique" warning: unique-id.asm(14) -> unique-id.asm::m(5) -> unique-id.asm::m::REPT~2(6): [-Wuser] _u6 +while expanding symbol "warn_unique" warning: unique-id.asm(14) -> unique-id.asm::m(8): [-Wuser] _u4 +while expanding symbol "warn_unique" FATAL: unique-id.asm(15): Macro argument '\@' not defined while expanding symbol "warn_unique" diff --git a/test/link/rst.asm b/test/link/rst.asm index 14df973d10..76f2afa06a 100644 --- a/test/link/rst.asm +++ b/test/link/rst.asm @@ -14,12 +14,8 @@ SECTION "calls", ROM0[0] defRST: MACRO -; FIXME: This is required, otherwise the lexer does not paste the two tokens -ADDR equs "$\1" -SECTION "rst\1", ROM0[ADDR] - -rst\1: - PURGE ADDR + SECTION "rst\1", ROM0[$\1] + rst\1: ENDM defRST 00 defRST 08