commit 26be5bb8b1e1c05ceab4b7620efa2a058a174886 (tree)
parent c9ee3c1e474a7b10fb806b60ef108057395a3cca
Author: Mitchell Hashimoto <mitchell.hashimoto@gmail.com>
Date: Thu, 3 Mar 2022 17:01:31 -0800
stage2: peer resolve *T to [*c]T
Diffstat:
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -18280,6 +18280,17 @@ fn resolvePeerTypes(
},
.Pointer => {
if (candidate_ty.ptrSize() == .C) {
+ // *T to [*c]T
+ if (chosen_ty_tag == .Pointer) {
+ const chosen_elem_ty = chosen_ty.childType();
+ const candidate_elem_ty = candidate_ty.childType();
+ if ((try sema.coerceInMemoryAllowed(block, chosen_elem_ty, candidate_elem_ty, false, target, src, src)) == .ok) {
+ chosen = candidate;
+ chosen_i = candidate_i + 1;
+ continue;
+ }
+ }
+
if (chosen_ty_tag == .Int or chosen_ty_tag == .ComptimeInt) {
chosen = candidate;
chosen_i = candidate_i + 1;
@@ -18290,6 +18301,15 @@ fn resolvePeerTypes(
}
}
+ // [*c]T and *T
+ if (chosen_ty_tag == .Pointer and chosen_ty.ptrSize() == .C) {
+ const chosen_elem_ty = chosen_ty.childType();
+ const candidate_elem_ty = candidate_ty.childType();
+ if ((try sema.coerceInMemoryAllowed(block, chosen_elem_ty, candidate_elem_ty, false, target, src, src)) == .ok) {
+ continue;
+ }
+ }
+
// *[N]T to [*]T
if (candidate_ty.ptrSize() == .Many and
chosen_ty_tag == .Pointer and
diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig
@@ -128,7 +128,11 @@ fn testDerefPtrOneVal() !void {
}
test "peer type resolution with C pointers" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
var ptr_one: *u8 = undefined;
var ptr_many: [*]u8 = undefined;
@@ -159,7 +163,11 @@ test "implicit casting between C pointer and optional non-C pointer" {
}
test "implicit cast error unions with non-optional to optional pointer" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
const S = struct {
fn doTheTest() !void {
@@ -376,7 +384,11 @@ test "pointer arithmetic affects the alignment" {
}
test "@ptrToInt on null optional at comptime" {
- if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
+ if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
{
const pointer = @intToPtr(?*u8, 0x000);