srctree

John Schmidt parent 8bd94759 00ff123b
Sema: fix compile error for switching on undefined union

Before this fix, passing an undefined union value to Sema.switchCondreturned an undefined value of the union type, not the tag type, sinceValue.unionTag forwards undefined values unchanged.This leads us into the .Union branch in Sema.zirSwitchBlock which isunreachable, now we take the .Enum branch instead.

inlinesplit
src/Sema.zig added: 19, removed: 4, total 15
@@ -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);
 
filename was Deleted added: 19, removed: 4, total 15
@@ -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