authorgravatar for evan@lagerdata.comEvan Haas <evan@lagerdata.com> 2020-12-29 11:07:04-08:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-01-03 15:08:32-08:00
log5cc131030c01e178453b12f235823124aa6a2d12
treeae3644c4dc94467f144f896ad193f7c6d39b9a8f
parent5aac2fc28111e59a2a05a4fae42b6e19d4e0b7ca

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

3 files changed, 40 insertions(+), 2 deletions(-)

src/translate_c.zig+1-1
......@@ -5027,7 +5027,7 @@ fn transFnNoProto(
50275027 is_pub: bool,
50285028) !*ast.Node.FnProto {
50295029 const cc = try transCC(rp, fn_ty, source_loc);
5030 const is_var_args = if (fn_decl_context) |ctx| !ctx.is_export else true;
5030 const is_var_args = if (fn_decl_context) |ctx| (!ctx.is_export and ctx.storage_class != .Static) else true;
50315031 return finishTransFnProto(rp, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);
50325032}
50335033
test/run_translated_c.zig+30
......@@ -657,4 +657,34 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
657657 \\ return 0;
658658 \\}
659659 , "");
660
661 cases.add("static K&R-style no prototype function declaration (empty parameter list)",
662 \\#include <stdlib.h>
663 \\static int foo() {
664 \\ return 42;
665 \\}
666 \\int main() {
667 \\ if (foo() != 42) abort();
668 \\ return 0;
669 \\}
670 , "");
671
672 cases.add("K&R-style static function prototype for unused function",
673 \\static int foo();
674 \\int main() {
675 \\ return 0;
676 \\}
677 , "");
678
679 cases.add("K&R-style static function prototype + separate definition",
680 \\#include <stdlib.h>
681 \\static int foo();
682 \\static int foo(int a, int b) {
683 \\ return a + b;
684 \\}
685 \\int main() {
686 \\ if (foo(40, 2) != 42) abort();
687 \\ return 0;
688 \\}
689 , "");
660690}
test/translate_c.zig+9-1
......@@ -1375,11 +1375,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
13751375 \\void b(void) {}
13761376 \\void c();
13771377 \\void d(void);
1378 \\static void e() {}
1379 \\static void f(void) {}
1380 \\static void g();
1381 \\static void h(void);
13781382 , &[_][]const u8{
13791383 \\pub export fn a() void {}
13801384 \\pub export fn b() void {}
13811385 \\pub extern fn c(...) void;
13821386 \\pub extern fn d() void;
1387 \\pub fn e() callconv(.C) void {}
1388 \\pub fn f() callconv(.C) void {}
1389 \\pub extern fn g() void;
1390 \\pub extern fn h() void;
13831391 });
13841392
13851393 cases.add("variable declarations",
......@@ -2938,7 +2946,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
29382946 \\pub fn a() callconv(.C) void {}
29392947 \\pub fn b() callconv(.C) void {}
29402948 \\pub export fn c() void {}
2941 \\pub fn foo(...) callconv(.C) void {}
2949 \\pub fn foo() callconv(.C) void {}
29422950 });
29432951
29442952 cases.add("casting away const and volatile",