aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-09-09 21:36:08 +0300
committerVeikka Tuominen <git@vexu.eu>2022-09-15 00:50:18 +0300
commit5e37da6ade7eb307d51c21a2dfcdbef23e9cbf08 (patch)
treea4549f045d0c87d67519eb1045d3ddccf84d9751 /src/Sema.zig
parentbf4a3df9a961e18a258d94fa35b0c433424e4bbe (diff)
downloadzig-5e37da6ade7eb307d51c21a2dfcdbef23e9cbf08.tar.gz
zig-5e37da6ade7eb307d51c21a2dfcdbef23e9cbf08.zip
Sema: check_comptime_control_flow needs to check runtime_index
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig23
1 files changed, 20 insertions, 3 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 71dcfef513..2cec686989 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -144,6 +144,7 @@ pub const Block = struct {
/// Non zero if a non-inline loop or a runtime conditional have been encountered.
/// Stores to to comptime variables are only allowed when var.runtime_index <= runtime_index.
runtime_index: Value.RuntimeIndex = .zero,
+ inline_block: Zir.Inst.Index = 0,
is_comptime: bool,
is_typeof: bool = false,
@@ -1157,9 +1158,20 @@ fn analyzeBodyInner(
},
.check_comptime_control_flow => {
if (!block.is_comptime) {
- if (block.runtime_cond orelse block.runtime_loop) |runtime_src| {
- const inst_data = sema.code.instructions.items(.data)[inst].node;
- const src = LazySrcLoc.nodeOffset(inst_data);
+ const inst_data = sema.code.instructions.items(.data)[inst].un_node;
+ const src = inst_data.src();
+ const inline_block = Zir.refToIndex(inst_data.operand).?;
+
+ var check_block = block;
+ const target_runtime_index = while (true) {
+ if (check_block.inline_block == inline_block) {
+ break check_block.runtime_index;
+ }
+ check_block = check_block.parent.?;
+ } else unreachable;
+
+ if (@enumToInt(target_runtime_index) < @enumToInt(block.runtime_index)) {
+ const runtime_src = block.runtime_cond orelse block.runtime_loop.?;
const msg = msg: {
const msg = try sema.errMsg(block, src, "comptime control flow inside runtime block", .{});
errdefer msg.destroy(sema.gpa);
@@ -1272,10 +1284,15 @@ fn analyzeBodyInner(
// current list of parameters and restore it later.
// Note: this probably needs to be resolved in a more general manner.
const prev_params = block.params;
+ const prev_inline_block = block.inline_block;
+ if (tags[inline_body[inline_body.len - 1]] == .repeat_inline) {
+ block.inline_block = inline_body[0];
+ }
block.params = .{};
defer {
block.params.deinit(gpa);
block.params = prev_params;
+ block.inline_block = prev_inline_block;
}
const opt_break_data = try sema.analyzeBodyBreak(block, inline_body);
// A runtime conditional branch that needs a post-hoc block to be