Commit faeb0ef032

Veikka Tuominen <git@vexu.eu>
2024-01-08 00:23:17
llvm: optional slices cannot be passed in parts when they allowzero
Closes #18428
1 parent 3f6e651
Changed files (2)
src
codegen
test
behavior
src/codegen/llvm.zig
@@ -11197,7 +11197,9 @@ const ParamTypeIterator = struct {
             .Unspecified, .Inline => {
                 it.zig_index += 1;
                 it.llvm_index += 1;
-                if (ty.isSlice(mod) or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(mod).isSlice(mod))) {
+                if (ty.isSlice(mod) or
+                    (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(mod).isSlice(mod) and !ty.ptrAllowsZero(mod)))
+                {
                     it.llvm_index += 1;
                     return .slice;
                 } else if (isByRef(ty, mod)) {
test/behavior/optional.zig
@@ -448,6 +448,23 @@ test "Optional slice size is optimized" {
     try expectEqualStrings(a.?, "hello");
 }
 
+test "Optional slice passed to function" {
+    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
+    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn foo(a: ?[]const u8) !void {
+            try std.testing.expectEqualStrings(a.?, "foo");
+        }
+        fn bar(a: ?[]allowzero const u8) !void {
+            try std.testing.expectEqualStrings(@ptrCast(a.?), "bar");
+        }
+    };
+    try S.foo("foo");
+    try S.bar("bar");
+}
+
 test "peer type resolution in nested if expressions" {
     if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
     if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;