authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-04-29 11:13:51-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-04-29 11:13:51-07:00
logc83ab7cc6a7d779eecd51eb10c46d1242aaf1d9d
tree0a079e25b35539cfa169cb529eec278c15003d4c
parent7baf0de807afc8c2c56cc1278e624e9103c30cfb
parentbd8b5c25ece2fa158196381004db6e655226576c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #15503 from r00ster91/noinline

Sema: emit error for always_inline call of noinline function

4 files changed, 38 insertions(+), 7 deletions(-)

lib/std/builtin.zig+1-1
......@@ -646,7 +646,7 @@ pub const CallModifier = enum {
646646 /// If this is not possible, a compile error is emitted instead.
647647 always_tail,
648648
649 /// Guarantees that the call will inlined at the callsite.
649 /// Guarantees that the call will be inlined at the callsite.
650650 /// If this is not possible, a compile error is emitted instead.
651651 always_inline,
652652
src/Sema.zig+8-2
......@@ -6565,7 +6565,10 @@ fn analyzeCall(
65656565 };
65666566
65676567 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", .{});
65696572 }
65706573
65716574 const gpa = sema.gpa;
......@@ -8784,7 +8787,8 @@ fn funcCommon(
87848787 if (!is_generic and block.params.items.len == 0 and !var_args and !inferred_error_set and
87858788 alignment.? == 0 and
87868789 address_space.? == target_util.defaultAddressSpace(target, .function) and
8787 section == .default)
8790 section == .default and
8791 !is_noinline)
87888792 {
87898793 if (bare_return_type.zigTypeTag() == .NoReturn and cc.? == .Unspecified) {
87908794 break :fn_ty Type.initTag(.fn_noreturn_no_args);
......@@ -9002,6 +9006,7 @@ fn funcCommon(
90029006 .addrspace_is_generic = address_space == null,
90039007 .is_var_args = var_args,
90049008 .is_generic = is_generic,
9009 .is_noinline = is_noinline,
90059010 .noalias_bits = noalias_bits,
90069011 });
90079012 };
......@@ -19217,6 +19222,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in
1921719222 .cc = cc,
1921819223 .is_var_args = is_var_args,
1921919224 .is_generic = false,
19225 .is_noinline = false,
1922019226 .align_is_generic = false,
1922119227 .cc_is_generic = false,
1922219228 .section_is_generic = false,
src/type.zig+13
......@@ -666,6 +666,9 @@ pub const Type = extern union {
666666 if (a_info.is_generic != b_info.is_generic)
667667 return false;
668668
669 if (a_info.is_noinline != b_info.is_noinline)
670 return false;
671
669672 if (a_info.noalias_bits != b_info.noalias_bits)
670673 return false;
671674
......@@ -1074,6 +1077,7 @@ pub const Type = extern union {
10741077 }
10751078 std.hash.autoHash(hasher, fn_info.is_var_args);
10761079 std.hash.autoHash(hasher, fn_info.is_generic);
1080 std.hash.autoHash(hasher, fn_info.is_noinline);
10771081 std.hash.autoHash(hasher, fn_info.noalias_bits);
10781082
10791083 std.hash.autoHash(hasher, fn_info.param_types.len);
......@@ -1454,6 +1458,7 @@ pub const Type = extern union {
14541458 .alignment = payload.alignment,
14551459 .is_var_args = payload.is_var_args,
14561460 .is_generic = payload.is_generic,
1461 .is_noinline = payload.is_noinline,
14571462 .comptime_params = comptime_params.ptr,
14581463 .align_is_generic = payload.align_is_generic,
14591464 .cc_is_generic = payload.cc_is_generic,
......@@ -2069,6 +2074,9 @@ pub const Type = extern union {
20692074
20702075 .function => {
20712076 const fn_info = ty.fnInfo();
2077 if (fn_info.is_noinline) {
2078 try writer.writeAll("noinline ");
2079 }
20722080 try writer.writeAll("fn(");
20732081 for (fn_info.param_types, 0..) |param_ty, i| {
20742082 if (i != 0) try writer.writeAll(", ");
......@@ -4863,6 +4871,7 @@ pub const Type = extern union {
48634871 .alignment = 0,
48644872 .is_var_args = false,
48654873 .is_generic = false,
4874 .is_noinline = false,
48664875 .align_is_generic = false,
48674876 .cc_is_generic = false,
48684877 .section_is_generic = false,
......@@ -4877,6 +4886,7 @@ pub const Type = extern union {
48774886 .alignment = 0,
48784887 .is_var_args = false,
48794888 .is_generic = false,
4889 .is_noinline = false,
48804890 .align_is_generic = false,
48814891 .cc_is_generic = false,
48824892 .section_is_generic = false,
......@@ -4891,6 +4901,7 @@ pub const Type = extern union {
48914901 .alignment = 0,
48924902 .is_var_args = false,
48934903 .is_generic = false,
4904 .is_noinline = false,
48944905 .align_is_generic = false,
48954906 .cc_is_generic = false,
48964907 .section_is_generic = false,
......@@ -4905,6 +4916,7 @@ pub const Type = extern union {
49054916 .alignment = 0,
49064917 .is_var_args = false,
49074918 .is_generic = false,
4919 .is_noinline = false,
49084920 .align_is_generic = false,
49094921 .cc_is_generic = false,
49104922 .section_is_generic = false,
......@@ -6367,6 +6379,7 @@ pub const Type = extern union {
63676379 cc: std.builtin.CallingConvention,
63686380 is_var_args: bool,
63696381 is_generic: bool,
6382 is_noinline: bool,
63706383 align_is_generic: bool,
63716384 cc_is_generic: bool,
63726385 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 {
1414 var baz = if (c) &baz1 else &baz2;
1515 @call(.compile_time, baz, .{});
1616}
17export fn entry6() void {
18 _ = @call(.always_inline, dummy, .{});
19}
20export fn entry7() void {
21 _ = @call(.always_inline, dummy2, .{});
22}
1723pub export fn entry() void {
1824 var call_me: *const fn () void = undefined;
1925 @call(.always_inline, call_me, .{});
2026}
27
2128fn foo() void {}
22fn bar() callconv(.Inline) void {}
29inline fn bar() void {}
2330fn baz1() void {}
2431fn baz2() void {}
32noinline fn dummy() u32 {
33 return 0;
34}
35noinline fn dummy2() void {}
2536
2637// error
2738// backend=stage2
......@@ -30,7 +41,8 @@ fn baz2() void {}
3041// :2:23: error: expected a tuple, found 'void'
3142// :5:21: error: unable to perform 'never_inline' call at compile-time
3243// :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
3445// :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