Skip to content

Commit

Permalink
Value: ensure that extern structs have their layout resolved in ptrField
Browse files Browse the repository at this point in the history
  • Loading branch information
kcbanner committed Mar 10, 2025
1 parent 539f3ef commit 6c46a9b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/Value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3779,6 +3779,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
.auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },
.@"extern" => {
// Well-defined layout, so just offset the pointer appropriately.
try aggregate_ty.resolveLayout(pt);
const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);
const field_align = a: {
const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {
Expand Down
28 changes: 28 additions & 0 deletions test/behavior/globals.zig
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,31 @@ test "global var can be indirectly self-referential" {
try std.testing.expect(S.bar.other == &S.foo);
try std.testing.expect(S.bar.other.other == &S.bar);
}

pub const Callbacks = extern struct {
key_callback: *const fn (key: i32) callconv(.c) i32,
};

var callbacks: Callbacks = undefined;
var callbacks_loaded: bool = false;

test "function pointer field call on global extern struct, conditional on global" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;

if (callbacks_loaded) {
try std.testing.expectEqual(42, callbacks.key_callback(42));
}
}

test "function pointer field call on global extern struct" {
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;

const S = struct {
fn keyCallback(key: i32) callconv(.c) i32 {
return key;
}
};

callbacks = Callbacks{ .key_callback = S.keyCallback };
try std.testing.expectEqual(42, callbacks.key_callback(42));
}

0 comments on commit 6c46a9b

Please sign in to comment.