Skip to content

Commit

Permalink
Fix expansions that start from the end of another expansion (#839)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Rangi42 authored Apr 17, 2021
1 parent 750e93b commit 9923fa3
Show file tree
Hide file tree
Showing 9 changed files with 94 additions and 91 deletions.
17 changes: 13 additions & 4 deletions src/asm/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -736,7 +736,11 @@ 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);
/*
* 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;
Expand Down Expand Up @@ -870,16 +874,21 @@ 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) {
/* 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 */
Expand Down
1 change: 1 addition & 0 deletions test/asm/equs-newline.err
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 1 addition & 5 deletions test/asm/equs-recursion.asm
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
recurse EQUS "recurse "
recurse EQUS "recurse"
recurse

; FIXME: also handle the following:
; recurse EQUS "recurse"
; recurse
6 changes: 1 addition & 5 deletions test/asm/interpolation-recursion.asm
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
recurse EQUS "\{recurse\} "
recurse EQUS "\{recurse\}"
{recurse}

; FIXME: also handle the following:
; recurse EQUS "\{recurse\}"
; {recurse}
130 changes: 65 additions & 65 deletions test/asm/interpolation-recursion.err
Original file line number Diff line number Diff line change
@@ -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}"
8 changes: 2 additions & 6 deletions test/asm/rst.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions test/asm/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ EOF
cat > quote\"file.err <<EOF
warning: quote"file.asm(1): [-Wuser]
quote"file.asm
while expanding symbol "__FILE__"
EOF
fi

Expand Down
8 changes: 8 additions & 0 deletions test/asm/unique-id.err
Original file line number Diff line number Diff line change
@@ -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"
8 changes: 2 additions & 6 deletions test/link/rst.asm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 9923fa3

Please sign in to comment.