aboutsummaryrefslogtreecommitdiff
path: root/src/Sema.zig
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2022-08-05 18:15:31 +0300
committerVeikka Tuominen <git@vexu.eu>2022-08-05 22:13:58 +0300
commitf46d7304b176cdc77053225943a7d5030dd0d4ee (patch)
tree483f0aa5303fe5a1ab4fbe9140d6dabf916d88b1 /src/Sema.zig
parent19d5ffc710faa23cd07a6dff23d4afc43c0c7f63 (diff)
downloadzig-f46d7304b176cdc77053225943a7d5030dd0d4ee.tar.gz
zig-f46d7304b176cdc77053225943a7d5030dd0d4ee.zip
stage2: add runtime safety for invalid enum values
Diffstat (limited to 'src/Sema.zig')
-rw-r--r--src/Sema.zig15
1 files changed, 13 insertions, 2 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 3b672ecd42..56e08d081b 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -6933,8 +6933,12 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
}
try sema.requireRuntimeBlock(block, src, operand_src);
- // TODO insert safety check to make sure the value matches an enum value
- return block.addTyOp(.intcast, dest_ty, operand);
+ const result = try block.addTyOp(.intcast, dest_ty, operand);
+ if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum() and sema.mod.comp.bin_file.options.use_llvm) {
+ const ok = try block.addUnOp(.is_named_enum_value, result);
+ try sema.addSafetyCheck(block, ok, .invalid_enum_value);
+ }
+ return result;
}
/// Pointer in, pointer out.
@@ -15887,6 +15891,11 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
const field_name = enum_ty.enumFieldName(field_index);
return sema.addStrLit(block, field_name);
}
+ try sema.requireRuntimeBlock(block, src, operand_src);
+ if (block.wantSafety() and sema.mod.comp.bin_file.options.use_llvm) {
+ const ok = try block.addUnOp(.is_named_enum_value, casted_operand);
+ try sema.addSafetyCheck(block, ok, .invalid_enum_value);
+ }
// In case the value is runtime-known, we have an AIR instruction for this instead
// of trying to lower it in Sema because an optimization pass may result in the operand
// being comptime-known, which would let us elide the `tag_name` AIR instruction.
@@ -20019,6 +20028,7 @@ pub const PanicId = enum {
integer_part_out_of_bounds,
corrupt_switch,
shift_rhs_too_big,
+ invalid_enum_value,
};
fn addSafetyCheck(
@@ -20316,6 +20326,7 @@ fn safetyPanic(
.integer_part_out_of_bounds => "integer part of floating point value out of bounds",
.corrupt_switch => "switch on corrupt value",
.shift_rhs_too_big => "shift amount is greater than the type size",
+ .invalid_enum_value => "invalid enum value",
};
const msg_inst = msg_inst: {