| author | |
| committer | |
| log | bd8b5c25ece2fa158196381004db6e655226576c |
| tree | 770abdc5199160fa4cb5b2eafb0baa06a300e2cd |
| parent | 0c9c9117bacfcff2b11ab658b89f192e27fc7c3d |
Fixes #15489
This also lays the groundwork for exposing the whether or not a function is
noinline in std.builtin.Fn as an `is_noinline: bool` field if we ever want to do that.3 files changed, 37 insertions(+), 6 deletions(-)
src/Sema.zig+8-2| ... | @@ -6565,7 +6565,10 @@ fn analyzeCall( | ... | @@ -6565,7 +6565,10 @@ fn analyzeCall( |
| 6565 | }; | 6565 | }; |
| 6566 | 6566 | ||
| 6567 | if (modifier == .never_inline and func_ty_info.cc == .Inline) { | 6567 | if (modifier == .never_inline and func_ty_info.cc == .Inline) { |
| 6568 | return sema.fail(block, call_src, "no-inline call of inline function", .{}); | 6568 | return sema.fail(block, call_src, "'never_inline' call of inline function", .{}); |
| 6569 | } | ||
| 6570 | if (modifier == .always_inline and func_ty_info.is_noinline) { | ||
| 6571 | return sema.fail(block, call_src, "'always_inline' call of noinline function", .{}); | ||
| 6569 | } | 6572 | } |
| 6570 | 6573 | ||
| 6571 | const gpa = sema.gpa; | 6574 | const gpa = sema.gpa; |
| ... | @@ -8784,7 +8787,8 @@ fn funcCommon( | ... | @@ -8784,7 +8787,8 @@ fn funcCommon( |
| 8784 | if (!is_generic and block.params.items.len == 0 and !var_args and !inferred_error_set and | 8787 | if (!is_generic and block.params.items.len == 0 and !var_args and !inferred_error_set and |
| 8785 | alignment.? == 0 and | 8788 | alignment.? == 0 and |
| 8786 | address_space.? == target_util.defaultAddressSpace(target, .function) and | 8789 | address_space.? == target_util.defaultAddressSpace(target, .function) and |
| 8787 | section == .default) | 8790 | section == .default and |
| 8791 | !is_noinline) | ||
| 8788 | { | 8792 | { |
| 8789 | if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Unspecified) { | 8793 | if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Unspecified) { |
| 8790 | break :fn_ty Type.initTag(.fn_noreturn_no_args); | 8794 | break :fn_ty Type.initTag(.fn_noreturn_no_args); |
| ... | @@ -9002,6 +9006,7 @@ fn funcCommon( | ... | @@ -9002,6 +9006,7 @@ fn funcCommon( |
| 9002 | .addrspace_is_generic = address_space == null, | 9006 | .addrspace_is_generic = address_space == null, |
| 9003 | .is_var_args = var_args, | 9007 | .is_var_args = var_args, |
| 9004 | .is_generic = is_generic, | 9008 | .is_generic = is_generic, |
| 9009 | .is_noinline = is_noinline, | ||
| 9005 | .noalias_bits = noalias_bits, | 9010 | .noalias_bits = noalias_bits, |
| 9006 | }); | 9011 | }); |
| 9007 | }; | 9012 | }; |
| ... | @@ -19217,6 +19222,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in | ... | @@ -19217,6 +19222,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in |
| 19217 | .cc = cc, | 19222 | .cc = cc, |
| 19218 | .is_var_args = is_var_args, | 19223 | .is_var_args = is_var_args, |
| 19219 | .is_generic = false, | 19224 | .is_generic = false, |
| 19225 | .is_noinline = false, | ||
| 19220 | .align_is_generic = false, | 19226 | .align_is_generic = false, |
| 19221 | .cc_is_generic = false, | 19227 | .cc_is_generic = false, |
| 19222 | .section_is_generic = false, | 19228 | .section_is_generic = false, |
src/type.zig+13| ... | @@ -666,6 +666,9 @@ pub const Type = extern union { | ... | @@ -666,6 +666,9 @@ pub const Type = extern union { |
| 666 | if (a_info.is_generic != b_info.is_generic) | 666 | if (a_info.is_generic != b_info.is_generic) |
| 667 | return false; | 667 | return false; |
| 668 | 668 | ||
| 669 | if (a_info.is_noinline != b_info.is_noinline) | ||
| 670 | return false; | ||
| 671 | |||
| 669 | if (a_info.noalias_bits != b_info.noalias_bits) | 672 | if (a_info.noalias_bits != b_info.noalias_bits) |
| 670 | return false; | 673 | return false; |
| 671 | 674 | ||
| ... | @@ -1074,6 +1077,7 @@ pub const Type = extern union { | ... | @@ -1074,6 +1077,7 @@ pub const Type = extern union { |
| 1074 | } | 1077 | } |
| 1075 | std.hash.autoHash(hasher, fn_info.is_var_args); | 1078 | std.hash.autoHash(hasher, fn_info.is_var_args); |
| 1076 | std.hash.autoHash(hasher, fn_info.is_generic); | 1079 | std.hash.autoHash(hasher, fn_info.is_generic); |
| 1080 | std.hash.autoHash(hasher, fn_info.is_noinline); | ||
| 1077 | std.hash.autoHash(hasher, fn_info.noalias_bits); | 1081 | std.hash.autoHash(hasher, fn_info.noalias_bits); |
| 1078 | 1082 | ||
| 1079 | std.hash.autoHash(hasher, fn_info.param_types.len); | 1083 | std.hash.autoHash(hasher, fn_info.param_types.len); |
| ... | @@ -1454,6 +1458,7 @@ pub const Type = extern union { | ... | @@ -1454,6 +1458,7 @@ pub const Type = extern union { |
| 1454 | .alignment = payload.alignment, | 1458 | .alignment = payload.alignment, |
| 1455 | .is_var_args = payload.is_var_args, | 1459 | .is_var_args = payload.is_var_args, |
| 1456 | .is_generic = payload.is_generic, | 1460 | .is_generic = payload.is_generic, |
| 1461 | .is_noinline = payload.is_noinline, | ||
| 1457 | .comptime_params = comptime_params.ptr, | 1462 | .comptime_params = comptime_params.ptr, |
| 1458 | .align_is_generic = payload.align_is_generic, | 1463 | .align_is_generic = payload.align_is_generic, |
| 1459 | .cc_is_generic = payload.cc_is_generic, | 1464 | .cc_is_generic = payload.cc_is_generic, |
| ... | @@ -2069,6 +2074,9 @@ pub const Type = extern union { | ... | @@ -2069,6 +2074,9 @@ pub const Type = extern union { |
| 2069 | 2074 | ||
| 2070 | .function => { | 2075 | .function => { |
| 2071 | const fn_info = ty.fnInfo(); | 2076 | const fn_info = ty.fnInfo(); |
| 2077 | if (fn_info.is_noinline) { | ||
| 2078 | try writer.writeAll("noinline "); | ||
| 2079 | } | ||
| 2072 | try writer.writeAll("fn("); | 2080 | try writer.writeAll("fn("); |
| 2073 | for (fn_info.param_types, 0..) |param_ty, i| { | 2081 | for (fn_info.param_types, 0..) |param_ty, i| { |
| 2074 | if (i != 0) try writer.writeAll(", "); | 2082 | if (i != 0) try writer.writeAll(", "); |
| ... | @@ -4863,6 +4871,7 @@ pub const Type = extern union { | ... | @@ -4863,6 +4871,7 @@ pub const Type = extern union { |
| 4863 | .alignment = 0, | 4871 | .alignment = 0, |
| 4864 | .is_var_args = false, | 4872 | .is_var_args = false, |
| 4865 | .is_generic = false, | 4873 | .is_generic = false, |
| 4874 | .is_noinline = false, | ||
| 4866 | .align_is_generic = false, | 4875 | .align_is_generic = false, |
| 4867 | .cc_is_generic = false, | 4876 | .cc_is_generic = false, |
| 4868 | .section_is_generic = false, | 4877 | .section_is_generic = false, |
| ... | @@ -4877,6 +4886,7 @@ pub const Type = extern union { | ... | @@ -4877,6 +4886,7 @@ pub const Type = extern union { |
| 4877 | .alignment = 0, | 4886 | .alignment = 0, |
| 4878 | .is_var_args = false, | 4887 | .is_var_args = false, |
| 4879 | .is_generic = false, | 4888 | .is_generic = false, |
| 4889 | .is_noinline = false, | ||
| 4880 | .align_is_generic = false, | 4890 | .align_is_generic = false, |
| 4881 | .cc_is_generic = false, | 4891 | .cc_is_generic = false, |
| 4882 | .section_is_generic = false, | 4892 | .section_is_generic = false, |
| ... | @@ -4891,6 +4901,7 @@ pub const Type = extern union { | ... | @@ -4891,6 +4901,7 @@ pub const Type = extern union { |
| 4891 | .alignment = 0, | 4901 | .alignment = 0, |
| 4892 | .is_var_args = false, | 4902 | .is_var_args = false, |
| 4893 | .is_generic = false, | 4903 | .is_generic = false, |
| 4904 | .is_noinline = false, | ||
| 4894 | .align_is_generic = false, | 4905 | .align_is_generic = false, |
| 4895 | .cc_is_generic = false, | 4906 | .cc_is_generic = false, |
| 4896 | .section_is_generic = false, | 4907 | .section_is_generic = false, |
| ... | @@ -4905,6 +4916,7 @@ pub const Type = extern union { | ... | @@ -4905,6 +4916,7 @@ pub const Type = extern union { |
| 4905 | .alignment = 0, | 4916 | .alignment = 0, |
| 4906 | .is_var_args = false, | 4917 | .is_var_args = false, |
| 4907 | .is_generic = false, | 4918 | .is_generic = false, |
| 4919 | .is_noinline = false, | ||
| 4908 | .align_is_generic = false, | 4920 | .align_is_generic = false, |
| 4909 | .cc_is_generic = false, | 4921 | .cc_is_generic = false, |
| 4910 | .section_is_generic = false, | 4922 | .section_is_generic = false, |
| ... | @@ -6367,6 +6379,7 @@ pub const Type = extern union { | ... | @@ -6367,6 +6379,7 @@ pub const Type = extern union { |
| 6367 | cc: std.builtin.CallingConvention, | 6379 | cc: std.builtin.CallingConvention, |
| 6368 | is_var_args: bool, | 6380 | is_var_args: bool, |
| 6369 | is_generic: bool, | 6381 | is_generic: bool, |
| 6382 | is_noinline: bool, | ||
| 6370 | align_is_generic: bool, | 6383 | align_is_generic: bool, |
| 6371 | cc_is_generic: bool, | 6384 | cc_is_generic: bool, |
| 6372 | section_is_generic: bool, | 6385 | section_is_generic: bool, |
test/cases/compile_errors/bad_usage_of_call.zig+16-4| ... | @@ -14,14 +14,25 @@ export fn entry5(c: bool) void { | ... | @@ -14,14 +14,25 @@ export fn entry5(c: bool) void { |
| 14 | var baz = if (c) &baz1 else &baz2; | 14 | var baz = if (c) &baz1 else &baz2; |
| 15 | @call(.compile_time, baz, .{}); | 15 | @call(.compile_time, baz, .{}); |
| 16 | } | 16 | } |
| 17 | export fn entry6() void { | ||
| 18 | _ = @call(.always_inline, dummy, .{}); | ||
| 19 | } | ||
| 20 | export fn entry7() void { | ||
| 21 | _ = @call(.always_inline, dummy2, .{}); | ||
| 22 | } | ||
| 17 | pub export fn entry() void { | 23 | pub export fn entry() void { |
| 18 | var call_me: *const fn () void = undefined; | 24 | var call_me: *const fn () void = undefined; |
| 19 | @call(.always_inline, call_me, .{}); | 25 | @call(.always_inline, call_me, .{}); |
| 20 | } | 26 | } |
| 27 | |||
| 21 | fn foo() void {} | 28 | fn foo() void {} |
| 22 | fn bar() callconv(.Inline) void {} | 29 | inline fn bar() void {} |
| 23 | fn baz1() void {} | 30 | fn baz1() void {} |
| 24 | fn baz2() void {} | 31 | fn baz2() void {} |
| 32 | noinline fn dummy() u32 { | ||
| 33 | return 0; | ||
| 34 | } | ||
| 35 | noinline fn dummy2() void {} | ||
| 25 | 36 | ||
| 26 | // error | 37 | // error |
| 27 | // backend=stage2 | 38 | // backend=stage2 |
| ... | @@ -30,7 +41,8 @@ fn baz2() void {} | ... | @@ -30,7 +41,8 @@ fn baz2() void {} |
| 30 | // :2:23: error: expected a tuple, found 'void' | 41 | // :2:23: error: expected a tuple, found 'void' |
| 31 | // :5:21: error: unable to perform 'never_inline' call at compile-time | 42 | // :5:21: error: unable to perform 'never_inline' call at compile-time |
| 32 | // :8:21: error: unable to perform 'never_tail' call at compile-time | 43 | // :8:21: error: unable to perform 'never_tail' call at compile-time |
| 33 | // :11:5: error: no-inline call of inline function | 44 | // :11:5: error: 'never_inline' call of inline function |
| 34 | // :15:26: error: modifier 'compile_time' requires a comptime-known function | 45 | // :15:26: error: modifier 'compile_time' requires a comptime-known function |
| 35 | // :19:27: error: modifier 'always_inline' requires a comptime-known function | 46 | // :18:9: error: 'always_inline' call of noinline function |
| 36 | 47 | // :21:9: error: 'always_inline' call of noinline function | |
| 48 | // :25:27: error: modifier 'always_inline' requires a comptime-known function |