Skip to content

Commit fa59153

Browse files
kcbannerandrewrk
authored andcommitted
Value: ensure that extern structs have their layout resolved in ptrField
1 parent 90084f4 commit fa59153

File tree

2 files changed

+29
-0
lines changed

2 files changed

+29
-0
lines changed

src/Value.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3013,6 +3013,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value {
30133013
.auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) },
30143014
.@"extern" => {
30153015
// Well-defined layout, so just offset the pointer appropriately.
3016+
try aggregate_ty.resolveLayout(pt);
30163017
const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu);
30173018
const field_align = a: {
30183019
const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: {

test/behavior/globals.zig

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,31 @@ test "global var can be indirectly self-referential" {
171171
try std.testing.expect(S.bar.other == &S.foo);
172172
try std.testing.expect(S.bar.other.other == &S.bar);
173173
}
174+
175+
pub const Callbacks = extern struct {
176+
key_callback: *const fn (key: i32) callconv(.c) i32,
177+
};
178+
179+
var callbacks: Callbacks = undefined;
180+
var callbacks_loaded: bool = false;
181+
182+
test "function pointer field call on global extern struct, conditional on global" {
183+
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
184+
185+
if (callbacks_loaded) {
186+
try std.testing.expectEqual(42, callbacks.key_callback(42));
187+
}
188+
}
189+
190+
test "function pointer field call on global extern struct" {
191+
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
192+
193+
const S = struct {
194+
fn keyCallback(key: i32) callconv(.c) i32 {
195+
return key;
196+
}
197+
};
198+
199+
callbacks = Callbacks{ .key_callback = S.keyCallback };
200+
try std.testing.expectEqual(42, callbacks.key_callback(42));
201+
}

0 commit comments

Comments
 (0)