summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorS. Gilles <sgilles@umd.edu>2020-06-07 05:17:13 -0400
committerS. Gilles <sgilles@umd.edu>2020-06-11 05:09:59 -0400
commit58a13c39b7f3e6ab0bf950908e98b9f0dfb7c951 (patch)
treeec199127faf5557b8b0d410e928dca1a54b47c2e
parentde1eabd91024f360845dfe7382581e0acbc368e1 (diff)
downloadmc-58a13c39b7f3e6ab0bf950908e98b9f0dfb7c951.tar.gz
Unify alignment for heterogeneous tuples.
This only appears to come into play when trying to match memory layout of tuples with structs, or when accessing deeply nested tuples.
-rw-r--r--6/typeinfo.c2
-rw-r--r--lib/std/varargs.myr2
-rw-r--r--test/fmtnest.myr18
-rw-r--r--test/tests1
4 files changed, 21 insertions, 2 deletions
diff --git a/6/typeinfo.c b/6/typeinfo.c
index c7bed27..f7ec797 100644
--- a/6/typeinfo.c
+++ b/6/typeinfo.c
@@ -331,7 +331,7 @@ tyalign(Type *ty)
break;
case Tytuple:
for (i = 0; i < ty->nsub; i++)
- align = max(align, tyalign(ty->sub[0]));
+ align = max(align, tyalign(ty->sub[i]));
break;
case Tyunion:
align = 4;
diff --git a/lib/std/varargs.myr b/lib/std/varargs.myr
index 90c2945..7a5e036 100644
--- a/lib/std/varargs.myr
+++ b/lib/std/varargs.myr
@@ -58,7 +58,7 @@ const vaenter = {ap
ty = vatype(ap)
match typedesc(ty)
| `Tyslice enc: -> [.args=sliceptr(ap.args), .tc=[.nelt=slicelen(ap.args), .rem=enc, .isiter=false]]
- | `Tytuple tc: -> [.args=ap.args, .tc=tc]
+ | `Tytuple tc: -> [.args=cursoralign(ap.args, ty), .tc=tc]
| `Tystruct tc: -> [.args=cursoralign(ap.args, ty), .tc=tc]
| `Tyarray (sz, enc): -> [.args=ap.args, .tc=[.nelt=sz, .rem=enc, .isiter=false]]
| `Tyname (name, enc): -> [.args=ap.args, .tc=typeenccursor(enc)]
diff --git a/test/fmtnest.myr b/test/fmtnest.myr
new file mode 100644
index 0000000..1d1d5f2
--- /dev/null
+++ b/test/fmtnest.myr
@@ -0,0 +1,18 @@
+use std
+
+type foo = struct
+ f2 : uint8
+ f3 : (uint8, flt64)
+;;
+
+const main = {
+ var f : foo = [ .f2 = 2, .f3 = (3, 4.4) ]
+ var str = std.fmt("{}", f)
+ for var j = 0; j < str.len; ++j
+ /* Try not to accidentally create any shell characters */
+ if str[j] == ('(' : byte) || str[j] == (')' : byte) || str[j] == ('[' : byte) || str[j] == (']' : byte) || str[j] == (' ' : byte) || str[j] == ('=' : byte)
+ str[j] = ('_' : byte)
+ ;;
+ ;;
+ std.put("{}\n", str)
+}
diff --git a/test/tests b/test/tests
index 20b67fe..cb496e1 100644
--- a/test/tests
+++ b/test/tests
@@ -176,5 +176,6 @@ B destructuretup E 0
B nestedgoto E 0
B initializer E 0
B fmtalign E 0
+B fmtnest P _.f2_2,_.f3__3,_4.4__
B implexpr P 12,z,hello
B implexpr-concrete P zigzag