authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-25 01:46:12-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-25 01:46:12-05:00
loge5bc5873d74713bedbc32817ed31370c3256418d
treedbd196cb4242ae111591238d923d100062fb86c6
parentb71a56c9df5e3b20d06cac24062456821b69dbba

rename "debug safety" to "runtime safety"

closes #437

36 files changed, 487 insertions(+), 509 deletions(-)

build.zig+1-1
......@@ -116,7 +116,7 @@ pub fn build(b: &Builder) -> %void {
116116 test_step.dependOn(tests.addBuildExampleTests(b, test_filter));
117117 test_step.dependOn(tests.addCompileErrorTests(b, test_filter));
118118 test_step.dependOn(tests.addAssembleAndLinkTests(b, test_filter));
119 test_step.dependOn(tests.addDebugSafetyTests(b, test_filter));
119 test_step.dependOn(tests.addRuntimeSafetyTests(b, test_filter));
120120 test_step.dependOn(tests.addTranslateCTests(b, test_filter));
121121 test_step.dependOn(tests.addGenHTests(b, test_filter));
122122}
doc/docgen.zig+1-1
......@@ -896,7 +896,7 @@ fn genHtml(allocator: &mem.Allocator, tokenizer: &Tokenizer, toc: &Toc, out: &io
896896 }
897897 if (mem.indexOf(u8, result.stderr, error_match) == null) {
898898 warn("{}\nExpected to find '{}' in stderr", result.stderr, error_match);
899 return parseError(tokenizer, code.source_token, "example did not have expected debug safety error message");
899 return parseError(tokenizer, code.source_token, "example did not have expected runtime safety error message");
900900 }
901901 const escaped_stderr = try escapeHtml(allocator, result.stderr);
902902 const colored_stderr = try termColor(allocator, escaped_stderr);
doc/langref.html.in+6-6
......@@ -3090,7 +3090,7 @@ fn doAThing(nullable_foo: ?&Foo) {
30903090 {#header_open|this#}
30913091 <p>TODO: example of this referring to Self struct</p>
30923092 <p>TODO: example of this referring to recursion function</p>
3093 <p>TODO: example of this referring to basic block for @setDebugSafety</p>
3093 <p>TODO: example of this referring to basic block for @setRuntimeSafety</p>
30943094 {#header_close#}
30953095 {#header_open|comptime#}
30963096 <p>
......@@ -4325,10 +4325,10 @@ test "call foo" {
43254325 Tells the optimizer that a function is rarely called.
43264326 </p>
43274327 {#header_close#}
4328 {#header_open|@setDebugSafety#}
4329 <pre><code class="zig">@setDebugSafety(scope, safety_on: bool)</code></pre>
4328 {#header_open|@setRuntimeSafety#}
4329 <pre><code class="zig">@setRuntimeSafety(safety_on: bool)</code></pre>
43304330 <p>
4331 Sets whether debug safety checks are on for a given scope.
4331 Sets whether runtime safety checks are on for the scope that contains the function call.
43324332 </p>
43334333
43344334 {#header_close#}
......@@ -4595,7 +4595,7 @@ pub fn build(b: &Builder) -> %void {
45954595 detected at compile-time, Zig emits an error. Most undefined behavior that
45964596 cannot be detected at compile-time can be detected at runtime. In these cases,
45974597 Zig has safety checks. Safety checks can be disabled on a per-block basis
4598 with <code>@setDebugSafety</code>. The {#link|ReleaseFast#}
4598 with <code>@setRuntimeSafety</code>. The {#link|ReleaseFast#}
45994599 build mode disables all safety checks in order to facilitate optimizations.
46004600 </p>
46014601 <p>
......@@ -5765,7 +5765,7 @@ hljs.registerLanguage("zig", function(t) {
57655765 a = t.IR + "\\s*\\(",
57665766 c = {
57675767 keyword: "const align var extern stdcallcc nakedcc volatile export pub noalias inline struct packed enum union break return try catch test continue unreachable comptime and or asm defer errdefer if else switch while for fn use bool f32 f64 void type noreturn error i8 u8 i16 u16 i32 u32 i64 u64 isize usize i8w u8w i16w i32w u32w i64w u64w isizew usizew c_short c_ushort c_int c_uint c_long c_ulong c_longlong c_ulonglong",
5768 built_in: "breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setDebugSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchg fence divExact truncate",
5768 built_in: "breakpoint returnAddress frameAddress fieldParentPtr setFloatMode IntType OpaqueType compileError compileLog setCold setRuntimeSafety setEvalBranchQuota offsetOf memcpy inlineCall setGlobalLinkage setGlobalSection divTrunc divFloor enumTagName intToPtr ptrToInt panic canImplicitCast ptrCast bitCast rem mod memset sizeOf alignOf alignCast maxValue minValue memberCount typeOf addWithOverflow subWithOverflow mulWithOverflow shlWithOverflow shlExact shrExact cInclude cDefine cUndef ctz clz import cImport errorName embedFile cmpxchg fence divExact truncate",
57695769 literal: "true false null undefined"
57705770 },
57715771 n = [e, t.CLCM, t.CBCM, s, r];
src-self-hosted/ir.zig+1-1
......@@ -33,7 +33,7 @@ pub const Instruction = struct {
3333 TypeOf,
3434 ToPtrType,
3535 PtrTypeChild,
36 SetDebugSafety,
36 SetRuntimeSafety,
3737 SetFloatMode,
3838 ArrayType,
3939 SliceType,
src/all_types.hpp+4-5
......@@ -1255,7 +1255,7 @@ enum BuiltinFnId {
12551255 BuiltinFnIdTruncate,
12561256 BuiltinFnIdIntType,
12571257 BuiltinFnIdSetCold,
1258 BuiltinFnIdSetDebugSafety,
1258 BuiltinFnIdSetRuntimeSafety,
12591259 BuiltinFnIdSetFloatMode,
12601260 BuiltinFnIdTypeName,
12611261 BuiltinFnIdCanImplicitCast,
......@@ -1836,7 +1836,7 @@ enum IrInstructionId {
18361836 IrInstructionIdToPtrType,
18371837 IrInstructionIdPtrTypeChild,
18381838 IrInstructionIdSetCold,
1839 IrInstructionIdSetDebugSafety,
1839 IrInstructionIdSetRuntimeSafety,
18401840 IrInstructionIdSetFloatMode,
18411841 IrInstructionIdArrayType,
18421842 IrInstructionIdSliceType,
......@@ -2214,11 +2214,10 @@ struct IrInstructionSetCold {
22142214 IrInstruction *is_cold;
22152215};
22162216
2217struct IrInstructionSetDebugSafety {
2217struct IrInstructionSetRuntimeSafety {
22182218 IrInstruction base;
22192219
2220 IrInstruction *scope_value;
2221 IrInstruction *debug_safety_on;
2220 IrInstruction *safety_on;
22222221};
22232222
22242223struct IrInstructionSetFloatMode {
src/codegen.cpp+68-68
......@@ -806,7 +806,7 @@ static bool ir_want_fast_math(CodeGen *g, IrInstruction *instruction) {
806806 return true;
807807}
808808
809static bool ir_want_debug_safety(CodeGen *g, IrInstruction *instruction) {
809static bool ir_want_runtime_safety(CodeGen *g, IrInstruction *instruction) {
810810 if (g->build_mode == BuildModeFastRelease)
811811 return false;
812812
......@@ -901,7 +901,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace
901901 LLVMBuildUnreachable(g->builder);
902902}
903903
904static void gen_debug_safety_crash(CodeGen *g, PanicMsgId msg_id) {
904static void gen_safety_crash(CodeGen *g, PanicMsgId msg_id) {
905905 gen_panic(g, get_panic_msg_ptr_val(g, msg_id), nullptr);
906906}
907907
......@@ -1140,7 +1140,7 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) {
11401140 return fn_val;
11411141}
11421142
1143static void gen_debug_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
1143static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val) {
11441144 LLVMValueRef safety_crash_err_fn = get_safety_crash_err_fn(g);
11451145 LLVMValueRef err_ret_trace_val = g->cur_err_ret_trace_val;
11461146 if (err_ret_trace_val == nullptr) {
......@@ -1179,7 +1179,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
11791179 LLVMBuildCondBr(g->builder, lower_ok_val, lower_ok_block, bounds_check_fail_block);
11801180
11811181 LLVMPositionBuilderAtEnd(g->builder, bounds_check_fail_block);
1182 gen_debug_safety_crash(g, PanicMsgIdBoundsCheckFailure);
1182 gen_safety_crash(g, PanicMsgIdBoundsCheckFailure);
11831183
11841184 if (upper_value) {
11851185 LLVMPositionBuilderAtEnd(g->builder, lower_ok_block);
......@@ -1190,7 +1190,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val,
11901190 LLVMPositionBuilderAtEnd(g->builder, ok_block);
11911191}
11921192
1193static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, TypeTableEntry *actual_type,
1193static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_runtime_safety, TypeTableEntry *actual_type,
11941194 TypeTableEntry *wanted_type, LLVMValueRef expr_val)
11951195{
11961196 assert(actual_type->id == wanted_type->id);
......@@ -1209,7 +1209,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12091209
12101210 if (actual_bits >= wanted_bits && actual_type->id == TypeTableEntryIdInt &&
12111211 !wanted_type->data.integral.is_signed && actual_type->data.integral.is_signed &&
1212 want_debug_safety)
1212 want_runtime_safety)
12131213 {
12141214 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
12151215 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntSGE, expr_val, zero, "");
......@@ -1219,7 +1219,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12191219 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
12201220
12211221 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1222 gen_debug_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
1222 gen_safety_crash(g, PanicMsgIdCastNegativeToUnsigned);
12231223
12241224 LLVMPositionBuilderAtEnd(g->builder, ok_block);
12251225 }
......@@ -1243,7 +1243,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12431243 return LLVMBuildFPTrunc(g->builder, expr_val, wanted_type->type_ref, "");
12441244 } else if (actual_type->id == TypeTableEntryIdInt) {
12451245 LLVMValueRef trunc_val = LLVMBuildTrunc(g->builder, expr_val, wanted_type->type_ref, "");
1246 if (!want_debug_safety) {
1246 if (!want_runtime_safety) {
12471247 return trunc_val;
12481248 }
12491249 LLVMValueRef orig_val;
......@@ -1258,7 +1258,7 @@ static LLVMValueRef gen_widen_or_shorten(CodeGen *g, bool want_debug_safety, Typ
12581258 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
12591259
12601260 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1261 gen_debug_safety_crash(g, PanicMsgIdCastTruncatedData);
1261 gen_safety_crash(g, PanicMsgIdCastTruncatedData);
12621262
12631263 LLVMPositionBuilderAtEnd(g->builder, ok_block);
12641264 return trunc_val;
......@@ -1286,7 +1286,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, TypeTableEntry *type_entry, AddS
12861286 LLVMBuildCondBr(g->builder, overflow_bit, fail_block, ok_block);
12871287
12881288 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1289 gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);
1289 gen_safety_crash(g, PanicMsgIdIntegerOverflow);
12901290
12911291 LLVMPositionBuilderAtEnd(g->builder, ok_block);
12921292 return result;
......@@ -1494,7 +1494,7 @@ static LLVMValueRef gen_overflow_shl_op(CodeGen *g, TypeTableEntry *type_entry,
14941494 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
14951495
14961496 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1497 gen_debug_safety_crash(g, PanicMsgIdShlOverflowedBits);
1497 gen_safety_crash(g, PanicMsgIdShlOverflowedBits);
14981498
14991499 LLVMPositionBuilderAtEnd(g->builder, ok_block);
15001500 return result;
......@@ -1519,7 +1519,7 @@ static LLVMValueRef gen_overflow_shr_op(CodeGen *g, TypeTableEntry *type_entry,
15191519 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
15201520
15211521 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1522 gen_debug_safety_crash(g, PanicMsgIdShrOverflowedBits);
1522 gen_safety_crash(g, PanicMsgIdShrOverflowedBits);
15231523
15241524 LLVMPositionBuilderAtEnd(g->builder, ok_block);
15251525 return result;
......@@ -1565,14 +1565,14 @@ static LLVMValueRef bigint_to_llvm_const(LLVMTypeRef type_ref, BigInt *bigint) {
15651565 }
15661566}
15671567
1568static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_math,
1568static LLVMValueRef gen_div(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
15691569 LLVMValueRef val1, LLVMValueRef val2,
15701570 TypeTableEntry *type_entry, DivKind div_kind)
15711571{
15721572 ZigLLVMSetFastMath(g->builder, want_fast_math);
15731573
15741574 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
1575 if (want_debug_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) {
1575 if (want_runtime_safety && (want_fast_math || type_entry->id != TypeTableEntryIdFloat)) {
15761576 LLVMValueRef is_zero_bit;
15771577 if (type_entry->id == TypeTableEntryIdInt) {
15781578 is_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, val2, zero, "");
......@@ -1586,7 +1586,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
15861586 LLVMBuildCondBr(g->builder, is_zero_bit, div_zero_fail_block, div_zero_ok_block);
15871587
15881588 LLVMPositionBuilderAtEnd(g->builder, div_zero_fail_block);
1589 gen_debug_safety_crash(g, PanicMsgIdDivisionByZero);
1589 gen_safety_crash(g, PanicMsgIdDivisionByZero);
15901590
15911591 LLVMPositionBuilderAtEnd(g->builder, div_zero_ok_block);
15921592
......@@ -1603,7 +1603,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16031603 LLVMBuildCondBr(g->builder, overflow_fail_bit, overflow_fail_block, overflow_ok_block);
16041604
16051605 LLVMPositionBuilderAtEnd(g->builder, overflow_fail_block);
1606 gen_debug_safety_crash(g, PanicMsgIdIntegerOverflow);
1606 gen_safety_crash(g, PanicMsgIdIntegerOverflow);
16071607
16081608 LLVMPositionBuilderAtEnd(g->builder, overflow_ok_block);
16091609 }
......@@ -1615,7 +1615,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16151615 case DivKindFloat:
16161616 return result;
16171617 case DivKindExact:
1618 if (want_debug_safety) {
1618 if (want_runtime_safety) {
16191619 LLVMValueRef floored = gen_floor(g, result, type_entry);
16201620 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactOk");
16211621 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "DivExactFail");
......@@ -1624,7 +1624,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16241624 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
16251625
16261626 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1627 gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);
1627 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
16281628
16291629 LLVMPositionBuilderAtEnd(g->builder, ok_block);
16301630 }
......@@ -1672,7 +1672,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16721672 return LLVMBuildUDiv(g->builder, val1, val2, "");
16731673 }
16741674 case DivKindExact:
1675 if (want_debug_safety) {
1675 if (want_runtime_safety) {
16761676 LLVMValueRef remainder_val;
16771677 if (type_entry->data.integral.is_signed) {
16781678 remainder_val = LLVMBuildSRem(g->builder, val1, val2, "");
......@@ -1686,7 +1686,7 @@ static LLVMValueRef gen_div(CodeGen *g, bool want_debug_safety, bool want_fast_m
16861686 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
16871687
16881688 LLVMPositionBuilderAtEnd(g->builder, fail_block);
1689 gen_debug_safety_crash(g, PanicMsgIdExactDivisionRemainder);
1689 gen_safety_crash(g, PanicMsgIdExactDivisionRemainder);
16901690
16911691 LLVMPositionBuilderAtEnd(g->builder, ok_block);
16921692 }
......@@ -1724,14 +1724,14 @@ enum RemKind {
17241724 RemKindMod,
17251725};
17261726
1727static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_math,
1727static LLVMValueRef gen_rem(CodeGen *g, bool want_runtime_safety, bool want_fast_math,
17281728 LLVMValueRef val1, LLVMValueRef val2,
17291729 TypeTableEntry *type_entry, RemKind rem_kind)
17301730{
17311731 ZigLLVMSetFastMath(g->builder, want_fast_math);
17321732
17331733 LLVMValueRef zero = LLVMConstNull(type_entry->type_ref);
1734 if (want_debug_safety) {
1734 if (want_runtime_safety) {
17351735 LLVMValueRef is_zero_bit;
17361736 if (type_entry->id == TypeTableEntryIdInt) {
17371737 LLVMIntPredicate pred = type_entry->data.integral.is_signed ? LLVMIntSLE : LLVMIntEQ;
......@@ -1746,7 +1746,7 @@ static LLVMValueRef gen_rem(CodeGen *g, bool want_debug_safety, bool want_fast_m
17461746 LLVMBuildCondBr(g->builder, is_zero_bit, rem_zero_fail_block, rem_zero_ok_block);
17471747
17481748 LLVMPositionBuilderAtEnd(g->builder, rem_zero_fail_block);
1749 gen_debug_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
1749 gen_safety_crash(g, PanicMsgIdRemainderDivisionByZero);
17501750
17511751 LLVMPositionBuilderAtEnd(g->builder, rem_zero_ok_block);
17521752 }
......@@ -1792,8 +1792,8 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
17921792 op_id == IrBinOpBitShiftRightExact);
17931793 TypeTableEntry *type_entry = op1->value.type;
17941794
1795 bool want_debug_safety = bin_op_instruction->safety_check_on &&
1796 ir_want_debug_safety(g, &bin_op_instruction->base);
1795 bool want_runtime_safety = bin_op_instruction->safety_check_on &&
1796 ir_want_runtime_safety(g, &bin_op_instruction->base);
17971797
17981798 LLVMValueRef op1_value = ir_llvm_value(g, op1);
17991799 LLVMValueRef op2_value = ir_llvm_value(g, op2);
......@@ -1841,7 +1841,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
18411841 bool is_wrapping = (op_id == IrBinOpAddWrap);
18421842 if (is_wrapping) {
18431843 return LLVMBuildAdd(g->builder, op1_value, op2_value, "");
1844 } else if (want_debug_safety) {
1844 } else if (want_runtime_safety) {
18451845 return gen_overflow_op(g, type_entry, AddSubMulAdd, op1_value, op2_value);
18461846 } else if (type_entry->data.integral.is_signed) {
18471847 return LLVMBuildNSWAdd(g->builder, op1_value, op2_value, "");
......@@ -1866,7 +1866,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
18661866 bool is_sloppy = (op_id == IrBinOpBitShiftLeftLossy);
18671867 if (is_sloppy) {
18681868 return LLVMBuildShl(g->builder, op1_value, op2_casted, "");
1869 } else if (want_debug_safety) {
1869 } else if (want_runtime_safety) {
18701870 return gen_overflow_shl_op(g, type_entry, op1_value, op2_casted);
18711871 } else if (type_entry->data.integral.is_signed) {
18721872 return ZigLLVMBuildNSWShl(g->builder, op1_value, op2_casted, "");
......@@ -1887,7 +1887,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
18871887 } else {
18881888 return LLVMBuildLShr(g->builder, op1_value, op2_casted, "");
18891889 }
1890 } else if (want_debug_safety) {
1890 } else if (want_runtime_safety) {
18911891 return gen_overflow_shr_op(g, type_entry, op1_value, op2_casted);
18921892 } else if (type_entry->data.integral.is_signed) {
18931893 return ZigLLVMBuildAShrExact(g->builder, op1_value, op2_casted, "");
......@@ -1904,7 +1904,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
19041904 bool is_wrapping = (op_id == IrBinOpSubWrap);
19051905 if (is_wrapping) {
19061906 return LLVMBuildSub(g->builder, op1_value, op2_value, "");
1907 } else if (want_debug_safety) {
1907 } else if (want_runtime_safety) {
19081908 return gen_overflow_op(g, type_entry, AddSubMulSub, op1_value, op2_value);
19091909 } else if (type_entry->data.integral.is_signed) {
19101910 return LLVMBuildNSWSub(g->builder, op1_value, op2_value, "");
......@@ -1923,7 +1923,7 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
19231923 bool is_wrapping = (op_id == IrBinOpMultWrap);
19241924 if (is_wrapping) {
19251925 return LLVMBuildMul(g->builder, op1_value, op2_value, "");
1926 } else if (want_debug_safety) {
1926 } else if (want_runtime_safety) {
19271927 return gen_overflow_op(g, type_entry, AddSubMulMul, op1_value, op2_value);
19281928 } else if (type_entry->data.integral.is_signed) {
19291929 return LLVMBuildNSWMul(g->builder, op1_value, op2_value, "");
......@@ -1934,22 +1934,22 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, IrExecutable *executable,
19341934 zig_unreachable();
19351935 }
19361936 case IrBinOpDivUnspecified:
1937 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1937 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
19381938 op1_value, op2_value, type_entry, DivKindFloat);
19391939 case IrBinOpDivExact:
1940 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1940 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
19411941 op1_value, op2_value, type_entry, DivKindExact);
19421942 case IrBinOpDivTrunc:
1943 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1943 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
19441944 op1_value, op2_value, type_entry, DivKindTrunc);
19451945 case IrBinOpDivFloor:
1946 return gen_div(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1946 return gen_div(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
19471947 op1_value, op2_value, type_entry, DivKindFloor);
19481948 case IrBinOpRemRem:
1949 return gen_rem(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1949 return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
19501950 op1_value, op2_value, type_entry, RemKindRem);
19511951 case IrBinOpRemMod:
1952 return gen_rem(g, want_debug_safety, ir_want_fast_math(g, &bin_op_instruction->base),
1952 return gen_rem(g, want_runtime_safety, ir_want_fast_math(g, &bin_op_instruction->base),
19531953 op1_value, op2_value, type_entry, RemKindMod);
19541954 }
19551955 zig_unreachable();
......@@ -2007,7 +2007,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
20072007 new_len = LLVMBuildMul(g->builder, src_len, src_size_val, "");
20082008 } else if (src_size == 1) {
20092009 LLVMValueRef dest_size_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, dest_size, false);
2010 if (ir_want_debug_safety(g, &cast_instruction->base)) {
2010 if (ir_want_runtime_safety(g, &cast_instruction->base)) {
20112011 LLVMValueRef remainder_val = LLVMBuildURem(g->builder, src_len, dest_size_val, "");
20122012 LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_usize->type_ref);
20132013 LLVMValueRef ok_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, remainder_val, zero, "");
......@@ -2016,7 +2016,7 @@ static LLVMValueRef ir_render_cast(CodeGen *g, IrExecutable *executable,
20162016 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
20172017
20182018 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2019 gen_debug_safety_crash(g, PanicMsgIdSliceWidenRemainder);
2019 gen_safety_crash(g, PanicMsgIdSliceWidenRemainder);
20202020
20212021 LLVMPositionBuilderAtEnd(g->builder, ok_block);
20222022 }
......@@ -2111,7 +2111,7 @@ static LLVMValueRef ir_render_widen_or_shorten(CodeGen *g, IrExecutable *executa
21112111 int_type = actual_type;
21122112 }
21132113 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
2114 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base), int_type,
2114 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base), int_type,
21152115 instruction->base.value.type, target_val);
21162116}
21172117
......@@ -2133,7 +2133,7 @@ static LLVMValueRef ir_render_int_to_enum(CodeGen *g, IrExecutable *executable,
21332133 TypeTableEntry *tag_int_type = wanted_type->data.enumeration.tag_int_type;
21342134
21352135 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
2136 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
2136 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
21372137 instruction->target->value.type, tag_int_type, target_val);
21382138}
21392139
......@@ -2147,7 +2147,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
21472147
21482148 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
21492149
2150 if (ir_want_debug_safety(g, &instruction->base)) {
2150 if (ir_want_runtime_safety(g, &instruction->base)) {
21512151 LLVMValueRef zero = LLVMConstNull(actual_type->type_ref);
21522152 LLVMValueRef neq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntNE, target_val, zero, "");
21532153 LLVMValueRef ok_bit;
......@@ -2171,7 +2171,7 @@ static LLVMValueRef ir_render_int_to_err(CodeGen *g, IrExecutable *executable, I
21712171 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
21722172
21732173 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2174 gen_debug_safety_crash(g, PanicMsgIdInvalidErrorCode);
2174 gen_safety_crash(g, PanicMsgIdInvalidErrorCode);
21752175
21762176 LLVMPositionBuilderAtEnd(g->builder, ok_block);
21772177 }
......@@ -2188,11 +2188,11 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
21882188 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
21892189
21902190 if (actual_type->id == TypeTableEntryIdPureError) {
2191 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
2191 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
21922192 g->err_tag_type, wanted_type, target_val);
21932193 } else if (actual_type->id == TypeTableEntryIdErrorUnion) {
21942194 if (!type_has_bits(actual_type->data.error.child_type)) {
2195 return gen_widen_or_shorten(g, ir_want_debug_safety(g, &instruction->base),
2195 return gen_widen_or_shorten(g, ir_want_runtime_safety(g, &instruction->base),
21962196 g->err_tag_type, wanted_type, target_val);
21972197 } else {
21982198 zig_panic("TODO");
......@@ -2205,8 +2205,8 @@ static LLVMValueRef ir_render_err_to_int(CodeGen *g, IrExecutable *executable, I
22052205static LLVMValueRef ir_render_unreachable(CodeGen *g, IrExecutable *executable,
22062206 IrInstructionUnreachable *unreachable_instruction)
22072207{
2208 if (ir_want_debug_safety(g, &unreachable_instruction->base)) {
2209 gen_debug_safety_crash(g, PanicMsgIdUnreachable);
2208 if (ir_want_runtime_safety(g, &unreachable_instruction->base)) {
2209 gen_safety_crash(g, PanicMsgIdUnreachable);
22102210 } else {
22112211 LLVMBuildUnreachable(g->builder);
22122212 }
......@@ -2248,7 +2248,7 @@ static LLVMValueRef ir_render_un_op(CodeGen *g, IrExecutable *executable, IrInst
22482248 } else if (expr_type->id == TypeTableEntryIdInt) {
22492249 if (op_id == IrUnOpNegationWrap) {
22502250 return LLVMBuildNeg(g->builder, expr, "");
2251 } else if (ir_want_debug_safety(g, &un_op_instruction->base)) {
2251 } else if (ir_want_runtime_safety(g, &un_op_instruction->base)) {
22522252 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(expr));
22532253 return gen_overflow_op(g, expr_type, AddSubMulSub, zero, expr);
22542254 } else if (expr_type->data.integral.is_signed) {
......@@ -2317,7 +2317,7 @@ static LLVMValueRef ir_render_decl_var(CodeGen *g, IrExecutable *executable,
23172317 var->align_bytes, 0, 0);
23182318 gen_assign_raw(g, var->value_ref, var_ptr_type, ir_llvm_value(g, init_value));
23192319 } else {
2320 bool want_safe = ir_want_debug_safety(g, &decl_var_instruction->base);
2320 bool want_safe = ir_want_runtime_safety(g, &decl_var_instruction->base);
23212321 if (want_safe) {
23222322 TypeTableEntry *usize = g->builtin_types.entry_usize;
23232323 uint64_t size_bytes = LLVMStoreSizeOfType(g->target_data_ref, var->value->type->type_ref);
......@@ -2409,7 +2409,7 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, IrExecutable *executable, IrI
24092409 if (!type_has_bits(array_type))
24102410 return nullptr;
24112411
2412 bool safety_check_on = ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on;
2412 bool safety_check_on = ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on;
24132413
24142414 if (array_type->id == TypeTableEntryIdArray) {
24152415 if (safety_check_on) {
......@@ -2593,7 +2593,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
25932593 return bitcasted_union_field_ptr;
25942594 }
25952595
2596 if (ir_want_debug_safety(g, &instruction->base)) {
2596 if (ir_want_runtime_safety(g, &instruction->base)) {
25972597 LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, "");
25982598 LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, "");
25992599
......@@ -2606,7 +2606,7 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, IrExecutable *executab
26062606 LLVMBuildCondBr(g->builder, ok_val, ok_block, bad_block);
26072607
26082608 LLVMPositionBuilderAtEnd(g->builder, bad_block);
2609 gen_debug_safety_crash(g, PanicMsgIdBadUnionField);
2609 gen_safety_crash(g, PanicMsgIdBadUnionField);
26102610
26112611 LLVMPositionBuilderAtEnd(g->builder, ok_block);
26122612 }
......@@ -2776,14 +2776,14 @@ static LLVMValueRef ir_render_unwrap_maybe(CodeGen *g, IrExecutable *executable,
27762776 TypeTableEntry *child_type = maybe_type->data.maybe.child_type;
27772777 LLVMValueRef maybe_ptr = ir_llvm_value(g, instruction->value);
27782778 LLVMValueRef maybe_handle = get_handle_value(g, maybe_ptr, maybe_type, ptr_type);
2779 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on) {
2779 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on) {
27802780 LLVMValueRef non_null_bit = gen_non_null_bit(g, maybe_type, maybe_handle);
27812781 LLVMBasicBlockRef ok_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeOk");
27822782 LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "UnwrapMaybeFail");
27832783 LLVMBuildCondBr(g->builder, non_null_bit, ok_block, fail_block);
27842784
27852785 LLVMPositionBuilderAtEnd(g->builder, fail_block);
2786 gen_debug_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
2786 gen_safety_crash(g, PanicMsgIdUnwrapMaybeFail);
27872787
27882788 LLVMPositionBuilderAtEnd(g->builder, ok_block);
27892789 }
......@@ -2913,7 +2913,7 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, IrExecutable *executable, IrI
29132913 }
29142914
29152915 LLVMValueRef err_val = ir_llvm_value(g, instruction->value);
2916 if (ir_want_debug_safety(g, &instruction->base)) {
2916 if (ir_want_runtime_safety(g, &instruction->base)) {
29172917 LLVMValueRef zero = LLVMConstNull(LLVMTypeOf(err_val));
29182918 LLVMValueRef end_val = LLVMConstInt(LLVMTypeOf(err_val), g->error_decls.length, false);
29192919 add_bounds_check(g, err_val, LLVMIntNE, zero, LLVMIntULT, end_val);
......@@ -2935,7 +2935,7 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, IrExecutable *executable
29352935
29362936 TypeTableEntry *tag_int_type = enum_type->data.enumeration.tag_int_type;
29372937 LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target);
2938 if (ir_want_debug_safety(g, &instruction->base)) {
2938 if (ir_want_runtime_safety(g, &instruction->base)) {
29392939 size_t field_count = enum_type->data.enumeration.src_field_count;
29402940
29412941 // if the field_count can't fit in the bits of the enum_type, then it can't possibly
......@@ -2988,8 +2988,8 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
29882988 LLVMValueRef target_val = ir_llvm_value(g, instruction->target);
29892989 assert(target_val);
29902990
2991 bool want_debug_safety = ir_want_debug_safety(g, &instruction->base);
2992 if (!want_debug_safety) {
2991 bool want_runtime_safety = ir_want_runtime_safety(g, &instruction->base);
2992 if (!want_runtime_safety) {
29932993 return target_val;
29942994 }
29952995
......@@ -3038,7 +3038,7 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I
30383038 LLVMBuildCondBr(g->builder, ok_bit, ok_block, fail_block);
30393039
30403040 LLVMPositionBuilderAtEnd(g->builder, fail_block);
3041 gen_debug_safety_crash(g, PanicMsgIdIncorrectAlignment);
3041 gen_safety_crash(g, PanicMsgIdIncorrectAlignment);
30423042
30433043 LLVMPositionBuilderAtEnd(g->builder, ok_block);
30443044
......@@ -3176,7 +3176,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
31763176
31773177 LLVMValueRef tmp_struct_ptr = instruction->tmp_ptr;
31783178
3179 bool want_debug_safety = instruction->safety_check_on && ir_want_debug_safety(g, &instruction->base);
3179 bool want_runtime_safety = instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base);
31803180
31813181 if (array_type->id == TypeTableEntryIdArray) {
31823182 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
......@@ -3187,7 +3187,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
31873187 end_val = LLVMConstInt(g->builtin_types.entry_usize->type_ref, array_type->data.array.len, false);
31883188 }
31893189
3190 if (want_debug_safety) {
3190 if (want_runtime_safety) {
31913191 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
31923192 if (instruction->end) {
31933193 LLVMValueRef array_end = LLVMConstInt(g->builtin_types.entry_usize->type_ref,
......@@ -3198,7 +3198,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
31983198 if (!type_has_bits(array_type)) {
31993199 LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, slice_len_index, "");
32003200
3201 // TODO if debug safety is on, store 0xaaaaaaa in ptr field
3201 // TODO if runtime safety is on, store 0xaaaaaaa in ptr field
32023202 LLVMValueRef len_value = LLVMBuildNSWSub(g->builder, end_val, start_val, "");
32033203 gen_store_untyped(g, len_value, len_field_ptr, 0, false);
32043204 return tmp_struct_ptr;
......@@ -3222,7 +3222,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
32223222 LLVMValueRef start_val = ir_llvm_value(g, instruction->start);
32233223 LLVMValueRef end_val = ir_llvm_value(g, instruction->end);
32243224
3225 if (want_debug_safety) {
3225 if (want_runtime_safety) {
32263226 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
32273227 }
32283228
......@@ -3246,7 +3246,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
32463246 assert(len_index != SIZE_MAX);
32473247
32483248 LLVMValueRef prev_end = nullptr;
3249 if (!instruction->end || want_debug_safety) {
3249 if (!instruction->end || want_runtime_safety) {
32503250 LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, "");
32513251 prev_end = gen_load_untyped(g, src_len_ptr, 0, false, "");
32523252 }
......@@ -3259,7 +3259,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, IrExecutable *executable, IrInst
32593259 end_val = prev_end;
32603260 }
32613261
3262 if (want_debug_safety) {
3262 if (want_runtime_safety) {
32633263 assert(prev_end);
32643264 add_bounds_check(g, start_val, LLVMIntEQ, nullptr, LLVMIntULE, end_val);
32653265 if (instruction->end) {
......@@ -3432,7 +3432,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
34323432 LLVMValueRef err_union_ptr = ir_llvm_value(g, instruction->value);
34333433 LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type);
34343434
3435 if (ir_want_debug_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {
3435 if (ir_want_runtime_safety(g, &instruction->base) && instruction->safety_check_on && g->error_decls.length > 1) {
34363436 LLVMValueRef err_val;
34373437 if (type_has_bits(child_type)) {
34383438 LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, "");
......@@ -3447,7 +3447,7 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, IrExecutable *execu
34473447 LLVMBuildCondBr(g->builder, cond_val, ok_block, err_block);
34483448
34493449 LLVMPositionBuilderAtEnd(g->builder, err_block);
3450 gen_debug_safety_crash_for_err(g, err_val);
3450 gen_safety_crash_for_err(g, err_val);
34513451
34523452 LLVMPositionBuilderAtEnd(g->builder, ok_block);
34533453 }
......@@ -3660,7 +3660,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
36603660 case IrInstructionIdPtrTypeChild:
36613661 case IrInstructionIdFieldPtr:
36623662 case IrInstructionIdSetCold:
3663 case IrInstructionIdSetDebugSafety:
3663 case IrInstructionIdSetRuntimeSafety:
36643664 case IrInstructionIdSetFloatMode:
36653665 case IrInstructionIdArrayType:
36663666 case IrInstructionIdSliceType:
......@@ -5238,7 +5238,7 @@ static void define_builtin_fns(CodeGen *g) {
52385238 create_builtin_fn(g, BuiltinFnIdCompileLog, "compileLog", SIZE_MAX);
52395239 create_builtin_fn(g, BuiltinFnIdIntType, "IntType", 2); // TODO rename to Int
52405240 create_builtin_fn(g, BuiltinFnIdSetCold, "setCold", 1);
5241 create_builtin_fn(g, BuiltinFnIdSetDebugSafety, "setDebugSafety", 2);
5241 create_builtin_fn(g, BuiltinFnIdSetRuntimeSafety, "setRuntimeSafety", 1);
52425242 create_builtin_fn(g, BuiltinFnIdSetFloatMode, "setFloatMode", 2);
52435243 create_builtin_fn(g, BuiltinFnIdPanic, "panic", 1);
52445244 create_builtin_fn(g, BuiltinFnIdPtrCast, "ptrCast", 2);
src/ir.cpp+46-65
......@@ -276,8 +276,8 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionSetCold *) {
276276 return IrInstructionIdSetCold;
277277}
278278
279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetDebugSafety *) {
280 return IrInstructionIdSetDebugSafety;
279static constexpr IrInstructionId ir_instruction_id(IrInstructionSetRuntimeSafety *) {
280 return IrInstructionIdSetRuntimeSafety;
281281}
282282
283283static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFloatMode *) {
......@@ -1275,15 +1275,13 @@ static IrInstruction *ir_build_set_cold(IrBuilder *irb, Scope *scope, AstNode *s
12751275 return &instruction->base;
12761276}
12771277
1278static IrInstruction *ir_build_set_debug_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
1279 IrInstruction *scope_value, IrInstruction *debug_safety_on)
1278static IrInstruction *ir_build_set_runtime_safety(IrBuilder *irb, Scope *scope, AstNode *source_node,
1279 IrInstruction *safety_on)
12801280{
1281 IrInstructionSetDebugSafety *instruction = ir_build_instruction<IrInstructionSetDebugSafety>(irb, scope, source_node);
1282 instruction->scope_value = scope_value;
1283 instruction->debug_safety_on = debug_safety_on;
1281 IrInstructionSetRuntimeSafety *instruction = ir_build_instruction<IrInstructionSetRuntimeSafety>(irb, scope, source_node);
1282 instruction->safety_on = safety_on;
12841283
1285 ir_ref_instruction(scope_value, irb->current_basic_block);
1286 ir_ref_instruction(debug_safety_on, irb->current_basic_block);
1284 ir_ref_instruction(safety_on, irb->current_basic_block);
12871285
12881286 return &instruction->base;
12891287}
......@@ -3087,19 +3085,14 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo
30873085
30883086 return ir_build_set_cold(irb, scope, node, arg0_value);
30893087 }
3090 case BuiltinFnIdSetDebugSafety:
3088 case BuiltinFnIdSetRuntimeSafety:
30913089 {
30923090 AstNode *arg0_node = node->data.fn_call_expr.params.at(0);
30933091 IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope);
30943092 if (arg0_value == irb->codegen->invalid_instruction)
30953093 return arg0_value;
30963094
3097 AstNode *arg1_node = node->data.fn_call_expr.params.at(1);
3098 IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope);
3099 if (arg1_value == irb->codegen->invalid_instruction)
3100 return arg1_value;
3101
3102 return ir_build_set_debug_safety(irb, scope, node, arg0_value, arg1_value);
3095 return ir_build_set_runtime_safety(irb, scope, node, arg0_value);
31033096 }
31043097 case BuiltinFnIdSetFloatMode:
31053098 {
......@@ -11607,72 +11600,60 @@ static TypeTableEntry *ir_analyze_instruction_set_cold(IrAnalyze *ira, IrInstruc
1160711600 ir_build_const_from(ira, &instruction->base);
1160811601 return ira->codegen->builtin_types.entry_void;
1160911602}
11610static TypeTableEntry *ir_analyze_instruction_set_debug_safety(IrAnalyze *ira,
11611 IrInstructionSetDebugSafety *set_debug_safety_instruction)
11603static TypeTableEntry *ir_analyze_instruction_set_runtime_safety(IrAnalyze *ira,
11604 IrInstructionSetRuntimeSafety *set_runtime_safety_instruction)
1161211605{
11613 IrInstruction *target_instruction = set_debug_safety_instruction->scope_value->other;
11614 TypeTableEntry *target_type = target_instruction->value.type;
11615 if (type_is_invalid(target_type))
11616 return ira->codegen->builtin_types.entry_invalid;
11617 ConstExprValue *target_val = ir_resolve_const(ira, target_instruction, UndefBad);
11618 if (!target_val)
11619 return ira->codegen->builtin_types.entry_invalid;
11620
1162111606 if (ira->new_irb.exec->is_inline) {
11622 // ignore setDebugSafety when running functions at compile time
11623 ir_build_const_from(ira, &set_debug_safety_instruction->base);
11607 // ignore setRuntimeSafety when running functions at compile time
11608 ir_build_const_from(ira, &set_runtime_safety_instruction->base);
1162411609 return ira->codegen->builtin_types.entry_void;
1162511610 }
1162611611
1162711612 bool *safety_off_ptr;
1162811613 AstNode **safety_set_node_ptr;
11629 if (target_type->id == TypeTableEntryIdBlock) {
11630 ScopeBlock *block_scope = (ScopeBlock *)target_val->data.x_block;
11631 safety_off_ptr = &block_scope->safety_off;
11632 safety_set_node_ptr = &block_scope->safety_set_node;
11633 } else if (target_type->id == TypeTableEntryIdFn) {
11634 FnTableEntry *target_fn = target_val->data.x_fn.fn_entry;
11635 assert(target_fn->def_scope);
11636 safety_off_ptr = &target_fn->def_scope->safety_off;
11637 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
11638 } else if (target_type->id == TypeTableEntryIdMetaType) {
11639 ScopeDecls *decls_scope;
11640 TypeTableEntry *type_arg = target_val->data.x_type;
11641 if (type_arg->id == TypeTableEntryIdStruct) {
11642 decls_scope = type_arg->data.structure.decls_scope;
11643 } else if (type_arg->id == TypeTableEntryIdEnum) {
11644 decls_scope = type_arg->data.enumeration.decls_scope;
11645 } else if (type_arg->id == TypeTableEntryIdUnion) {
11646 decls_scope = type_arg->data.unionation.decls_scope;
11614
11615 Scope *scope = set_runtime_safety_instruction->base.scope;
11616 while (scope != nullptr) {
11617 if (scope->id == ScopeIdBlock) {
11618 ScopeBlock *block_scope = (ScopeBlock *)scope;
11619 safety_off_ptr = &block_scope->safety_off;
11620 safety_set_node_ptr = &block_scope->safety_set_node;
11621 break;
11622 } else if (scope->id == ScopeIdFnDef) {
11623 ScopeFnDef *def_scope = (ScopeFnDef *)scope;
11624 FnTableEntry *target_fn = def_scope->fn_entry;
11625 assert(target_fn->def_scope != nullptr);
11626 safety_off_ptr = &target_fn->def_scope->safety_off;
11627 safety_set_node_ptr = &target_fn->def_scope->safety_set_node;
11628 break;
11629 } else if (scope->id == ScopeIdDecls) {
11630 ScopeDecls *decls_scope = (ScopeDecls *)scope;
11631 safety_off_ptr = &decls_scope->safety_off;
11632 safety_set_node_ptr = &decls_scope->safety_set_node;
11633 break;
1164711634 } else {
11648 ir_add_error_node(ira, target_instruction->source_node,
11649 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&type_arg->name)));
11650 return ira->codegen->builtin_types.entry_invalid;
11635 scope = scope->parent;
11636 continue;
1165111637 }
11652 safety_off_ptr = &decls_scope->safety_off;
11653 safety_set_node_ptr = &decls_scope->safety_set_node;
11654 } else {
11655 ir_add_error_node(ira, target_instruction->source_node,
11656 buf_sprintf("expected scope reference, found type '%s'", buf_ptr(&target_type->name)));
11657 return ira->codegen->builtin_types.entry_invalid;
1165811638 }
11639 assert(scope != nullptr);
1165911640
11660 IrInstruction *debug_safety_on_value = set_debug_safety_instruction->debug_safety_on->other;
11661 bool want_debug_safety;
11662 if (!ir_resolve_bool(ira, debug_safety_on_value, &want_debug_safety))
11641 IrInstruction *safety_on_value = set_runtime_safety_instruction->safety_on->other;
11642 bool want_runtime_safety;
11643 if (!ir_resolve_bool(ira, safety_on_value, &want_runtime_safety))
1166311644 return ira->codegen->builtin_types.entry_invalid;
1166411645
11665 AstNode *source_node = set_debug_safety_instruction->base.source_node;
11646 AstNode *source_node = set_runtime_safety_instruction->base.source_node;
1166611647 if (*safety_set_node_ptr) {
1166711648 ErrorMsg *msg = ir_add_error_node(ira, source_node,
11668 buf_sprintf("debug safety set twice for same scope"));
11649 buf_sprintf("runtime safety set twice for same scope"));
1166911650 add_error_note(ira->codegen, msg, *safety_set_node_ptr, buf_sprintf("first set here"));
1167011651 return ira->codegen->builtin_types.entry_invalid;
1167111652 }
1167211653 *safety_set_node_ptr = source_node;
11673 *safety_off_ptr = !want_debug_safety;
11654 *safety_off_ptr = !want_runtime_safety;
1167411655
11675 ir_build_const_from(ira, &set_debug_safety_instruction->base);
11656 ir_build_const_from(ira, &set_runtime_safety_instruction->base);
1167611657 return ira->codegen->builtin_types.entry_void;
1167711658}
1167811659
......@@ -15293,8 +15274,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1529315274 return ir_analyze_instruction_ptr_type_child(ira, (IrInstructionPtrTypeChild *)instruction);
1529415275 case IrInstructionIdSetCold:
1529515276 return ir_analyze_instruction_set_cold(ira, (IrInstructionSetCold *)instruction);
15296 case IrInstructionIdSetDebugSafety:
15297 return ir_analyze_instruction_set_debug_safety(ira, (IrInstructionSetDebugSafety *)instruction);
15277 case IrInstructionIdSetRuntimeSafety:
15278 return ir_analyze_instruction_set_runtime_safety(ira, (IrInstructionSetRuntimeSafety *)instruction);
1529815279 case IrInstructionIdSetFloatMode:
1529915280 return ir_analyze_instruction_set_float_mode(ira, (IrInstructionSetFloatMode *)instruction);
1530015281 case IrInstructionIdSliceType:
......@@ -15530,7 +15511,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1553015511 case IrInstructionIdReturn:
1553115512 case IrInstructionIdUnreachable:
1553215513 case IrInstructionIdSetCold:
15533 case IrInstructionIdSetDebugSafety:
15514 case IrInstructionIdSetRuntimeSafety:
1553415515 case IrInstructionIdSetFloatMode:
1553515516 case IrInstructionIdImport:
1553615517 case IrInstructionIdCompileErr:
src/ir_print.cpp+5-7
......@@ -374,11 +374,9 @@ static void ir_print_set_cold(IrPrint *irp, IrInstructionSetCold *instruction) {
374374 fprintf(irp->f, ")");
375375}
376376
377static void ir_print_set_debug_safety(IrPrint *irp, IrInstructionSetDebugSafety *instruction) {
378 fprintf(irp->f, "@setDebugSafety(");
379 ir_print_other_instruction(irp, instruction->scope_value);
380 fprintf(irp->f, ", ");
381 ir_print_other_instruction(irp, instruction->debug_safety_on);
377static void ir_print_set_runtime_safety(IrPrint *irp, IrInstructionSetRuntimeSafety *instruction) {
378 fprintf(irp->f, "@setRuntimeSafety(");
379 ir_print_other_instruction(irp, instruction->safety_on);
382380 fprintf(irp->f, ")");
383381}
384382
......@@ -1090,8 +1088,8 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
10901088 case IrInstructionIdSetCold:
10911089 ir_print_set_cold(irp, (IrInstructionSetCold *)instruction);
10921090 break;
1093 case IrInstructionIdSetDebugSafety:
1094 ir_print_set_debug_safety(irp, (IrInstructionSetDebugSafety *)instruction);
1091 case IrInstructionIdSetRuntimeSafety:
1092 ir_print_set_runtime_safety(irp, (IrInstructionSetRuntimeSafety *)instruction);
10951093 break;
10961094 case IrInstructionIdSetFloatMode:
10971095 ir_print_set_float_mode(irp, (IrInstructionSetFloatMode *)instruction);
std/math/index.zig+6-6
......@@ -331,7 +331,7 @@ pub fn absInt(x: var) -> %@typeOf(x) {
331331 if (x == @minValue(@typeOf(x)))
332332 return error.Overflow;
333333 {
334 @setDebugSafety(this, false);
334 @setRuntimeSafety(false);
335335 return if (x < 0) -x else x;
336336 }
337337}
......@@ -350,7 +350,7 @@ pub const absFloat = @import("fabs.zig").fabs;
350350error DivisionByZero;
351351error Overflow;
352352pub fn divTrunc(comptime T: type, numerator: T, denominator: T) -> %T {
353 @setDebugSafety(this, false);
353 @setRuntimeSafety(false);
354354 if (denominator == 0)
355355 return error.DivisionByZero;
356356 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
......@@ -375,7 +375,7 @@ fn testDivTrunc() {
375375error DivisionByZero;
376376error Overflow;
377377pub fn divFloor(comptime T: type, numerator: T, denominator: T) -> %T {
378 @setDebugSafety(this, false);
378 @setRuntimeSafety(false);
379379 if (denominator == 0)
380380 return error.DivisionByZero;
381381 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
......@@ -401,7 +401,7 @@ error DivisionByZero;
401401error Overflow;
402402error UnexpectedRemainder;
403403pub fn divExact(comptime T: type, numerator: T, denominator: T) -> %T {
404 @setDebugSafety(this, false);
404 @setRuntimeSafety(false);
405405 if (denominator == 0)
406406 return error.DivisionByZero;
407407 if (@typeId(T) == builtin.TypeId.Int and T.is_signed and numerator == @minValue(T) and denominator == -1)
......@@ -431,7 +431,7 @@ fn testDivExact() {
431431error DivisionByZero;
432432error NegativeDenominator;
433433pub fn mod(comptime T: type, numerator: T, denominator: T) -> %T {
434 @setDebugSafety(this, false);
434 @setRuntimeSafety(false);
435435 if (denominator == 0)
436436 return error.DivisionByZero;
437437 if (denominator < 0)
......@@ -458,7 +458,7 @@ fn testMod() {
458458error DivisionByZero;
459459error NegativeDenominator;
460460pub fn rem(comptime T: type, numerator: T, denominator: T) -> %T {
461 @setDebugSafety(this, false);
461 @setRuntimeSafety(false);
462462 if (denominator == 0)
463463 return error.DivisionByZero;
464464 if (denominator < 0)
std/mem.zig+2-2
......@@ -156,9 +156,9 @@ pub const FixedBufferAllocator = struct {
156156/// dest.len must be >= source.len.
157157pub fn copy(comptime T: type, dest: []T, source: []const T) {
158158 // TODO instead of manually doing this check for the whole array
159 // and turning off debug safety, the compiler should detect loops like
159 // and turning off runtime safety, the compiler should detect loops like
160160 // this and automatically omit safety checks for loops
161 @setDebugSafety(this, false);
161 @setRuntimeSafety(false);
162162 assert(dest.len >= source.len);
163163 for (source) |s, i| dest[i] = s;
164164}
std/special/builtin.zig+4-4
......@@ -3,7 +3,7 @@
33
44const builtin = @import("builtin");
55
6// Avoid dragging in the debug safety mechanisms into this .o file,
6// Avoid dragging in the runtime safety mechanisms into this .o file,
77// unless we're trying to test this file.
88pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noreturn {
99 if (builtin.is_test) {
......@@ -18,7 +18,7 @@ pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noret
1818// The semantics of memset is dictated by the corresponding
1919// LLVM intrinsics, not by the libc API.
2020export fn memset(dest: ?&u8, c: u8, n: usize) {
21 @setDebugSafety(this, false);
21 @setRuntimeSafety(false);
2222
2323 var index: usize = 0;
2424 while (index != n) : (index += 1)
......@@ -29,7 +29,7 @@ export fn memset(dest: ?&u8, c: u8, n: usize) {
2929// The semantics of memcpy is dictated by the corresponding
3030// LLVM intrinsics, not by the libc API.
3131export fn memcpy(noalias dest: ?&u8, noalias src: ?&const u8, n: usize) {
32 @setDebugSafety(this, false);
32 @setRuntimeSafety(false);
3333
3434 var index: usize = 0;
3535 while (index != n) : (index += 1)
......@@ -58,7 +58,7 @@ export fn floor(x: f64) -> f64 { return math.floor(x); }
5858export fn ceil(x: f64) -> f64 { return math.ceil(x); }
5959
6060fn generic_fmod(comptime T: type, x: T, y: T) -> T {
61 @setDebugSafety(this, false);
61 @setRuntimeSafety(false);
6262
6363 const uint = @IntType(false, T.bit_count);
6464 const log2uint = math.Log2Int(uint);
std/special/compiler_rt/aulldiv.zig+1-1
......@@ -1,5 +1,5 @@
11pub nakedcc fn _aulldiv() {
2 @setDebugSafety(this, false);
2 @setRuntimeSafety(false);
33 asm volatile (
44 \\.intel_syntax noprefix
55 \\
std/special/compiler_rt/aullrem.zig+1-1
......@@ -1,5 +1,5 @@
11pub nakedcc fn _aullrem() {
2 @setDebugSafety(this, false);
2 @setRuntimeSafety(false);
33 asm volatile (
44 \\.intel_syntax noprefix
55 \\
std/special/compiler_rt/comparetf2.zig+3-3
......@@ -22,7 +22,7 @@ const builtin = @import("builtin");
2222const is_test = builtin.is_test;
2323
2424pub extern fn __letf2(a: f128, b: f128) -> c_int {
25 @setDebugSafety(this, is_test);
25 @setRuntimeSafety(is_test);
2626
2727 const aInt = @bitCast(rep_t, a);
2828 const bInt = @bitCast(rep_t, b);
......@@ -67,7 +67,7 @@ const GE_GREATER = c_int(1);
6767const GE_UNORDERED = c_int(-1); // Note: different from LE_UNORDERED
6868
6969pub extern fn __getf2(a: f128, b: f128) -> c_int {
70 @setDebugSafety(this, is_test);
70 @setRuntimeSafety(is_test);
7171
7272 const aInt = @bitCast(srep_t, a);
7373 const bInt = @bitCast(srep_t, b);
......@@ -94,7 +94,7 @@ pub extern fn __getf2(a: f128, b: f128) -> c_int {
9494}
9595
9696pub extern fn __unordtf2(a: f128, b: f128) -> c_int {
97 @setDebugSafety(this, is_test);
97 @setRuntimeSafety(is_test);
9898
9999 const aAbs = @bitCast(rep_t, a) & absMask;
100100 const bAbs = @bitCast(rep_t, b) & absMask;
std/special/compiler_rt/fixuint.zig+3-3
......@@ -2,7 +2,7 @@ const is_test = @import("builtin").is_test;
22const Log2Int = @import("../../math/index.zig").Log2Int;
33
44pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuint_t {
5 @setDebugSafety(this, is_test);
5 @setRuntimeSafety(is_test);
66
77 const rep_t = switch (fp_t) {
88 f32 => u32,
......@@ -48,12 +48,12 @@ pub fn fixuint(comptime fp_t: type, comptime fixuint_t: type, a: fp_t) -> fixuin
4848 if (exponent < significandBits) {
4949 // TODO this is a workaround for the mysterious "integer cast truncated bits"
5050 // happening on the next line
51 @setDebugSafety(this, false);
51 @setRuntimeSafety(false);
5252 return fixuint_t(significand >> Log2Int(rep_t)(significandBits - exponent));
5353 } else {
5454 // TODO this is a workaround for the mysterious "integer cast truncated bits"
5555 // happening on the next line
56 @setDebugSafety(this, false);
56 @setRuntimeSafety(false);
5757 return fixuint_t(significand) << Log2Int(fixuint_t)(exponent - significandBits);
5858 }
5959}
std/special/compiler_rt/fixunsdfdi.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunsdfdi(a: f64) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f64, u64, a);
77}
88
std/special/compiler_rt/fixunsdfsi.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunsdfsi(a: f64) -> u32 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f64, u32, a);
77}
88
std/special/compiler_rt/fixunsdfti.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunsdfti(a: f64) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f64, u128, a);
77}
88
std/special/compiler_rt/fixunssfdi.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunssfdi(a: f32) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f32, u64, a);
77}
88
std/special/compiler_rt/fixunssfsi.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunssfsi(a: f32) -> u32 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f32, u32, a);
77}
88
std/special/compiler_rt/fixunssfti.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunssfti(a: f32) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f32, u128, a);
77}
88
std/special/compiler_rt/fixunstfdi.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunstfdi(a: f128) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f128, u64, a);
77}
88
std/special/compiler_rt/fixunstfsi.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunstfsi(a: f128) -> u32 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f128, u32, a);
77}
88
std/special/compiler_rt/fixunstfti.zig+1-1
......@@ -2,7 +2,7 @@ const fixuint = @import("fixuint.zig").fixuint;
22const builtin = @import("builtin");
33
44pub extern fn __fixunstfti(a: f128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return fixuint(f128, u128, a);
77}
88
std/special/compiler_rt/index.zig+11-11
......@@ -72,7 +72,7 @@ const assert = @import("../../index.zig").debug.assert;
7272
7373const __udivmoddi4 = @import("udivmoddi4.zig").__udivmoddi4;
7474
75// Avoid dragging in the debug safety mechanisms into this .o file,
75// Avoid dragging in the runtime safety mechanisms into this .o file,
7676// unless we're trying to test this file.
7777pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noreturn {
7878 @setCold(true);
......@@ -84,12 +84,12 @@ pub fn panic(msg: []const u8, error_return_trace: ?&builtin.StackTrace) -> noret
8484}
8585
8686extern fn __udivdi3(a: u64, b: u64) -> u64 {
87 @setDebugSafety(this, is_test);
87 @setRuntimeSafety(is_test);
8888 return __udivmoddi4(a, b, null);
8989}
9090
9191extern fn __umoddi3(a: u64, b: u64) -> u64 {
92 @setDebugSafety(this, is_test);
92 @setRuntimeSafety(is_test);
9393
9494 var r: u64 = undefined;
9595 _ = __udivmoddi4(a, b, &r);
......@@ -101,7 +101,7 @@ const AeabiUlDivModResult = extern struct {
101101 rem: u64,
102102};
103103extern fn __aeabi_uldivmod(numerator: u64, denominator: u64) -> AeabiUlDivModResult {
104 @setDebugSafety(this, is_test);
104 @setRuntimeSafety(is_test);
105105 var result: AeabiUlDivModResult = undefined;
106106 result.quot = __udivmoddi4(numerator, denominator, &result.rem);
107107 return result;
......@@ -133,7 +133,7 @@ fn isArmArch() -> bool {
133133}
134134
135135nakedcc fn __aeabi_uidivmod() {
136 @setDebugSafety(this, false);
136 @setRuntimeSafety(false);
137137 asm volatile (
138138 \\ push { lr }
139139 \\ sub sp, sp, #4
......@@ -150,7 +150,7 @@ nakedcc fn __aeabi_uidivmod() {
150150// This routine is windows specific
151151// http://msdn.microsoft.com/en-us/library/ms648426.aspx
152152nakedcc fn _chkstk() align(4) {
153 @setDebugSafety(this, false);
153 @setRuntimeSafety(false);
154154
155155 asm volatile (
156156 \\ push %%ecx
......@@ -174,7 +174,7 @@ nakedcc fn _chkstk() align(4) {
174174}
175175
176176nakedcc fn __chkstk() align(4) {
177 @setDebugSafety(this, false);
177 @setRuntimeSafety(false);
178178
179179 asm volatile (
180180 \\ push %%rcx
......@@ -201,7 +201,7 @@ nakedcc fn __chkstk() align(4) {
201201// This routine is windows specific
202202// http://msdn.microsoft.com/en-us/library/ms648426.aspx
203203nakedcc fn __chkstk_ms() align(4) {
204 @setDebugSafety(this, false);
204 @setRuntimeSafety(false);
205205
206206 asm volatile (
207207 \\ push %%ecx
......@@ -225,7 +225,7 @@ nakedcc fn __chkstk_ms() align(4) {
225225}
226226
227227nakedcc fn ___chkstk_ms() align(4) {
228 @setDebugSafety(this, false);
228 @setRuntimeSafety(false);
229229
230230 asm volatile (
231231 \\ push %%rcx
......@@ -249,7 +249,7 @@ nakedcc fn ___chkstk_ms() align(4) {
249249}
250250
251251extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
252 @setDebugSafety(this, is_test);
252 @setRuntimeSafety(is_test);
253253
254254 const d = __udivsi3(a, b);
255255 *rem = u32(i32(a) -% (i32(d) * i32(b)));
......@@ -258,7 +258,7 @@ extern fn __udivmodsi4(a: u32, b: u32, rem: &u32) -> u32 {
258258
259259
260260extern fn __udivsi3(n: u32, d: u32) -> u32 {
261 @setDebugSafety(this, is_test);
261 @setRuntimeSafety(is_test);
262262
263263 const n_uword_bits: c_uint = u32.bit_count;
264264 // special cases
std/special/compiler_rt/udivmod.zig+1-1
......@@ -5,7 +5,7 @@ const low = switch (builtin.endian) { builtin.Endian.Big => 1, builtin.Endian.Li
55const high = 1 - low;
66
77pub fn udivmod(comptime DoubleInt: type, a: DoubleInt, b: DoubleInt, maybe_rem: ?&DoubleInt) -> DoubleInt {
8 @setDebugSafety(this, is_test);
8 @setRuntimeSafety(is_test);
99
1010 const SingleInt = @IntType(false, @divExact(DoubleInt.bit_count, 2));
1111 const SignedDoubleInt = @IntType(true, DoubleInt.bit_count);
std/special/compiler_rt/udivmoddi4.zig+1-1
......@@ -2,7 +2,7 @@ const udivmod = @import("udivmod.zig").udivmod;
22const builtin = @import("builtin");
33
44pub extern fn __udivmoddi4(a: u64, b: u64, maybe_rem: ?&u64) -> u64 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return udivmod(u64, a, b, maybe_rem);
77}
88
std/special/compiler_rt/udivmodti4.zig+1-1
......@@ -2,7 +2,7 @@ const udivmod = @import("udivmod.zig").udivmod;
22const builtin = @import("builtin");
33
44pub extern fn __udivmodti4(a: u128, b: u128, maybe_rem: ?&u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return udivmod(u128, a, b, maybe_rem);
77}
88
std/special/compiler_rt/udivti3.zig+1-1
......@@ -2,6 +2,6 @@ const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const builtin = @import("builtin");
33
44pub extern fn __udivti3(a: u128, b: u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 return __udivmodti4(a, b, null);
77}
std/special/compiler_rt/umodti3.zig+1-1
......@@ -2,7 +2,7 @@ const __udivmodti4 = @import("udivmodti4.zig").__udivmodti4;
22const builtin = @import("builtin");
33
44pub extern fn __umodti3(a: u128, b: u128) -> u128 {
5 @setDebugSafety(this, builtin.is_test);
5 @setRuntimeSafety(builtin.is_test);
66 var r: u128 = undefined;
77 _ = __udivmodti4(a, b, &r);
88 return r;
test/cases/eval.zig+4-4
......@@ -223,13 +223,13 @@ test "comptime iterate over fn ptr list" {
223223 assert(performFn('w', 99) == 99);
224224}
225225
226test "eval @setDebugSafety at compile-time" {
227 const result = comptime fnWithSetDebugSafety();
226test "eval @setRuntimeSafety at compile-time" {
227 const result = comptime fnWithSetRuntimeSafety();
228228 assert(result == 1234);
229229}
230230
231fn fnWithSetDebugSafety() -> i32{
232 @setDebugSafety(this, true);
231fn fnWithSetRuntimeSafety() -> i32{
232 @setRuntimeSafety(true);
233233 return 1234;
234234}
235235
test/cases/slice.zig+1-1
......@@ -17,7 +17,7 @@ test "slice child property" {
1717 assert(@typeOf(slice).Child == i32);
1818}
1919
20test "debug safety lets us slice from len..len" {
20test "runtime safety lets us slice from len..len" {
2121 var an_array = []u8{1, 2, 3};
2222 assert(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
2323}
test/compile_errors.zig+4-4
......@@ -1867,13 +1867,13 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
18671867 ,
18681868 ".tmp_source.zig:3:20: error: cast from 'u16' to 'u8' truncates bits");
18691869
1870 cases.add("@setDebugSafety twice for same scope",
1870 cases.add("@setRuntimeSafety twice for same scope",
18711871 \\export fn foo() {
1872 \\ @setDebugSafety(this, false);
1873 \\ @setDebugSafety(this, false);
1872 \\ @setRuntimeSafety(false);
1873 \\ @setRuntimeSafety(false);
18741874 \\}
18751875 ,
1876 ".tmp_source.zig:3:5: error: debug safety set twice for same scope",
1876 ".tmp_source.zig:3:5: error: runtime safety set twice for same scope",
18771877 ".tmp_source.zig:2:5: note: first set here");
18781878
18791879 cases.add("@setFloatMode twice for same scope",
test/debug_safety.zig deleted-286
......@@ -1,286 +0,0 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.CompareOutputContext) {
4 cases.addDebugSafety("calling panic",
5 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\pub fn main() -> %void {
9 \\ @panic("oh no");
10 \\}
11 );
12
13 cases.addDebugSafety("out of bounds slice access",
14 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
15 \\ @import("std").os.exit(126);
16 \\}
17 \\pub fn main() -> %void {
18 \\ const a = []i32{1, 2, 3, 4};
19 \\ baz(bar(a));
20 \\}
21 \\fn bar(a: []const i32) -> i32 {
22 \\ return a[4];
23 \\}
24 \\fn baz(a: i32) { }
25 );
26
27 cases.addDebugSafety("integer addition overflow",
28 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
29 \\ @import("std").os.exit(126);
30 \\}
31 \\error Whatever;
32 \\pub fn main() -> %void {
33 \\ const x = add(65530, 10);
34 \\ if (x == 0) return error.Whatever;
35 \\}
36 \\fn add(a: u16, b: u16) -> u16 {
37 \\ return a + b;
38 \\}
39 );
40
41 cases.addDebugSafety("integer subtraction overflow",
42 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
43 \\ @import("std").os.exit(126);
44 \\}
45 \\error Whatever;
46 \\pub fn main() -> %void {
47 \\ const x = sub(10, 20);
48 \\ if (x == 0) return error.Whatever;
49 \\}
50 \\fn sub(a: u16, b: u16) -> u16 {
51 \\ return a - b;
52 \\}
53 );
54
55 cases.addDebugSafety("integer multiplication overflow",
56 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
57 \\ @import("std").os.exit(126);
58 \\}
59 \\error Whatever;
60 \\pub fn main() -> %void {
61 \\ const x = mul(300, 6000);
62 \\ if (x == 0) return error.Whatever;
63 \\}
64 \\fn mul(a: u16, b: u16) -> u16 {
65 \\ return a * b;
66 \\}
67 );
68
69 cases.addDebugSafety("integer negation overflow",
70 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
71 \\ @import("std").os.exit(126);
72 \\}
73 \\error Whatever;
74 \\pub fn main() -> %void {
75 \\ const x = neg(-32768);
76 \\ if (x == 32767) return error.Whatever;
77 \\}
78 \\fn neg(a: i16) -> i16 {
79 \\ return -a;
80 \\}
81 );
82
83 cases.addDebugSafety("signed integer division overflow",
84 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
85 \\ @import("std").os.exit(126);
86 \\}
87 \\error Whatever;
88 \\pub fn main() -> %void {
89 \\ const x = div(-32768, -1);
90 \\ if (x == 32767) return error.Whatever;
91 \\}
92 \\fn div(a: i16, b: i16) -> i16 {
93 \\ return @divTrunc(a, b);
94 \\}
95 );
96
97 cases.addDebugSafety("signed shift left overflow",
98 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
99 \\ @import("std").os.exit(126);
100 \\}
101 \\error Whatever;
102 \\pub fn main() -> %void {
103 \\ const x = shl(-16385, 1);
104 \\ if (x == 0) return error.Whatever;
105 \\}
106 \\fn shl(a: i16, b: u4) -> i16 {
107 \\ return @shlExact(a, b);
108 \\}
109 );
110
111 cases.addDebugSafety("unsigned shift left overflow",
112 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
113 \\ @import("std").os.exit(126);
114 \\}
115 \\error Whatever;
116 \\pub fn main() -> %void {
117 \\ const x = shl(0b0010111111111111, 3);
118 \\ if (x == 0) return error.Whatever;
119 \\}
120 \\fn shl(a: u16, b: u4) -> u16 {
121 \\ return @shlExact(a, b);
122 \\}
123 );
124
125 cases.addDebugSafety("signed shift right overflow",
126 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
127 \\ @import("std").os.exit(126);
128 \\}
129 \\error Whatever;
130 \\pub fn main() -> %void {
131 \\ const x = shr(-16385, 1);
132 \\ if (x == 0) return error.Whatever;
133 \\}
134 \\fn shr(a: i16, b: u4) -> i16 {
135 \\ return @shrExact(a, b);
136 \\}
137 );
138
139 cases.addDebugSafety("unsigned shift right overflow",
140 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
141 \\ @import("std").os.exit(126);
142 \\}
143 \\error Whatever;
144 \\pub fn main() -> %void {
145 \\ const x = shr(0b0010111111111111, 3);
146 \\ if (x == 0) return error.Whatever;
147 \\}
148 \\fn shr(a: u16, b: u4) -> u16 {
149 \\ return @shrExact(a, b);
150 \\}
151 );
152
153 cases.addDebugSafety("integer division by zero",
154 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
155 \\ @import("std").os.exit(126);
156 \\}
157 \\error Whatever;
158 \\pub fn main() -> %void {
159 \\ const x = div0(999, 0);
160 \\}
161 \\fn div0(a: i32, b: i32) -> i32 {
162 \\ return @divTrunc(a, b);
163 \\}
164 );
165
166 cases.addDebugSafety("exact division failure",
167 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
168 \\ @import("std").os.exit(126);
169 \\}
170 \\error Whatever;
171 \\pub fn main() -> %void {
172 \\ const x = divExact(10, 3);
173 \\ if (x == 0) return error.Whatever;
174 \\}
175 \\fn divExact(a: i32, b: i32) -> i32 {
176 \\ return @divExact(a, b);
177 \\}
178 );
179
180 cases.addDebugSafety("cast []u8 to bigger slice of wrong size",
181 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
182 \\ @import("std").os.exit(126);
183 \\}
184 \\error Whatever;
185 \\pub fn main() -> %void {
186 \\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
187 \\ if (x.len == 0) return error.Whatever;
188 \\}
189 \\fn widenSlice(slice: []align(1) const u8) -> []align(1) const i32 {
190 \\ return ([]align(1) const i32)(slice);
191 \\}
192 );
193
194 cases.addDebugSafety("value does not fit in shortening cast",
195 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
196 \\ @import("std").os.exit(126);
197 \\}
198 \\error Whatever;
199 \\pub fn main() -> %void {
200 \\ const x = shorten_cast(200);
201 \\ if (x == 0) return error.Whatever;
202 \\}
203 \\fn shorten_cast(x: i32) -> i8 {
204 \\ return i8(x);
205 \\}
206 );
207
208 cases.addDebugSafety("signed integer not fitting in cast to unsigned integer",
209 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
210 \\ @import("std").os.exit(126);
211 \\}
212 \\error Whatever;
213 \\pub fn main() -> %void {
214 \\ const x = unsigned_cast(-10);
215 \\ if (x == 0) return error.Whatever;
216 \\}
217 \\fn unsigned_cast(x: i32) -> u32 {
218 \\ return u32(x);
219 \\}
220 );
221
222 cases.addDebugSafety("unwrap error",
223 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
224 \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
225 \\ @import("std").os.exit(126); // good
226 \\ }
227 \\ @import("std").os.exit(0); // test failed
228 \\}
229 \\error Whatever;
230 \\pub fn main() -> %void {
231 \\ bar() catch unreachable;
232 \\}
233 \\fn bar() -> %void {
234 \\ return error.Whatever;
235 \\}
236 );
237
238 cases.addDebugSafety("cast integer to error and no code matches",
239 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
240 \\ @import("std").os.exit(126);
241 \\}
242 \\pub fn main() -> %void {
243 \\ _ = bar(9999);
244 \\}
245 \\fn bar(x: u32) -> error {
246 \\ return error(x);
247 \\}
248 );
249
250 cases.addDebugSafety("@alignCast misaligned",
251 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
252 \\ @import("std").os.exit(126);
253 \\}
254 \\error Wrong;
255 \\pub fn main() -> %void {
256 \\ var array align(4) = []u32{0x11111111, 0x11111111};
257 \\ const bytes = ([]u8)(array[0..]);
258 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
259 \\}
260 \\fn foo(bytes: []u8) -> u32 {
261 \\ const slice4 = bytes[1..5];
262 \\ const int_slice = ([]u32)(@alignCast(4, slice4));
263 \\ return int_slice[0];
264 \\}
265 );
266
267 cases.addDebugSafety("bad union field access",
268 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
269 \\ @import("std").os.exit(126);
270 \\}
271 \\
272 \\const Foo = union {
273 \\ float: f32,
274 \\ int: u32,
275 \\};
276 \\
277 \\pub fn main() -> %void {
278 \\ var f = Foo { .int = 42 };
279 \\ bar(&f);
280 \\}
281 \\
282 \\fn bar(f: &Foo) {
283 \\ f.float = 12.34;
284 \\}
285 );
286}
test/runtime_safety.zig created+286
......@@ -0,0 +1,286 @@
1const tests = @import("tests.zig");
2
3pub fn addCases(cases: &tests.CompareOutputContext) {
4 cases.addRuntimeSafety("calling panic",
5 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
6 \\ @import("std").os.exit(126);
7 \\}
8 \\pub fn main() -> %void {
9 \\ @panic("oh no");
10 \\}
11 );
12
13 cases.addRuntimeSafety("out of bounds slice access",
14 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
15 \\ @import("std").os.exit(126);
16 \\}
17 \\pub fn main() -> %void {
18 \\ const a = []i32{1, 2, 3, 4};
19 \\ baz(bar(a));
20 \\}
21 \\fn bar(a: []const i32) -> i32 {
22 \\ return a[4];
23 \\}
24 \\fn baz(a: i32) { }
25 );
26
27 cases.addRuntimeSafety("integer addition overflow",
28 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
29 \\ @import("std").os.exit(126);
30 \\}
31 \\error Whatever;
32 \\pub fn main() -> %void {
33 \\ const x = add(65530, 10);
34 \\ if (x == 0) return error.Whatever;
35 \\}
36 \\fn add(a: u16, b: u16) -> u16 {
37 \\ return a + b;
38 \\}
39 );
40
41 cases.addRuntimeSafety("integer subtraction overflow",
42 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
43 \\ @import("std").os.exit(126);
44 \\}
45 \\error Whatever;
46 \\pub fn main() -> %void {
47 \\ const x = sub(10, 20);
48 \\ if (x == 0) return error.Whatever;
49 \\}
50 \\fn sub(a: u16, b: u16) -> u16 {
51 \\ return a - b;
52 \\}
53 );
54
55 cases.addRuntimeSafety("integer multiplication overflow",
56 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
57 \\ @import("std").os.exit(126);
58 \\}
59 \\error Whatever;
60 \\pub fn main() -> %void {
61 \\ const x = mul(300, 6000);
62 \\ if (x == 0) return error.Whatever;
63 \\}
64 \\fn mul(a: u16, b: u16) -> u16 {
65 \\ return a * b;
66 \\}
67 );
68
69 cases.addRuntimeSafety("integer negation overflow",
70 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
71 \\ @import("std").os.exit(126);
72 \\}
73 \\error Whatever;
74 \\pub fn main() -> %void {
75 \\ const x = neg(-32768);
76 \\ if (x == 32767) return error.Whatever;
77 \\}
78 \\fn neg(a: i16) -> i16 {
79 \\ return -a;
80 \\}
81 );
82
83 cases.addRuntimeSafety("signed integer division overflow",
84 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
85 \\ @import("std").os.exit(126);
86 \\}
87 \\error Whatever;
88 \\pub fn main() -> %void {
89 \\ const x = div(-32768, -1);
90 \\ if (x == 32767) return error.Whatever;
91 \\}
92 \\fn div(a: i16, b: i16) -> i16 {
93 \\ return @divTrunc(a, b);
94 \\}
95 );
96
97 cases.addRuntimeSafety("signed shift left overflow",
98 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
99 \\ @import("std").os.exit(126);
100 \\}
101 \\error Whatever;
102 \\pub fn main() -> %void {
103 \\ const x = shl(-16385, 1);
104 \\ if (x == 0) return error.Whatever;
105 \\}
106 \\fn shl(a: i16, b: u4) -> i16 {
107 \\ return @shlExact(a, b);
108 \\}
109 );
110
111 cases.addRuntimeSafety("unsigned shift left overflow",
112 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
113 \\ @import("std").os.exit(126);
114 \\}
115 \\error Whatever;
116 \\pub fn main() -> %void {
117 \\ const x = shl(0b0010111111111111, 3);
118 \\ if (x == 0) return error.Whatever;
119 \\}
120 \\fn shl(a: u16, b: u4) -> u16 {
121 \\ return @shlExact(a, b);
122 \\}
123 );
124
125 cases.addRuntimeSafety("signed shift right overflow",
126 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
127 \\ @import("std").os.exit(126);
128 \\}
129 \\error Whatever;
130 \\pub fn main() -> %void {
131 \\ const x = shr(-16385, 1);
132 \\ if (x == 0) return error.Whatever;
133 \\}
134 \\fn shr(a: i16, b: u4) -> i16 {
135 \\ return @shrExact(a, b);
136 \\}
137 );
138
139 cases.addRuntimeSafety("unsigned shift right overflow",
140 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
141 \\ @import("std").os.exit(126);
142 \\}
143 \\error Whatever;
144 \\pub fn main() -> %void {
145 \\ const x = shr(0b0010111111111111, 3);
146 \\ if (x == 0) return error.Whatever;
147 \\}
148 \\fn shr(a: u16, b: u4) -> u16 {
149 \\ return @shrExact(a, b);
150 \\}
151 );
152
153 cases.addRuntimeSafety("integer division by zero",
154 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
155 \\ @import("std").os.exit(126);
156 \\}
157 \\error Whatever;
158 \\pub fn main() -> %void {
159 \\ const x = div0(999, 0);
160 \\}
161 \\fn div0(a: i32, b: i32) -> i32 {
162 \\ return @divTrunc(a, b);
163 \\}
164 );
165
166 cases.addRuntimeSafety("exact division failure",
167 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
168 \\ @import("std").os.exit(126);
169 \\}
170 \\error Whatever;
171 \\pub fn main() -> %void {
172 \\ const x = divExact(10, 3);
173 \\ if (x == 0) return error.Whatever;
174 \\}
175 \\fn divExact(a: i32, b: i32) -> i32 {
176 \\ return @divExact(a, b);
177 \\}
178 );
179
180 cases.addRuntimeSafety("cast []u8 to bigger slice of wrong size",
181 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
182 \\ @import("std").os.exit(126);
183 \\}
184 \\error Whatever;
185 \\pub fn main() -> %void {
186 \\ const x = widenSlice([]u8{1, 2, 3, 4, 5});
187 \\ if (x.len == 0) return error.Whatever;
188 \\}
189 \\fn widenSlice(slice: []align(1) const u8) -> []align(1) const i32 {
190 \\ return ([]align(1) const i32)(slice);
191 \\}
192 );
193
194 cases.addRuntimeSafety("value does not fit in shortening cast",
195 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
196 \\ @import("std").os.exit(126);
197 \\}
198 \\error Whatever;
199 \\pub fn main() -> %void {
200 \\ const x = shorten_cast(200);
201 \\ if (x == 0) return error.Whatever;
202 \\}
203 \\fn shorten_cast(x: i32) -> i8 {
204 \\ return i8(x);
205 \\}
206 );
207
208 cases.addRuntimeSafety("signed integer not fitting in cast to unsigned integer",
209 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
210 \\ @import("std").os.exit(126);
211 \\}
212 \\error Whatever;
213 \\pub fn main() -> %void {
214 \\ const x = unsigned_cast(-10);
215 \\ if (x == 0) return error.Whatever;
216 \\}
217 \\fn unsigned_cast(x: i32) -> u32 {
218 \\ return u32(x);
219 \\}
220 );
221
222 cases.addRuntimeSafety("unwrap error",
223 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
224 \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) {
225 \\ @import("std").os.exit(126); // good
226 \\ }
227 \\ @import("std").os.exit(0); // test failed
228 \\}
229 \\error Whatever;
230 \\pub fn main() -> %void {
231 \\ bar() catch unreachable;
232 \\}
233 \\fn bar() -> %void {
234 \\ return error.Whatever;
235 \\}
236 );
237
238 cases.addRuntimeSafety("cast integer to error and no code matches",
239 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
240 \\ @import("std").os.exit(126);
241 \\}
242 \\pub fn main() -> %void {
243 \\ _ = bar(9999);
244 \\}
245 \\fn bar(x: u32) -> error {
246 \\ return error(x);
247 \\}
248 );
249
250 cases.addRuntimeSafety("@alignCast misaligned",
251 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
252 \\ @import("std").os.exit(126);
253 \\}
254 \\error Wrong;
255 \\pub fn main() -> %void {
256 \\ var array align(4) = []u32{0x11111111, 0x11111111};
257 \\ const bytes = ([]u8)(array[0..]);
258 \\ if (foo(bytes) != 0x11111111) return error.Wrong;
259 \\}
260 \\fn foo(bytes: []u8) -> u32 {
261 \\ const slice4 = bytes[1..5];
262 \\ const int_slice = ([]u32)(@alignCast(4, slice4));
263 \\ return int_slice[0];
264 \\}
265 );
266
267 cases.addRuntimeSafety("bad union field access",
268 \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn {
269 \\ @import("std").os.exit(126);
270 \\}
271 \\
272 \\const Foo = union {
273 \\ float: f32,
274 \\ int: u32,
275 \\};
276 \\
277 \\pub fn main() -> %void {
278 \\ var f = Foo { .int = 42 };
279 \\ bar(&f);
280 \\}
281 \\
282 \\fn bar(f: &Foo) {
283 \\ f.float = 12.34;
284 \\}
285 );
286}
test/tests.zig+15-15
......@@ -17,7 +17,7 @@ const compare_output = @import("compare_output.zig");
1717const build_examples = @import("build_examples.zig");
1818const compile_errors = @import("compile_errors.zig");
1919const assemble_and_link = @import("assemble_and_link.zig");
20const debug_safety = @import("debug_safety.zig");
20const runtime_safety = @import("runtime_safety.zig");
2121const translate_c = @import("translate_c.zig");
2222const gen_h = @import("gen_h.zig");
2323
......@@ -64,16 +64,16 @@ pub fn addCompareOutputTests(b: &build.Builder, test_filter: ?[]const u8) -> &bu
6464 return cases.step;
6565}
6666
67pub fn addDebugSafetyTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {
67pub fn addRuntimeSafetyTests(b: &build.Builder, test_filter: ?[]const u8) -> &build.Step {
6868 const cases = b.allocator.create(CompareOutputContext) catch unreachable;
6969 *cases = CompareOutputContext {
7070 .b = b,
71 .step = b.step("test-debug-safety", "Run the debug safety tests"),
71 .step = b.step("test-runtime-safety", "Run the runtime safety tests"),
7272 .test_index = 0,
7373 .test_filter = test_filter,
7474 };
7575
76 debug_safety.addCases(cases);
76 runtime_safety.addCases(cases);
7777
7878 return cases.step;
7979}
......@@ -192,7 +192,7 @@ pub const CompareOutputContext = struct {
192192 const Special = enum {
193193 None,
194194 Asm,
195 DebugSafety,
195 RuntimeSafety,
196196 };
197197
198198 const TestCase = struct {
......@@ -314,7 +314,7 @@ pub const CompareOutputContext = struct {
314314 }
315315 };
316316
317 const DebugSafetyRunStep = struct {
317 const RuntimeSafetyRunStep = struct {
318318 step: build.Step,
319319 context: &CompareOutputContext,
320320 exe_path: []const u8,
......@@ -322,23 +322,23 @@ pub const CompareOutputContext = struct {
322322 test_index: usize,
323323
324324 pub fn create(context: &CompareOutputContext, exe_path: []const u8,
325 name: []const u8) -> &DebugSafetyRunStep
325 name: []const u8) -> &RuntimeSafetyRunStep
326326 {
327327 const allocator = context.b.allocator;
328 const ptr = allocator.create(DebugSafetyRunStep) catch unreachable;
329 *ptr = DebugSafetyRunStep {
328 const ptr = allocator.create(RuntimeSafetyRunStep) catch unreachable;
329 *ptr = RuntimeSafetyRunStep {
330330 .context = context,
331331 .exe_path = exe_path,
332332 .name = name,
333333 .test_index = context.test_index,
334 .step = build.Step.init("DebugSafetyRun", allocator, make),
334 .step = build.Step.init("RuntimeSafetyRun", allocator, make),
335335 };
336336 context.test_index += 1;
337337 return ptr;
338338 }
339339
340340 fn make(step: &build.Step) -> %void {
341 const self = @fieldParentPtr(DebugSafetyRunStep, "step", step);
341 const self = @fieldParentPtr(RuntimeSafetyRunStep, "step", step);
342342 const b = self.context.b;
343343
344344 const full_exe_path = b.pathFromRoot(self.exe_path);
......@@ -420,8 +420,8 @@ pub const CompareOutputContext = struct {
420420 self.addCase(tc);
421421 }
422422
423 pub fn addDebugSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) {
424 const tc = self.createExtra(name, source, undefined, Special.DebugSafety);
423 pub fn addRuntimeSafety(self: &CompareOutputContext, name: []const u8, source: []const u8) {
424 const tc = self.createExtra(name, source, undefined, Special.RuntimeSafety);
425425 self.addCase(tc);
426426 }
427427
......@@ -481,7 +481,7 @@ pub const CompareOutputContext = struct {
481481 self.step.dependOn(&run_and_cmp_output.step);
482482 }
483483 },
484 Special.DebugSafety => {
484 Special.RuntimeSafety => {
485485 const annotated_case_name = fmt.allocPrint(self.b.allocator, "safety {}", case.name) catch unreachable;
486486 if (self.test_filter) |filter| {
487487 if (mem.indexOf(u8, annotated_case_name, filter) == null)
......@@ -499,7 +499,7 @@ pub const CompareOutputContext = struct {
499499 exe.step.dependOn(&write_src.step);
500500 }
501501
502 const run_and_cmp_output = DebugSafetyRunStep.create(self, exe.getOutputPath(), annotated_case_name);
502 const run_and_cmp_output = RuntimeSafetyRunStep.create(self, exe.getOutputPath(), annotated_case_name);
503503 run_and_cmp_output.step.dependOn(&exe.step);
504504
505505 self.step.dependOn(&run_and_cmp_output.step);