ref: 9923fa3eee8924d1fd49117bcbd9339e17a1a241
parent: 750e93be3de46f50220ce4920f064380ec9b704f
author: Rangi <35663410+Rangi42@users.noreply.github.com>
date: Sat Apr 17 09:14:40 EDT 2021
Fix expansions that start from the end of another expansion (#839) 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
--- a/src/asm/lexer.c
+++ b/src/asm/lexer.c
@@ -736,7 +736,11 @@
static int peekInternal(uint8_t distance)
{
for (struct Expansion *exp = lexerState->expansions; exp; exp = exp->parent) {
- assert(exp->offset < exp->size);
+ /*
+ * An expansion that has reached its end will have `exp->offset` == `exp->size`,
+ * and `peekInternal` will continue with its parent
+ */
+ assert(exp->offset <= exp->size);
if (distance < exp->size - exp->offset)
return exp->contents.unowned[exp->offset + distance];
distance -= exp->size - exp->offset;
@@ -870,16 +874,21 @@
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) {
- /* When an expansion is done, free it and move up to its parent */
+ if (lexerState->expansions->offset > lexerState->expansions->size) {
+ /*
+ * When advancing would go past an expansion's end, free it,
+ * move up to its parent, and try again to advance
+ */
struct Expansion *exp = lexerState->expansions;
lexerState->expansions = lexerState->expansions->parent;
freeExpansion(exp);
+ goto restart;
}
} else {
/* Advance within the file contents */
--- a/test/asm/equs-newline.err
+++ b/test/asm/equs-newline.err
@@ -3,5 +3,6 @@
while expanding symbol "ACT"
warning: equs-newline.asm(3): [-Wuser]
Second
+while expanding symbol "ACT"
warning: equs-newline.asm(4): [-Wuser]
Third
--- 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
--- 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}
--- 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}"
--- a/test/asm/rst.asm
+++ b/test/asm/rst.asm
@@ -16,12 +16,8 @@
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
--- a/test/asm/test.sh
+++ b/test/asm/test.sh
@@ -62,6 +62,7 @@
cat > quote\"file.err <<EOF
warning: quote"file.asm(1): [-Wuser]
quote"file.asm
+while expanding symbol "__FILE__"
EOF
fi
--- a/test/asm/unique-id.err
+++ b/test/asm/unique-id.err
@@ -1,19 +1,27 @@
warning: unique-id.asm(12) -> 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"
--- a/test/link/rst.asm
+++ b/test/link/rst.asm
@@ -14,12 +14,8 @@
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