Commit 6672ee9eb3

LemonBoy <thatlemon@gmail.com>
2019-05-14 23:30:31
Fix too eager comptime evaluation of error ptr
1 parent b660134
Changed files (4)
src
test
stage1
behavior
src/ir.cpp
@@ -21126,17 +21126,19 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_code(IrAnalyze *ira, IrI
         ConstExprValue *ptr_val = ir_resolve_const(ira, base_ptr, UndefBad);
         if (!ptr_val)
             return ira->codegen->invalid_instruction;
-        ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);
-        if (err_union_val == nullptr)
-            return ira->codegen->invalid_instruction;
-        if (err_union_val->special != ConstValSpecialRuntime) {
-            ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
-            assert(err);
+        if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
+            ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);
+            if (err_union_val == nullptr)
+                return ira->codegen->invalid_instruction;
+            if (err_union_val->special != ConstValSpecialRuntime) {
+                ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
+                assert(err);
 
-            IrInstruction *result = ir_const(ira, &instruction->base,
-                    type_entry->data.error_union.err_set_type);
-            result->value.data.x_err_set = err;
-            return result;
+                IrInstruction *result = ir_const(ira, &instruction->base,
+                                                 type_entry->data.error_union.err_set_type);
+                result->value.data.x_err_set = err;
+                return result;
+            }
         }
     }
 
@@ -21179,21 +21181,23 @@ static IrInstruction *ir_analyze_instruction_unwrap_err_payload(IrAnalyze *ira,
         ConstExprValue *ptr_val = ir_resolve_const(ira, value, UndefBad);
         if (!ptr_val)
             return ira->codegen->invalid_instruction;
-        ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);
-        if (err_union_val == nullptr)
-            return ira->codegen->invalid_instruction;
-        if (err_union_val->special != ConstValSpecialRuntime) {
-            ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
-            if (err != nullptr) {
-                ir_add_error(ira, &instruction->base,
-                    buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));
+        if (ptr_val->data.x_ptr.mut != ConstPtrMutRuntimeVar) {
+            ConstExprValue *err_union_val = const_ptr_pointee(ira, ira->codegen, ptr_val, instruction->base.source_node);
+            if (err_union_val == nullptr)
                 return ira->codegen->invalid_instruction;
-            }
+            if (err_union_val->special != ConstValSpecialRuntime) {
+                ErrorTableEntry *err = err_union_val->data.x_err_union.error_set->data.x_err_set;
+                if (err != nullptr) {
+                    ir_add_error(ira, &instruction->base,
+                                 buf_sprintf("caught unexpected error '%s'", buf_ptr(&err->name)));
+                    return ira->codegen->invalid_instruction;
+                }
 
-            IrInstruction *result = ir_const(ira, &instruction->base, result_type);
-            result->value.data.x_ptr.special = ConstPtrSpecialRef;
-            result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload;
-            return result;
+                IrInstruction *result = ir_const(ira, &instruction->base, result_type);
+                result->value.data.x_ptr.special = ConstPtrSpecialRef;
+                result->value.data.x_ptr.data.ref.pointee = err_union_val->data.x_err_union.payload;
+                return result;
+            }
         }
     }
 
src/ir_print.cpp
@@ -1941,3 +1941,14 @@ void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_si
         }
     }
 }
+
+void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size) {
+    IrPrint ir_print = {};
+    IrPrint *irp = &ir_print;
+    irp->codegen = codegen;
+    irp->f = f;
+    irp->indent = indent_size;
+    irp->indent_size = indent_size;
+
+    ir_print_instruction(irp, instruction);
+}
src/ir_print.hpp
@@ -13,5 +13,6 @@
 #include <stdio.h>
 
 void ir_print(CodeGen *codegen, FILE *f, IrExecutable *executable, int indent_size);
+void ir_print_instruction(CodeGen *codegen, FILE *f, IrInstruction *instruction, int indent_size);
 
 #endif
test/stage1/behavior/if.zig
@@ -35,3 +35,20 @@ fn elseIfExpressionF(c: u8) u8 {
         return u8(2);
     }
 }
+
+// #2297
+var global_with_val: anyerror!u32 = 0;
+var global_with_err: anyerror!u32 = error.SomeError;
+
+test "unwrap mutable global var" {
+    if (global_with_val) |v| {
+        expect(v == 0);
+    } else |e| {
+        unreachable;
+    }
+    if (global_with_err) |_| {
+        unreachable;
+    } else |e| {
+        expect(e == error.SomeError);
+    }
+}