Fixed a problem reported by thefox: A symbol reference with an explicit scope
specification that is used when the scope is already closed, has be made a trampoline symbol later, referencing a symbol outside of the scope explicit specified. git-svn-id: svn://svn.cc65.org/cc65/trunk@5880 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -138,7 +138,7 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E)
|
|||||||
int Cmp = SB_Compare (Name, SymName);
|
int Cmp = SB_Compare (Name, SymName);
|
||||||
if (Cmp < 0 && T->Left) {
|
if (Cmp < 0 && T->Left) {
|
||||||
T = T->Left;
|
T = T->Left;
|
||||||
} else if (Cmp > 0&& T->Right) {
|
} else if (Cmp > 0 && T->Right) {
|
||||||
T = T->Right;
|
T = T->Right;
|
||||||
} else {
|
} else {
|
||||||
/* Found or end of search, return the result */
|
/* Found or end of search, return the result */
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -67,12 +67,13 @@ struct HLLDbgSym;
|
|||||||
#define SF_IMPORT 0x0008 /* Import this symbol */
|
#define SF_IMPORT 0x0008 /* Import this symbol */
|
||||||
#define SF_GLOBAL 0x0010 /* Global symbol */
|
#define SF_GLOBAL 0x0010 /* Global symbol */
|
||||||
#define SF_LOCAL 0x0020 /* Cheap local symbol */
|
#define SF_LOCAL 0x0020 /* Cheap local symbol */
|
||||||
#define SF_LABEL 0x0080 /* Used as a label */
|
#define SF_LABEL 0x0040 /* Used as a label */
|
||||||
#define SF_VAR 0x0100 /* Variable symbol */
|
#define SF_VAR 0x0080 /* Variable symbol */
|
||||||
#define SF_FORCED 0x0400 /* Forced import, SF_IMPORT also set */
|
#define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */
|
||||||
#define SF_MULTDEF 0x2000 /* Multiply defined symbol */
|
#define SF_FIXED 0x0200 /* May not be trampoline */
|
||||||
#define SF_DEFINED 0x4000 /* Defined */
|
#define SF_MULTDEF 0x1000 /* Multiply defined symbol */
|
||||||
#define SF_REFERENCED 0x8000 /* Referenced */
|
#define SF_DEFINED 0x2000 /* Defined */
|
||||||
|
#define SF_REFERENCED 0x4000 /* Referenced */
|
||||||
|
|
||||||
/* Combined values */
|
/* Combined values */
|
||||||
#define SF_REFIMP (SF_REFERENCED|SF_IMPORT) /* A ref'd import */
|
#define SF_REFIMP (SF_REFERENCED|SF_IMPORT) /* A ref'd import */
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -266,6 +266,9 @@ void SymLeaveLevel (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Mark the scope as closed */
|
||||||
|
CurrentScope->Flags |= ST_CLOSED;
|
||||||
|
|
||||||
/* Leave the scope */
|
/* Leave the scope */
|
||||||
CurrentScope = CurrentScope->Parent;
|
CurrentScope = CurrentScope->Parent;
|
||||||
}
|
}
|
||||||
@@ -385,13 +388,22 @@ SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew)
|
|||||||
|
|
||||||
/* If we found an entry, return it */
|
/* If we found an entry, return it */
|
||||||
if (Cmp == 0) {
|
if (Cmp == 0) {
|
||||||
|
if (SymTabIsClosed (Scope)) {
|
||||||
|
S->Flags |= SF_FIXED;
|
||||||
|
}
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AllocNew) {
|
if (AllocNew) {
|
||||||
|
|
||||||
/* Otherwise create a new entry, insert and return it */
|
/* Otherwise create a new entry, insert and return it. If the scope is
|
||||||
|
* already closed, mark the symbol as fixed so it won't be resolved
|
||||||
|
* by a symbol in the enclosing scopes later.
|
||||||
|
*/
|
||||||
SymEntry* N = NewSymEntry (Name, SF_NONE);
|
SymEntry* N = NewSymEntry (Name, SF_NONE);
|
||||||
|
if (SymTabIsClosed (Scope)) {
|
||||||
|
N->Flags |= SF_FIXED;
|
||||||
|
}
|
||||||
N->Sym.Tab = Scope;
|
N->Sym.Tab = Scope;
|
||||||
if (S == 0) {
|
if (S == 0) {
|
||||||
Scope->Table[Hash] = N;
|
Scope->Table[Hash] = N;
|
||||||
@@ -423,8 +435,8 @@ SymEntry* SymFindAny (SymTable* Scope, const StrBuf* Name)
|
|||||||
* because for such symbols there is a real entry in one of the parent
|
* because for such symbols there is a real entry in one of the parent
|
||||||
* scopes.
|
* scopes.
|
||||||
*/
|
*/
|
||||||
Sym = SymFind (Scope, Name, SYM_FIND_EXISTING);
|
unsigned Hash = HashBuf (Name) % Scope->TableSlots;
|
||||||
if (Sym) {
|
if (SymSearchTree (Scope->Table[Hash], Name, &Sym) == 0) {
|
||||||
if (Sym->Flags & SF_UNUSED) {
|
if (Sym->Flags & SF_UNUSED) {
|
||||||
Sym = 0;
|
Sym = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -449,15 +461,16 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
{
|
{
|
||||||
/* Undefined symbol. It may be...
|
/* Undefined symbol. It may be...
|
||||||
*
|
*
|
||||||
* - An undefined symbol in a nested lexical level. In this
|
* - An undefined symbol in a nested lexical level. If the symbol is not
|
||||||
* case, search for the symbol in the higher levels and
|
* fixed to this level, search for the symbol in the higher levels and
|
||||||
* make the entry a trampoline entry if we find one.
|
* make the entry a trampoline entry if we find one.
|
||||||
*
|
*
|
||||||
* - If the symbol is not found, it is a real undefined symbol.
|
* - If the symbol is not found, it is a real undefined symbol. If the
|
||||||
* If the AutoImport flag is set, make it an import. If the
|
* AutoImport flag is set, make it an import. If the AutoImport flag is
|
||||||
* AutoImport flag is not set, it's an error.
|
* not set, it's an error.
|
||||||
*/
|
*/
|
||||||
SymEntry* Sym = 0;
|
SymEntry* Sym = 0;
|
||||||
|
if ((S->Flags & SF_FIXED) == 0) {
|
||||||
SymTable* Tab = GetSymParentScope (S);
|
SymTable* Tab = GetSymParentScope (S);
|
||||||
while (Tab) {
|
while (Tab) {
|
||||||
Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING);
|
Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING);
|
||||||
@@ -470,6 +483,7 @@ static void SymCheckUndefined (SymEntry* S)
|
|||||||
/* No matching symbol found in this level. Look further */
|
/* No matching symbol found in this level. Look further */
|
||||||
Tab = Tab->Parent;
|
Tab = Tab->Parent;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Sym) {
|
if (Sym) {
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2011, Ullrich von Bassewitz */
|
/* (C) 1998-2012, Ullrich von Bassewitz */
|
||||||
/* Roemerstrasse 52 */
|
/* Roemerstrasse 52 */
|
||||||
/* D-70794 Filderstadt */
|
/* D-70794 Filderstadt */
|
||||||
/* EMail: uz@cc65.org */
|
/* EMail: uz@cc65.org */
|
||||||
@@ -58,6 +58,7 @@
|
|||||||
/* Symbol table flags */
|
/* Symbol table flags */
|
||||||
#define ST_NONE 0x00 /* No flags */
|
#define ST_NONE 0x00 /* No flags */
|
||||||
#define ST_DEFINED 0x01 /* Scope has been defined */
|
#define ST_DEFINED 0x01 /* Scope has been defined */
|
||||||
|
#define ST_CLOSED 0x02 /* Scope is closed */
|
||||||
|
|
||||||
/* A symbol table */
|
/* A symbol table */
|
||||||
typedef struct SymTable SymTable;
|
typedef struct SymTable SymTable;
|
||||||
@@ -136,6 +137,16 @@ INLINE unsigned char GetSymTabType (const SymTable* S)
|
|||||||
# define GetSymTabType(S) ((S)->Type)
|
# define GetSymTabType(S) ((S)->Type)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(HAVE_INLINE)
|
||||||
|
INLINE int SymTabIsClosed (const SymTable* S)
|
||||||
|
/* Return true if the symbol table has been closed */
|
||||||
|
{
|
||||||
|
return (S->Flags & ST_CLOSED) != 0;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define SymTabIsClosed(S) (((S)->Flags & ST_CLOSED) != 0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void SymCheck (void);
|
void SymCheck (void);
|
||||||
/* Run through all symbols and check for anomalies and errors */
|
/* Run through all symbols and check for anomalies and errors */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user