as: Fix handling local labels - scc - simple c99 compiler
 (HTM) git clone git://git.simple-cc.org/scc
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 22cde750b3e0d4605e5fbdc127c03b8d28338ec0
 (DIR) parent b6a9d725edd7db0e2ef5e23db0d543242b989220
 (HTM) Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
       Date:   Sun, 11 Feb 2024 09:41:07 +0100
       
       as: Fix handling local labels
       
       Local labels had several problems:
       
               - They were overring the current label
               - They were not corrected located using lookup()
       
       Diffstat:
         M src/cmd/as/symbol.c                 |      22 +++++++++++++++++-----
       
       1 file changed, 17 insertions(+), 5 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/as/symbol.c b/src/cmd/as/symbol.c
       @@ -4,6 +4,7 @@
        #include <stdlib.h>
        #include <string.h>
        
       +#include <scc/cstd.h>
        #include <scc/scc.h>
        #include "as.h"
        
       @@ -15,10 +16,9 @@ Section *sabs, *sbss, *sdata, *stext;
        Symbol *linesym, *symlist;
        int pass;
        
       -static Symbol *hashtbl[HASHSIZ], *symlast;
       +static Symbol *hashtbl[HASHSIZ], *symlast, *cursym;
        static Alloc *tmpalloc;
        
       -
        #ifndef NDEBUG
        void
        dumpstab(char *msg)
       @@ -45,8 +45,19 @@ lookup(char *name)
        {
                unsigned h;
                Symbol *sym, **list;
       -        int c, symtype;
       +        int r, c, symtype;
                char *t;
       +        char buf[INTIDENTSIZ+1];
       +
       +        if (*name == '.' && cursym) {
       +                if (!cursym)
       +                        error("local label '%s' without global label", name);
       +                t = cursym->name.buf;
       +                r = snprintf(buf, sizeof(buf), "%s%s", t, name);
       +                if (r < 0 || r >= sizeof(buf))
       +                        error("too long local label '%s%s'", t, name);
       +                name = buf;
       +        }
        
                h = genhash(name) & HASHSIZ-1;
        
       @@ -79,13 +90,14 @@ lookup(char *name)
        Symbol *
        deflabel(char *name)
        {
       -        static Symbol *cursym;
       +        int local = 0;
                Symbol *sym;
                char label[MAXSYM+1];
        
                if (*name == '.') {
                        int r;
        
       +                local = 1;
                        if (!cursym) {
                                error("local label '%s' without global label", name);
                                return NULL;
       @@ -109,7 +121,7 @@ deflabel(char *name)
                sym->value = cursec->curpc;
                sym->section = cursec;
        
       -        if (*name != '.')
       +        if (!local)
                        cursym = sym;
                return sym;
        }