aboutsummaryrefslogtreecommitdiff
path: root/src/Module.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-07-16 16:27:37 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-08-18 17:11:32 -0700
commit6e313eb1107d4f5d7b0ada0a67c810ce90e79bf5 (patch)
tree11a0dd0f9dd004e8509321cd8ee757100832d89e /src/Module.zig
parentc5ba941b77fbdb06841f28142420c6786f2a4d0c (diff)
downloadzig-6e313eb1107d4f5d7b0ada0a67c810ce90e79bf5.tar.gz
zig-6e313eb1107d4f5d7b0ada0a67c810ce90e79bf5.zip
stage2: agree with LLVM that `@alignOf(u128)` is 8
on x86_64 and similar targets.
Diffstat (limited to 'src/Module.zig')
-rw-r--r--src/Module.zig30
1 files changed, 25 insertions, 5 deletions
diff --git a/src/Module.zig b/src/Module.zig
index 995fdda7ea..6d2180e8e7 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -935,13 +935,33 @@ pub const Struct = struct {
/// If true then `default_val` is the comptime field value.
is_comptime: bool,
- /// Returns the field alignment, assuming the struct is not packed.
- pub fn normalAlignment(field: Field, target: Target) u32 {
- if (field.abi_align == 0) {
- return field.ty.abiAlignment(target);
- } else {
+ /// Returns the field alignment. If the struct is packed, returns 0.
+ pub fn alignment(
+ field: Field,
+ target: Target,
+ layout: std.builtin.Type.ContainerLayout,
+ ) u32 {
+ if (field.abi_align != 0) {
+ assert(layout != .Packed);
return field.abi_align;
}
+
+ switch (layout) {
+ .Packed => return 0,
+ .Auto => return field.ty.abiAlignment(target),
+ .Extern => {
+ // This logic is duplicated in Type.abiAlignmentAdvanced.
+ const ty_abi_align = field.ty.abiAlignment(target);
+
+ if (field.ty.isAbiInt() and field.ty.intInfo(target).bits >= 128) {
+ // The C ABI requires 128 bit integer fields of structs
+ // to be 16-bytes aligned.
+ return @maximum(ty_abi_align, 16);
+ }
+
+ return ty_abi_align;
+ },
+ }
}
};