mirror of
https://github.com/ziglang/zig.git
synced 2024-11-27 07:32:44 +00:00
fix cast from invalid non-exhaustive enum to union
This commit is contained in:
parent
1e835e0fcc
commit
2948f2d262
16
src/ir.cpp
16
src/ir.cpp
@ -14177,7 +14177,14 @@ static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr,
|
||||
if (!val)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
TypeUnionField *union_field = find_union_field_by_tag(wanted_type, &val->data.x_enum_tag);
|
||||
assert(union_field != nullptr);
|
||||
if (union_field == nullptr) {
|
||||
Buf *int_buf = buf_alloc();
|
||||
bigint_append_buf(int_buf, &target->value->data.x_enum_tag, 10);
|
||||
|
||||
ir_add_error(ira, &target->base,
|
||||
buf_sprintf("no tag by value %s", buf_ptr(int_buf)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
ZigType *field_type = resolve_union_field_type(ira->codegen, union_field);
|
||||
if (field_type == nullptr)
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
@ -14213,6 +14220,13 @@ static IrInstGen *ir_analyze_enum_to_union(IrAnalyze *ira, IrInst* source_instr,
|
||||
return result;
|
||||
}
|
||||
|
||||
if (target->value->type->data.enumeration.non_exhaustive) {
|
||||
ir_add_error(ira, source_instr,
|
||||
buf_sprintf("runtime cast to union '%s' from non-exhustive enum",
|
||||
buf_ptr(&wanted_type->name)));
|
||||
return ira->codegen->invalid_inst_gen;
|
||||
}
|
||||
|
||||
// if the union has all fields 0 bits, we can do it
|
||||
// and in fact it's a noop cast because the union value is just the enum value
|
||||
if (wanted_type->data.unionation.gen_field_count == 0) {
|
||||
|
@ -51,6 +51,29 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
|
||||
"tmp.zig:17:23: error: cannot adjust alignment of zero sized type 'fn(u32) anytype'",
|
||||
});
|
||||
|
||||
cases.addTest("invalid non-exhaustive enum to union",
|
||||
\\const E = enum(u8) {
|
||||
\\ a,
|
||||
\\ b,
|
||||
\\ _,
|
||||
\\};
|
||||
\\const U = union(E) {
|
||||
\\ a,
|
||||
\\ b,
|
||||
\\};
|
||||
\\export fn foo() void {
|
||||
\\ var e = @intToEnum(E, 15);
|
||||
\\ var u: U = e;
|
||||
\\}
|
||||
\\export fn bar() void {
|
||||
\\ const e = @intToEnum(E, 15);
|
||||
\\ var u: U = e;
|
||||
\\}
|
||||
, &[_][]const u8{
|
||||
"tmp.zig:12:16: error: runtime cast to union 'U' from non-exhustive enum",
|
||||
"tmp.zig:16:16: error: no tag by value 15",
|
||||
});
|
||||
|
||||
cases.addTest("switching with exhaustive enum has '_' prong ",
|
||||
\\const E = enum{
|
||||
\\ a,
|
||||
|
Loading…
Reference in New Issue
Block a user