aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-10-06 17:25:00 +0300
committerVeikka Tuominen <git@vexu.eu>2022-10-07 11:04:02 +0300
commit2315e1b41073a8d6a7f7fe3deb98ec98e45d72f6 (patch)
tree1dc47e22eb261a98825051e31f691a39c1e87f97 /src
parent29ae6515f3adc23df3d889acaf7ec62a2d01b707 (diff)
downloadzig-2315e1b41073a8d6a7f7fe3deb98ec98e45d72f6.tar.gz
zig-2315e1b41073a8d6a7f7fe3deb98ec98e45d72f6.zip
safety: add safety check for hitting else branch on a corrupt enum value
Closes #7053
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig15
1 files changed, 15 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index ef45bf7174..ca8e91dd68 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -9998,6 +9998,8 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
}
+ const backend_supports_is_named_enum = sema.mod.comp.bin_file.options.use_llvm;
+
if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) {
if (empty_enum) {
return Air.Inst.Ref.void_value;
@@ -10008,6 +10010,12 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) {
return Air.Inst.Ref.unreachable_value;
}
+ if (backend_supports_is_named_enum and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and
+ (!operand_ty.isNonexhaustiveEnum() or union_originally))
+ {
+ const ok = try block.addUnOp(.is_named_enum_value, operand);
+ try sema.addSafetyCheck(block, ok, .corrupt_switch);
+ }
return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges);
}
@@ -10465,6 +10473,13 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError
case_block.wip_capture_scope = wip_captures.scope;
case_block.inline_case_capture = .none;
+ if (backend_supports_is_named_enum and special.body.len != 0 and block.wantSafety() and
+ operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally))
+ {
+ const ok = try case_block.addUnOp(.is_named_enum_value, operand);
+ try sema.addSafetyCheck(&case_block, ok, .corrupt_switch);
+ }
+
const analyze_body = if (union_originally and !special.is_inline)
for (seen_enum_fields) |seen_field, index| {
if (seen_field != null) continue;