| author | |
| committer | |
| log | 7b57454cc11371b71097967656e19f0a1736d733 |
| tree | 4eff514fcb0a0c1f95ac253624c4f705fe95b03e |
| parent | d973b40884be1c7874805c81981cac7edca5605b |
* error return tracing is disabled in release-fast mode
* add @errorReturnTrace
* zig build API changes build return type from `void` to `%void`
* allow `void`, `noreturn`, and `u8` from main. closes #53522 files changed, 198 insertions(+), 112 deletions(-)
doc/langref.html.in+8| ... | ... | @@ -142,6 +142,7 @@ |
| 142 | 142 | <li><a href="#builtin-TagType">@TagType</a></li> |
| 143 | 143 | <li><a href="#builtin-EnumTagType">@EnumTagType</a></li> |
| 144 | 144 | <li><a href="#builtin-errorName">@errorName</a></li> |
| 145 | <li><a href="#builtin-errorReturnTrace">@errorReturnTrace</a></li> | |
| 145 | 146 | <li><a href="#builtin-fence">@fence</a></li> |
| 146 | 147 | <li><a href="#builtin-fieldParentPtr">@fieldParentPtr</a></li> |
| 147 | 148 | <li><a href="#builtin-frameAddress">@frameAddress</a></li> |
| ... | ... | @@ -4412,6 +4413,13 @@ test.zig:6:2: error: found compile log statement |
| 4412 | 4413 | or all calls have a compile-time known value for <code>err</code>, then no |
| 4413 | 4414 | error name table will be generated. |
| 4414 | 4415 | </p> |
| 4416 | <h3 id="builtin-errorReturnTrace">@errorReturnTrace</h3> | |
| 4417 | <pre><code class="zig">@errorReturnTrace() -&gt; ?&amp;builtin.StackTrace</code></pre> | |
| 4418 | <p> | |
| 4419 | If the binary is built with error return tracing, and this function is invoked in a | |
| 4420 | function that calls a function with an error or error union return type, returns a | |
| 4421 | stack trace object. Otherwise returns `null`. | |
| 4422 | </p> | |
| 4415 | 4423 | <h3 id="builtin-fence">@fence</h3> |
| 4416 | 4424 | <pre><code class="zig">@fence(order: AtomicOrder)</code></pre> |
| 4417 | 4425 | <p> |
example/mix_o_files/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) { | |
| 3 | pub fn build(b: &Builder) -> %void { | |
| 4 | 4 | const obj = b.addObject("base64", "base64.zig"); |
| 5 | 5 | |
| 6 | 6 | const exe = b.addCExecutable("test"); |
example/shared_library/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) { | |
| 3 | pub fn build(b: &Builder) -> %void { | |
| 4 | 4 | const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0)); |
| 5 | 5 | |
| 6 | 6 | const exe = b.addCExecutable("test"); |
src/all_types.hpp+7| ... | ... | @@ -1274,6 +1274,7 @@ enum BuiltinFnId { |
| 1274 | 1274 | BuiltinFnIdSetAlignStack, |
| 1275 | 1275 | BuiltinFnIdArgType, |
| 1276 | 1276 | BuiltinFnIdExport, |
| 1277 | BuiltinFnIdErrorReturnTrace, | |
| 1277 | 1278 | }; |
| 1278 | 1279 | |
| 1279 | 1280 | struct BuiltinFnEntry { |
| ... | ... | @@ -1499,6 +1500,7 @@ struct CodeGen { |
| 1499 | 1500 | Buf triple_str; |
| 1500 | 1501 | BuildMode build_mode; |
| 1501 | 1502 | bool is_test_build; |
| 1503 | bool have_err_ret_tracing; | |
| 1502 | 1504 | uint32_t target_os_index; |
| 1503 | 1505 | uint32_t target_arch_index; |
| 1504 | 1506 | uint32_t target_environ_index; |
| ... | ... | @@ -1902,6 +1904,7 @@ enum IrInstructionId { |
| 1902 | 1904 | IrInstructionIdSetAlignStack, |
| 1903 | 1905 | IrInstructionIdArgType, |
| 1904 | 1906 | IrInstructionIdExport, |
| 1907 | IrInstructionIdErrorReturnTrace, | |
| 1905 | 1908 | }; |
| 1906 | 1909 | |
| 1907 | 1910 | struct IrInstruction { |
| ... | ... | @@ -2723,6 +2726,10 @@ struct IrInstructionExport { |
| 2723 | 2726 | IrInstruction *target; |
| 2724 | 2727 | }; |
| 2725 | 2728 | |
| 2729 | struct IrInstructionErrorReturnTrace { | |
| 2730 | IrInstruction base; | |
| 2731 | }; | |
| 2732 | ||
| 2726 | 2733 | static const size_t slice_ptr_index = 0; |
| 2727 | 2734 | static const size_t slice_len_index = 1; |
| 2728 | 2735 |
src/analyze.cpp+3-9| ... | ... | @@ -925,8 +925,9 @@ TypeTableEntry *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) { |
| 925 | 925 | if (!skip_debug_info) { |
| 926 | 926 | bool first_arg_return = calling_convention_does_first_arg_return(fn_type_id->cc) && |
| 927 | 927 | handle_is_ptr(fn_type_id->return_type); |
| 928 | bool prefix_arg_error_return_trace = fn_type_id->return_type->id == TypeTableEntryIdErrorUnion || | |
| 929 | fn_type_id->return_type->id == TypeTableEntryIdPureError; | |
| 928 | bool prefix_arg_error_return_trace = g->have_err_ret_tracing && | |
| 929 | (fn_type_id->return_type->id == TypeTableEntryIdErrorUnion || | |
| 930 | fn_type_id->return_type->id == TypeTableEntryIdPureError); | |
| 930 | 931 | // +1 for maybe making the first argument the return value |
| 931 | 932 | // +1 for maybe last argument the error return trace |
| 932 | 933 | LLVMTypeRef *gen_param_types = allocate<LLVMTypeRef>(2 + fn_type_id->param_count); |
| ... | ... | @@ -2711,13 +2712,6 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { |
| 2711 | 2712 | { |
| 2712 | 2713 | if (g->have_pub_main && buf_eql_str(&fn_table_entry->symbol_name, "main")) { |
| 2713 | 2714 | g->main_fn = fn_table_entry; |
| 2714 | TypeTableEntry *err_void = get_error_type(g, g->builtin_types.entry_void); | |
| 2715 | TypeTableEntry *actual_return_type = fn_table_entry->type_entry->data.fn.fn_type_id.return_type; | |
| 2716 | if (actual_return_type != err_void) { | |
| 2717 | add_node_error(g, fn_proto->return_type, | |
| 2718 | buf_sprintf("expected return type of main to be '%%void', instead is '%s'", | |
| 2719 | buf_ptr(&actual_return_type->name))); | |
| 2720 | } | |
| 2721 | 2715 | } else if ((import->package == g->panic_package || g->have_pub_panic) && |
| 2722 | 2716 | buf_eql_str(&fn_table_entry->symbol_name, "panic")) |
| 2723 | 2717 | { |
src/codegen.cpp+49-29| ... | ... | @@ -404,7 +404,10 @@ static LLVMLinkage to_llvm_linkage(GlobalLinkageId id) { |
| 404 | 404 | zig_unreachable(); |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | static uint32_t get_err_ret_trace_arg_index(FnTableEntry *fn_table_entry) { | |
| 407 | static uint32_t get_err_ret_trace_arg_index(CodeGen *g, FnTableEntry *fn_table_entry) { | |
| 408 | if (!g->have_err_ret_tracing) { | |
| 409 | return UINT32_MAX; | |
| 410 | } | |
| 408 | 411 | TypeTableEntry *fn_type = fn_table_entry->type_entry; |
| 409 | 412 | TypeTableEntry *return_type = fn_type->data.fn.fn_type_id.return_type; |
| 410 | 413 | if (return_type->id != TypeTableEntryIdErrorUnion && return_type->id != TypeTableEntryIdPureError) { |
| ... | ... | @@ -572,7 +575,7 @@ static LLVMValueRef fn_llvm_value(CodeGen *g, FnTableEntry *fn_table_entry) { |
| 572 | 575 | } |
| 573 | 576 | } |
| 574 | 577 | |
| 575 | uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(fn_table_entry); | |
| 578 | uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry); | |
| 576 | 579 | if (err_ret_trace_arg_index != UINT32_MAX) { |
| 577 | 580 | addLLVMArgAttr(fn_table_entry->llvm_value, (unsigned)err_ret_trace_arg_index, "nonnull"); |
| 578 | 581 | } |
| ... | ... | @@ -1415,31 +1418,33 @@ static LLVMValueRef ir_render_return(CodeGen *g, IrExecutable *executable, IrIns |
| 1415 | 1418 | LLVMValueRef value = ir_llvm_value(g, return_instruction->value); |
| 1416 | 1419 | TypeTableEntry *return_type = return_instruction->value->value.type; |
| 1417 | 1420 | |
| 1418 | bool is_err_return = false; | |
| 1419 | if (return_type->id == TypeTableEntryIdErrorUnion) { | |
| 1420 | if (return_instruction->value->value.special == ConstValSpecialStatic) { | |
| 1421 | is_err_return = return_instruction->value->value.data.x_err_union.err != nullptr; | |
| 1422 | } else if (return_instruction->value->value.special == ConstValSpecialRuntime) { | |
| 1423 | is_err_return = return_instruction->value->value.data.rh_error_union == RuntimeHintErrorUnionError; | |
| 1424 | // TODO: emit a branch to check if the return value is an error | |
| 1421 | if (g->have_err_ret_tracing) { | |
| 1422 | bool is_err_return = false; | |
| 1423 | if (return_type->id == TypeTableEntryIdErrorUnion) { | |
| 1424 | if (return_instruction->value->value.special == ConstValSpecialStatic) { | |
| 1425 | is_err_return = return_instruction->value->value.data.x_err_union.err != nullptr; | |
| 1426 | } else if (return_instruction->value->value.special == ConstValSpecialRuntime) { | |
| 1427 | is_err_return = return_instruction->value->value.data.rh_error_union == RuntimeHintErrorUnionError; | |
| 1428 | // TODO: emit a branch to check if the return value is an error | |
| 1429 | } | |
| 1430 | } else if (return_type->id == TypeTableEntryIdPureError) { | |
| 1431 | is_err_return = true; | |
| 1432 | } | |
| 1433 | if (is_err_return) { | |
| 1434 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn_val, "ReturnError"); | |
| 1435 | LLVMValueRef block_address = LLVMBlockAddress(g->cur_fn_val, return_block); | |
| 1436 | ||
| 1437 | LLVMValueRef return_err_fn = get_return_err_fn(g); | |
| 1438 | LLVMValueRef args[] = { | |
| 1439 | g->cur_err_ret_trace_val, | |
| 1440 | block_address, | |
| 1441 | }; | |
| 1442 | LLVMBuildBr(g->builder, return_block); | |
| 1443 | LLVMPositionBuilderAtEnd(g->builder, return_block); | |
| 1444 | LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, return_err_fn, args, 2, | |
| 1445 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, ""); | |
| 1446 | LLVMSetTailCall(call_instruction, true); | |
| 1425 | 1447 | } |
| 1426 | } else if (return_type->id == TypeTableEntryIdPureError) { | |
| 1427 | is_err_return = true; | |
| 1428 | } | |
| 1429 | if (is_err_return) { | |
| 1430 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(g->cur_fn_val, "ReturnError"); | |
| 1431 | LLVMValueRef block_address = LLVMBlockAddress(g->cur_fn_val, return_block); | |
| 1432 | ||
| 1433 | LLVMValueRef return_err_fn = get_return_err_fn(g); | |
| 1434 | LLVMValueRef args[] = { | |
| 1435 | g->cur_err_ret_trace_val, | |
| 1436 | block_address, | |
| 1437 | }; | |
| 1438 | LLVMBuildBr(g->builder, return_block); | |
| 1439 | LLVMPositionBuilderAtEnd(g->builder, return_block); | |
| 1440 | LLVMValueRef call_instruction = ZigLLVMBuildCall(g->builder, return_err_fn, args, 2, | |
| 1441 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_FnInlineAuto, ""); | |
| 1442 | LLVMSetTailCall(call_instruction, true); | |
| 1443 | 1448 | } |
| 1444 | 1449 | if (handle_is_ptr(return_type)) { |
| 1445 | 1450 | if (calling_convention_does_first_arg_return(g->cur_fn->type_entry->data.fn.fn_type_id.cc)) { |
| ... | ... | @@ -2475,7 +2480,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstr |
| 2475 | 2480 | TypeTableEntry *src_return_type = fn_type_id->return_type; |
| 2476 | 2481 | bool ret_has_bits = type_has_bits(src_return_type); |
| 2477 | 2482 | bool first_arg_ret = ret_has_bits && handle_is_ptr(src_return_type); |
| 2478 | bool prefix_arg_err_ret_stack = src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdPureError; | |
| 2483 | bool prefix_arg_err_ret_stack = g->have_err_ret_tracing && (src_return_type->id == TypeTableEntryIdErrorUnion || src_return_type->id == TypeTableEntryIdPureError); | |
| 2479 | 2484 | size_t actual_param_count = instruction->arg_count + (first_arg_ret ? 1 : 0) + (prefix_arg_err_ret_stack ? 1 : 0); |
| 2480 | 2485 | bool is_var_args = fn_type_id->is_var_args; |
| 2481 | 2486 | LLVMValueRef *gen_param_values = allocate<LLVMValueRef>(actual_param_count); |
| ... | ... | @@ -3031,6 +3036,16 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, IrExecutable *executable, I |
| 3031 | 3036 | return target_val; |
| 3032 | 3037 | } |
| 3033 | 3038 | |
| 3039 | static LLVMValueRef ir_render_error_return_trace(CodeGen *g, IrExecutable *executable, | |
| 3040 | IrInstructionErrorReturnTrace *instruction) | |
| 3041 | { | |
| 3042 | TypeTableEntry *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(g); | |
| 3043 | if (g->cur_err_ret_trace_val == nullptr) { | |
| 3044 | return LLVMConstNull(ptr_to_stack_trace_type->type_ref); | |
| 3045 | } | |
| 3046 | return g->cur_err_ret_trace_val; | |
| 3047 | } | |
| 3048 | ||
| 3034 | 3049 | static LLVMAtomicOrdering to_LLVMAtomicOrdering(AtomicOrder atomic_order) { |
| 3035 | 3050 | switch (atomic_order) { |
| 3036 | 3051 | case AtomicOrderUnordered: return LLVMAtomicOrderingUnordered; |
| ... | ... | @@ -3804,6 +3819,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3804 | 3819 | return ir_render_field_parent_ptr(g, executable, (IrInstructionFieldParentPtr *)instruction); |
| 3805 | 3820 | case IrInstructionIdAlignCast: |
| 3806 | 3821 | return ir_render_align_cast(g, executable, (IrInstructionAlignCast *)instruction); |
| 3822 | case IrInstructionIdErrorReturnTrace: | |
| 3823 | return ir_render_error_return_trace(g, executable, (IrInstructionErrorReturnTrace *)instruction); | |
| 3807 | 3824 | } |
| 3808 | 3825 | zig_unreachable(); |
| 3809 | 3826 | } |
| ... | ... | @@ -4653,10 +4670,10 @@ static void do_code_gen(CodeGen *g) { |
| 4653 | 4670 | build_all_basic_blocks(g, fn_table_entry); |
| 4654 | 4671 | clear_debug_source_node(g); |
| 4655 | 4672 | |
| 4656 | uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(fn_table_entry); | |
| 4673 | uint32_t err_ret_trace_arg_index = get_err_ret_trace_arg_index(g, fn_table_entry); | |
| 4657 | 4674 | if (err_ret_trace_arg_index != UINT32_MAX) { |
| 4658 | 4675 | g->cur_err_ret_trace_val = LLVMGetParam(fn, err_ret_trace_arg_index); |
| 4659 | } else if (fn_table_entry->calls_errorable_function) { | |
| 4676 | } else if (g->have_err_ret_tracing && fn_table_entry->calls_errorable_function) { | |
| 4660 | 4677 | // TODO call graph analysis to find out what this number needs to be for every function |
| 4661 | 4678 | static const size_t stack_trace_ptr_count = 30; |
| 4662 | 4679 | |
| ... | ... | @@ -5251,6 +5268,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 5251 | 5268 | create_builtin_fn(g, BuiltinFnIdSetAlignStack, "setAlignStack", 1); |
| 5252 | 5269 | create_builtin_fn(g, BuiltinFnIdArgType, "ArgType", 2); |
| 5253 | 5270 | create_builtin_fn(g, BuiltinFnIdExport, "export", 3); |
| 5271 | create_builtin_fn(g, BuiltinFnIdErrorReturnTrace, "errorReturnTrace", 0); | |
| 5254 | 5272 | } |
| 5255 | 5273 | |
| 5256 | 5274 | static const char *bool_to_str(bool b) { |
| ... | ... | @@ -5553,6 +5571,8 @@ static void init(CodeGen *g) { |
| 5553 | 5571 | } |
| 5554 | 5572 | } |
| 5555 | 5573 | |
| 5574 | g->have_err_ret_tracing = g->build_mode != BuildModeFastRelease; | |
| 5575 | ||
| 5556 | 5576 | define_builtin_fns(g); |
| 5557 | 5577 | define_builtin_compile_vars(g); |
| 5558 | 5578 | } |
src/ir.cpp+35| ... | ... | @@ -572,6 +572,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionArgType *) { |
| 572 | 572 | return IrInstructionIdArgType; |
| 573 | 573 | } |
| 574 | 574 | |
| 575 | static constexpr IrInstructionId ir_instruction_id(IrInstructionErrorReturnTrace *) { | |
| 576 | return IrInstructionIdErrorReturnTrace; | |
| 577 | } | |
| 578 | ||
| 575 | 579 | template<typename T> |
| 576 | 580 | static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 577 | 581 | T *special_instruction = allocate<T>(1); |
| ... | ... | @@ -2305,6 +2309,12 @@ static IrInstruction *ir_build_arg_type(IrBuilder *irb, Scope *scope, AstNode *s |
| 2305 | 2309 | return &instruction->base; |
| 2306 | 2310 | } |
| 2307 | 2311 | |
| 2312 | static IrInstruction *ir_build_error_return_trace(IrBuilder *irb, Scope *scope, AstNode *source_node) { | |
| 2313 | IrInstructionErrorReturnTrace *instruction = ir_build_instruction<IrInstructionErrorReturnTrace>(irb, scope, source_node); | |
| 2314 | ||
| 2315 | return &instruction->base; | |
| 2316 | } | |
| 2317 | ||
| 2308 | 2318 | static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) { |
| 2309 | 2319 | results[ReturnKindUnconditional] = 0; |
| 2310 | 2320 | results[ReturnKindError] = 0; |
| ... | ... | @@ -3731,6 +3741,10 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 3731 | 3741 | |
| 3732 | 3742 | return ir_build_export(irb, scope, node, arg0_value, arg1_value, arg2_value); |
| 3733 | 3743 | } |
| 3744 | case BuiltinFnIdErrorReturnTrace: | |
| 3745 | { | |
| 3746 | return ir_build_error_return_trace(irb, scope, node); | |
| 3747 | } | |
| 3734 | 3748 | } |
| 3735 | 3749 | zig_unreachable(); |
| 3736 | 3750 | } |
| ... | ... | @@ -9568,6 +9582,24 @@ static TypeTableEntry *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructi |
| 9568 | 9582 | return ira->codegen->builtin_types.entry_void; |
| 9569 | 9583 | } |
| 9570 | 9584 | |
| 9585 | static TypeTableEntry *ir_analyze_instruction_error_return_trace(IrAnalyze *ira, | |
| 9586 | IrInstructionErrorReturnTrace *instruction) | |
| 9587 | { | |
| 9588 | FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec); | |
| 9589 | TypeTableEntry *ptr_to_stack_trace_type = get_ptr_to_stack_trace_type(ira->codegen); | |
| 9590 | TypeTableEntry *nullable_type = get_maybe_type(ira->codegen, ptr_to_stack_trace_type); | |
| 9591 | if (fn_entry == nullptr || !fn_entry->calls_errorable_function || !ira->codegen->have_err_ret_tracing) { | |
| 9592 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | |
| 9593 | out_val->data.x_maybe = nullptr; | |
| 9594 | return nullable_type; | |
| 9595 | } | |
| 9596 | ||
| 9597 | IrInstruction *new_instruction = ir_build_error_return_trace(&ira->new_irb, instruction->base.scope, | |
| 9598 | instruction->base.source_node); | |
| 9599 | ir_link_new_instruction(new_instruction, &instruction->base); | |
| 9600 | return nullable_type; | |
| 9601 | } | |
| 9602 | ||
| 9571 | 9603 | static bool ir_analyze_fn_call_inline_arg(IrAnalyze *ira, AstNode *fn_proto_node, |
| 9572 | 9604 | IrInstruction *arg, Scope **exec_scope, size_t *next_proto_i) |
| 9573 | 9605 | { |
| ... | ... | @@ -15324,6 +15356,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 15324 | 15356 | return ir_analyze_instruction_tag_type(ira, (IrInstructionTagType *)instruction); |
| 15325 | 15357 | case IrInstructionIdExport: |
| 15326 | 15358 | return ir_analyze_instruction_export(ira, (IrInstructionExport *)instruction); |
| 15359 | case IrInstructionIdErrorReturnTrace: | |
| 15360 | return ir_analyze_instruction_error_return_trace(ira, (IrInstructionErrorReturnTrace *)instruction); | |
| 15327 | 15361 | } |
| 15328 | 15362 | zig_unreachable(); |
| 15329 | 15363 | } |
| ... | ... | @@ -15507,6 +15541,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 15507 | 15541 | case IrInstructionIdOpaqueType: |
| 15508 | 15542 | case IrInstructionIdArgType: |
| 15509 | 15543 | case IrInstructionIdTagType: |
| 15544 | case IrInstructionIdErrorReturnTrace: | |
| 15510 | 15545 | return false; |
| 15511 | 15546 | case IrInstructionIdAsm: |
| 15512 | 15547 | { |
src/ir_print.cpp+7| ... | ... | @@ -996,6 +996,10 @@ static void ir_print_export(IrPrint *irp, IrInstructionExport *instruction) { |
| 996 | 996 | } |
| 997 | 997 | } |
| 998 | 998 | |
| 999 | static void ir_print_error_return_trace(IrPrint *irp, IrInstructionErrorReturnTrace *instruction) { | |
| 1000 | fprintf(irp->f, "@errorReturnTrace()"); | |
| 1001 | } | |
| 1002 | ||
| 999 | 1003 | |
| 1000 | 1004 | static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1001 | 1005 | ir_print_prefix(irp, instruction); |
| ... | ... | @@ -1308,6 +1312,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1308 | 1312 | case IrInstructionIdExport: |
| 1309 | 1313 | ir_print_export(irp, (IrInstructionExport *)instruction); |
| 1310 | 1314 | break; |
| 1315 | case IrInstructionIdErrorReturnTrace: | |
| 1316 | ir_print_error_return_trace(irp, (IrInstructionErrorReturnTrace *)instruction); | |
| 1317 | break; | |
| 1311 | 1318 | } |
| 1312 | 1319 | fprintf(irp->f, "\n"); |
| 1313 | 1320 | } |
std/build.zig+2-2| ... | ... | @@ -247,11 +247,11 @@ pub const Builder = struct { |
| 247 | 247 | defer wanted_steps.deinit(); |
| 248 | 248 | |
| 249 | 249 | if (step_names.len == 0) { |
| 250 | wanted_steps.append(&self.default_step) catch unreachable; | |
| 250 | try wanted_steps.append(&self.default_step); | |
| 251 | 251 | } else { |
| 252 | 252 | for (step_names) |step_name| { |
| 253 | 253 | const s = try self.getTopLevelStepByName(step_name); |
| 254 | wanted_steps.append(s) catch unreachable; | |
| 254 | try wanted_steps.append(s); | |
| 255 | 255 | } |
| 256 | 256 | } |
| 257 | 257 |
std/debug/index.zig+6-3| ... | ... | @@ -56,7 +56,7 @@ pub fn dumpCurrentStackTrace() { |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | /// Tries to print a stack trace to stderr, unbuffered, and ignores any error returned. |
| 59 | pub fn dumpStackTrace(stack_trace: &builtin.StackTrace) { | |
| 59 | pub fn dumpStackTrace(stack_trace: &const builtin.StackTrace) { | |
| 60 | 60 | const stderr = getStderrStream() catch return; |
| 61 | 61 | const debug_info = openSelfDebugInfo(global_allocator) catch |err| { |
| 62 | 62 | stderr.print("Unable to open debug info: {}\n", @errorName(err)) catch return; |
| ... | ... | @@ -127,7 +127,7 @@ const RESET = "\x1b[0m"; |
| 127 | 127 | error PathNotFound; |
| 128 | 128 | error InvalidDebugInfo; |
| 129 | 129 | |
| 130 | pub fn writeStackTrace(stack_trace: &builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator, | |
| 130 | pub fn writeStackTrace(stack_trace: &const builtin.StackTrace, out_stream: &io.OutStream, allocator: &mem.Allocator, | |
| 131 | 131 | debug_info: &ElfStackTrace, tty_color: bool) -> %void |
| 132 | 132 | { |
| 133 | 133 | var frame_index: usize = undefined; |
| ... | ... | @@ -167,6 +167,9 @@ pub fn writeCurrentStackTrace(out_stream: &io.OutStream, allocator: &mem.Allocat |
| 167 | 167 | } |
| 168 | 168 | |
| 169 | 169 | fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, address: usize) -> %void { |
| 170 | if (builtin.os == builtin.Os.windows) { | |
| 171 | return error.UnsupportedDebugInfo; | |
| 172 | } | |
| 170 | 173 | // TODO we really should be able to convert @sizeOf(usize) * 2 to a string literal |
| 171 | 174 | // at compile time. I'll call it issue #313 |
| 172 | 175 | const ptr_hex = if (@sizeOf(usize) == 4) "0x{x8}" else "0x{x16}"; |
| ... | ... | @@ -177,7 +180,7 @@ fn printSourceAtAddress(debug_info: &ElfStackTrace, out_stream: &io.OutStream, a |
| 177 | 180 | return; |
| 178 | 181 | }; |
| 179 | 182 | const compile_unit_name = try compile_unit.die.getAttrString(debug_info, DW.AT_name); |
| 180 | if (getLineNumberInfo(debug_info, compile_unit, usize(address) - 1)) |line_info| { | |
| 183 | if (getLineNumberInfo(debug_info, compile_unit, address - 1)) |line_info| { | |
| 181 | 184 | defer line_info.deinit(); |
| 182 | 185 | try out_stream.print(WHITE ++ "{}:{}:{}" ++ RESET ++ ": " ++ |
| 183 | 186 | DIM ++ ptr_hex ++ " in ??? ({})" ++ RESET ++ "\n", |
std/io.zig+1-1| ... | ... | @@ -224,7 +224,7 @@ pub const File = struct { |
| 224 | 224 | }; |
| 225 | 225 | } |
| 226 | 226 | }, |
| 227 | else => @compileError("unsupported OS"), | |
| 227 | else => @compileError("unsupported OS: " ++ @tagName(builtin.os)), | |
| 228 | 228 | } |
| 229 | 229 | } |
| 230 | 230 |
std/os/index.zig+2-9| ... | ... | @@ -148,7 +148,7 @@ pub coldcc fn abort() -> noreturn { |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | 150 | /// Exits the program cleanly with the specified status code. |
| 151 | pub coldcc fn exit(status: i32) -> noreturn { | |
| 151 | pub coldcc fn exit(status: u8) -> noreturn { | |
| 152 | 152 | if (builtin.link_libc) { |
| 153 | 153 | c.exit(status); |
| 154 | 154 | } |
| ... | ... | @@ -157,14 +157,7 @@ pub coldcc fn exit(status: i32) -> noreturn { |
| 157 | 157 | posix.exit(status); |
| 158 | 158 | }, |
| 159 | 159 | Os.windows => { |
| 160 | // Map a possibly negative status code to a non-negative status for the systems default | |
| 161 | // integer width. | |
| 162 | const p_status = if (@sizeOf(c_uint) < @sizeOf(u32)) | |
| 163 | @truncate(c_uint, @bitCast(u32, status)) | |
| 164 | else | |
| 165 | c_uint(@bitCast(u32, status)); | |
| 166 | ||
| 167 | windows.ExitProcess(p_status); | |
| 160 | windows.ExitProcess(status); | |
| 168 | 161 | }, |
| 169 | 162 | else => @compileError("Unsupported OS"), |
| 170 | 163 | } |
std/special/bootstrap.zig+35-10| ... | ... | @@ -21,8 +21,7 @@ comptime { |
| 21 | 21 | } |
| 22 | 22 | |
| 23 | 23 | extern fn zenMain() -> noreturn { |
| 24 | root.main() catch std.os.posix.exit(1); | |
| 25 | std.os.posix.exit(0); | |
| 24 | std.os.posix.exit(callMain()); | |
| 26 | 25 | } |
| 27 | 26 | |
| 28 | 27 | nakedcc fn _start() -> noreturn { |
| ... | ... | @@ -43,29 +42,55 @@ nakedcc fn _start() -> noreturn { |
| 43 | 42 | extern fn WinMainCRTStartup() -> noreturn { |
| 44 | 43 | @setAlignStack(16); |
| 45 | 44 | |
| 46 | root.main() catch std.os.windows.ExitProcess(1); | |
| 47 | std.os.windows.ExitProcess(0); | |
| 45 | std.os.windows.ExitProcess(callMain()); | |
| 48 | 46 | } |
| 49 | 47 | |
| 50 | 48 | fn posixCallMainAndExit() -> noreturn { |
| 51 | 49 | const argc = *argc_ptr; |
| 52 | 50 | const argv = @ptrCast(&&u8, &argc_ptr[1]); |
| 53 | 51 | const envp = @ptrCast(&?&u8, &argv[argc + 1]); |
| 54 | callMain(argc, argv, envp) catch std.os.posix.exit(1); | |
| 55 | std.os.posix.exit(0); | |
| 52 | std.os.posix.exit(callMainWithArgs(argc, argv, envp)); | |
| 56 | 53 | } |
| 57 | 54 | |
| 58 | fn callMain(argc: usize, argv: &&u8, envp: &?&u8) -> %void { | |
| 55 | fn callMainWithArgs(argc: usize, argv: &&u8, envp: &?&u8) -> u8 { | |
| 59 | 56 | std.os.ArgIteratorPosix.raw = argv[0..argc]; |
| 60 | 57 | |
| 61 | 58 | var env_count: usize = 0; |
| 62 | 59 | while (envp[env_count] != null) : (env_count += 1) {} |
| 63 | 60 | std.os.posix_environ_raw = @ptrCast(&&u8, envp)[0..env_count]; |
| 64 | 61 | |
| 65 | return root.main(); | |
| 62 | return callMain(); | |
| 66 | 63 | } |
| 67 | 64 | |
| 68 | 65 | extern fn main(c_argc: i32, c_argv: &&u8, c_envp: &?&u8) -> i32 { |
| 69 | callMain(usize(c_argc), c_argv, c_envp) catch return 1; | |
| 70 | return 0; | |
| 66 | return callMainWithArgs(usize(c_argc), c_argv, c_envp); | |
| 67 | } | |
| 68 | ||
| 69 | fn callMain() -> u8 { | |
| 70 | switch (@typeId(@typeOf(root.main).ReturnType)) { | |
| 71 | builtin.TypeId.NoReturn => { | |
| 72 | root.main(); | |
| 73 | }, | |
| 74 | builtin.TypeId.Void => { | |
| 75 | root.main(); | |
| 76 | return 0; | |
| 77 | }, | |
| 78 | builtin.TypeId.Int => { | |
| 79 | if (@typeOf(root.main).ReturnType.bit_count != 8) { | |
| 80 | @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); | |
| 81 | } | |
| 82 | return root.main(); | |
| 83 | }, | |
| 84 | builtin.TypeId.ErrorUnion => { | |
| 85 | root.main() catch |err| { | |
| 86 | std.debug.warn("error: {}\n", @errorName(err)); | |
| 87 | if (@errorReturnTrace()) |trace| { | |
| 88 | std.debug.dumpStackTrace(trace); | |
| 89 | } | |
| 90 | return 1; | |
| 91 | }; | |
| 92 | return 0; | |
| 93 | }, | |
| 94 | else => @compileError("expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"), | |
| 95 | } | |
| 71 | 96 | } |
std/special/build_runner.zig+4-4| ... | ... | @@ -14,7 +14,7 @@ pub fn main() -> %void { |
| 14 | 14 | var arg_it = os.args(); |
| 15 | 15 | |
| 16 | 16 | // TODO use a more general purpose allocator here |
| 17 | var inc_allocator = std.heap.IncrementingAllocator.init(40 * 1024 * 1024) catch unreachable; | |
| 17 | var inc_allocator = try std.heap.IncrementingAllocator.init(40 * 1024 * 1024); | |
| 18 | 18 | defer inc_allocator.deinit(); |
| 19 | 19 | |
| 20 | 20 | const allocator = &inc_allocator.allocator; |
| ... | ... | @@ -107,12 +107,12 @@ pub fn main() -> %void { |
| 107 | 107 | return usageAndErr(&builder, false, try stderr_stream); |
| 108 | 108 | } |
| 109 | 109 | } else { |
| 110 | targets.append(arg) catch unreachable; | |
| 110 | try targets.append(arg); | |
| 111 | 111 | } |
| 112 | 112 | } |
| 113 | 113 | |
| 114 | 114 | builder.setInstallPrefix(prefix); |
| 115 | root.build(&builder) catch unreachable; | |
| 115 | try root.build(&builder); | |
| 116 | 116 | |
| 117 | 117 | if (builder.validateUserInputDidItFail()) |
| 118 | 118 | return usageAndErr(&builder, true, try stderr_stream); |
| ... | ... | @@ -129,7 +129,7 @@ fn usage(builder: &Builder, already_ran_build: bool, out_stream: &io.OutStream) |
| 129 | 129 | // run the build script to collect the options |
| 130 | 130 | if (!already_ran_build) { |
| 131 | 131 | builder.setInstallPrefix(null); |
| 132 | root.build(builder) catch unreachable; | |
| 132 | try root.build(builder); | |
| 133 | 133 | } |
| 134 | 134 | |
| 135 | 135 | // This usage text has to be synchronized with src/main.cpp |
std/special/test_runner.zig+1-8| ... | ... | @@ -8,14 +8,7 @@ pub fn main() -> %void { |
| 8 | 8 | for (test_fn_list) |test_fn, i| { |
| 9 | 9 | warn("Test {}/{} {}...", i + 1, test_fn_list.len, test_fn.name); |
| 10 | 10 | |
| 11 | if (builtin.is_test) { | |
| 12 | test_fn.func() catch unreachable; | |
| 13 | } else { | |
| 14 | test_fn.func() catch |err| { | |
| 15 | warn("{}\n", err); | |
| 16 | return err; | |
| 17 | }; | |
| 18 | } | |
| 11 | try test_fn.func(); | |
| 19 | 12 | |
| 20 | 13 | warn("OK\n"); |
| 21 | 14 | } |
test/compile_errors.zig+9-9| ... | ... | @@ -1,6 +1,15 @@ |
| 1 | 1 | const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: &tests.CompileErrorContext) { |
| 4 | cases.add("wrong return type for main", | |
| 5 | \\pub fn main() -> f32 { } | |
| 6 | , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); | |
| 7 | ||
| 8 | cases.add("double ?? on main return value", | |
| 9 | \\pub fn main() -> ??void { | |
| 10 | \\} | |
| 11 | , "error: expected return type of main to be 'u8', 'noreturn', 'void', or '%void'"); | |
| 12 | ||
| 4 | 13 | cases.add("bad identifier in function with struct defined inside function which references local const", |
| 5 | 14 | \\export fn entry() { |
| 6 | 15 | \\ const BlockKind = u32; |
| ... | ... | @@ -1059,15 +1068,6 @@ pub fn addCases(cases: &tests.CompileErrorContext) { |
| 1059 | 1068 | , |
| 1060 | 1069 | ".tmp_source.zig:2:5: error: expected type 'void', found 'error'"); |
| 1061 | 1070 | |
| 1062 | cases.add("wrong return type for main", | |
| 1063 | \\pub fn main() { } | |
| 1064 | , ".tmp_source.zig:1:15: error: expected return type of main to be '%void', instead is 'void'"); | |
| 1065 | ||
| 1066 | cases.add("double ?? on main return value", | |
| 1067 | \\pub fn main() -> ??void { | |
| 1068 | \\} | |
| 1069 | , ".tmp_source.zig:1:18: error: expected return type of main to be '%void', instead is '??void'"); | |
| 1070 | ||
| 1071 | 1071 | cases.add("invalid pointer for var type", |
| 1072 | 1072 | \\extern fn ext() -> usize; |
| 1073 | 1073 | \\var bytes: [ext()]u8 = undefined; |
test/debug_safety.zig+20-20| ... | ... | @@ -2,7 +2,7 @@ const tests = @import("tests.zig"); |
| 2 | 2 | |
| 3 | 3 | pub fn addCases(cases: &tests.CompareOutputContext) { |
| 4 | 4 | cases.addDebugSafety("calling panic", |
| 5 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 5 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 6 | 6 | \\ @import("std").os.exit(126); |
| 7 | 7 | \\} |
| 8 | 8 | \\pub fn main() -> %void { |
| ... | ... | @@ -11,7 +11,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 11 | 11 | ); |
| 12 | 12 | |
| 13 | 13 | cases.addDebugSafety("out of bounds slice access", |
| 14 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 14 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 15 | 15 | \\ @import("std").os.exit(126); |
| 16 | 16 | \\} |
| 17 | 17 | \\pub fn main() -> %void { |
| ... | ... | @@ -25,7 +25,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 25 | 25 | ); |
| 26 | 26 | |
| 27 | 27 | cases.addDebugSafety("integer addition overflow", |
| 28 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 28 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 29 | 29 | \\ @import("std").os.exit(126); |
| 30 | 30 | \\} |
| 31 | 31 | \\error Whatever; |
| ... | ... | @@ -39,7 +39,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 39 | 39 | ); |
| 40 | 40 | |
| 41 | 41 | cases.addDebugSafety("integer subtraction overflow", |
| 42 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 42 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 43 | 43 | \\ @import("std").os.exit(126); |
| 44 | 44 | \\} |
| 45 | 45 | \\error Whatever; |
| ... | ... | @@ -53,7 +53,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 53 | 53 | ); |
| 54 | 54 | |
| 55 | 55 | cases.addDebugSafety("integer multiplication overflow", |
| 56 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 56 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 57 | 57 | \\ @import("std").os.exit(126); |
| 58 | 58 | \\} |
| 59 | 59 | \\error Whatever; |
| ... | ... | @@ -67,7 +67,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 67 | 67 | ); |
| 68 | 68 | |
| 69 | 69 | cases.addDebugSafety("integer negation overflow", |
| 70 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 70 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 71 | 71 | \\ @import("std").os.exit(126); |
| 72 | 72 | \\} |
| 73 | 73 | \\error Whatever; |
| ... | ... | @@ -81,7 +81,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 81 | 81 | ); |
| 82 | 82 | |
| 83 | 83 | cases.addDebugSafety("signed integer division overflow", |
| 84 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 84 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 85 | 85 | \\ @import("std").os.exit(126); |
| 86 | 86 | \\} |
| 87 | 87 | \\error Whatever; |
| ... | ... | @@ -95,7 +95,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 95 | 95 | ); |
| 96 | 96 | |
| 97 | 97 | cases.addDebugSafety("signed shift left overflow", |
| 98 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 98 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 99 | 99 | \\ @import("std").os.exit(126); |
| 100 | 100 | \\} |
| 101 | 101 | \\error Whatever; |
| ... | ... | @@ -109,7 +109,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 109 | 109 | ); |
| 110 | 110 | |
| 111 | 111 | cases.addDebugSafety("unsigned shift left overflow", |
| 112 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 112 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 113 | 113 | \\ @import("std").os.exit(126); |
| 114 | 114 | \\} |
| 115 | 115 | \\error Whatever; |
| ... | ... | @@ -123,7 +123,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 123 | 123 | ); |
| 124 | 124 | |
| 125 | 125 | cases.addDebugSafety("signed shift right overflow", |
| 126 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 126 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 127 | 127 | \\ @import("std").os.exit(126); |
| 128 | 128 | \\} |
| 129 | 129 | \\error Whatever; |
| ... | ... | @@ -137,7 +137,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 137 | 137 | ); |
| 138 | 138 | |
| 139 | 139 | cases.addDebugSafety("unsigned shift right overflow", |
| 140 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 140 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 141 | 141 | \\ @import("std").os.exit(126); |
| 142 | 142 | \\} |
| 143 | 143 | \\error Whatever; |
| ... | ... | @@ -151,7 +151,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 151 | 151 | ); |
| 152 | 152 | |
| 153 | 153 | cases.addDebugSafety("integer division by zero", |
| 154 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 154 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 155 | 155 | \\ @import("std").os.exit(126); |
| 156 | 156 | \\} |
| 157 | 157 | \\error Whatever; |
| ... | ... | @@ -164,7 +164,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 164 | 164 | ); |
| 165 | 165 | |
| 166 | 166 | cases.addDebugSafety("exact division failure", |
| 167 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 167 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 168 | 168 | \\ @import("std").os.exit(126); |
| 169 | 169 | \\} |
| 170 | 170 | \\error Whatever; |
| ... | ... | @@ -178,7 +178,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 178 | 178 | ); |
| 179 | 179 | |
| 180 | 180 | cases.addDebugSafety("cast []u8 to bigger slice of wrong size", |
| 181 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 181 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 182 | 182 | \\ @import("std").os.exit(126); |
| 183 | 183 | \\} |
| 184 | 184 | \\error Whatever; |
| ... | ... | @@ -192,7 +192,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 192 | 192 | ); |
| 193 | 193 | |
| 194 | 194 | cases.addDebugSafety("value does not fit in shortening cast", |
| 195 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 195 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 196 | 196 | \\ @import("std").os.exit(126); |
| 197 | 197 | \\} |
| 198 | 198 | \\error Whatever; |
| ... | ... | @@ -206,7 +206,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 206 | 206 | ); |
| 207 | 207 | |
| 208 | 208 | cases.addDebugSafety("signed integer not fitting in cast to unsigned integer", |
| 209 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 209 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 210 | 210 | \\ @import("std").os.exit(126); |
| 211 | 211 | \\} |
| 212 | 212 | \\error Whatever; |
| ... | ... | @@ -220,7 +220,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 220 | 220 | ); |
| 221 | 221 | |
| 222 | 222 | cases.addDebugSafety("unwrap error", |
| 223 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 223 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 224 | 224 | \\ if (@import("std").mem.eql(u8, message, "attempt to unwrap error: Whatever")) { |
| 225 | 225 | \\ @import("std").os.exit(126); // good |
| 226 | 226 | \\ } |
| ... | ... | @@ -236,7 +236,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 236 | 236 | ); |
| 237 | 237 | |
| 238 | 238 | cases.addDebugSafety("cast integer to error and no code matches", |
| 239 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 239 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 240 | 240 | \\ @import("std").os.exit(126); |
| 241 | 241 | \\} |
| 242 | 242 | \\pub fn main() -> %void { |
| ... | ... | @@ -248,7 +248,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 248 | 248 | ); |
| 249 | 249 | |
| 250 | 250 | cases.addDebugSafety("@alignCast misaligned", |
| 251 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 251 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 252 | 252 | \\ @import("std").os.exit(126); |
| 253 | 253 | \\} |
| 254 | 254 | \\error Wrong; |
| ... | ... | @@ -265,7 +265,7 @@ pub fn addCases(cases: &tests.CompareOutputContext) { |
| 265 | 265 | ); |
| 266 | 266 | |
| 267 | 267 | cases.addDebugSafety("bad union field access", |
| 268 | \\pub fn panic(message: []const u8) -> noreturn { | |
| 268 | \\pub fn panic(message: []const u8, stack_trace: ?&@import("builtin").StackTrace) -> noreturn { | |
| 269 | 269 | \\ @import("std").os.exit(126); |
| 270 | 270 | \\} |
| 271 | 271 | \\ |
test/standalone/issue_339/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) { | |
| 3 | pub fn build(b: &Builder) -> %void { | |
| 4 | 4 | const obj = b.addObject("test", "test.zig"); |
| 5 | 5 | |
| 6 | 6 | const test_step = b.step("test", "Test the program"); |
test/standalone/issue_339/test.zig+2-1| ... | ... | @@ -1,4 +1,5 @@ |
| 1 | pub fn panic(msg: []const u8) -> noreturn { @breakpoint(); while (true) {} } | |
| 1 | const StackTrace = @import("builtin").StackTrace; | |
| 2 | pub fn panic(msg: []const u8, stack_trace: ?&StackTrace) -> noreturn { @breakpoint(); while (true) {} } | |
| 2 | 3 | |
| 3 | 4 | fn bar() -> %void {} |
| 4 | 5 |
test/standalone/pkg_import/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) { | |
| 3 | pub fn build(b: &Builder) -> %void { | |
| 4 | 4 | const exe = b.addExecutable("test", "test.zig"); |
| 5 | 5 | exe.addPackagePath("my_pkg", "pkg.zig"); |
| 6 | 6 |
test/standalone/use_alias/build.zig+1-1| ... | ... | @@ -1,6 +1,6 @@ |
| 1 | 1 | const Builder = @import("std").build.Builder; |
| 2 | 2 | |
| 3 | pub fn build(b: &Builder) { | |
| 3 | pub fn build(b: &Builder) -> %void { | |
| 4 | 4 | b.addCIncludePath("."); |
| 5 | 5 | |
| 6 | 6 | const main = b.addTest("main.zig"); |
test/tests.zig+2-2| ... | ... | @@ -50,6 +50,7 @@ const test_targets = []TestTarget { |
| 50 | 50 | }; |
| 51 | 51 | |
| 52 | 52 | error TestFailed; |
| 53 | error CompilationIncorrectlySucceeded; | |
| 53 | 54 | |
| 54 | 55 | const max_stdout_size = 1 * 1024 * 1024; // 1 MB |
| 55 | 56 | |
| ... | ... | @@ -607,8 +608,7 @@ pub const CompileErrorContext = struct { |
| 607 | 608 | switch (term) { |
| 608 | 609 | Term.Exited => |code| { |
| 609 | 610 | if (code == 0) { |
| 610 | warn("Compilation incorrectly succeeded\n"); | |
| 611 | return error.TestFailed; | |
| 611 | return error.CompilationIncorrectlySucceeded; | |
| 612 | 612 | } |
| 613 | 613 | }, |
| 614 | 614 | else => { |