diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index 1048bfbc2..c57fcff2a 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -211,6 +211,8 @@ static void SymReplaceExprRefs (SymEntry* S) void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags) /* Define a new symbol */ { + int Redef = 0; /* Flag for symbol redefinition */ + if (S->Flags & SF_IMPORT) { /* Defined symbol is marked as imported external symbol */ Error ("Symbol '%m%p' is already an import", GetSymName (S)); @@ -238,6 +240,7 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags */ FreeExpr (S->Expr); S->Expr = 0; + Redef = 1; } } @@ -291,8 +294,10 @@ void SymDef (SymEntry* S, ExprNode* Expr, unsigned char AddrSize, unsigned Flags } } - /* If this is not a local symbol, remember it as the last global one */ - if ((S->Flags & SF_LOCAL) == 0) { + /* If this is not a local symbol and not a redefinition for a variable + ** symbol, remember it as the last global one. + */ + if ((S->Flags & SF_LOCAL) == 0 && !Redef) { SymLast = S; } } diff --git a/test/asm/err/bug505.s b/test/asm/err/bug505.s new file mode 100644 index 000000000..8cb0e2f18 --- /dev/null +++ b/test/asm/err/bug505.s @@ -0,0 +1,28 @@ +; Test for #505 taken from the issue +; Redefining a variable symbol "reopens" the old name space for cheap locals +; Behavior should be: First definition of a variable symbol opens a new +; scope for cheap locals, redefinitions of the same symbols do not. + +;this starts a new scope for cheap local lables +SomeSymbol .set 4 + + jmp @CheapLocal1 + +@CheapLocal0: + + .byte $8b + +CheapLocalScopeBreaker0: + +CheapLocalScopeBreaker1: + +CheapLocalScopeBreaker2: + +CheapLocalScopeBreaker3: + +;this continues the same cheap scope as before, regardless of the many global labels in between +SomeSymbol .set 5 + +@CheapLocal1: + + lda @CheapLocal0