diff --git a/src/analyze.cpp b/src/analyze.cpp index dece277c0..7d75bef7d 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -3333,21 +3333,15 @@ void add_var_export(CodeGen *g, ZigVar *var, const char *symbol_name, GlobalLink global_export->linkage = linkage; } -void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, bool ccc) { - if (ccc) { - if (strcmp(symbol_name, "main") == 0 && g->libc_link_lib != nullptr) { - g->have_c_main = true; - } else if (strcmp(symbol_name, "WinMain") == 0 && - g->zig_target->os == OsWindows) - { +void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc) { + if (cc == CallingConventionC && strcmp(symbol_name, "main") == 0 && g->libc_link_lib != nullptr) { + g->have_c_main = true; + } else if (cc == CallingConventionStdcall && g->zig_target->os == OsWindows) { + if (strcmp(symbol_name, "WinMain") == 0) { g->have_winmain = true; - } else if (strcmp(symbol_name, "WinMainCRTStartup") == 0 && - g->zig_target->os == OsWindows) - { + } else if (strcmp(symbol_name, "WinMainCRTStartup") == 0) { g->have_winmain_crt_startup = true; - } else if (strcmp(symbol_name, "DllMainCRTStartup") == 0 && - g->zig_target->os == OsWindows) - { + } else if (strcmp(symbol_name, "DllMainCRTStartup") == 0) { g->have_dllmain_crt_startup = true; } } @@ -3377,8 +3371,24 @@ static void resolve_decl_fn(CodeGen *g, TldFn *tld_fn) { } if (fn_proto->is_export) { - bool ccc = (fn_proto->cc == CallingConventionUnspecified || fn_proto->cc == CallingConventionC); - add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), GlobalLinkageIdStrong, ccc); + switch (fn_proto->cc) { + case CallingConventionAsync: { + add_node_error(g, fn_def_node, + buf_sprintf("exported function cannot be async")); + } break; + case CallingConventionC: + case CallingConventionNaked: + case CallingConventionCold: + case CallingConventionStdcall: + case CallingConventionUnspecified: + // An exported function without a specific calling + // convention defaults to C + CallingConvention cc = (fn_proto->cc != CallingConventionUnspecified) ? + fn_proto->cc : CallingConventionC; + add_fn_export(g, fn_table_entry, buf_ptr(&fn_table_entry->symbol_name), + GlobalLinkageIdStrong, cc); + break; + } } if (!is_extern) { diff --git a/src/analyze.hpp b/src/analyze.hpp index afcadd828..05eb97139 100644 --- a/src/analyze.hpp +++ b/src/analyze.hpp @@ -202,7 +202,7 @@ ZigType *get_align_amt_type(CodeGen *g); ZigPackage *new_anonymous_package(void); Buf *const_value_to_buffer(ZigValue *const_val); -void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, bool ccc); +void add_fn_export(CodeGen *g, ZigFn *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage, CallingConvention cc); void add_var_export(CodeGen *g, ZigVar *fn_table_entry, const char *symbol_name, GlobalLinkageId linkage); diff --git a/src/ir.cpp b/src/ir.cpp index 044caa4d4..50479c1ab 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16134,8 +16134,7 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio case CallingConventionNaked: case CallingConventionCold: case CallingConventionStdcall: - add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, - cc == CallingConventionC); + add_fn_export(ira->codegen, fn_entry, buf_ptr(symbol_name), global_linkage_id, cc); break; } } break; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 26290b944..65ff8e454 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,10 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + \\export async fn foo() void {} + , "tmp.zig:1:1: error: exported function cannot be async"); + cases.addCase(x: { var tc = cases.create("@newStackCall on unsupported target", \\export fn entry() void {