Skip to content

Commit 87cf278

Browse files
committed
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 commit 87cf278

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

src/codegen/llvm.zig

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,7 +1966,7 @@ pub const Object = struct {
19661966

19671967
for (tuple.types) |field_ty, i| {
19681968
const field_val = tuple.values[i];
1969-
if (field_val.tag() != .unreachable_value) continue;
1969+
if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
19701970

19711971
const field_size = field_ty.abiSize(target);
19721972
const field_align = field_ty.abiAlignment(target);
@@ -2901,7 +2901,7 @@ pub const DeclGen = struct {
29012901

29022902
for (tuple.types) |field_ty, i| {
29032903
const field_val = tuple.values[i];
2904-
if (field_val.tag() != .unreachable_value) continue;
2904+
if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
29052905

29062906
const field_align = field_ty.abiAlignment(target);
29072907
big_align = @max(big_align, field_align);
@@ -10207,7 +10207,7 @@ fn llvmFieldIndex(
1020710207
const tuple = ty.tupleFields();
1020810208
var llvm_field_index: c_uint = 0;
1020910209
for (tuple.types) |field_ty, i| {
10210-
if (tuple.values[i].tag() != .unreachable_value) continue;
10210+
if (tuple.values[i].tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue;
1021110211

1021210212
const field_align = field_ty.abiAlignment(target);
1021310213
big_align = @max(big_align, field_align);
@@ -10771,7 +10771,7 @@ fn isByRef(ty: Type) bool {
1077110771
const tuple = ty.tupleFields();
1077210772
var count: usize = 0;
1077310773
for (tuple.values) |field_val, i| {
10774-
if (field_val.tag() != .unreachable_value) continue;
10774+
if (field_val.tag() != .unreachable_value or !tuple.types[i].hasRuntimeBits()) continue;
1077510775

1077610776
count += 1;
1077710777
if (count > max_fields_byval) return true;

src/type.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5759,7 +5759,7 @@ pub const Type = extern union {
57595759

57605760
for (tuple.types) |field_ty, i| {
57615761
const field_val = tuple.values[i];
5762-
if (field_val.tag() != .unreachable_value) {
5762+
if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) {
57635763
// comptime field
57645764
if (i == index) return offset;
57655765
continue;

test/behavior/tuple.zig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,3 +323,13 @@ test "zero sized struct in tuple handled correctly" {
323323
var s: State = undefined;
324324
try expect(s.do() == 0);
325325
}
326+
327+
test "tuple type with void field and a runtime field" {
328+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
329+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
330+
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
331+
332+
const T = std.meta.Tuple(&[_]type{ usize, void });
333+
var t: T = .{ 5, {} };
334+
try expect(t[0] == 5);
335+
}

0 commit comments

Comments
 (0)