| author | |
| committer | |
| log | 527df938e19574cc254100e9394581a9f46e644c |
| tree | 9891ce505362ea7deccbb1af09e7e2bf6889e3db |
| parent | 1d34616236521176b3173935951f14b5224b53a3 |
| signature |
2 files changed, 29 insertions(+), 0 deletions(-)
src/Value.zig+1| ... | @@ -3779,6 +3779,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { | ... | @@ -3779,6 +3779,7 @@ pub fn ptrField(parent_ptr: Value, field_idx: u32, pt: Zcu.PerThread) !Value { |
| 3779 | .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) }, | 3779 | .auto => break :field .{ field_ty, try aggregate_ty.fieldAlignmentSema(field_idx, pt) }, |
| 3780 | .@"extern" => { | 3780 | .@"extern" => { |
| 3781 | // Well-defined layout, so just offset the pointer appropriately. | 3781 | // Well-defined layout, so just offset the pointer appropriately. |
| 3782 | try aggregate_ty.resolveLayout(pt); | ||
| 3782 | const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu); | 3783 | const byte_off = aggregate_ty.structFieldOffset(field_idx, zcu); |
| 3783 | const field_align = a: { | 3784 | const field_align = a: { |
| 3784 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { | 3785 | const parent_align = if (parent_ptr_info.flags.alignment == .none) pa: { |
test/behavior/globals.zig+28| ... | @@ -167,3 +167,31 @@ test "global var can be indirectly self-referential" { | ... | @@ -167,3 +167,31 @@ test "global var can be indirectly self-referential" { |
| 167 | try std.testing.expect(S.bar.other == &S.foo); | 167 | try std.testing.expect(S.bar.other == &S.foo); |
| 168 | try std.testing.expect(S.bar.other.other == &S.bar); | 168 | try std.testing.expect(S.bar.other.other == &S.bar); |
| 169 | } | 169 | } |
| 170 | |||
| 171 | pub const Callbacks = extern struct { | ||
| 172 | key_callback: *const fn (key: i32) callconv(.c) i32, | ||
| 173 | }; | ||
| 174 | |||
| 175 | var callbacks: Callbacks = undefined; | ||
| 176 | var callbacks_loaded: bool = false; | ||
| 177 | |||
| 178 | test "function pointer field call on global extern struct, conditional on global" { | ||
| 179 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 180 | |||
| 181 | if (callbacks_loaded) { | ||
| 182 | try std.testing.expectEqual(42, callbacks.key_callback(42)); | ||
| 183 | } | ||
| 184 | } | ||
| 185 | |||
| 186 | test "function pointer field call on global extern struct" { | ||
| 187 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; | ||
| 188 | |||
| 189 | const S = struct { | ||
| 190 | fn keyCallback(key: i32) callconv(.c) i32 { | ||
| 191 | return key; | ||
| 192 | } | ||
| 193 | }; | ||
| 194 | |||
| 195 | callbacks = Callbacks{ .key_callback = S.keyCallback }; | ||
| 196 | try std.testing.expectEqual(42, callbacks.key_callback(42)); | ||
| 197 | } |