| author | |
| committer | |
| log | c83ab7cc6a7d779eecd51eb10c46d1242aaf1d9d |
| tree | 0a079e25b35539cfa169cb529eec278c15003d4c |
| parent | 7baf0de807afc8c2c56cc1278e624e9103c30cfb |
| parent | bd8b5c25ece2fa158196381004db6e655226576c |
| signature |
Sema: emit error for always_inline call of noinline function4 files changed, 38 insertions(+), 7 deletions(-)
lib/std/builtin.zig+1-1| ... | ... | @@ -646,7 +646,7 @@ pub const CallModifier = enum { |
| 646 | 646 | /// If this is not possible, a compile error is emitted instead. |
| 647 | 647 | always_tail, |
| 648 | 648 | |
| 649 | /// Guarantees that the call will inlined at the callsite. | |
| 649 | /// Guarantees that the call will be inlined at the callsite. | |
| 650 | 650 | /// If this is not possible, a compile error is emitted instead. |
| 651 | 651 | always_inline, |
| 652 | 652 |
src/Sema.zig+8-2| ... | ... | @@ -6565,7 +6565,10 @@ fn analyzeCall( |
| 6565 | 6565 | }; |
| 6566 | 6566 | |
| 6567 | 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 | 6574 | const gpa = sema.gpa; |
| ... | ... | @@ -8784,7 +8787,8 @@ fn funcCommon( |
| 8784 | 8787 | if (!is_generic and block.params.items.len == 0 and !var_args and !inferred_error_set and |
| 8785 | 8788 | alignment.? == 0 and |
| 8786 | 8789 | address_space.? == target_util.defaultAddressSpace(target, .function) and |
| 8787 | section == .default) | |
| 8790 | section == .default and | |
| 8791 | !is_noinline) | |
| 8788 | 8792 | { |
| 8789 | 8793 | if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Unspecified) { |
| 8790 | 8794 | break :fn_ty Type.initTag(.fn_noreturn_no_args); |
| ... | ... | @@ -9002,6 +9006,7 @@ fn funcCommon( |
| 9002 | 9006 | .addrspace_is_generic = address_space == null, |
| 9003 | 9007 | .is_var_args = var_args, |
| 9004 | 9008 | .is_generic = is_generic, |
| 9009 | .is_noinline = is_noinline, | |
| 9005 | 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 | 19222 | .cc = cc, |
| 19218 | 19223 | .is_var_args = is_var_args, |
| 19219 | 19224 | .is_generic = false, |
| 19225 | .is_noinline = false, | |
| 19220 | 19226 | .align_is_generic = false, |
| 19221 | 19227 | .cc_is_generic = false, |
| 19222 | 19228 | .section_is_generic = false, |
src/type.zig+13| ... | ... | @@ -666,6 +666,9 @@ pub const Type = extern union { |
| 666 | 666 | if (a_info.is_generic != b_info.is_generic) |
| 667 | 667 | return false; |
| 668 | 668 | |
| 669 | if (a_info.is_noinline != b_info.is_noinline) | |
| 670 | return false; | |
| 671 | ||
| 669 | 672 | if (a_info.noalias_bits != b_info.noalias_bits) |
| 670 | 673 | return false; |
| 671 | 674 | |
| ... | ... | @@ -1074,6 +1077,7 @@ pub const Type = extern union { |
| 1074 | 1077 | } |
| 1075 | 1078 | std.hash.autoHash(hasher, fn_info.is_var_args); |
| 1076 | 1079 | std.hash.autoHash(hasher, fn_info.is_generic); |
| 1080 | std.hash.autoHash(hasher, fn_info.is_noinline); | |
| 1077 | 1081 | std.hash.autoHash(hasher, fn_info.noalias_bits); |
| 1078 | 1082 | |
| 1079 | 1083 | std.hash.autoHash(hasher, fn_info.param_types.len); |
| ... | ... | @@ -1454,6 +1458,7 @@ pub const Type = extern union { |
| 1454 | 1458 | .alignment = payload.alignment, |
| 1455 | 1459 | .is_var_args = payload.is_var_args, |
| 1456 | 1460 | .is_generic = payload.is_generic, |
| 1461 | .is_noinline = payload.is_noinline, | |
| 1457 | 1462 | .comptime_params = comptime_params.ptr, |
| 1458 | 1463 | .align_is_generic = payload.align_is_generic, |
| 1459 | 1464 | .cc_is_generic = payload.cc_is_generic, |
| ... | ... | @@ -2069,6 +2074,9 @@ pub const Type = extern union { |
| 2069 | 2074 | |
| 2070 | 2075 | .function => { |
| 2071 | 2076 | const fn_info = ty.fnInfo(); |
| 2077 | if (fn_info.is_noinline) { | |
| 2078 | try writer.writeAll("noinline "); | |
| 2079 | } | |
| 2072 | 2080 | try writer.writeAll("fn("); |
| 2073 | 2081 | for (fn_info.param_types, 0..) |param_ty, i| { |
| 2074 | 2082 | if (i != 0) try writer.writeAll(", "); |
| ... | ... | @@ -4863,6 +4871,7 @@ pub const Type = extern union { |
| 4863 | 4871 | .alignment = 0, |
| 4864 | 4872 | .is_var_args = false, |
| 4865 | 4873 | .is_generic = false, |
| 4874 | .is_noinline = false, | |
| 4866 | 4875 | .align_is_generic = false, |
| 4867 | 4876 | .cc_is_generic = false, |
| 4868 | 4877 | .section_is_generic = false, |
| ... | ... | @@ -4877,6 +4886,7 @@ pub const Type = extern union { |
| 4877 | 4886 | .alignment = 0, |
| 4878 | 4887 | .is_var_args = false, |
| 4879 | 4888 | .is_generic = false, |
| 4889 | .is_noinline = false, | |
| 4880 | 4890 | .align_is_generic = false, |
| 4881 | 4891 | .cc_is_generic = false, |
| 4882 | 4892 | .section_is_generic = false, |
| ... | ... | @@ -4891,6 +4901,7 @@ pub const Type = extern union { |
| 4891 | 4901 | .alignment = 0, |
| 4892 | 4902 | .is_var_args = false, |
| 4893 | 4903 | .is_generic = false, |
| 4904 | .is_noinline = false, | |
| 4894 | 4905 | .align_is_generic = false, |
| 4895 | 4906 | .cc_is_generic = false, |
| 4896 | 4907 | .section_is_generic = false, |
| ... | ... | @@ -4905,6 +4916,7 @@ pub const Type = extern union { |
| 4905 | 4916 | .alignment = 0, |
| 4906 | 4917 | .is_var_args = false, |
| 4907 | 4918 | .is_generic = false, |
| 4919 | .is_noinline = false, | |
| 4908 | 4920 | .align_is_generic = false, |
| 4909 | 4921 | .cc_is_generic = false, |
| 4910 | 4922 | .section_is_generic = false, |
| ... | ... | @@ -6367,6 +6379,7 @@ pub const Type = extern union { |
| 6367 | 6379 | cc: std.builtin.CallingConvention, |
| 6368 | 6380 | is_var_args: bool, |
| 6369 | 6381 | is_generic: bool, |
| 6382 | is_noinline: bool, | |
| 6370 | 6383 | align_is_generic: bool, |
| 6371 | 6384 | cc_is_generic: bool, |
| 6372 | 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 | var baz = if (c) &baz1 else &baz2; |
| 15 | 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 | 23 | pub export fn entry() void { |
| 18 | 24 | var call_me: *const fn () void = undefined; |
| 19 | 25 | @call(.always_inline, call_me, .{}); |
| 20 | 26 | } |
| 27 | ||
| 21 | 28 | fn foo() void {} |
| 22 | fn bar() callconv(.Inline) void {} | |
| 29 | inline fn bar() void {} | |
| 23 | 30 | fn baz1() void {} |
| 24 | 31 | fn baz2() void {} |
| 32 | noinline fn dummy() u32 { | |
| 33 | return 0; | |
| 34 | } | |
| 35 | noinline fn dummy2() void {} | |
| 25 | 36 | |
| 26 | 37 | // error |
| 27 | 38 | // backend=stage2 |
| ... | ... | @@ -30,7 +41,8 @@ fn baz2() void {} |
| 30 | 41 | // :2:23: error: expected a tuple, found 'void' |
| 31 | 42 | // :5:21: error: unable to perform 'never_inline' call at compile-time |
| 32 | 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 | 45 | // :15:26: error: modifier 'compile_time' requires a comptime-known function |
| 35 | // :19:27: error: modifier 'always_inline' requires a comptime-known function | |
| 36 | ||
| 46 | // :18:9: error: 'always_inline' call of noinline function | |
| 47 | // :21:9: error: 'always_inline' call of noinline function | |
| 48 | // :25:27: error: modifier 'always_inline' requires a comptime-known function |