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(...@@ -5027,7 +5027,7 @@ fn transFnNoProto(
5027 is_pub: bool,5027 is_pub: bool,
5028) !*ast.Node.FnProto {5028) !*ast.Node.FnProto {
5029 const cc = try transCC(rp, fn_ty, source_loc);5029 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;
5031 return finishTransFnProto(rp, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);5031 return finishTransFnProto(rp, null, null, fn_ty, source_loc, fn_decl_context, is_var_args, cc, is_pub);
5032}5032}
50335033
test/run_translated_c.zig+30
...@@ -657,4 +657,34 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -657,4 +657,34 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
657 \\ return 0;657 \\ return 0;
658 \\}658 \\}
659 , "");659 , "");
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 , "");
660}690}
test/translate_c.zig+9-1
...@@ -1375,11 +1375,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -1375,11 +1375,19 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
1375 \\void b(void) {}1375 \\void b(void) {}
1376 \\void c();1376 \\void c();
1377 \\void d(void);1377 \\void d(void);
1378 \\static void e() {}
1379 \\static void f(void) {}
1380 \\static void g();
1381 \\static void h(void);
1378 , &[_][]const u8{1382 , &[_][]const u8{
1379 \\pub export fn a() void {}1383 \\pub export fn a() void {}
1380 \\pub export fn b() void {}1384 \\pub export fn b() void {}
1381 \\pub extern fn c(...) void;1385 \\pub extern fn c(...) void;
1382 \\pub extern fn d() void;1386 \\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;
1383 });1391 });
13841392
1385 cases.add("variable declarations",1393 cases.add("variable declarations",
...@@ -2938,7 +2946,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {...@@ -2938,7 +2946,7 @@ pub fn addCases(cases: *tests.TranslateCContext) void {
2938 \\pub fn a() callconv(.C) void {}2946 \\pub fn a() callconv(.C) void {}
2939 \\pub fn b() callconv(.C) void {}2947 \\pub fn b() callconv(.C) void {}
2940 \\pub export fn c() void {}2948 \\pub export fn c() void {}
2941 \\pub fn foo(...) callconv(.C) void {}2949 \\pub fn foo() callconv(.C) void {}
2942 });2950 });
29432951
2944 cases.add("casting away const and volatile",2952 cases.add("casting away const and volatile",