Commit e4e3d7ab41

Alex Rønne Petersen <alex@alexrp.com>
2024-10-28 21:57:29
Sema: Disallow calling functions with certain special calling conventions.
1 parent f508e22
Changed files (2)
src/Sema.zig
@@ -7574,13 +7574,13 @@ fn analyzeCall(
     if (try sema.resolveValue(func)) |func_val|
         if (func_val.isUndef(zcu))
             return sema.failWithUseOfUndef(block, call_src);
-    if (cc == .naked) {
+    if (!callConvIsCallable(cc)) {
         const maybe_func_inst = try sema.funcDeclSrcInst(func);
         const msg = msg: {
             const msg = try sema.errMsg(
                 func_src,
-                "unable to call function with naked calling convention",
-                .{},
+                "unable to call function with calling convention '{s}'",
+                .{@tagName(cc)},
             );
             errdefer msg.destroy(sema.gpa);
 
@@ -9764,6 +9764,33 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:
     }
 }
 
+fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
+    return switch (cc) {
+        .naked,
+
+        .arm_interrupt,
+        .avr_interrupt,
+        .avr_signal,
+        .csky_interrupt,
+        .m68k_interrupt,
+        .mips_interrupt,
+        .mips64_interrupt,
+        .riscv32_interrupt,
+        .riscv64_interrupt,
+        .x86_interrupt,
+        .x86_64_interrupt,
+
+        .amdgcn_kernel,
+        .nvptx_kernel,
+        .spirv_kernel,
+        .spirv_fragment,
+        .spirv_vertex,
+        => false,
+
+        else => true,
+    };
+}
+
 fn checkMergeAllowed(sema: *Sema, block: *Block, src: LazySrcLoc, peer_ty: Type) !void {
     const pt = sema.pt;
     const zcu = pt.zcu;
test/cases/compile_errors/calling_function_with_naked_calling_convention.zig
@@ -1,11 +1,11 @@
 export fn entry() void {
     foo();
 }
-fn foo() callconv(.Naked) void {}
+fn foo() callconv(.naked) void {}
 
 // error
 // backend=llvm
 // target=native
 //
-// :2:5: error: unable to call function with naked calling convention
+// :2:5: error: unable to call function with calling convention 'naked'
 // :4:1: note: function declared here