summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Moody <moody@posixcafe.org>2023-01-28 04:43:10 +0000
committerJacob Moody <moody@posixcafe.org>2023-01-28 04:43:10 +0000
commitf9096fcdfd46f5bf566e87107675bfd439771a44 (patch)
tree59de61ec48706af262f05e040c9bee19b935f3e1
parent7f8246fd97a12477f9dd21c68a3d81b4c4b46852 (diff)
6c: copy all of packed structs in OAS
code assumed struct was aligned to atleast LONG. For packed structs we need to copy the reaminder as well. Repro: typedef struct { char a; char b; short c; short d; char e; char f; char g; char h; } A; void main(int argc, char **argv) { A a1, a2; a2.a = 1; a2.b = 2; a2.c = 3; a2.d = 4; a2.e = 5; a2.f = 6; a2.g = 7; a2.h = 8; a1 = a2; print("%d %d %d %d %d %d %d %d\n", a1.a, a1.b, a1.c, a1.d, a1.e, a1.f, a1.g, a1.h); }
-rw-r--r--sys/src/cmd/6c/cgen.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/sys/src/cmd/6c/cgen.c b/sys/src/cmd/6c/cgen.c
index 05b285946..b87c14a60 100644
--- a/sys/src/cmd/6c/cgen.c
+++ b/sys/src/cmd/6c/cgen.c
@@ -1400,7 +1400,7 @@ sugen(Node *n, Node *nn, long w)
Prog *p1;
Node nod0, nod1, nod2, nod3, nod4, *l, *r;
Type *t;
- int v, c, mt, mo;
+ int v, c, mt, mo, re;
vlong o0, o1;
if(n == Z || n->type == T)
@@ -1683,6 +1683,7 @@ copy:
}
o0 = n->xoffset;
o1 = nn->xoffset;
+ re = w % ewidth[mt];
w /= ewidth[mt];
while(--w >= 0) {
gins(mo, n, &nod0);
@@ -1690,6 +1691,12 @@ copy:
n->xoffset += ewidth[mt];
nn->xoffset += ewidth[mt];
}
+ while(--re >= 0) {
+ gins(AMOVB, n, &nod0);
+ gins(AMOVB, &nod0, nn);
+ n->xoffset += 1;
+ nn->xoffset += 1;
+ }
n->xoffset = o0;
nn->xoffset = o1;
if(nn == &nod2)