authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-14 15:43:24-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-12-14 15:43:24-05:00
log3a3cc7bf76eab3ef239991e686c114baeaf4672e
treebada8181ef3097bed0bb5a771f61059c04a4d323
parentcca49b84b659ecd6b942e84129f873443ffc7966

IR: panic with a TODO instead of generating invalid code

for returning from a function without running maybe and error defers

1 files changed, 34 insertions(+), 2 deletions(-)

src/ir.cpp+34-2
......@@ -1709,6 +1709,24 @@ static IrInstruction *ir_build_alignof(IrBuilder *irb, Scope *scope, AstNode *so
17091709 return &instruction->base;
17101710}
17111711
1712static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
1713 results[ReturnKindUnconditional] = 0;
1714 results[ReturnKindError] = 0;
1715 results[ReturnKindMaybe] = 0;
1716
1717 while (inner_scope != outer_scope) {
1718 assert(inner_scope);
1719 if (inner_scope->id == ScopeIdDefer) {
1720 AstNode *defer_node = inner_scope->source_node;
1721 assert(defer_node->type == NodeTypeDefer);
1722 ReturnKind defer_kind = defer_node->data.defer.kind;
1723 results[defer_kind] += 1;
1724
1725 }
1726 inner_scope = inner_scope->parent;
1727 }
1728}
1729
17121730static void ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope,
17131731 bool gen_error_defers, bool gen_maybe_defers)
17141732{
......@@ -1762,8 +1780,22 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
17621780 return_value = ir_build_const_void(irb, scope, node);
17631781 }
17641782
1765 // TODO conditionally gen maybe defers and error defers
1766 ir_gen_defers_for_block(irb, scope, outer_scope, false, false);
1783 size_t defer_counts[3];
1784 ir_count_defers(irb, scope, outer_scope, defer_counts);
1785 if (defer_counts[ReturnKindError] > 0) {
1786 // TODO in this situation we need to make a conditional
1787 // branch on the return value. we potentially must make multiple conditional branches,
1788 // if unconditional defers are interleaved with error defers.
1789 zig_panic("TODO handle error defers");
1790 } else if (defer_counts[ReturnKindMaybe] > 0) {
1791 // TODO in this situation we need to make a conditional
1792 // branch on the maybe value. we potentially must make multiple conditional branches,
1793 // if unconditional defers are interleaved with error defers.
1794 zig_panic("TODO handle maybe defers");
1795 } else {
1796 // generate unconditional defers
1797 ir_gen_defers_for_block(irb, scope, outer_scope, false, false);
1798 }
17671799 return ir_build_return(irb, scope, node, return_value);
17681800 }
17691801 case ReturnKindError: