authorgravatar for me@paperdave.netdave caruso <me@paperdave.net> 2024-06-02 21:29:31-07:00
committergravatar for me@paperdave.netdave caruso <me@paperdave.net> 2024-06-02 21:29:31-07:00
log2205bf12c2792b8eef92453a207a8521c32055c4
tree00970ad12c0f49872dfcfab47c0e4a2ec80735e1
parent10d7c1ff53ea46517327987a11764dd46ec8cb7f
signature Commit is signed but in an unrecognized format.

fix(sema): quit block analysis when hitting `noreturn`


3 files changed, 21 insertions(+), 5 deletions(-)

CHANGELOG.md+1
......@@ -2,6 +2,7 @@
22
33- fix(sema): miscompilation using left side of all binary expression for both sides
44- fix(sema): handle recursive function calls
5- fix(sema): quit block analysis when hitting `noreturn`
56
67## 0.1.3
78
src/core/JsLink.zig+5-2
......@@ -147,12 +147,15 @@ fn printDecl(link: *JsLink, decl_index: Decl.Index, writer: anytype) !void {
147147 const decl = link.comp.intern_pool.declPtrConst(decl_index);
148148 const tree = &decl.codegen.?;
149149
150 try writer.writeAll("(");
150 if (tree.param_count != 1)
151 try writer.writeAll("(");
151152 for (0..tree.param_count) |id| {
152153 try link.printLocal(@intCast(id), writer);
153154 if (id != tree.param_count - 1) try writer.writeAll(", ");
154155 }
155 try writer.writeAll(") => ");
156 if (tree.param_count != 1)
157 try writer.writeAll(")");
158 try writer.writeAll(" => ");
156159
157160 const stmts = tree.mainStatements();
158161 if (stmts.len == 1 and tree.nodeTag(stmts[0]) == .stmt_return) {
src/core/Sema.zig+15-3
......@@ -33,7 +33,10 @@ pub const Error = error{
3333
3434 // TODO: add handling of this
3535 TooManyValues,
36 // TODO: add handling of this
3637 HasNulls,
38 // TODO: remove this from the primary error set
39 HitNoReturn,
3740
3841 OutOfMemory,
3942} || Comp.File.GetTegError;
......@@ -210,11 +213,14 @@ pub fn analyzeBlock(s: *Sema, in: Teg.Inst.Index) Error!Air.Inst.Ref {
210213 const block = try s.addBlock();
211214 try s.inst_map.add(in, block.block_index.toRef());
212215
213 var last: Air.Inst.Ref = undefined;
216 var last: Air.Inst.Ref = Value.void.toAir();
214217 const instructions = s.code.blockInstructions(in);
215218 assert(instructions.len != 0);
216219 for (instructions) |inst| {
217 last = try s.analyzeCode(inst);
220 last = s.analyzeCode(inst) catch |err| switch (err) {
221 error.HitNoReturn => break,
222 else => return err,
223 };
218224 }
219225
220226 if (scratch_top + 1 == s.scratch.items.len) {
......@@ -585,7 +591,10 @@ fn analyzeRefToBlock(s: *Sema, in: Teg.Inst.Ref) Error!Air.Inst.Ref {
585591 const scratch_top = s.scratch.items.len;
586592 defer s.scratch.shrinkRetainingCapacity(scratch_top);
587593
588 const visited = try s.resolveRefRuntime(in);
594 const visited = s.resolveRefRuntime(in) catch |err| switch (err) {
595 error.HitNoReturn => Value.void.toAir(),
596 else => return err,
597 };
589598
590599 if (scratch_top == s.scratch.items.len and visited.kind == .value) {
591600 return visited;
......@@ -665,6 +674,9 @@ fn coerceRef(s: *Sema, src: InstOp, value: Air.Inst.Ref, to: Type) !Air.Inst.Ref
665674 if (from == to) {
666675 return value;
667676 }
677 if (from == .noreturn) {
678 return error.HitNoReturn;
679 }
668680 if (from == .@"opaque") {
669681 return value;
670682 }