mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Type: correctly handle ABI align strat for optionals and error unions
Closes #12984
This commit is contained in:
parent
3122601242
commit
2a4e89e0c9
20
src/type.zig
20
src/type.zig
@ -3458,12 +3458,21 @@ pub const Type = extern union {
|
||||
else => {},
|
||||
}
|
||||
|
||||
const payload_size = switch (try child_type.abiSizeAdvanced(target, strat)) {
|
||||
.scalar => |elem_size| elem_size,
|
||||
.val => switch (strat) {
|
||||
.sema_kit => unreachable,
|
||||
.eager => unreachable,
|
||||
.lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
|
||||
},
|
||||
};
|
||||
|
||||
// Optional types are represented as a struct with the child type as the first
|
||||
// field and a boolean as the second. Since the child type's abi alignment is
|
||||
// guaranteed to be >= that of bool's (1 byte) the added size is exactly equal
|
||||
// to the child type's ABI alignment.
|
||||
return AbiSizeAdvanced{
|
||||
.scalar = child_type.abiAlignment(target) + child_type.abiSize(target),
|
||||
.scalar = child_type.abiAlignment(target) + payload_size,
|
||||
};
|
||||
},
|
||||
|
||||
@ -3478,7 +3487,14 @@ pub const Type = extern union {
|
||||
}
|
||||
const code_align = abiAlignment(Type.anyerror, target);
|
||||
const payload_align = abiAlignment(data.payload, target);
|
||||
const payload_size = abiSize(data.payload, target);
|
||||
const payload_size = switch (try data.payload.abiSizeAdvanced(target, strat)) {
|
||||
.scalar => |elem_size| elem_size,
|
||||
.val => switch (strat) {
|
||||
.sema_kit => unreachable,
|
||||
.eager => unreachable,
|
||||
.lazy => |arena| return AbiSizeAdvanced{ .val = try Value.Tag.lazy_size.create(arena, ty) },
|
||||
},
|
||||
};
|
||||
|
||||
var size: u64 = 0;
|
||||
if (code_align > payload_align) {
|
||||
|
||||
@ -98,6 +98,7 @@ test {
|
||||
_ = @import("behavior/bugs/12911.zig");
|
||||
_ = @import("behavior/bugs/12928.zig");
|
||||
_ = @import("behavior/bugs/12945.zig");
|
||||
_ = @import("behavior/bugs/12984.zig");
|
||||
_ = @import("behavior/byteswap.zig");
|
||||
_ = @import("behavior/byval_arg_var.zig");
|
||||
_ = @import("behavior/call.zig");
|
||||
|
||||
22
test/behavior/bugs/12984.zig
Normal file
22
test/behavior/bugs/12984.zig
Normal file
@ -0,0 +1,22 @@
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
pub fn DeleagateWithContext(comptime Function: type) type {
|
||||
const ArgArgs = std.meta.ArgsTuple(Function);
|
||||
return struct {
|
||||
t: ArgArgs,
|
||||
};
|
||||
}
|
||||
|
||||
pub const OnConfirm = DeleagateWithContext(fn (bool) void);
|
||||
pub const CustomDraw = DeleagateWithContext(fn (?OnConfirm) void);
|
||||
|
||||
test "simple test" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
|
||||
var c: CustomDraw = undefined;
|
||||
_ = c;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user