From: uz Date: Sat, 27 Oct 2012 11:49:37 +0000 (+0000) Subject: Fixed a problem reported by thefox: A symbol reference with an explicit scope X-Git-Tag: V2.14~194 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=acb3fcb9c7edf907a4ac163c3b50a8ac025ca63d;p=cc65 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 --- diff --git a/src/ca65/symentry.c b/src/ca65/symentry.c index 3e1830cb8..576a24b03 100644 --- a/src/ca65/symentry.c +++ b/src/ca65/symentry.c @@ -90,7 +90,7 @@ SymEntry* NewSymEntry (const StrBuf* Name, unsigned Flags) S->RefLines = EmptyCollection; for (I = 0; I < sizeof (S->GuessedUse) / sizeof (S->GuessedUse[0]); ++I) { S->GuessedUse[I] = 0; - } + } S->HLLSym = 0; S->Flags = Flags; S->DebugSymId = ~0U; @@ -138,7 +138,7 @@ int SymSearchTree (SymEntry* T, const StrBuf* Name, SymEntry** E) int Cmp = SB_Compare (Name, SymName); if (Cmp < 0 && T->Left) { T = T->Left; - } else if (Cmp > 0&& T->Right) { + } else if (Cmp > 0 && T->Right) { T = T->Right; } else { /* Found or end of search, return the result */ diff --git a/src/ca65/symentry.h b/src/ca65/symentry.h index 506e89f4b..c0039d00f 100644 --- a/src/ca65/symentry.h +++ b/src/ca65/symentry.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2011, Ullrich von Bassewitz */ +/* (C) 1998-2012, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -67,12 +67,13 @@ struct HLLDbgSym; #define SF_IMPORT 0x0008 /* Import this symbol */ #define SF_GLOBAL 0x0010 /* Global symbol */ #define SF_LOCAL 0x0020 /* Cheap local symbol */ -#define SF_LABEL 0x0080 /* Used as a label */ -#define SF_VAR 0x0100 /* Variable symbol */ -#define SF_FORCED 0x0400 /* Forced import, SF_IMPORT also set */ -#define SF_MULTDEF 0x2000 /* Multiply defined symbol */ -#define SF_DEFINED 0x4000 /* Defined */ -#define SF_REFERENCED 0x8000 /* Referenced */ +#define SF_LABEL 0x0040 /* Used as a label */ +#define SF_VAR 0x0080 /* Variable symbol */ +#define SF_FORCED 0x0100 /* Forced import, SF_IMPORT also set */ +#define SF_FIXED 0x0200 /* May not be trampoline */ +#define SF_MULTDEF 0x1000 /* Multiply defined symbol */ +#define SF_DEFINED 0x2000 /* Defined */ +#define SF_REFERENCED 0x4000 /* Referenced */ /* Combined values */ #define SF_REFIMP (SF_REFERENCED|SF_IMPORT) /* A ref'd import */ diff --git a/src/ca65/symtab.c b/src/ca65/symtab.c index 2bd2149fc..eaaab444e 100644 --- a/src/ca65/symtab.c +++ b/src/ca65/symtab.c @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2011, Ullrich von Bassewitz */ +/* (C) 1998-2012, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -266,6 +266,9 @@ void SymLeaveLevel (void) } } + /* Mark the scope as closed */ + CurrentScope->Flags |= ST_CLOSED; + /* Leave the scope */ CurrentScope = CurrentScope->Parent; } @@ -385,13 +388,22 @@ SymEntry* SymFind (SymTable* Scope, const StrBuf* Name, int AllocNew) /* If we found an entry, return it */ if (Cmp == 0) { + if (SymTabIsClosed (Scope)) { + S->Flags |= SF_FIXED; + } return S; } 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); + if (SymTabIsClosed (Scope)) { + N->Flags |= SF_FIXED; + } N->Sym.Tab = Scope; if (S == 0) { 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 * scopes. */ - Sym = SymFind (Scope, Name, SYM_FIND_EXISTING); - if (Sym) { + unsigned Hash = HashBuf (Name) % Scope->TableSlots; + if (SymSearchTree (Scope->Table[Hash], Name, &Sym) == 0) { if (Sym->Flags & SF_UNUSED) { Sym = 0; } else { @@ -449,26 +461,28 @@ static void SymCheckUndefined (SymEntry* S) { /* Undefined symbol. It may be... * - * - An undefined symbol in a nested lexical level. In this - * case, search for the symbol in the higher levels and + * - An undefined symbol in a nested lexical level. If the symbol is not + * fixed to this level, search for the symbol in the higher levels and * make the entry a trampoline entry if we find one. * - * - If the symbol is not found, it is a real undefined symbol. - * If the AutoImport flag is set, make it an import. If the - * AutoImport flag is not set, it's an error. + * - If the symbol is not found, it is a real undefined symbol. If the + * AutoImport flag is set, make it an import. If the AutoImport flag is + * not set, it's an error. */ SymEntry* Sym = 0; - SymTable* Tab = GetSymParentScope (S); - while (Tab) { - Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING); - if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) { - /* We've found a symbol in a higher level that is - * either defined in the source, or an import. - */ - break; + if ((S->Flags & SF_FIXED) == 0) { + SymTable* Tab = GetSymParentScope (S); + while (Tab) { + Sym = SymFind (Tab, GetStrBuf (S->Name), SYM_FIND_EXISTING); + if (Sym && (Sym->Flags & (SF_DEFINED | SF_IMPORT)) != 0) { + /* We've found a symbol in a higher level that is + * either defined in the source, or an import. + */ + break; + } + /* No matching symbol found in this level. Look further */ + Tab = Tab->Parent; } - /* No matching symbol found in this level. Look further */ - Tab = Tab->Parent; } if (Sym) { diff --git a/src/ca65/symtab.h b/src/ca65/symtab.h index ea7e66515..4ef2ea93c 100644 --- a/src/ca65/symtab.h +++ b/src/ca65/symtab.h @@ -6,7 +6,7 @@ /* */ /* */ /* */ -/* (C) 1998-2011, Ullrich von Bassewitz */ +/* (C) 1998-2012, Ullrich von Bassewitz */ /* Roemerstrasse 52 */ /* D-70794 Filderstadt */ /* EMail: uz@cc65.org */ @@ -58,6 +58,7 @@ /* Symbol table flags */ #define ST_NONE 0x00 /* No flags */ #define ST_DEFINED 0x01 /* Scope has been defined */ +#define ST_CLOSED 0x02 /* Scope is closed */ /* A symbol table */ typedef struct SymTable SymTable; @@ -136,6 +137,16 @@ INLINE unsigned char GetSymTabType (const SymTable* S) # define GetSymTabType(S) ((S)->Type) #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); /* Run through all symbols and check for anomalies and errors */