From 6b9dc82fa596ac2470810bfda53d61e2add93d33 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Wed, 7 Oct 2020 17:38:42 -0600 Subject: stage1: Compile error instead of falling back to C for unsupported cc --- src/stage1/analyze.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'src/stage1/analyze.cpp') diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index 547d2d9ae2..57239b6c4a 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -1880,6 +1880,58 @@ ZigType *get_auto_err_set_type(CodeGen *g, ZigFn *fn_entry) { return err_set_type; } +// Sync this with get_llvm_cc in codegen.cpp +static Error emit_error_unless_callconv_allowed_for_target(CodeGen *g, AstNode *source_node, CallingConvention cc) { + Error ret = ErrorNone; + const char *allowed_platforms = nullptr; + switch (cc) { + case CallingConventionUnspecified: + case CallingConventionC: + case CallingConventionNaked: + case CallingConventionAsync: + break; + case CallingConventionInterrupt: + if (g->zig_target->arch != ZigLLVM_x86 + && g->zig_target->arch != ZigLLVM_x86_64 + && g->zig_target->arch != ZigLLVM_avr + && g->zig_target->arch != ZigLLVM_msp430) + { + allowed_platforms = "x86, x86_64, AVR, and MS430"; + } + break; + case CallingConventionSignal: + if (g->zig_target->arch != ZigLLVM_avr) + allowed_platforms = "AVR"; + break; + case CallingConventionStdcall: + case CallingConventionFastcall: + case CallingConventionThiscall: + if (g->zig_target->arch != ZigLLVM_x86) + allowed_platforms = "x86"; + break; + case CallingConventionVectorcall: + if (g->zig_target->arch != ZigLLVM_x86 + && !(target_is_arm(g->zig_target) && target_arch_pointer_bit_width(g->zig_target->arch) == 64)) + { + allowed_platforms = "x86 and AArch64"; + } + break; + case CallingConventionAPCS: + case CallingConventionAAPCS: + case CallingConventionAAPCSVFP: + if (!target_is_arm(g->zig_target)) + allowed_platforms = "ARM"; + } + if (allowed_platforms != nullptr) { + add_node_error(g, source_node, buf_sprintf( + "callconv '%s' is only available on %s, not %s", + calling_convention_name(cc), allowed_platforms, + target_arch_name(g->zig_target->arch))); + ret = ErrorSemanticAnalyzeFail; + } + return ret; +} + static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_scope, ZigFn *fn_entry, CallingConvention cc) { @@ -2014,6 +2066,9 @@ static ZigType *analyze_fn_type(CodeGen *g, AstNode *proto_node, Scope *child_sc fn_entry->align_bytes = fn_type_id.alignment; } + if ((err = emit_error_unless_callconv_allowed_for_target(g, proto_node, cc))) + return g->builtin_types.entry_invalid; + if (fn_proto->return_anytype_token != nullptr) { if (!calling_convention_allows_zig_types(fn_type_id.cc)) { add_node_error(g, fn_proto->return_type, -- cgit v1.2.3