aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-05-24 15:10:18 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-05-24 15:34:52 -0700
commitc711c788f0a840f45d0d7423efe2f946b47caafb (patch)
tree48f57fc696e485937a7b96477657bdd8cdaff534 /src/codegen.zig
parentc847a462ae11e0d483ad877b3ecc9ec291c29bb3 (diff)
downloadzig-c711c788f0a840f45d0d7423efe2f946b47caafb.tar.gz
zig-c711c788f0a840f45d0d7423efe2f946b47caafb.zip
stage2: fixes for error unions, optionals, errors
* `?E` where E is an error set with only one field now lowers the same as `bool`. * Fix implementation of errUnionErrOffset and errUnionPayloadOffset to properly compute the offset of each field. Also name them the same as the corresponding LLVM functions and have the same function signature, to avoid confusion. This fixes a bug where wasm was passing the error union type instead of the payload type. * Fix C backend handling of optionals with zero-bit payload types. * C backend: separate out airOptionalPayload and airOptionalPayloadPtr which reduces branching and cleans up control flow. * Make Type.isNoReturn return true for error sets with no fields. * Make `?error{}` have only one possible value (null).
Diffstat (limited to 'src/codegen.zig')
-rw-r--r--src/codegen.zig28
1 files changed, 16 insertions, 12 deletions
diff --git a/src/codegen.zig b/src/codegen.zig
index 86f2613b5f..fbe462959e 100644
--- a/src/codegen.zig
+++ b/src/codegen.zig
@@ -891,18 +891,22 @@ fn lowerDeclRef(
return Result{ .appended = {} };
}
-pub fn errUnionPayloadOffset(ty: Type, target: std.Target) u64 {
- const payload_ty = ty.errorUnionPayload();
- return if (Type.anyerror.abiAlignment(target) >= payload_ty.abiAlignment(target))
- Type.anyerror.abiSize(target)
- else
- 0;
+pub fn errUnionPayloadOffset(payload_ty: Type, target: std.Target) u64 {
+ const payload_align = payload_ty.abiAlignment(target);
+ const error_align = Type.anyerror.abiAlignment(target);
+ if (payload_align >= error_align) {
+ return 0;
+ } else {
+ return mem.alignForwardGeneric(u64, Type.anyerror.abiSize(target), payload_align);
+ }
}
-pub fn errUnionErrOffset(ty: Type, target: std.Target) u64 {
- const payload_ty = ty.errorUnionPayload();
- return if (Type.anyerror.abiAlignment(target) >= payload_ty.abiAlignment(target))
- 0
- else
- payload_ty.abiSize(target);
+pub fn errUnionErrorOffset(payload_ty: Type, target: std.Target) u64 {
+ const payload_align = payload_ty.abiAlignment(target);
+ const error_align = Type.anyerror.abiAlignment(target);
+ if (payload_align >= error_align) {
+ return mem.alignForwardGeneric(u64, payload_ty.abiSize(target), error_align);
+ } else {
+ return 0;
+ }
}