authorchloe caruso <git@paperclover.net> 2024-06-02 21:29:31-07:00
committerchloe caruso <git@paperclover.net> 2024-06-02 21:29:31-07:00
logf499572ffea4cab93d28e2480bcc9a4234f59089
tree00970ad12c0f49872dfcfab47c0e4a2ec80735e1
parent53ee7a83199844ed2d12713b4817127001550a0d

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


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

CHANGELOG.md+1
...@@ -2,6 +2,7 @@...@@ -2,6 +2,7 @@
22
3- fix(sema): miscompilation using left side of all binary expression for both sides3- fix(sema): miscompilation using left side of all binary expression for both sides
4- fix(sema): handle recursive function calls4- fix(sema): handle recursive function calls
5- fix(sema): quit block analysis when hitting `noreturn`
56
6## 0.1.37## 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 {...@@ -147,12 +147,15 @@ fn printDecl(link: *JsLink, decl_index: Decl.Index, writer: anytype) !void {
147 const decl = link.comp.intern_pool.declPtrConst(decl_index);147 const decl = link.comp.intern_pool.declPtrConst(decl_index);
148 const tree = &decl.codegen.?;148 const tree = &decl.codegen.?;
149149
150 try writer.writeAll("(");150 if (tree.param_count != 1)
151 try writer.writeAll("(");
151 for (0..tree.param_count) |id| {152 for (0..tree.param_count) |id| {
152 try link.printLocal(@intCast(id), writer);153 try link.printLocal(@intCast(id), writer);
153 if (id != tree.param_count - 1) try writer.writeAll(", ");154 if (id != tree.param_count - 1) try writer.writeAll(", ");
154 }155 }
155 try writer.writeAll(") => ");156 if (tree.param_count != 1)
157 try writer.writeAll(")");
158 try writer.writeAll(" => ");
156159
157 const stmts = tree.mainStatements();160 const stmts = tree.mainStatements();
158 if (stmts.len == 1 and tree.nodeTag(stmts[0]) == .stmt_return) {161 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{...@@ -33,7 +33,10 @@ pub const Error = error{
3333
34 // TODO: add handling of this34 // TODO: add handling of this
35 TooManyValues,35 TooManyValues,
36 // TODO: add handling of this
36 HasNulls,37 HasNulls,
38 // TODO: remove this from the primary error set
39 HitNoReturn,
3740
38 OutOfMemory,41 OutOfMemory,
39} || Comp.File.GetTegError;42} || Comp.File.GetTegError;
...@@ -210,11 +213,14 @@ pub fn analyzeBlock(s: *Sema, in: Teg.Inst.Index) Error!Air.Inst.Ref {...@@ -210,11 +213,14 @@ pub fn analyzeBlock(s: *Sema, in: Teg.Inst.Index) Error!Air.Inst.Ref {
210 const block = try s.addBlock();213 const block = try s.addBlock();
211 try s.inst_map.add(in, block.block_index.toRef());214 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();
214 const instructions = s.code.blockInstructions(in);217 const instructions = s.code.blockInstructions(in);
215 assert(instructions.len != 0);218 assert(instructions.len != 0);
216 for (instructions) |inst| {219 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 };
218 }224 }
219225
220 if (scratch_top + 1 == s.scratch.items.len) {226 if (scratch_top + 1 == s.scratch.items.len) {
...@@ -585,7 +591,10 @@ fn analyzeRefToBlock(s: *Sema, in: Teg.Inst.Ref) Error!Air.Inst.Ref {...@@ -585,7 +591,10 @@ fn analyzeRefToBlock(s: *Sema, in: Teg.Inst.Ref) Error!Air.Inst.Ref {
585 const scratch_top = s.scratch.items.len;591 const scratch_top = s.scratch.items.len;
586 defer s.scratch.shrinkRetainingCapacity(scratch_top);592 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
590 if (scratch_top == s.scratch.items.len and visited.kind == .value) {599 if (scratch_top == s.scratch.items.len and visited.kind == .value) {
591 return visited;600 return visited;
...@@ -665,6 +674,9 @@ fn coerceRef(s: *Sema, src: InstOp, value: Air.Inst.Ref, to: Type) !Air.Inst.Ref...@@ -665,6 +674,9 @@ fn coerceRef(s: *Sema, src: InstOp, value: Air.Inst.Ref, to: Type) !Air.Inst.Ref
665 if (from == to) {674 if (from == to) {
666 return value;675 return value;
667 }676 }
677 if (from == .noreturn) {
678 return error.HitNoReturn;
679 }
668 if (from == .@"opaque") {680 if (from == .@"opaque") {
669 return value;681 return value;
670 }682 }