authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-03-21 18:33:54+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-03-21 20:54:05-04:00
logdc79f181a56cad17f429bbb7fd176e49bf3d66da
tree4aa0c56887fb3f197b692d999c8a2771d984cca7
parentbeea478acc2491289ec3e3bbdcec3b68f65d6e62
signaturelock-open Commit is signed but in an unrecognized format.

ir: Disallow comparison between enum literal and untagged enum

Closes #4770

2 files changed, 20 insertions(+), 0 deletions(-)

src/ir.cpp+9
...@@ -16286,6 +16286,15 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i...@@ -16286,6 +16286,15 @@ static IrInstGen *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstSrcBinOp *bin_op_i
16286 IrInstGen *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2;16286 IrInstGen *union_val = op1->value->type->id == ZigTypeIdUnion ? op1 : op2;
16287 IrInstGen *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1;16287 IrInstGen *enum_val = op1->value->type->id == ZigTypeIdUnion ? op2 : op1;
1628816288
16289 if (!is_tagged_union(union_val->value->type)) {
16290 ErrorMsg *msg = ir_add_error_node(ira, source_node,
16291 buf_sprintf("comparison of union and enum literal is only valid for tagged union types"));
16292 add_error_note(ira->codegen, msg, union_val->value->type->data.unionation.decl_node,
16293 buf_sprintf("type %s is not a tagged union",
16294 buf_ptr(&union_val->value->type->name)));
16295 return ira->codegen->invalid_inst_gen;
16296 }
16297
16289 ZigType *tag_type = union_val->value->type->data.unionation.tag_type;16298 ZigType *tag_type = union_val->value->type->data.unionation.tag_type;
16290 assert(tag_type != nullptr);16299 assert(tag_type != nullptr);
1629116300
test/compile_errors.zig+11
...@@ -14,6 +14,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -14,6 +14,17 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
14 "tmp.zig:2:15: error: unused variable: 'a'",14 "tmp.zig:2:15: error: unused variable: 'a'",
15 });15 });
1616
17 cases.addTest("comparison of non-tagged union and enum literal",
18 \\export fn entry() void {
19 \\ const U = union { A: u32, B: u64 };
20 \\ var u = U{ .A = 42 };
21 \\ var ok = u == .A;
22 \\}
23 , &[_][]const u8{
24 "tmp.zig:4:16: error: comparison of union and enum literal is only valid for tagged union types",
25 "tmp.zig:2:15: note: type U is not a tagged union",
26 });
27
17 cases.addTest("shift on type with non-power-of-two size",28 cases.addTest("shift on type with non-power-of-two size",
18 \\export fn entry() void {29 \\export fn entry() void {
19 \\ const S = struct {30 \\ const S = struct {