diff --git a/src/Sema.zig b/src/Sema.zig index e0a8d1fe00..2736abbd2a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -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); diff --git a/test/cases/compile_errors/switch_on_undefined_union.zig b/test/cases/compile_errors/switch_on_undefined_union.zig new file mode 100644 index 0000000000..762363dd08 --- /dev/null +++ b/test/cases/compile_errors/switch_on_undefined_union.zig @@ -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