diff options
| author | Veikka Tuominen <git@vexu.eu> | 2022-10-06 17:25:00 +0300 |
|---|---|---|
| committer | Veikka Tuominen <git@vexu.eu> | 2022-10-07 11:04:02 +0300 |
| commit | 2315e1b41073a8d6a7f7fe3deb98ec98e45d72f6 (patch) | |
| tree | 1dc47e22eb261a98825051e31f691a39c1e87f97 /src | |
| parent | 29ae6515f3adc23df3d889acaf7ec62a2d01b707 (diff) | |
| download | zig-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.zig | 15 |
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; |
