scc

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

commit b36e3b65309bdaa5515cb2d9a6313998e174e35d
parent 6ac1bf55142759cdd9837f9c11103d1b0e4e15f7
Author: Roberto E. Vargas Caballero <k0ga@shike2.com>
Date:   Sat, 13 Nov 2021 16:50:02 +0100

cc1: Emit padding bytes

Types have alignment that we were ignoring when we were
emitting constants, that was making that the data didn't
match correctly the layout of the desired output.

Diffstat:
Minclude/scc/scc/scc.h | 1+
Msrc/cmd/cc/cc1/code.c | 43+++++++++++++++++++++++++++++++++----------
2 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/include/scc/scc/scc.h b/include/scc/scc/scc.h @@ -15,6 +15,7 @@ extern int enadebug; #define TUINT_MAX ULLONG_MAX #define TINT_MAX LLONG_MAX #define TFLOAT double +#define SIZET size_t struct items { char **s; diff --git a/src/cmd/cc/cc1/code.c b/src/cmd/cc/cc1/code.c @@ -335,14 +335,36 @@ emitstring(Symbol *sym, Type *tp) } } +static Node * +zeronode(Type *tp) +{ + return simplify(convert(constnode(zero), tp, 0)); +} + +static int +emitpadding(Type *tp, SIZET *addr) +{ + SIZET n; + int i; + + n = *addr & tp->align-1; + for (i = 0; i < n; i++) + emitexp(OEXPR, zeronode(chartype)); + *addr += n; + + return n; +} + static void -emitdesig(Node *np, Type *tp) +emitdesig(Node *np, Type *tp, SIZET *addr) { Symbol *sym; - size_t n; /* TODO: This should be SIZET */ + SIZET n; Node *aux; Type *p; + emitpadding(tp, addr); + if (!np) { sym = NULL; } else { @@ -351,6 +373,7 @@ emitdesig(Node *np, Type *tp) sym = np->sym; if (sym->flags & SSTRING) { emitstring(sym, tp); + *addr += tp->n.elem; return; } if ((sym->flags & SINITLST) == 0) @@ -361,24 +384,23 @@ emitdesig(Node *np, Type *tp) case PTR: case INT: case ENUM: - if (sym) - aux = *sym->u.init; - else - aux = simplify(convert(constnode(zero), tp, 0)); + aux = sym ? *sym->u.init : zeronode(tp); + *addr += aux->type->size; emitexp(OEXPR, aux); break; case UNION: - n = tp->n.elem-1; aux = (sym) ? sym->u.init[0] : NULL; - emitdesig(aux, aux->type); + emitdesig(aux, aux->type, addr); + emitpadding(tp, addr); break; case STRUCT: case ARY: for (n = 0; n < tp->n.elem; ++n) { aux = (sym) ? sym->u.init[n] : NULL; p = (tp->op == ARY) ? tp->type : tp->p.fields[n]->type; - emitdesig(aux, p); + emitdesig(aux, p, addr); } + emitpadding(tp, addr); break; default: abort(); @@ -399,9 +421,10 @@ static void emitinit(int op, void *arg) { Node *np = arg; + SIZET addr = 0; fputs("\t(\n", outfp); - emitdesig(np, np->type); + emitdesig(np, np->type, &addr); fputs(")\n", outfp); }