diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 90048f004..e87c75e88 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -765,8 +765,10 @@ gb_internal bool check_builtin_c_procedure(CheckerContext *c, Operand *operand, return false; } + c->allow_c_vararg_param = true; Operand args = {}; check_expr(c, &args, ce->args[1]); + c->allow_c_vararg_param = false; if (list.mode == Addressing_Invalid) { return false; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 4709691c5..b71cec4d9 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -1968,6 +1968,14 @@ gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *nam break; case Entity_Variable: + if ((e->flags & EntityFlag_CVarArg) && !c->allow_c_vararg_param) { + ERROR_BLOCK(); + error(o->expr, "'#c_vararg' parameter '%.*s' cannot be used directly", LIT(name)); + error_line("\tSuggestion: use c_va_start to convert C varargs to c_va_list\n"); + o->mode = Addressing_Invalid; + o->type = t_invalid; + return e; + } e->flags |= EntityFlag_Used; if (type == t_invalid) { o->type = t_invalid; diff --git a/src/checker.hpp b/src/checker.hpp index cd2e580d8..1a53018e3 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -834,6 +834,7 @@ struct CheckerContext { bool hide_polymorphic_errors; bool in_polymorphic_specialization; bool allow_arrow_right_selector_expr; + bool allow_c_vararg_param; u8 bit_field_bit_size; Scope * polymorphic_scope;