scc

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

commit 433adcd26eaa7d73aaa761abfabc90c3e850e41e
parent 178f43cfd06bac8c689e70a66dfd63cc10347ceb
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); }