| ... | @@ -1820,12 +1820,7 @@ fn analyzeAsType( | ... | @@ -1820,12 +1820,7 @@ fn analyzeAsType( |
| 1820 | } | 1820 | } |
| 1821 | | 1821 | |
| 1822 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { | 1822 | pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { |
| 1823 | const backend_supports_error_return_tracing = | 1823 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; |
| 1824 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 1825 | if (!backend_supports_error_return_tracing) { | | |
| 1826 | // TODO implement this feature in all the backends and then delete this branch | | |
| 1827 | return; | | |
| 1828 | } | | |
| 1829 | | 1824 | |
| 1830 | assert(!block.is_comptime); | 1825 | assert(!block.is_comptime); |
| 1831 | var err_trace_block = block.makeSubBlock(); | 1826 | var err_trace_block = block.makeSubBlock(); |
| ... | @@ -5906,9 +5901,8 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { | ... | @@ -5906,9 +5901,8 @@ fn funcDeclSrc(sema: *Sema, func_inst: Air.Inst.Ref) !?*Decl { |
| 5906 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { | 5901 | pub fn analyzeSaveErrRetIndex(sema: *Sema, block: *Block) SemaError!Air.Inst.Ref { |
| 5907 | const src = sema.src; | 5902 | const src = sema.src; |
| 5908 | | 5903 | |
| 5909 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 5904 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return .none; |
| 5910 | if (!backend_supports_error_return_tracing or !sema.mod.comp.bin_file.options.error_return_tracing) | 5905 | if (!sema.mod.comp.bin_file.options.error_return_tracing) return .none; |
| 5911 | return .none; | | |
| 5912 | | 5906 | |
| 5913 | if (block.is_comptime) | 5907 | if (block.is_comptime) |
| 5914 | return .none; | 5908 | return .none; |
| ... | @@ -6146,8 +6140,7 @@ fn zirCall( | ... | @@ -6146,8 +6140,7 @@ fn zirCall( |
| 6146 | if (sema.owner_func == null or !sema.owner_func.?.calls_or_awaits_errorable_fn) | 6140 | if (sema.owner_func == null or !sema.owner_func.?.calls_or_awaits_errorable_fn) |
| 6147 | input_is_error = false; // input was an error type, but no errorable fn's were actually called | 6141 | input_is_error = false; // input was an error type, but no errorable fn's were actually called |
| 6148 | | 6142 | |
| 6149 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 6143 | if (sema.mod.backendSupportsFeature(.error_return_trace) and sema.mod.comp.bin_file.options.error_return_tracing and |
| 6150 | if (backend_supports_error_return_tracing and sema.mod.comp.bin_file.options.error_return_tracing and | | |
| 6151 | !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) | 6144 | !block.is_comptime and !block.is_typeof and (input_is_error or pop_error_return_trace)) |
| 6152 | { | 6145 | { |
| 6153 | const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: { | 6146 | const call_inst: Air.Inst.Ref = if (modifier == .always_tail) undefined else b: { |
| ... | @@ -7934,11 +7927,8 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A | ... | @@ -7934,11 +7927,8 @@ fn zirIntToEnum(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A |
| 7934 | | 7927 | |
| 7935 | try sema.requireRuntimeBlock(block, src, operand_src); | 7928 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 7936 | const result = try block.addTyOp(.intcast, dest_ty, operand); | 7929 | const result = try block.addTyOp(.intcast, dest_ty, operand); |
| 7937 | if (block.wantSafety() and | 7930 | if (block.wantSafety() and !dest_ty.isNonexhaustiveEnum() and |
| 7938 | !dest_ty.isNonexhaustiveEnum() and | 7931 | sema.mod.backendSupportsFeature(.is_named_enum_value)) |
| 7939 | // TODO instead of "use_llvm", check a different condition so that backends | | |
| 7940 | // can advertise themselves as supporting these extra AIR instructions for safety. | | |
| 7941 | sema.mod.comp.bin_file.options.use_llvm) | | |
| 7942 | { | 7932 | { |
| 7943 | const ok = try block.addUnOp(.is_named_enum_value, result); | 7933 | const ok = try block.addUnOp(.is_named_enum_value, result); |
| 7944 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); | 7934 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); |
| ... | @@ -10656,8 +10646,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10656,8 +10646,6 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10656 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); | 10646 | return sema.resolveBlockBody(block, src, &child_block, special.body, inst, merges); |
| 10657 | } | 10647 | } |
| 10658 | | 10648 | |
| 10659 | const backend_supports_is_named_enum = sema.mod.comp.bin_file.options.use_llvm; | | |
| 10660 | | | |
| 10661 | if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) { | 10649 | if (scalar_cases_len + multi_cases_len == 0 and !special.is_inline) { |
| 10662 | if (empty_enum) { | 10650 | if (empty_enum) { |
| 10663 | return Air.Inst.Ref.void_value; | 10651 | return Air.Inst.Ref.void_value; |
| ... | @@ -10668,7 +10656,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10668,7 +10656,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10668 | if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) { | 10656 | if (err_set and try sema.maybeErrorUnwrap(block, special.body, operand)) { |
| 10669 | return Air.Inst.Ref.unreachable_value; | 10657 | return Air.Inst.Ref.unreachable_value; |
| 10670 | } | 10658 | } |
| 10671 | if (backend_supports_is_named_enum and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and | 10659 | if (sema.mod.backendSupportsFeature(.is_named_enum_value) and block.wantSafety() and operand_ty.zigTypeTag() == .Enum and |
| 10672 | (!operand_ty.isNonexhaustiveEnum() or union_originally)) | 10660 | (!operand_ty.isNonexhaustiveEnum() or union_originally)) |
| 10673 | { | 10661 | { |
| 10674 | try sema.zirDbgStmt(block, cond_dbg_node_index); | 10662 | try sema.zirDbgStmt(block, cond_dbg_node_index); |
| ... | @@ -11138,7 +11126,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -11138,7 +11126,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 11138 | case_block.wip_capture_scope = wip_captures.scope; | 11126 | case_block.wip_capture_scope = wip_captures.scope; |
| 11139 | case_block.inline_case_capture = .none; | 11127 | case_block.inline_case_capture = .none; |
| 11140 | | 11128 | |
| 11141 | if (backend_supports_is_named_enum and special.body.len != 0 and block.wantSafety() and | 11129 | if (sema.mod.backendSupportsFeature(.is_named_enum_value) and special.body.len != 0 and block.wantSafety() and |
| 11142 | operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally)) | 11130 | operand_ty.zigTypeTag() == .Enum and (!operand_ty.isNonexhaustiveEnum() or union_originally)) |
| 11143 | { | 11131 | { |
| 11144 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); | 11132 | try sema.zirDbgStmt(&case_block, cond_dbg_node_index); |
| ... | @@ -11451,10 +11439,7 @@ fn validateSwitchNoRange( | ... | @@ -11451,10 +11439,7 @@ fn validateSwitchNoRange( |
| 11451 | } | 11439 | } |
| 11452 | | 11440 | |
| 11453 | fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool { | 11441 | fn maybeErrorUnwrap(sema: *Sema, block: *Block, body: []const Zir.Inst.Index, operand: Air.Inst.Ref) !bool { |
| 11454 | const this_feature_is_implemented_in_the_backend = | 11442 | if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) return false; |
| 11455 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 11456 | | | |
| 11457 | if (!this_feature_is_implemented_in_the_backend) return false; | | |
| 11458 | | 11443 | |
| 11459 | const tags = sema.code.instructions.items(.tag); | 11444 | const tags = sema.code.instructions.items(.tag); |
| 11460 | for (body) |inst| { | 11445 | for (body) |inst| { |
| ... | @@ -16968,20 +16953,17 @@ fn retWithErrTracing( | ... | @@ -16968,20 +16953,17 @@ fn retWithErrTracing( |
| 16968 | } | 16953 | } |
| 16969 | | 16954 | |
| 16970 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { | 16955 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| 16971 | // TODO implement this feature in all the backends and then delete this check. | 16956 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return false; |
| 16972 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | | |
| 16973 | | 16957 | |
| 16974 | return fn_ret_ty.isError() and | 16958 | return fn_ret_ty.isError() and |
| 16975 | sema.mod.comp.bin_file.options.error_return_tracing and | 16959 | sema.mod.comp.bin_file.options.error_return_tracing; |
| 16976 | backend_supports_error_return_tracing; | | |
| 16977 | } | 16960 | } |
| 16978 | | 16961 | |
| 16979 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { | 16962 | fn zirSaveErrRetIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void { |
| 16980 | const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index; | 16963 | const inst_data = sema.code.instructions.items(.data)[inst].save_err_ret_index; |
| 16981 | | 16964 | |
| 16982 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 16965 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; |
| 16983 | const ok = backend_supports_error_return_tracing and sema.mod.comp.bin_file.options.error_return_tracing; | 16966 | if (!sema.mod.comp.bin_file.options.error_return_tracing) return; |
| 16984 | if (!ok) return; | | |
| 16985 | | 16967 | |
| 16986 | // This is only relevant at runtime. | 16968 | // This is only relevant at runtime. |
| 16987 | if (block.is_comptime or block.is_typeof) return; | 16969 | if (block.is_comptime or block.is_typeof) return; |
| ... | @@ -17003,11 +16985,9 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) | ... | @@ -17003,11 +16985,9 @@ fn zirRestoreErrRetIndex(sema: *Sema, start_block: *Block, inst: Zir.Inst.Index) |
| 17003 | // This is only relevant at runtime. | 16985 | // This is only relevant at runtime. |
| 17004 | if (start_block.is_comptime or start_block.is_typeof) return; | 16986 | if (start_block.is_comptime or start_block.is_typeof) return; |
| 17005 | | 16987 | |
| 17006 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 16988 | if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; |
| 17007 | const ok = sema.owner_func.?.calls_or_awaits_errorable_fn and | 16989 | if (!sema.owner_func.?.calls_or_awaits_errorable_fn) return; |
| 17008 | sema.mod.comp.bin_file.options.error_return_tracing and | 16990 | if (!sema.mod.comp.bin_file.options.error_return_tracing) return; |
| 17009 | backend_supports_error_return_tracing; | | |
| 17010 | if (!ok) return; | | |
| 17011 | | 16991 | |
| 17012 | const tracy = trace(@src()); | 16992 | const tracy = trace(@src()); |
| 17013 | defer tracy.end(); | 16993 | defer tracy.end(); |
| ... | @@ -17986,14 +17966,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -17986,14 +17966,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 17986 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); | 17966 | const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); |
| 17987 | const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); | 17967 | const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); |
| 17988 | | 17968 | |
| 17989 | // TODO implement this feature in all the backends and then delete this check. | | |
| 17990 | const backend_supports_error_return_tracing = | | |
| 17991 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 17992 | | | |
| 17993 | if (sema.owner_func != null and | 17969 | if (sema.owner_func != null and |
| 17994 | sema.owner_func.?.calls_or_awaits_errorable_fn and | 17970 | sema.owner_func.?.calls_or_awaits_errorable_fn and |
| 17995 | sema.mod.comp.bin_file.options.error_return_tracing and | 17971 | sema.mod.comp.bin_file.options.error_return_tracing and |
| 17996 | backend_supports_error_return_tracing) | 17972 | sema.mod.backendSupportsFeature(.error_return_trace)) |
| 17997 | { | 17973 | { |
| 17998 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); | 17974 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 17999 | } | 17975 | } |
| ... | @@ -18173,7 +18149,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air | ... | @@ -18173,7 +18149,7 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18173 | return sema.addStrLit(block, field_name); | 18149 | return sema.addStrLit(block, field_name); |
| 18174 | } | 18150 | } |
| 18175 | try sema.requireRuntimeBlock(block, src, operand_src); | 18151 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 18176 | if (block.wantSafety() and sema.mod.comp.bin_file.options.use_llvm) { | 18152 | if (block.wantSafety() and sema.mod.backendSupportsFeature(.is_named_enum_value)) { |
| 18177 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); | 18153 | const ok = try block.addUnOp(.is_named_enum_value, casted_operand); |
| 18178 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); | 18154 | try sema.addSafetyCheck(block, ok, .invalid_enum_value); |
| 18179 | } | 18155 | } |
| ... | @@ -19467,7 +19443,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat | ... | @@ -19467,7 +19443,7 @@ fn zirErrSetCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstDat |
| 19467 | } | 19443 | } |
| 19468 | | 19444 | |
| 19469 | try sema.requireRuntimeBlock(block, src, operand_src); | 19445 | try sema.requireRuntimeBlock(block, src, operand_src); |
| 19470 | if (block.wantSafety() and !dest_ty.isAnyError() and sema.mod.comp.bin_file.options.use_llvm) { | 19446 | if (block.wantSafety() and !dest_ty.isAnyError() and sema.mod.backendSupportsFeature(.error_set_has_value)) { |
| 19471 | const err_int_inst = try block.addBitCast(Type.err_int, operand); | 19447 | const err_int_inst = try block.addBitCast(Type.err_int, operand); |
| 19472 | const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst); | 19448 | const ok = try block.addTyOp(.error_set_has_value, dest_ty, err_int_inst); |
| 19473 | try sema.addSafetyCheck(block, ok, .invalid_error_code); | 19449 | try sema.addSafetyCheck(block, ok, .invalid_error_code); |
| ... | @@ -22656,11 +22632,7 @@ fn panicWithMsg( | ... | @@ -22656,11 +22632,7 @@ fn panicWithMsg( |
| 22656 | const mod = sema.mod; | 22632 | const mod = sema.mod; |
| 22657 | const arena = sema.arena; | 22633 | const arena = sema.arena; |
| 22658 | | 22634 | |
| 22659 | const this_feature_is_implemented_in_the_backend = | 22635 | if (!mod.backendSupportsFeature(.panic_fn)) { |
| 22660 | mod.comp.bin_file.options.target.ofmt == .c or | | |
| 22661 | mod.comp.bin_file.options.use_llvm; | | |
| 22662 | if (!this_feature_is_implemented_in_the_backend) { | | |
| 22663 | // TODO implement this feature in all the backends and then delete this branch | | |
| 22664 | _ = try block.addNoOp(.breakpoint); | 22636 | _ = try block.addNoOp(.breakpoint); |
| 22665 | _ = try block.addNoOp(.unreach); | 22637 | _ = try block.addNoOp(.unreach); |
| 22666 | return; | 22638 | return; |
| ... | @@ -22709,11 +22681,7 @@ fn panicUnwrapError( | ... | @@ -22709,11 +22681,7 @@ fn panicUnwrapError( |
| 22709 | defer fail_block.instructions.deinit(gpa); | 22681 | defer fail_block.instructions.deinit(gpa); |
| 22710 | | 22682 | |
| 22711 | { | 22683 | { |
| 22712 | const this_feature_is_implemented_in_the_backend = | 22684 | if (!sema.mod.backendSupportsFeature(.panic_unwrap_error)) { |
| 22713 | sema.mod.comp.bin_file.options.use_llvm; | | |
| 22714 | | | |
| 22715 | if (!this_feature_is_implemented_in_the_backend) { | | |
| 22716 | // TODO implement this feature in all the backends and then delete this branch | | |
| 22717 | _ = try fail_block.addNoOp(.breakpoint); | 22685 | _ = try fail_block.addNoOp(.breakpoint); |
| 22718 | _ = try fail_block.addNoOp(.unreach); | 22686 | _ = try fail_block.addNoOp(.unreach); |
| 22719 | } else { | 22687 | } else { |
| ... | @@ -22839,18 +22807,12 @@ fn safetyCheckFormatted( | ... | @@ -22839,18 +22807,12 @@ fn safetyCheckFormatted( |
| 22839 | | 22807 | |
| 22840 | defer fail_block.instructions.deinit(gpa); | 22808 | defer fail_block.instructions.deinit(gpa); |
| 22841 | | 22809 | |
| 22842 | { | 22810 | if (!sema.mod.backendSupportsFeature(.safety_check_formatted)) { |
| 22843 | const this_feature_is_implemented_in_the_backend = | 22811 | _ = try fail_block.addNoOp(.breakpoint); |
| 22844 | sema.mod.comp.bin_file.options.use_llvm; | 22812 | _ = try fail_block.addNoOp(.unreach); |
| 22845 | | 22813 | } else { |
| 22846 | if (!this_feature_is_implemented_in_the_backend) { | 22814 | const panic_fn = try sema.getBuiltin(func); |
| 22847 | // TODO implement this feature in all the backends and then delete this branch | 22815 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null); |
| 22848 | _ = try fail_block.addNoOp(.breakpoint); | | |
| 22849 | _ = try fail_block.addNoOp(.unreach); | | |
| 22850 | } else { | | |
| 22851 | const panic_fn = try sema.getBuiltin(func); | | |
| 22852 | _ = try sema.analyzeCall(&fail_block, panic_fn, sema.src, sema.src, .auto, false, args, null); | | |
| 22853 | } | | |
| 22854 | } | 22816 | } |
| 22855 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); | 22817 | try sema.addSafetyCheckExtra(parent_block, ok, &fail_block); |
| 22856 | } | 22818 | } |