authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-05 22:15:33-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-12-05 22:15:33-05:00
logbb6b4f8db2bf793f4118ee68a05ff0b4df52c318
tree67ca7168162faac52ba4b86231e35e83719c0dd4
parentc49ee9f632dd5ee7f341e9093234f39c19a32115

fix enum with 1 member causing segfault

closes #647

2 files changed, 24 insertions(+), 2 deletions(-)

src/ir.cpp+7-2
...@@ -9504,6 +9504,10 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -9504,6 +9504,10 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
9504 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, instructions, 2);9504 TypeTableEntry *resolved_type = ir_resolve_peer_types(ira, bin_op_instruction->base.source_node, instructions, 2);
9505 if (type_is_invalid(resolved_type))9505 if (type_is_invalid(resolved_type))
9506 return resolved_type;9506 return resolved_type;
9507 type_ensure_zero_bits_known(ira->codegen, resolved_type);
9508 if (type_is_invalid(resolved_type))
9509 return resolved_type;
9510
95079511
9508 AstNode *source_node = bin_op_instruction->base.source_node;9512 AstNode *source_node = bin_op_instruction->base.source_node;
9509 switch (resolved_type->id) {9513 switch (resolved_type->id) {
...@@ -9568,7 +9572,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -9568,7 +9572,8 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
95689572
9569 ConstExprValue *op1_val = &casted_op1->value;9573 ConstExprValue *op1_val = &casted_op1->value;
9570 ConstExprValue *op2_val = &casted_op2->value;9574 ConstExprValue *op2_val = &casted_op2->value;
9571 if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) {9575 bool one_possible_value = !type_requires_comptime(resolved_type) && !type_has_bits(resolved_type);
9576 if (one_possible_value || (value_is_comptime(op1_val) && value_is_comptime(op2_val))) {
9572 bool answer;9577 bool answer;
9573 if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) {9578 if (resolved_type->id == TypeTableEntryIdNumLitFloat || resolved_type->id == TypeTableEntryIdFloat) {
9574 Cmp cmp_result = float_cmp(op1_val, op2_val);9579 Cmp cmp_result = float_cmp(op1_val, op2_val);
...@@ -9577,7 +9582,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -9577,7 +9582,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
9577 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);9582 Cmp cmp_result = bigint_cmp(&op1_val->data.x_bigint, &op2_val->data.x_bigint);
9578 answer = resolve_cmp_op_id(op_id, cmp_result);9583 answer = resolve_cmp_op_id(op_id, cmp_result);
9579 } else {9584 } else {
9580 bool are_equal = resolved_type->id == TypeTableEntryIdVoid || const_values_equal(op1_val, op2_val);9585 bool are_equal = one_possible_value || const_values_equal(op1_val, op2_val);
9581 if (op_id == IrBinOpCmpEq) {9586 if (op_id == IrBinOpCmpEq) {
9582 answer = are_equal;9587 answer = are_equal;
9583 } else if (op_id == IrBinOpCmpNotEq) {9588 } else if (op_id == IrBinOpCmpNotEq) {
test/cases/enum.zig+17
...@@ -349,3 +349,20 @@ test "cast integer literal to enum" {...@@ -349,3 +349,20 @@ test "cast integer literal to enum" {
349 assert(MultipleChoice2(0) == MultipleChoice2.Unspecified1);349 assert(MultipleChoice2(0) == MultipleChoice2.Unspecified1);
350 assert(MultipleChoice2(40) == MultipleChoice2.B);350 assert(MultipleChoice2(40) == MultipleChoice2.B);
351}351}
352
353const EnumWithOneMember = enum {
354 Eof,
355};
356
357fn doALoopThing(id: EnumWithOneMember) {
358 while (true) {
359 if (id == EnumWithOneMember.Eof) {
360 break;
361 }
362 @compileError("above if condition should be comptime");
363 }
364}
365
366test "comparison operator on enum with one member is comptime known" {
367 doALoopThing(EnumWithOneMember.Eof);
368}