authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2024-01-31 12:06:47+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-02-09 13:51:51-08:00
log731ff120d0ee68f3ce2eb30648eeaf96a283142d
treedf9c78eec99467ce10264bc6d0b81bfb9d682040
parent32f30399e5cd42af2d670321979aa424803b1819

Sema: catch runtime stores to comptime variables through calls


2 files changed, 29 insertions(+), 11 deletions(-)

src/Sema.zig+14-11
...@@ -341,8 +341,8 @@ pub const Block = struct {...@@ -341,8 +341,8 @@ pub const Block = struct {
341 label: ?*Label = null,341 label: ?*Label = null,
342 inlining: ?*Inlining,342 inlining: ?*Inlining,
343 /// If runtime_index is not 0 then one of these is guaranteed to be non null.343 /// If runtime_index is not 0 then one of these is guaranteed to be non null.
344 runtime_cond: ?LazySrcLoc = null,344 runtime_cond: ?Module.SrcLoc = null,
345 runtime_loop: ?LazySrcLoc = null,345 runtime_loop: ?Module.SrcLoc = null,
346 /// This Decl is the Decl according to the Zig source code corresponding to this Block.346 /// This Decl is the Decl according to the Zig source code corresponding to this Block.
347 /// This can vary during inline or comptime function calls. See `Sema.owner_decl`347 /// This can vary during inline or comptime function calls. See `Sema.owner_decl`
348 /// for the one that will be the same for all Block instances.348 /// for the one that will be the same for all Block instances.
...@@ -1504,7 +1504,7 @@ fn analyzeBodyInner(...@@ -1504,7 +1504,7 @@ fn analyzeBodyInner(
1504 const msg = try sema.errMsg(block, src, "comptime control flow inside runtime block", .{});1504 const msg = try sema.errMsg(block, src, "comptime control flow inside runtime block", .{});
1505 errdefer msg.destroy(sema.gpa);1505 errdefer msg.destroy(sema.gpa);
15061506
1507 try sema.errNote(block, runtime_src, msg, "runtime control flow here", .{});1507 try mod.errNoteNonLazy(runtime_src, msg, "runtime control flow here", .{});
1508 break :msg msg;1508 break :msg msg;
1509 };1509 };
1510 return sema.failWithOwnedErrorMsg(block, msg);1510 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -5761,7 +5761,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError...@@ -5761,7 +5761,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError
5761 var child_block = parent_block.makeSubBlock();5761 var child_block = parent_block.makeSubBlock();
5762 child_block.label = &label;5762 child_block.label = &label;
5763 child_block.runtime_cond = null;5763 child_block.runtime_cond = null;
5764 child_block.runtime_loop = src;5764 child_block.runtime_loop = src.toSrcLoc(mod.declPtr(child_block.src_decl), mod);
5765 child_block.runtime_index.increment();5765 child_block.runtime_index.increment();
5766 const merges = &child_block.label.?.merges;5766 const merges = &child_block.label.?.merges;
57675767
...@@ -6049,7 +6049,7 @@ fn analyzeBlockBody(...@@ -6049,7 +6049,7 @@ fn analyzeBlockBody(
6049 errdefer msg.destroy(sema.gpa);6049 errdefer msg.destroy(sema.gpa);
60506050
6051 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;6051 const runtime_src = child_block.runtime_cond orelse child_block.runtime_loop.?;
6052 try sema.errNote(child_block, runtime_src, msg, "runtime control flow here", .{});6052 try mod.errNoteNonLazy(runtime_src, msg, "runtime control flow here", .{});
60536053
6054 const child_src_decl = mod.declPtr(child_block.src_decl);6054 const child_src_decl = mod.declPtr(child_block.src_decl);
6055 try sema.explainWhyTypeIsComptime(msg, type_src.toSrcLoc(child_src_decl, mod), resolved_ty);6055 try sema.explainWhyTypeIsComptime(msg, type_src.toSrcLoc(child_src_decl, mod), resolved_ty);
...@@ -7458,6 +7458,9 @@ fn analyzeCall(...@@ -7458,6 +7458,9 @@ fn analyzeCall(
7458 .is_comptime = is_comptime_call,7458 .is_comptime = is_comptime_call,
7459 .comptime_reason = comptime_reason,7459 .comptime_reason = comptime_reason,
7460 .error_return_trace_index = block.error_return_trace_index,7460 .error_return_trace_index = block.error_return_trace_index,
7461 .runtime_cond = block.runtime_cond,
7462 .runtime_loop = block.runtime_loop,
7463 .runtime_index = block.runtime_index,
7461 };7464 };
74627465
7463 const merges = &child_block.inlining.?.merges;7466 const merges = &child_block.inlining.?.merges;
...@@ -11533,7 +11536,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp...@@ -11533,7 +11536,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp
1153311536
11534 var sub_block = child_block.makeSubBlock();11537 var sub_block = child_block.makeSubBlock();
11535 sub_block.runtime_loop = null;11538 sub_block.runtime_loop = null;
11536 sub_block.runtime_cond = main_operand_src;11539 sub_block.runtime_cond = main_operand_src.toSrcLoc(mod.declPtr(child_block.src_decl), mod);
11537 sub_block.runtime_index.increment();11540 sub_block.runtime_index.increment();
11538 defer sub_block.instructions.deinit(gpa);11541 defer sub_block.instructions.deinit(gpa);
1153911542
...@@ -12268,7 +12271,7 @@ fn analyzeSwitchRuntimeBlock(...@@ -12268,7 +12271,7 @@ fn analyzeSwitchRuntimeBlock(
1226812271
12269 var case_block = child_block.makeSubBlock();12272 var case_block = child_block.makeSubBlock();
12270 case_block.runtime_loop = null;12273 case_block.runtime_loop = null;
12271 case_block.runtime_cond = operand_src;12274 case_block.runtime_cond = operand_src.toSrcLoc(mod.declPtr(child_block.src_decl), mod);
12272 case_block.runtime_index.increment();12275 case_block.runtime_index.increment();
12273 defer case_block.instructions.deinit(gpa);12276 defer case_block.instructions.deinit(gpa);
1227412277
...@@ -18810,7 +18813,7 @@ fn zirBoolBr(...@@ -18810,7 +18813,7 @@ fn zirBoolBr(
1881018813
18811 var child_block = parent_block.makeSubBlock();18814 var child_block = parent_block.makeSubBlock();
18812 child_block.runtime_loop = null;18815 child_block.runtime_loop = null;
18813 child_block.runtime_cond = lhs_src;18816 child_block.runtime_cond = lhs_src.toSrcLoc(mod.declPtr(child_block.src_decl), mod);
18814 child_block.runtime_index.increment();18817 child_block.runtime_index.increment();
18815 defer child_block.instructions.deinit(gpa);18818 defer child_block.instructions.deinit(gpa);
1881618819
...@@ -19004,7 +19007,7 @@ fn zirCondbr(...@@ -19004,7 +19007,7 @@ fn zirCondbr(
19004 // instructions array in between using it for the then block and else block.19007 // instructions array in between using it for the then block and else block.
19005 var sub_block = parent_block.makeSubBlock();19008 var sub_block = parent_block.makeSubBlock();
19006 sub_block.runtime_loop = null;19009 sub_block.runtime_loop = null;
19007 sub_block.runtime_cond = cond_src;19010 sub_block.runtime_cond = cond_src.toSrcLoc(mod.declPtr(parent_block.src_decl), mod);
19008 sub_block.runtime_index.increment();19011 sub_block.runtime_index.increment();
19009 defer sub_block.instructions.deinit(gpa);19012 defer sub_block.instructions.deinit(gpa);
1901019013
...@@ -23543,7 +23546,7 @@ fn checkComptimeVarStore(...@@ -23543,7 +23546,7 @@ fn checkComptimeVarStore(
23543 const msg = msg: {23546 const msg = msg: {
23544 const msg = try sema.errMsg(block, src, "store to comptime variable depends on runtime condition", .{});23547 const msg = try sema.errMsg(block, src, "store to comptime variable depends on runtime condition", .{});
23545 errdefer msg.destroy(sema.gpa);23548 errdefer msg.destroy(sema.gpa);
23546 try sema.errNote(block, cond_src, msg, "runtime condition here", .{});23549 try sema.mod.errNoteNonLazy(cond_src, msg, "runtime condition here", .{});
23547 break :msg msg;23550 break :msg msg;
23548 };23551 };
23549 return sema.failWithOwnedErrorMsg(block, msg);23552 return sema.failWithOwnedErrorMsg(block, msg);
...@@ -23552,7 +23555,7 @@ fn checkComptimeVarStore(...@@ -23552,7 +23555,7 @@ fn checkComptimeVarStore(
23552 const msg = msg: {23555 const msg = msg: {
23553 const msg = try sema.errMsg(block, src, "cannot store to comptime variable in non-inline loop", .{});23556 const msg = try sema.errMsg(block, src, "cannot store to comptime variable in non-inline loop", .{});
23554 errdefer msg.destroy(sema.gpa);23557 errdefer msg.destroy(sema.gpa);
23555 try sema.errNote(block, loop_src, msg, "non-inline loop here", .{});23558 try sema.mod.errNoteNonLazy(loop_src, msg, "non-inline loop here", .{});
23556 break :msg msg;23559 break :msg msg;
23557 };23560 };
23558 return sema.failWithOwnedErrorMsg(block, msg);23561 return sema.failWithOwnedErrorMsg(block, msg);
test/cases/compile_errors/store_to_comptime_var_through_call.zig created+15
...@@ -0,0 +1,15 @@
1export fn entry(b: bool) void {
2 comptime var int = 0;
3 if (b) {
4 comptime incr(&int);
5 }
6}
7fn incr(x: *comptime_int) void {
8 x.* += 1;
9}
10
11// error
12//
13// :8:9: error: store to comptime variable depends on runtime condition
14// :3:9: note: runtime condition here
15// :4:22: note: called from here