authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-27 18:59:46-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-27 18:59:46-05:00
log37ab960492885c24a6b135f7955188d5f81d9a5a
treebeaebb1abf528171a3ca244c18e9bc6ee65b6463
parentb38b96784406c1d9e5f4246442f9414dba6812d2
signaturelock-open Commit is signed but in an unrecognized format.

fix not handling undefined u0 correctly


2 files changed, 36 insertions(+), 5 deletions(-)

src/ir.cpp+23-5
...@@ -15644,9 +15644,27 @@ static IrInstGen *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type,...@@ -15644,9 +15644,27 @@ static IrInstGen *ir_evaluate_bin_op_cmp(IrAnalyze *ira, ZigType *resolved_type,
15644}15644}
1564515645
15646// Returns ErrorNotLazy when the value cannot be determined15646// Returns ErrorNotLazy when the value cannot be determined
15647static Error lazy_cmp_zero(AstNode *source_node, ZigValue *val, Cmp *result) {15647static Error lazy_cmp_zero(CodeGen *codegen, AstNode *source_node, ZigValue *val, Cmp *result) {
15648 Error err;15648 Error err;
1564915649
15650 switch (type_has_one_possible_value(codegen, val->type)) {
15651 case OnePossibleValueInvalid:
15652 return ErrorSemanticAnalyzeFail;
15653 case OnePossibleValueNo:
15654 break;
15655 case OnePossibleValueYes:
15656 switch (val->type->id) {
15657 case ZigTypeIdInt:
15658 src_assert(val->type->data.integral.bit_count == 0, source_node);
15659 *result = CmpEQ;
15660 return ErrorNone;
15661 case ZigTypeIdUndefined:
15662 return ErrorNotLazy;
15663 default:
15664 zig_unreachable();
15665 }
15666 }
15667
15650 switch (val->special) {15668 switch (val->special) {
15651 case ConstValSpecialRuntime:15669 case ConstValSpecialRuntime:
15652 case ConstValSpecialUndef:15670 case ConstValSpecialUndef:
...@@ -15700,12 +15718,12 @@ static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr,...@@ -15700,12 +15718,12 @@ static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr,
15700 // Before resolving the values, we special case comparisons against zero. These can often15718 // Before resolving the values, we special case comparisons against zero. These can often
15701 // be done without resolving lazy values, preventing potential dependency loops.15719 // be done without resolving lazy values, preventing potential dependency loops.
15702 Cmp op1_cmp_zero;15720 Cmp op1_cmp_zero;
15703 if ((err = lazy_cmp_zero(source_instr->source_node, op1_val, &op1_cmp_zero))) {15721 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1_val, &op1_cmp_zero))) {
15704 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally;15722 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally;
15705 return ira->codegen->trace_err;15723 return ira->codegen->trace_err;
15706 }15724 }
15707 Cmp op2_cmp_zero;15725 Cmp op2_cmp_zero;
15708 if ((err = lazy_cmp_zero(source_instr->source_node, op2_val, &op2_cmp_zero))) {15726 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2_val, &op2_cmp_zero))) {
15709 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally;15727 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally;
15710 return ira->codegen->trace_err;15728 return ira->codegen->trace_err;
15711 }15729 }
...@@ -15869,14 +15887,14 @@ static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_i...@@ -15869,14 +15887,14 @@ static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_i
15869 }15887 }
15870 Cmp op1_cmp_zero;15888 Cmp op1_cmp_zero;
15871 bool have_op1_cmp_zero = false;15889 bool have_op1_cmp_zero = false;
15872 if ((err = lazy_cmp_zero(source_instr->source_node, op1->value, &op1_cmp_zero))) {15890 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op1->value, &op1_cmp_zero))) {
15873 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen;15891 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen;
15874 } else {15892 } else {
15875 have_op1_cmp_zero = true;15893 have_op1_cmp_zero = true;
15876 }15894 }
15877 Cmp op2_cmp_zero;15895 Cmp op2_cmp_zero;
15878 bool have_op2_cmp_zero = false;15896 bool have_op2_cmp_zero = false;
15879 if ((err = lazy_cmp_zero(source_instr->source_node, op2->value, &op2_cmp_zero))) {15897 if ((err = lazy_cmp_zero(ira->codegen, source_instr->source_node, op2->value, &op2_cmp_zero))) {
15880 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen;15898 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen;
15881 } else {15899 } else {
15882 have_op2_cmp_zero = true;15900 have_op2_cmp_zero = true;
test/stage1/behavior/eval.zig+13
...@@ -804,3 +804,16 @@ test "comptime assign int to optional int" {...@@ -804,3 +804,16 @@ test "comptime assign int to optional int" {
804 expectEqual(20, x.?);804 expectEqual(20, x.?);
805 }805 }
806}806}
807
808test "return 0 from function that has u0 return type" {
809 const S = struct {
810 fn foo_zero() u0 {
811 return 0;
812 }
813 };
814 comptime {
815 if (S.foo_zero() != 0) {
816 @compileError("test failed");
817 }
818 }
819}