Static function declarations with no prototype should not be variadic

If a static function is defined with no argument list and no prototype
is given, it should be treated as a function that takes no arguments
rather than as a variadic function.

Fixes #7594
This commit is contained in:
Evan Haas 2020-12-29 11:07:04 -08:00 committed by Andrew Kelley
parent 5aac2fc281
commit 5cc131030c
3 changed files with 40 additions and 2 deletions

View File

@ -5027,7 +5027,7 @@ fn transFnNoProto(
is_pub: bool,
) !*ast.Node.FnProto {
const cc = try transCC(rp, fn_ty, source_loc);
const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true;
const is_var_args = if (fn_decl_context) |ctx| (!ctx.is_export and ctx.storage_class != .Static) else true;
return finishTransFnProto(rp, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);
}

View File

@ -657,4 +657,34 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
\\ return 0;
\\}
, "");
cases.add("static K&R-style no prototype function declaration (empty parameter list)",
\\#include <stdlib.h>
\\static int foo() {
\\ return 42;
\\}
\\int main() {
\\ if (foo() != 42) abort();
\\ return 0;
\\}
, "");
cases.add("K&R-style static function prototype for unused function",
\\static int foo();
\\int main() {
\\ return 0;
\\}
, "");
cases.add("K&R-style static function prototype + separate definition",
\\#include <stdlib.h>
\\static int foo();
\\static int foo(int a, int b) {
\\ return a + b;
\\}
\\int main() {
\\ if (foo(40, 2) != 42) abort();
\\ return 0;
\\}
, "");
}

View File

@ -1375,11 +1375,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\void b(void) {}
\\void c();
\\void d(void);
\\static void e() {}
\\static void f(void) {}
\\static void g();
\\static void h(void);
, &[_][]const u8{
\\pub export fn a() void {}
\\pub export fn b() void {}
\\pub extern fn c(...) void;
\\pub extern fn d() void;
\\pub fn e() callconv(.C) void {}
\\pub fn f() callconv(.C) void {}
\\pub extern fn g() void;
\\pub extern fn h() void;
});
cases.add("variable declarations",
@ -2938,7 +2946,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
\\pub fn a() callconv(.C) void {}
\\pub fn b() callconv(.C) void {}
\\pub export fn c() void {}
\\pub fn foo(...) callconv(.C) void {}
\\pub fn foo() callconv(.C) void {}
});
cases.add("casting away const and volatile",