scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | Submodules | README | LICENSE

commit 22cde750b3e0d4605e5fbdc127c03b8d28338ec0
parent b6a9d725edd7db0e2ef5e23db0d543242b989220
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:
Msrc/cmd/as/symbol.c | 22+++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)

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; }