| author | |
| committer | |
| log | fa5915389640c2b00a093914fd803d7d87dc2e91 |
| tree | 93e55c1055de800943b15c8941e27bbd8b58e008 |
| parent | 90084f4ae329c89466bc8c74bd6e00db3f2a3803 |
2 files changed, 29 insertions(+), 0 deletions(-)
src/Value.zig+1| ... | @@ -3013,6 +3013,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { | ... | @@ -3013,6 +3013,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3013 | .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) }, | 3013 | .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) }, |
| 3014 | .@"extern" => { | 3014 | .@"extern" => { |
| 3015 | // Well-defined layout, so just offset the pointer appropriately. | 3015 | // Well-defined layout, so just offset the pointer appropriately. |
| 3016 | try aggregate_ty.resolveLayout(pt); | ||
| 3016 | const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu); | 3017 | const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu); |
| 3017 | const field_align = a: { | 3018 | const field_align = a: { |
| 3018 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { | 3019 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { |
test/behavior/globals.zig+28| ... | @@ -171,3 +171,31 @@ test "global var can be indirectly self-referential" { | ... | @@ -171,3 +171,31 @@ test "global var can be indirectly self-referential" { |
| 171 | try std.testing.expect(S.bar.other == &S.foo); | 171 | try std.testing.expect(S.bar.other == &S.foo); |
| 172 | try std.testing.expect(S.bar.other.other == &S.bar); | 172 | try std.testing.expect(S.bar.other.other == &S.bar); |
| 173 | } | 173 | } |
| 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 | } |