]> git.sur5r.net Git - cc65/commitdiff
Fixed a problem reported by thefox: A symbol reference with an explicit scope
authoruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 27 Oct 2012 11:49:37 +0000 (11:49 +0000)
committeruz <uz@b7a2c559-68d2-44c3-8de9-860c34a00d81>
Sat, 27 Oct 2012 11:49:37 +0000 (11:49 +0000)
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

src/ca65/symentry.c
src/ca65/symentry.h
src/ca65/symtab.c
src/ca65/symtab.h

index 3e1830cb83593b75e13d3aed826bc4b6e71affdf..576a24b035ef3878710efbf4ebac0474ecc288b5 100644 (file)
@@ -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 */
index 506e89f4b2f3e70fac4b8267e58c0118df849f15..c0039d00f283731a4b14d334ef2a495d3bede149 100644 (file)
@@ -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 */
index 2bd2149fc118c7141682b7c8000df4fff9eccdb9..eaaab444efd3b81a605ed1ca90e2185235d94f1d 100644 (file)
@@ -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) {
index ea7e66515c7bed5e036b9b522ee3b74c3671d77d..4ef2ea93c114ef99c6ec89f357697abf44ab4052 100644 (file)
@@ -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 */