cproc

Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.nihaljere.xyz/cproc
Log | Files | Refs | Submodules | README | LICENSE

commit fca0b26275a82c480a5286c281834dad6887b410
parent b6e582d2842aa21e24a70675b760bba331dc0d72
Author: Michael Forney <mforney@mforney.org>
Date:   Mon, 15 Apr 2019 01:11:08 -0700

Handle static sub-initializers

Diffstat:
Mqbe.c | 25+++++++++++++++++--------
Rtests/initializer-replace.c -> tests/initializer-replace-local.c | 0
Rtests/initializer-replace.qbe -> tests/initializer-replace-local.qbe | 0
Atests/initializer-replace-static.c | 6++++++
Atests/initializer-replace-static.qbe | 1+
5 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/qbe.c b/qbe.c @@ -1234,15 +1234,24 @@ emitdata(struct decl *d, struct init *init) emitvalue(d->value); printf(" = align %d { ", d->align); - for (; init; init = init->next) { - if (init->start < offset) /* XXX: sub-initializer may overlap */ - continue; - if (offset < init->start) - printf("z %" PRIu64 ", ", init->start - offset); - printf("%c ", init->expr->type->kind == TYPEARRAY ? init->expr->type->base->repr->ext : init->expr->type->repr->ext); - dataitem(init->expr, init->end - init->start); + while (init) { + cur = init; + while (init = init->next, init && init->start < cur->end) { + /* + XXX: Currently, if multiple union members are + initialized, these assertions may not hold. + (https://todo.sr.ht/~mcf/cc-issues/38) + */ + assert(cur->expr->kind == EXPRSTRING); + assert(init->expr->kind == EXPRCONST); + cur->expr->string.data[init->start - cur->start] = init->expr->constant.i; + } + if (offset < cur->start) + printf("z %" PRIu64 ", ", cur->start - offset); + printf("%c ", cur->expr->type->kind == TYPEARRAY ? cur->expr->type->base->repr->ext : cur->expr->type->repr->ext); + dataitem(cur->expr, cur->end - cur->start); fputs(", ", stdout); - offset = init->end; + offset = cur->end; } assert(offset <= d->type->size); if (offset < d->type->size) diff --git a/tests/initializer-replace.c b/tests/initializer-replace-local.c diff --git a/tests/initializer-replace.qbe b/tests/initializer-replace-local.qbe diff --git a/tests/initializer-replace-static.c b/tests/initializer-replace-static.c @@ -0,0 +1,6 @@ +struct { + char s[6]; +} x = { + .s = "hello", + .s[1] = 'a', +}; diff --git a/tests/initializer-replace-static.qbe b/tests/initializer-replace-static.qbe @@ -0,0 +1 @@ +export data $x = align 1 { b "hallo", z 1, }