aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--qbe.c25
-rw-r--r--tests/initializer-replace-local.c (renamed from tests/initializer-replace.c)0
-rw-r--r--tests/initializer-replace-local.qbe (renamed from tests/initializer-replace.qbe)0
-rw-r--r--tests/initializer-replace-static.c6
-rw-r--r--tests/initializer-replace-static.qbe1
5 files changed, 24 insertions, 8 deletions
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.c b/tests/initializer-replace-local.c
index 8b93ef2..8b93ef2 100644
--- a/tests/initializer-replace.c
+++ b/tests/initializer-replace-local.c
diff --git a/tests/initializer-replace.qbe b/tests/initializer-replace-local.qbe
index 72ad90a..72ad90a 100644
--- 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
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, }