diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2021-09-15 19:55:57 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-09-15 19:55:57 -0700 |
| commit | d5c1d24964b0ee8ad37beb8e2a907e8caa645e07 (patch) | |
| tree | e7756f5ac6c7d3eb80fb9ab5845c123fbab425fa /src/type.zig | |
| parent | b67d1810be3234c363ee2929ffcc91083bfb0ae5 (diff) | |
| download | zig-d5c1d24964b0ee8ad37beb8e2a907e8caa645e07.tar.gz zig-d5c1d24964b0ee8ad37beb8e2a907e8caa645e07.zip | |
stage2: fix "cmpxchg with ptr" test case
* Sema: fix atomic operand checking to allow pointers.
* LLVM backend: implement pointer-like optional constants.
* LLVM backend: fix `is_non_null` and `optional_payload` instructions
to support pointer-like optionals.
* Type: introduce `isPtrAtRuntime` method.
* Type: fix `isPtrLikeOptional` to get the correct answer for allowzero
pointers and slices.
Diffstat (limited to 'src/type.zig')
| -rw-r--r-- | src/type.zig | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/src/type.zig b/src/type.zig index 2403893133..d9a641474f 100644 --- a/src/type.zig +++ b/src/type.zig @@ -2191,6 +2191,44 @@ pub const Type = extern union { }; } + pub fn isPtrAtRuntime(self: Type) bool { + switch (self.tag()) { + .c_const_pointer, + .c_mut_pointer, + .many_const_pointer, + .many_mut_pointer, + .manyptr_const_u8, + .manyptr_u8, + .optional_single_const_pointer, + .optional_single_mut_pointer, + .single_const_pointer, + .single_const_pointer_to_comptime_int, + .single_mut_pointer, + => return true, + + .pointer => switch (self.castTag(.pointer).?.data.size) { + .Slice => return false, + .One, .Many, .C => return true, + }, + + .optional => { + var buf: Payload.ElemType = undefined; + const child_type = self.optionalChild(&buf); + // optionals of zero sized pointers behave like bools + if (!child_type.hasCodeGenBits()) return false; + if (child_type.zigTypeTag() != .Pointer) return false; + + const info = child_type.ptrInfo().data; + switch (info.size) { + .Slice, .C => return false, + .Many, .One => return !info.@"allowzero", + } + }, + + else => return false, + } + } + /// Asserts that the type is an optional pub fn isPtrLikeOptional(self: Type) bool { switch (self.tag()) { @@ -2203,8 +2241,13 @@ pub const Type = extern union { const child_type = self.optionalChild(&buf); // optionals of zero sized pointers behave like bools if (!child_type.hasCodeGenBits()) return false; + if (child_type.zigTypeTag() != .Pointer) return false; - return child_type.zigTypeTag() == .Pointer and !child_type.isCPtr(); + const info = child_type.ptrInfo().data; + switch (info.size) { + .Slice, .C => return false, + .Many, .One => return !info.@"allowzero", + } }, else => unreachable, } |
