From fca0b26275a82c480a5286c281834dad6887b410 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Mon, 15 Apr 2019 01:11:08 -0700 Subject: Handle static sub-initializers --- qbe.c | 25 +++++++++++++++++-------- tests/initializer-replace-local.c | 10 ++++++++++ tests/initializer-replace-local.qbe | 22 ++++++++++++++++++++++ tests/initializer-replace-static.c | 6 ++++++ tests/initializer-replace-static.qbe | 1 + tests/initializer-replace.c | 10 ---------- tests/initializer-replace.qbe | 22 ---------------------- 7 files changed, 56 insertions(+), 40 deletions(-) create mode 100644 tests/initializer-replace-local.c create mode 100644 tests/initializer-replace-local.qbe create mode 100644 tests/initializer-replace-static.c create mode 100644 tests/initializer-replace-static.qbe delete mode 100644 tests/initializer-replace.c delete mode 100644 tests/initializer-replace.qbe diff --git a/qbe.c b/qbe.c index 7130002..0d14949 100644 --- 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-local.c b/tests/initializer-replace-local.c new file mode 100644 index 0000000..8b93ef2 --- /dev/null +++ b/tests/initializer-replace-local.c @@ -0,0 +1,10 @@ +void f(void) { + struct { + char s[6]; + } x = { + .s[0] = 'x', + .s[4] = 'y', + .s = "hello", + .s[1] = 'a', + }; +} diff --git a/tests/initializer-replace-local.qbe b/tests/initializer-replace-local.qbe new file mode 100644 index 0000000..72ad90a --- /dev/null +++ b/tests/initializer-replace-local.qbe @@ -0,0 +1,22 @@ +export +function $f() { +@start.1 + %.1 =l alloc4 6 +@body.2 + %.2 =l add %.1, 0 + storeb 104, %.2 + %.3 =l add %.1, 1 + storeb 101, %.3 + %.4 =l add %.1, 2 + storeb 108, %.4 + %.5 =l add %.1, 3 + storeb 108, %.5 + %.6 =l add %.1, 4 + storeb 111, %.6 + %.7 =l add %.1, 1 + %.8 =w copy 97 + storeb %.8, %.7 + %.9 =l add %.1, 5 + storeb 0, %.9 + ret +} diff --git a/tests/initializer-replace-static.c b/tests/initializer-replace-static.c new file mode 100644 index 0000000..c1fa376 --- /dev/null +++ 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 new file mode 100644 index 0000000..18b774e --- /dev/null +++ b/tests/initializer-replace-static.qbe @@ -0,0 +1 @@ +export data $x = align 1 { b "hallo", z 1, } diff --git a/tests/initializer-replace.c b/tests/initializer-replace.c deleted file mode 100644 index 8b93ef2..0000000 --- a/tests/initializer-replace.c +++ /dev/null @@ -1,10 +0,0 @@ -void f(void) { - struct { - char s[6]; - } x = { - .s[0] = 'x', - .s[4] = 'y', - .s = "hello", - .s[1] = 'a', - }; -} diff --git a/tests/initializer-replace.qbe b/tests/initializer-replace.qbe deleted file mode 100644 index 72ad90a..0000000 --- a/tests/initializer-replace.qbe +++ /dev/null @@ -1,22 +0,0 @@ -export -function $f() { -@start.1 - %.1 =l alloc4 6 -@body.2 - %.2 =l add %.1, 0 - storeb 104, %.2 - %.3 =l add %.1, 1 - storeb 101, %.3 - %.4 =l add %.1, 2 - storeb 108, %.4 - %.5 =l add %.1, 3 - storeb 108, %.5 - %.6 =l add %.1, 4 - storeb 111, %.6 - %.7 =l add %.1, 1 - %.8 =w copy 97 - storeb %.8, %.7 - %.9 =l add %.1, 5 - storeb 0, %.9 - ret -} -- cgit v1.2.3