Commit 87cf2783eb

Veikka Tuominen <git@vexu.eu>
2022-11-12 12:11:54
llvm: check that tuple fields have runtime bits
Just checking that they aren't comptime isn't enough for `@Type` constructed tuples. Closes #13531
1 parent a760ce5
Changed files (3)
src
test
behavior
src/codegen/llvm.zig
@@ -1966,7 +1966,7 @@ pub const Object = struct {
 
                     for (tuple.types) |field_ty, i| {
                         const field_val = tuple.values[i];
-                        if (field_val.tag() != .unreachable_value) continue;
+                        if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
 
                         const field_size = field_ty.abiSize(target);
                         const field_align = field_ty.abiAlignment(target);
@@ -2901,7 +2901,7 @@ pub const DeclGen = struct {
 
                     for (tuple.types) |field_ty, i| {
                         const field_val = tuple.values[i];
-                        if (field_val.tag() != .unreachable_value) continue;
+                        if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
 
                         const field_align = field_ty.abiAlignment(target);
                         big_align = @max(big_align, field_align);
@@ -10207,7 +10207,7 @@ fn llvmFieldIndex(
         const tuple = ty.tupleFields();
         var llvm_field_index: c_uint = 0;
         for (tuple.types) |field_ty, i| {
-            if (tuple.values[i].tag() != .unreachable_value) continue;
+            if (tuple.values[i].tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
 
             const field_align = field_ty.abiAlignment(target);
             big_align = @max(big_align, field_align);
@@ -10771,7 +10771,7 @@ fn isByRef(ty: Type) bool {
                 const tuple = ty.tupleFields();
                 var count: usize = 0;
                 for (tuple.values) |field_val, i| {
-                    if (field_val.tag() != .unreachable_value) continue;
+                    if (field_val.tag() != .unreachable_value or !tuple.types[i].hasRuntimeBits()) continue;
 
                     count += 1;
                     if (count > max_fields_byval) return true;
src/type.zig
@@ -5759,7 +5759,7 @@ pub const Type = extern union {
 
                 for (tuple.types) |field_ty, i| {
                     const field_val = tuple.values[i];
-                    if (field_val.tag() != .unreachable_value) {
+                    if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) {
                         // comptime field
                         if (i == index) return offset;
                         continue;
test/behavior/tuple.zig
@@ -323,3 +323,13 @@ test "zero sized struct in tuple handled correctly" {
     var s: State = undefined;
     try expect(s.do() == 0);
 }
+
+test "tuple type with void field and a runtime field" {
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
+
+    const T = std.meta.Tuple(&[_]type{ usize, void });
+    var t: T = .{ 5, {} };
+    try expect(t[0] == 5);
+}