| author | |
| committer | |
| log | 54eb0f2daa2cf5237da05e3cfad5800b9ccf424e |
| tree | dd1eb2e1a9a936a6d48bacff436a4ded191ffb34 |
| parent | 8eb96c32e38d687c2b2f1488105538dda8dd5b0b |
| parent | 9cad44770a15d189cddb749bc1b2fca9e24b858f |
| signature |
stage2: fix branches on undefined values6 files changed, 45 insertions(+), 6 deletions(-)
src/Module.zig+2| ... | @@ -4430,6 +4430,8 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { | ... | @@ -4430,6 +4430,8 @@ pub fn semaFile(mod: *Module, file: *File) SemaError!void { |
| 4430 | new_decl.has_linksection_or_addrspace = false; | 4430 | new_decl.has_linksection_or_addrspace = false; |
| 4431 | new_decl.ty = ty_ty; | 4431 | new_decl.ty = ty_ty; |
| 4432 | new_decl.val = struct_val; | 4432 | new_decl.val = struct_val; |
| 4433 | new_decl.@"align" = 0; | ||
| 4434 | new_decl.@"linksection" = null; | ||
| 4433 | new_decl.has_tv = true; | 4435 | new_decl.has_tv = true; |
| 4434 | new_decl.owns_tv = true; | 4436 | new_decl.owns_tv = true; |
| 4435 | new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive. | 4437 | new_decl.alive = true; // This Decl corresponds to a File and is therefore always alive. |
src/Sema.zig+11-4| ... | @@ -8107,6 +8107,13 @@ fn funcCommon( | ... | @@ -8107,6 +8107,13 @@ fn funcCommon( |
| 8107 | for (comptime_params) |ct| is_generic = is_generic or ct; | 8107 | for (comptime_params) |ct| is_generic = is_generic or ct; |
| 8108 | is_generic = is_generic or ret_ty_requires_comptime; | 8108 | is_generic = is_generic or ret_ty_requires_comptime; |
| 8109 | 8109 | ||
| 8110 | if (!is_generic and sema.wantErrorReturnTracing(return_type)) { | ||
| 8111 | // Make sure that StackTrace's fields are resolved so that the backend can | ||
| 8112 | // lower this fn type. | ||
| 8113 | const unresolved_stack_trace_ty = try sema.getBuiltinType(block, ret_ty_src, "StackTrace"); | ||
| 8114 | _ = try sema.resolveTypeFields(block, ret_ty_src, unresolved_stack_trace_ty); | ||
| 8115 | } | ||
| 8116 | |||
| 8110 | break :fn_ty try Type.Tag.function.create(sema.arena, .{ | 8117 | break :fn_ty try Type.Tag.function.create(sema.arena, .{ |
| 8111 | .param_types = param_types, | 8118 | .param_types = param_types, |
| 8112 | .comptime_params = comptime_params.ptr, | 8119 | .comptime_params = comptime_params.ptr, |
| ... | @@ -15631,7 +15638,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir | ... | @@ -15631,7 +15638,7 @@ fn zirRetLoad(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Zir |
| 15631 | return sema.analyzeRet(block, operand, src); | 15638 | return sema.analyzeRet(block, operand, src); |
| 15632 | } | 15639 | } |
| 15633 | 15640 | ||
| 15634 | if (sema.wantErrorReturnTracing()) { | 15641 | if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) { |
| 15635 | const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr); | 15642 | const is_non_err = try sema.analyzePtrIsNonErr(block, src, ret_ptr); |
| 15636 | return retWithErrTracing(sema, block, src, is_non_err, .ret_load, ret_ptr); | 15643 | return retWithErrTracing(sema, block, src, is_non_err, .ret_load, ret_ptr); |
| 15637 | } | 15644 | } |
| ... | @@ -15698,11 +15705,11 @@ fn retWithErrTracing( | ... | @@ -15698,11 +15705,11 @@ fn retWithErrTracing( |
| 15698 | return always_noreturn; | 15705 | return always_noreturn; |
| 15699 | } | 15706 | } |
| 15700 | 15707 | ||
| 15701 | fn wantErrorReturnTracing(sema: *Sema) bool { | 15708 | fn wantErrorReturnTracing(sema: *Sema, fn_ret_ty: Type) bool { |
| 15702 | // TODO implement this feature in all the backends and then delete this check. | 15709 | // TODO implement this feature in all the backends and then delete this check. |
| 15703 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; | 15710 | const backend_supports_error_return_tracing = sema.mod.comp.bin_file.options.use_llvm; |
| 15704 | 15711 | ||
| 15705 | return sema.fn_ret_ty.isError() and | 15712 | return fn_ret_ty.isError() and |
| 15706 | sema.mod.comp.bin_file.options.error_return_tracing and | 15713 | sema.mod.comp.bin_file.options.error_return_tracing and |
| 15707 | backend_supports_error_return_tracing; | 15714 | backend_supports_error_return_tracing; |
| 15708 | } | 15715 | } |
| ... | @@ -15754,7 +15761,7 @@ fn analyzeRet( | ... | @@ -15754,7 +15761,7 @@ fn analyzeRet( |
| 15754 | 15761 | ||
| 15755 | try sema.resolveTypeLayout(block, src, sema.fn_ret_ty); | 15762 | try sema.resolveTypeLayout(block, src, sema.fn_ret_ty); |
| 15756 | 15763 | ||
| 15757 | if (sema.wantErrorReturnTracing()) { | 15764 | if (sema.wantErrorReturnTracing(sema.fn_ret_ty)) { |
| 15758 | // Avoid adding a frame to the error return trace in case the value is comptime-known | 15765 | // Avoid adding a frame to the error return trace in case the value is comptime-known |
| 15759 | // to be not an error. | 15766 | // to be not an error. |
| 15760 | const is_non_err = try sema.analyzeIsNonErr(block, src, operand); | 15767 | const is_non_err = try sema.analyzeIsNonErr(block, src, operand); |
src/codegen/llvm.zig+5-2| ... | @@ -2332,10 +2332,13 @@ pub const Object = struct { | ... | @@ -2332,10 +2332,13 @@ pub const Object = struct { |
| 2332 | // buffer is only used for int_type, `builtin` is a struct. | 2332 | // buffer is only used for int_type, `builtin` is a struct. |
| 2333 | const builtin_ty = mod.declPtr(builtin_decl).val.toType(undefined); | 2333 | const builtin_ty = mod.declPtr(builtin_decl).val.toType(undefined); |
| 2334 | const builtin_namespace = builtin_ty.getNamespace().?; | 2334 | const builtin_namespace = builtin_ty.getNamespace().?; |
| 2335 | const stack_trace_decl = builtin_namespace.decls | 2335 | const stack_trace_decl_index = builtin_namespace.decls |
| 2336 | .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?; | 2336 | .getKeyAdapted(stack_trace_str, Module.DeclAdapter{ .mod = mod }).?; |
| 2337 | const stack_trace_decl = mod.declPtr(stack_trace_decl_index); | ||
| 2337 | 2338 | ||
| 2338 | return mod.declPtr(stack_trace_decl).val.toType(undefined); | 2339 | // Sema should have ensured that StackTrace was analyzed. |
| 2340 | assert(stack_trace_decl.has_tv); | ||
| 2341 | return stack_trace_decl.val.toType(undefined); | ||
| 2339 | } | 2342 | } |
| 2340 | }; | 2343 | }; |
| 2341 | 2344 |
test/standalone.zig+2| ... | @@ -97,4 +97,6 @@ pub fn addCases(cases: *tests.StandaloneContext) void { | ... | @@ -97,4 +97,6 @@ pub fn addCases(cases: *tests.StandaloneContext) void { |
| 97 | // Disabled due to tripping LLVM 13 assertion: | 97 | // Disabled due to tripping LLVM 13 assertion: |
| 98 | // https://github.com/ziglang/zig/issues/12015 | 98 | // https://github.com/ziglang/zig/issues/12015 |
| 99 | //cases.add("tools/update_spirv_features.zig"); | 99 | //cases.add("tools/update_spirv_features.zig"); |
| 100 | |||
| 101 | cases.addBuildFile("test/standalone/issue_13030/build.zig", .{ .build_modes = true }); | ||
| 100 | } | 102 | } |
test/standalone/issue_13030/build.zig created+18| ... | @@ -0,0 +1,18 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const builtin = @import("builtin"); | ||
| 3 | const Builder = std.build.Builder; | ||
| 4 | const CrossTarget = std.zig.CrossTarget; | ||
| 5 | |||
| 6 | pub fn build(b: *Builder) void { | ||
| 7 | const mode = b.standardReleaseOptions(); | ||
| 8 | const target = b.standardTargetOptions(.{}); | ||
| 9 | |||
| 10 | const obj = b.addObject("main", "main.zig"); | ||
| 11 | obj.setBuildMode(mode); | ||
| 12 | |||
| 13 | obj.setTarget(target); | ||
| 14 | b.default_step.dependOn(&obj.step); | ||
| 15 | |||
| 16 | const test_step = b.step("test", "Test the program"); | ||
| 17 | test_step.dependOn(&obj.step); | ||
| 18 | } | ||
test/standalone/issue_13030/main.zig created+7| ... | @@ -0,0 +1,7 @@ | ||
| 1 | fn b(comptime T: type) ?*const fn () error{}!T { | ||
| 2 | return null; | ||
| 3 | } | ||
| 4 | |||
| 5 | export fn entry() void { | ||
| 6 | _ = b(void); | ||
| 7 | } | ||