Prevent purging referenced symbols

This is an immediate fix for #492, although #342 is needed to implement the
desired functionality.
This commit is contained in:
ISSOtm
2020-03-21 15:42:52 +01:00
parent eb445271df
commit 03967bd623
5 changed files with 42 additions and 0 deletions

View File

@@ -33,6 +33,7 @@ struct sSymbol {
bool isConstant; /* Whether the symbol's value is currently known */ bool isConstant; /* Whether the symbol's value is currently known */
bool isExported; /* Whether the symbol is to be exported */ bool isExported; /* Whether the symbol is to be exported */
bool isBuiltin; /* Whether the symbol is a built-in */ bool isBuiltin; /* Whether the symbol is a built-in */
bool isReferenced; /* Whether the symbol is referenced in a RPN expr */
struct sSymbol *pScope; struct sSymbol *pScope;
struct sSymbol *pNext; struct sSymbol *pNext;
struct Section *pSection; struct Section *pSection;

View File

@@ -127,6 +127,7 @@ static struct sSymbol *createsymbol(char const *s)
(*ppsym)->isConstant = false; (*ppsym)->isConstant = false;
(*ppsym)->isExported = false; (*ppsym)->isExported = false;
(*ppsym)->isBuiltin = false; (*ppsym)->isBuiltin = false;
(*ppsym)->isReferenced = false;
(*ppsym)->pScope = NULL; (*ppsym)->pScope = NULL;
(*ppsym)->pNext = NULL; (*ppsym)->pNext = NULL;
(*ppsym)->pSection = NULL; (*ppsym)->pSection = NULL;
@@ -211,6 +212,11 @@ struct sSymbol *sym_FindSymbol(char const *tzName)
return findsymbol(tzName, pscope); return findsymbol(tzName, pscope);
} }
static inline bool isReferenced(struct sSymbol const *sym)
{
return sym->isReferenced;
}
/* /*
* Purge a symbol * Purge a symbol
*/ */
@@ -230,6 +236,9 @@ void sym_Purge(char const *tzName)
yyerror("'%s' not defined", tzName); yyerror("'%s' not defined", tzName);
} else if ((*ppSym)->isBuiltin) { } else if ((*ppSym)->isBuiltin) {
yyerror("Built-in symbol '%s' cannot be purged", tzName); yyerror("Built-in symbol '%s' cannot be purged", tzName);
} else if (isReferenced(*ppSym)) {
yyerror("Symbol \"%s\" is referenced and thus cannot be purged",
tzName);
} else { } else {
struct sSymbol *pSym; struct sSymbol *pSym;
@@ -468,6 +477,7 @@ struct sSymbol *sym_AddReloc(char const *tzSym)
else if (sym_IsDefined(nsym)) else if (sym_IsDefined(nsym))
yyerror("'%s' already defined in %s(%d)", tzSym, yyerror("'%s' already defined in %s(%d)", tzSym,
nsym->tzFileName, nsym->nFileLine); nsym->tzFileName, nsym->nFileLine);
/* If the symbol already exists as a ref, just "take over" it */
nsym->nValue = nPC; nsym->nValue = nPC;
nsym->type = SYM_LABEL; nsym->type = SYM_LABEL;
@@ -544,6 +554,7 @@ void sym_Ref(char const *tzSym)
nsym = createsymbol(tzSym); nsym = createsymbol(tzSym);
nsym->type = SYM_REF; nsym->type = SYM_REF;
} }
nsym->isReferenced = true;
} }
/* /*

23
test/asm/purge-ref.asm Normal file
View File

@@ -0,0 +1,23 @@
SECTION "test", ROM0 ; Important: do not purge this!
dw ref
PURGE ref
OK:
PURGE OK
dw NotOK
NotOK:
PURGE NotOK
EvenLessOK:
dw EvenLessOK
PURGE EvenLessOK
SECTION "fixed", ROM0[0]
Maybe:
dw Maybe
; This is currently fine because the expression above is fully evaluated
; above, so it's fine as of now... but changing it might make sense
PURGE Maybe

7
test/asm/purge-ref.err Normal file
View File

@@ -0,0 +1,7 @@
ERROR: purge-ref.asm(4):
Symbol "ref" is referenced and thus cannot be purged
ERROR: purge-ref.asm(11):
Symbol "NotOK" is referenced and thus cannot be purged
ERROR: purge-ref.asm(15):
Symbol "EvenLessOK" is referenced and thus cannot be purged
error: Assembly aborted (3 errors)!

0
test/asm/purge-ref.out Normal file
View File