authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-16 16:07:03-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-01-16 16:07:03-05:00
log867686af420bab965f63359499a526f35e875c9a
tree081d9129e01e9dd3953a3a65c9856cf56b77cbcd
parentfdbc2d8da1c707859af8f8bb42a27ae9d3a62159

equality comparison of void types is known at compile time

closes #56

2 files changed, 26 insertions(+), 3 deletions(-)

src/ir.cpp+7-3
...@@ -94,8 +94,12 @@ static Buf *exec_c_import_buf(IrExecutable *exec) {...@@ -94,8 +94,12 @@ static Buf *exec_c_import_buf(IrExecutable *exec) {
94 return exec->c_import_buf;94 return exec->c_import_buf;
95}95}
9696
97static bool value_is_comptime(ConstExprValue *const_val) {
98 return const_val->special != ConstValSpecialRuntime;
99}
100
97static bool instr_is_comptime(IrInstruction *instruction) {101static bool instr_is_comptime(IrInstruction *instruction) {
98 return instruction->value.special != ConstValSpecialRuntime;102 return value_is_comptime(&instruction->value);
99}103}
100104
101static bool instr_is_unreachable(IrInstruction *instruction) {105static bool instr_is_unreachable(IrInstruction *instruction) {
...@@ -6907,7 +6911,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -6907,7 +6911,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
69076911
6908 ConstExprValue *op1_val = &casted_op1->value;6912 ConstExprValue *op1_val = &casted_op1->value;
6909 ConstExprValue *op2_val = &casted_op2->value;6913 ConstExprValue *op2_val = &casted_op2->value;
6910 if (op1_val->special != ConstValSpecialRuntime && op2_val->special != ConstValSpecialRuntime) {6914 if ((value_is_comptime(op1_val) && value_is_comptime(op2_val)) || resolved_type->id == TypeTableEntryIdVoid) {
6911 bool type_can_gt_lt_cmp = (resolved_type->id == TypeTableEntryIdNumLitFloat ||6915 bool type_can_gt_lt_cmp = (resolved_type->id == TypeTableEntryIdNumLitFloat ||
6912 resolved_type->id == TypeTableEntryIdNumLitInt ||6916 resolved_type->id == TypeTableEntryIdNumLitInt ||
6913 resolved_type->id == TypeTableEntryIdFloat ||6917 resolved_type->id == TypeTableEntryIdFloat ||
...@@ -6933,7 +6937,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp...@@ -6933,7 +6937,7 @@ static TypeTableEntry *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp
69336937
6934 answer = bignum_cmp(&op1_val->data.x_bignum, &op2_val->data.x_bignum);6938 answer = bignum_cmp(&op1_val->data.x_bignum, &op2_val->data.x_bignum);
6935 } else {6939 } else {
6936 bool are_equal = const_values_equal(op1_val, op2_val);6940 bool are_equal = resolved_type->id == TypeTableEntryIdVoid || const_values_equal(op1_val, op2_val);
6937 if (op_id == IrBinOpCmpEq) {6941 if (op_id == IrBinOpCmpEq) {
6938 answer = are_equal;6942 answer = are_equal;
6939 } else if (op_id == IrBinOpCmpNotEq) {6943 } else if (op_id == IrBinOpCmpNotEq) {
test/run_tests.cpp+19
...@@ -1605,6 +1605,25 @@ fn derp() {...@@ -1605,6 +1605,25 @@ fn derp() {
1605}1605}
1606 )SOURCE", 1, ".tmp_source.zig:7:13: error: cannot assign to constant");1606 )SOURCE", 1, ".tmp_source.zig:7:13: error: cannot assign to constant");
16071607
1608 add_compile_fail_case("compare void with void is compile time known", R"SOURCE(
1609const Foo = struct {
1610 a: void,
1611 b: i32,
1612 c: void,
1613};
1614
1615fn f() {
1616 const foo = Foo {
1617 .a = {},
1618 .b = 1,
1619 .c = {},
1620 };
1621 if (foo.a != {}) {
1622 @unreachable();
1623 }
1624}
1625 )SOURCE", 1, ".tmp_source.zig:14:15: error: condition is always false; unnecessary if statement");
1626
1608}1627}
16091628
1610//////////////////////////////////////////////////////////////////////////////1629//////////////////////////////////////////////////////////////////////////////