Skip to content

Commit

Permalink
Static function declarations with no prototype should not be variadic
Browse files Browse the repository at this point in the history
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 ziglang#7594
  • Loading branch information
ehaas committed Dec 29, 2020
1 parent 0b46c27 commit 30d7e8d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 3 deletions.
3 changes: 1 addition & 2 deletions src/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -2168,7 +2168,6 @@ fn transCCast(
// @boolToInt returns either a comptime_int or a u1
// TODO: if dst_type is 1 bit & signed (bitfield) we need @bitCast
// instead of @as

const builtin_node = try rp.c.createBuiltinCall("@boolToInt", 1);
builtin_node.params()[0] = expr;
builtin_node.rparen_token = try appendToken(rp.c, .RParen, ")");
Expand Down Expand Up @@ -5027,7 +5026,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);
}

Expand Down
30 changes: 30 additions & 0 deletions test/run_translated_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
\\}
, "");
}
10 changes: 9 additions & 1 deletion test/translate_c.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down

0 comments on commit 30d7e8d

Please sign in to comment.