Skip to content

Commit faeb0ef

Browse files
committed
llvm: optional slices cannot be passed in parts when they allowzero
Closes #18428
1 parent 3f6e651 commit faeb0ef

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/codegen/llvm.zig

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11197,7 +11197,9 @@ const ParamTypeIterator = struct {
1119711197
.Unspecified, .Inline => {
1119811198
it.zig_index += 1;
1119911199
it.llvm_index += 1;
11200-
if (ty.isSlice(mod) or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(mod).isSlice(mod))) {
11200+
if (ty.isSlice(mod) or
11201+
(ty.zigTypeTag(mod) == .Optional and ty.optionalChild(mod).isSlice(mod) and !ty.ptrAllowsZero(mod)))
11202+
{
1120111203
it.llvm_index += 1;
1120211204
return .slice;
1120311205
} else if (isByRef(ty, mod)) {

test/behavior/optional.zig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,23 @@ test "Optional slice size is optimized" {
448448
try expectEqualStrings(a.?, "hello");
449449
}
450450

451+
test "Optional slice passed to function" {
452+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
453+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
454+
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
455+
456+
const S = struct {
457+
fn foo(a: ?[]const u8) !void {
458+
try std.testing.expectEqualStrings(a.?, "foo");
459+
}
460+
fn bar(a: ?[]allowzero const u8) !void {
461+
try std.testing.expectEqualStrings(@ptrCast(a.?), "bar");
462+
}
463+
};
464+
try S.foo("foo");
465+
try S.bar("bar");
466+
}
467+
451468
test "peer type resolution in nested if expressions" {
452469
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
453470
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;

0 commit comments

Comments
 (0)