Commit 898e4473e8

Xavier Bouchoux <xavierb@gmail.com>
2023-03-19 13:56:37
CBE: implement aggregateInit() for array of array case.
fixes `error(compilation): clang failed with stderr: error: array type 'uint32_t[10]' (aka 'unsigned int[10]') is not assignable`
1 parent f7204c7
Changed files (2)
src
codegen
test
behavior
src/codegen/c.zig
@@ -6852,17 +6852,35 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue {
     switch (inst_ty.zigTypeTag()) {
         .Array, .Vector => {
             const elem_ty = inst_ty.childType();
-            for (resolved_elements, 0..) |element, i| {
-                try f.writeCValue(writer, local, .Other);
-                try writer.print("[{d}] = ", .{i});
-                try f.writeCValue(writer, element, .Other);
-                try writer.writeAll(";\n");
-            }
-            if (inst_ty.sentinel()) |sentinel| {
-                try f.writeCValue(writer, local, .Other);
-                try writer.print("[{d}] = ", .{resolved_elements.len});
-                try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
-                try writer.writeAll(";\n");
+
+            const is_array = lowersToArray(elem_ty, target);
+            const need_memcpy = is_array;
+            if (need_memcpy) {
+                for (resolved_elements, 0..) |element, i| {
+                    try writer.writeAll("memcpy(");
+                    try f.writeCValue(writer, local, .Other);
+                    try writer.print("[{d}]", .{i});
+                    try writer.writeAll(", ");
+                    try f.writeCValue(writer, element, .Other);
+                    try writer.writeAll(", sizeof(");
+                    try f.renderType(writer, elem_ty);
+                    try writer.writeAll("))");
+                    try writer.writeAll(";\n");
+                }
+                assert(inst_ty.sentinel() == null);
+            } else {
+                for (resolved_elements, 0..) |element, i| {
+                    try f.writeCValue(writer, local, .Other);
+                    try writer.print("[{d}] = ", .{i});
+                    try f.writeCValue(writer, element, .Other);
+                    try writer.writeAll(";\n");
+                }
+                if (inst_ty.sentinel()) |sentinel| {
+                    try f.writeCValue(writer, local, .Other);
+                    try writer.print("[{d}] = ", .{resolved_elements.len});
+                    try f.object.dg.renderValue(writer, elem_ty, sentinel, .Other);
+                    try writer.writeAll(";\n");
+                }
             }
         },
         .Struct => switch (inst_ty.containerLayout()) {
test/behavior/array.zig
@@ -669,3 +669,13 @@ test "runtime initialized sentinel-terminated array literal" {
     try std.testing.expect(g[2] == 0x99);
     try std.testing.expect(g[3] == 0x99);
 }
+
+test "array of array agregate init" {
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+
+    var a = [1]u32{11} ** 10;
+    var b = [1][10]u32{a} ** 2;
+    try std.testing.expect(b[1][1] == 11);
+}