diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2022-03-24 17:44:37 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2022-03-24 17:47:39 -0700 |
| commit | 9a1d5001d4bf1f28bd0f23e8b936d677e0e5aac8 (patch) | |
| tree | 610bf3b91a5a02521b956fbb3ac7187f6f8449fc /src | |
| parent | f5f5b9373deae53a544497147cfd1380df34c000 (diff) | |
| download | zig-9a1d5001d4bf1f28bd0f23e8b936d677e0e5aac8.tar.gz zig-9a1d5001d4bf1f28bd0f23e8b936d677e0e5aac8.zip | |
Sema: fix false negative detecting comptime const
The code for detecting when a local const initialization expression
ended up being comptime-known gave up when it encountered dbg_stmt
instructions, but such instructions are not supposed to matter.
Diffstat (limited to 'src')
| -rw-r--r-- | src/Sema.zig | 50 |
1 files changed, 41 insertions, 9 deletions
diff --git a/src/Sema.zig b/src/Sema.zig index 277e4a6ba6..e8ef948abd 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2731,17 +2731,49 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com // instructions from the block, replacing the inst_map entry // corresponding to the ZIR alloc instruction with a constant // decl_ref pointing at our new Decl. + // dbg_stmt instructions may be interspersed into this pattern + // which must be ignored. if (block.instructions.items.len < 3) break :ct; - // zig fmt: off - const const_inst = block.instructions.items[block.instructions.items.len - 3]; - const bitcast_inst = block.instructions.items[block.instructions.items.len - 2]; - const store_inst = block.instructions.items[block.instructions.items.len - 1]; - const air_tags = sema.air_instructions.items(.tag); + var search_index: usize = block.instructions.items.len; + const air_tags = sema.air_instructions.items(.tag); const air_datas = sema.air_instructions.items(.data); - if (air_tags[const_inst] != .constant) break :ct; - if (air_tags[bitcast_inst] != .bitcast ) break :ct; - if (air_tags[store_inst] != .store ) break :ct; - // zig fmt: on + + const store_inst = while (true) { + if (search_index == 0) break :ct; + search_index -= 1; + + const candidate = block.instructions.items[search_index]; + switch (air_tags[candidate]) { + .dbg_stmt => continue, + .store => break candidate, + else => break :ct, + } + } else unreachable; // TODO shouldn't need this + + const bitcast_inst = while (true) { + if (search_index == 0) break :ct; + search_index -= 1; + + const candidate = block.instructions.items[search_index]; + switch (air_tags[candidate]) { + .dbg_stmt => continue, + .bitcast => break candidate, + else => break :ct, + } + } else unreachable; // TODO shouldn't need this + + const const_inst = while (true) { + if (search_index == 0) break :ct; + search_index -= 1; + + const candidate = block.instructions.items[search_index]; + switch (air_tags[candidate]) { + .dbg_stmt => continue, + .constant => break candidate, + else => break :ct, + } + } else unreachable; // TODO shouldn't need this + const store_op = air_datas[store_inst].bin_op; const store_val = (try sema.resolveMaybeUndefVal(block, src, store_op.rhs)) orelse break :ct; if (store_op.lhs != Air.indexToRef(bitcast_inst)) break :ct; |
