Commit 08a871f625

Josh Wolfe <thejoshwolfe@gmail.com>
2017-04-24 07:33:06
defer requires expr to be void. closes #341
1 parent ac79711
Changed files (2)
src/ir.cpp
@@ -2051,6 +2051,18 @@ static IrInstruction *ir_build_check_switch_prongs(IrBuilder *irb, Scope *scope,
     return &instruction->base;
 }
 
+static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node,
+    IrInstruction* statement_value)
+{
+    IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>(
+            irb, scope, source_node);
+    instruction->statement_value = statement_value;
+
+    ir_ref_instruction(statement_value, irb->current_basic_block);
+
+    return &instruction->base;
+}
+
 static IrInstruction *ir_build_test_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
         IrInstruction *type_value, TypeTableEntryId type_id)
 {
@@ -3139,7 +3151,11 @@ static bool ir_gen_defers_for_block(IrBuilder *irb, Scope *inner_scope, Scope *o
                 (gen_error_defers && defer_kind == ReturnKindError))
             {
                 AstNode *defer_expr_node = defer_node->data.defer.expr;
-                ir_gen_node(irb, defer_expr_node, defer_node->data.defer.expr_scope);
+                Scope *defer_expr_scope = defer_node->data.defer.expr_scope;
+                IrInstruction *defer_expr_value = ir_gen_node(irb, defer_expr_node, defer_expr_scope);
+                if (defer_expr_value != irb->codegen->invalid_instruction) {
+                    ir_mark_gen(ir_build_check_statement_is_void(irb, defer_expr_scope, defer_expr_node, defer_expr_value));
+                }
             }
 
         }
@@ -3348,18 +3364,6 @@ static ScopeBlock *find_block_scope(IrExecutable *exec, Scope *scope) {
     return nullptr;
 }
 
-static IrInstruction *ir_build_check_statement_is_void(IrBuilder *irb, Scope *scope, AstNode *source_node,
-    IrInstruction* statement_value)
-{
-    IrInstructionCheckStatementIsVoid *instruction = ir_build_instruction<IrInstructionCheckStatementIsVoid>(
-            irb, scope, source_node);
-    instruction->statement_value = statement_value;
-
-    ir_ref_instruction(statement_value, irb->current_basic_block);
-
-    return &instruction->base;
-}
-
 static IrInstruction *ir_gen_block(IrBuilder *irb, Scope *parent_scope, AstNode *block_node) {
     assert(block_node->type == NodeTypeBlock);
 
test/compile_errors.zig
@@ -1379,6 +1379,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
         \\}
     , ".tmp_source.zig:2:12: error: expression value is ignored");
 
+    cases.add("ignored defered statement value",
+        \\export fn foo() {
+        \\    defer bar();
+        \\}
+        \\fn bar() -> %i32 { 0 }
+    , ".tmp_source.zig:2:14: error: expression value is ignored");
+
     cases.add("integer literal on a non-comptime var",
         \\export fn foo() {
         \\    var i = 0;