aboutsummaryrefslogtreecommitdiff
path: root/src/type.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-01-19 16:30:25 +0200
committerVeikka Tuominen <git@vexu.eu>2023-01-22 00:12:37 +0200
commita492a607d5410b1136db3a63fabd01c10827144c (patch)
tree03b8a57ab199edd346ae666e890000d80721f5b3 /src/type.zig
parentd284c00fda45b943f4ed5244ae1cb9e7f90f481f (diff)
downloadzig-a492a607d5410b1136db3a63fabd01c10827144c.tar.gz
zig-a492a607d5410b1136db3a63fabd01c10827144c.zip
type: correct condition for eliding pointer alignment canonicalization
Closes #14373
Diffstat (limited to 'src/type.zig')
-rw-r--r--src/type.zig40
1 files changed, 34 insertions, 6 deletions
diff --git a/src/type.zig b/src/type.zig
index 65391aabfc..dd4be91937 100644
--- a/src/type.zig
+++ b/src/type.zig
@@ -3789,6 +3789,39 @@ pub const Type = extern union {
}
}
+ /// Returns true if the type's layout is already resolved and it is safe
+ /// to use `abiSize`, `abiAlignment` and `bitSize` on it.
+ pub fn layoutIsResolved(ty: Type) bool {
+ switch (ty.zigTypeTag()) {
+ .Struct => {
+ if (ty.castTag(.@"struct")) |struct_ty| {
+ return struct_ty.data.haveLayout();
+ }
+ return true;
+ },
+ .Union => {
+ if (ty.cast(Payload.Union)) |union_ty| {
+ return union_ty.data.haveLayout();
+ }
+ return true;
+ },
+ .Array => {
+ if (ty.arrayLenIncludingSentinel() == 0) return true;
+ return ty.childType().layoutIsResolved();
+ },
+ .Optional => {
+ var buf: Type.Payload.ElemType = undefined;
+ const payload_ty = ty.optionalChild(&buf);
+ return payload_ty.layoutIsResolved();
+ },
+ .ErrorUnion => {
+ const payload_ty = ty.errorUnionPayload();
+ return payload_ty.layoutIsResolved();
+ },
+ else => return true,
+ }
+ }
+
pub fn isSinglePointer(self: Type) bool {
return switch (self.tag()) {
.single_const_pointer,
@@ -6498,12 +6531,7 @@ pub const Type = extern union {
// pointee type needs to be resolved more, that needs to be done before calling
// this ptr() function.
if (d.@"align" != 0) canonicalize: {
- if (d.pointee_type.castTag(.@"struct")) |struct_ty| {
- if (!struct_ty.data.haveLayout()) break :canonicalize;
- }
- if (d.pointee_type.cast(Payload.Union)) |union_ty| {
- if (!union_ty.data.haveLayout()) break :canonicalize;
- }
+ if (!d.pointee_type.layoutIsResolved()) break :canonicalize;
if (d.@"align" == d.pointee_type.abiAlignment(target)) {
d.@"align" = 0;
}