Commit 0153f3a8f9

Andrew Kelley <andrew@ziglang.org>
2023-07-19 02:12:19
Sema: fix crash: array_in_c_exported_function
Fuck it, we're storing decl indexes in LazySrcLoc now.
1 parent 47499bf
Changed files (3)
src/Module.zig
@@ -1821,8 +1821,8 @@ pub const SrcLoc = struct {
         return tree.firstToken(src_loc.parent_decl_node);
     }
 
-    pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.TokenIndex {
-        return @as(Ast.Node.Index, @bitCast(offset + @as(i32, @bitCast(src_loc.parent_decl_node))));
+    pub fn declRelativeToNodeIndex(src_loc: SrcLoc, offset: i32) Ast.Node.Index {
+        return @bitCast(offset + @as(i32, @bitCast(src_loc.parent_decl_node)));
     }
 
     pub const Span = struct {
@@ -2829,14 +2829,15 @@ pub const LazySrcLoc = union(enum) {
     /// The Decl is determined contextually.
     for_capture_from_input: i32,
     /// The source location points to the argument node of a function call.
-    /// The Decl is determined contextually.
     call_arg: struct {
+        decl: Decl.Index,
         /// Points to the function call AST node.
         call_node_offset: i32,
         /// The index of the argument the source location points to.
         arg_index: u32,
     },
     fn_proto_param: struct {
+        decl: Decl.Index,
         /// Points to the function prototype AST node.
         fn_proto_node_offset: i32,
         /// The index of the parameter the source location points to.
@@ -2931,13 +2932,18 @@ pub const LazySrcLoc = union(enum) {
             .node_offset_store_operand,
             .for_input,
             .for_capture_from_input,
-            .call_arg,
-            .fn_proto_param,
             => .{
                 .file_scope = decl.getFileScope(mod),
                 .parent_decl_node = decl.src_node,
                 .lazy = lazy,
             },
+            inline .call_arg,
+            .fn_proto_param,
+            => |x| .{
+                .file_scope = decl.getFileScope(mod),
+                .parent_decl_node = mod.declPtr(x.decl).src_node,
+                .lazy = lazy,
+            },
         };
     }
 };
src/Sema.zig
@@ -6997,10 +6997,14 @@ fn analyzeCall(
         var has_comptime_args = false;
         var arg_i: u32 = 0;
         for (fn_info.param_body) |inst| {
-            const arg_src: LazySrcLoc = .{ .call_arg = .{
-                .call_node_offset = call_src.node_offset.x,
-                .arg_index = arg_i,
-            } };
+            const arg_src: LazySrcLoc = if (arg_i == 0 and bound_arg_src != null)
+                bound_arg_src.?
+            else
+                .{ .call_arg = .{
+                    .decl = block.src_decl,
+                    .call_node_offset = call_src.node_offset.x,
+                    .arg_index = arg_i - @intFromBool(bound_arg_src != null),
+                } };
             try sema.analyzeInlineCallArg(
                 block,
                 &child_block,
@@ -7356,7 +7360,7 @@ fn analyzeInlineCallArg(
             }
             const casted_arg = sema.coerceExtra(arg_block, param_ty.toType(), uncasted_arg, arg_src, .{ .param_src = .{
                 .func_inst = func_inst,
-                .param_i = @as(u32, @intCast(arg_i.*)),
+                .param_i = @intCast(arg_i.*),
             } }) catch |err| switch (err) {
                 error.NotCoercible => unreachable,
                 else => |e| return e,
@@ -7586,6 +7590,7 @@ fn instantiateGenericCall(
             const arg_src: LazySrcLoc = if (total_i == 0 and bound_arg_src != null)
                 bound_arg_src.?
             else if (call_src == .node_offset) .{ .call_arg = .{
+                .decl = block.src_decl,
                 .call_node_offset = call_src.node_offset.x,
                 .arg_index = @intCast(total_i),
             } } else .unneeded;
@@ -8729,6 +8734,7 @@ fn funcCommon(
             break :blk @as(u1, @truncate(noalias_bits >> index)) != 0;
         };
         const param_src: LazySrcLoc = .{ .fn_proto_param = .{
+            .decl = block.src_decl,
             .fn_proto_node_offset = src_node_offset,
             .param_index = @intCast(i),
         } };
@@ -9316,9 +9322,10 @@ fn zirParamAnytype(
             return;
         }
         const arg_src: LazySrcLoc = if (sema.generic_call_src == .node_offset) .{ .call_arg = .{
+            .decl = sema.generic_call_decl.unwrap().?,
             .call_node_offset = sema.generic_call_src.node_offset.x,
             .arg_index = param_index,
-        } } else .unneeded;
+        } } else src;
 
         if (comptime_syntax) {
             if (try sema.resolveMaybeUndefVal(air_ref)) |val| {
@@ -9326,15 +9333,7 @@ fn zirParamAnytype(
                 return;
             }
             const msg = msg: {
-                const fallback_src = src.toSrcLoc(mod.declPtr(block.src_decl), mod);
-                const src_loc = if (sema.generic_call_decl.unwrap()) |decl|
-                    if (arg_src != .unneeded)
-                        arg_src.toSrcLoc(mod.declPtr(decl), mod)
-                    else
-                        fallback_src
-                else
-                    fallback_src;
-
+                const src_loc = arg_src.toSrcLoc(mod.declPtr(block.src_decl), mod);
                 const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{
                     @as([]const u8, "runtime-known argument passed to comptime parameter"),
                 });
@@ -9354,15 +9353,7 @@ fn zirParamAnytype(
                 return;
             }
             const msg = msg: {
-                const fallback_src = src.toSrcLoc(mod.declPtr(block.src_decl), mod);
-                const src_loc = if (sema.generic_call_decl.unwrap()) |decl|
-                    if (arg_src != .unneeded)
-                        arg_src.toSrcLoc(mod.declPtr(decl), mod)
-                    else
-                        fallback_src
-                else
-                    fallback_src;
-
+                const src_loc = arg_src.toSrcLoc(mod.declPtr(block.src_decl), mod);
                 const msg = try Module.ErrorMsg.create(gpa, src_loc, "{s}", .{
                     @as([]const u8, "runtime-known argument passed to comptime-only type parameter"),
                 });
test/cases/compile_errors/array_in_c_exported_function.zig
@@ -10,7 +10,7 @@ export fn zig_return_array() [10]u8 {
 // backend=stage2
 // target=native
 //
-// :1:21: error: parameter of type '[10]u8' not allowed in function with calling convention 'C'
-// :1:21: note: arrays are not allowed as a parameter type
+// :1:24: error: parameter of type '[10]u8' not allowed in function with calling convention 'C'
+// :1:24: note: arrays are not allowed as a parameter type
 // :5:30: error: return type '[10]u8' not allowed in function with calling convention 'C'
 // :5:30: note: arrays are not allowed as a return type