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
signature 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,
1564415644}
1564515645
1564615646// 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) {
1564815648 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
1565015668 switch (val->special) {
1565115669 case ConstValSpecialRuntime:
1565215670 case ConstValSpecialUndef:
......@@ -15700,12 +15718,12 @@ static ErrorMsg *ir_eval_bin_op_cmp_scalar(IrAnalyze *ira, IrInst* source_instr,
1570015718 // Before resolving the values, we special case comparisons against zero. These can often
1570115719 // be done without resolving lazy values, preventing potential dependency loops.
1570215720 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))) {
1570415722 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally;
1570515723 return ira->codegen->trace_err;
1570615724 }
1570715725 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))) {
1570915727 if (err == ErrorNotLazy) goto never_mind_just_calculate_it_normally;
1571015728 return ira->codegen->trace_err;
1571115729 }
......@@ -15869,14 +15887,14 @@ static IrInstGen *ir_analyze_bin_op_cmp_numeric(IrAnalyze *ira, IrInst *source_i
1586915887 }
1587015888 Cmp op1_cmp_zero;
1587115889 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))) {
1587315891 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen;
1587415892 } else {
1587515893 have_op1_cmp_zero = true;
1587615894 }
1587715895 Cmp op2_cmp_zero;
1587815896 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))) {
1588015898 if (err != ErrorNotLazy) return ira->codegen->invalid_inst_gen;
1588115899 } else {
1588215900 have_op2_cmp_zero = true;
test/stage1/behavior/eval.zig+13
......@@ -804,3 +804,16 @@ test "comptime assign int to optional int" {
804804 expectEqual(20, x.?);
805805 }
806806}
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}