mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Sema: fix compile error for switching on undefined union
Before this fix, passing an undefined union value to `Sema.switchCond` returned an undefined value of the union type, not the tag type, since `Value.unionTag` forwards undefined values unchanged. This leads us into the `.Union` branch in `Sema.zirSwitchBlock` which is unreachable, now we take the `.Enum` branch instead.
This commit is contained in:
parent
8bd94759bf
commit
00ff123b1e
@ -11658,7 +11658,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index, operand_is_r
|
||||
|
||||
// Validate for duplicate items, missing else prong, and invalid range.
|
||||
switch (operand_ty.zigTypeTag(mod)) {
|
||||
.Union => unreachable, // handled in zirSwitchCond
|
||||
.Union => unreachable, // handled in `switchCond`
|
||||
.Enum => {
|
||||
seen_enum_fields = try gpa.alloc(?Module.SwitchProngSrc, operand_ty.enumFieldCount(mod));
|
||||
empty_enum = seen_enum_fields.len == 0 and !operand_ty.isNonexhaustiveEnum(mod);
|
||||
@ -33747,7 +33747,10 @@ fn unionToTag(
|
||||
return Air.internedToRef(opv.toIntern());
|
||||
}
|
||||
if (try sema.resolveValue(un)) |un_val| {
|
||||
return Air.internedToRef(un_val.unionTag(mod).?.toIntern());
|
||||
const tag_val = un_val.unionTag(mod).?;
|
||||
if (tag_val.isUndef(mod))
|
||||
return try mod.undefRef(enum_ty);
|
||||
return Air.internedToRef(tag_val.toIntern());
|
||||
}
|
||||
try sema.requireRuntimeBlock(block, un_src, null);
|
||||
return block.addTyOp(.get_union_tag, enum_ty, un);
|
||||
|
||||
12
test/cases/compile_errors/switch_on_undefined_union.zig
Normal file
12
test/cases/compile_errors/switch_on_undefined_union.zig
Normal file
@ -0,0 +1,12 @@
|
||||
export fn entry() void {
|
||||
const U = union(enum) { a: bool, b: bool };
|
||||
switch (@as(U, undefined)) {
|
||||
.a, .b => {},
|
||||
}
|
||||
}
|
||||
|
||||
// error
|
||||
// backend=stage2
|
||||
// target=native
|
||||
//
|
||||
// :3:5: error: use of undefined value here causes undefined behavior
|
||||
Loading…
x
Reference in New Issue
Block a user