From 36dcace0a744cf0fab957adc05a9ed5c0156e574 Mon Sep 17 00:00:00 2001 From: Delyan Angelov Date: Wed, 23 Dec 2020 20:53:56 +0200 Subject: [PATCH] cgen: fix compiling call expressions with no varargs (tcc bug) --- vlib/v/gen/cheaders.v | 18 +++++++++--------- vlib/v/gen/fn.v | 3 ++- vlib/v/tests/vargs_empty_param_test.v | 20 ++++++++++++++++++++ 3 files changed, 31 insertions(+), 10 deletions(-) create mode 100644 vlib/v/tests/vargs_empty_param_test.v diff --git a/vlib/v/gen/cheaders.v b/vlib/v/gen/cheaders.v index 0e1c796a83..aff32839db 100644 --- a/vlib/v/gen/cheaders.v +++ b/vlib/v/gen/cheaders.v @@ -3,10 +3,9 @@ module gen // NB: @@@ here serve as placeholders. // They will be replaced with correct strings // for each constant, during C code generation. - const ( // V_COMMIT_HASH is generated by cmd/tools/gen_vc.v . - c_commit_hash_default = ' + c_commit_hash_default = ' #ifndef V_COMMIT_HASH #define V_COMMIT_HASH "@@@" #endif @@ -17,8 +16,8 @@ const ( #define V_CURRENT_COMMIT_HASH "@@@" #endif ' - - c_common_macros = ' + c_common_macros = ' +#define EMPTY_VARG_INITIALIZATION 0 #define EMPTY_STRUCT_DECLARATION #define EMPTY_STRUCT_INITIALIZATION 0 // Due to a tcc bug, the length of an array needs to be specified, but GCC crashes if it is... @@ -53,8 +52,10 @@ const ( #endif #ifdef __TINYC__ + #undef EMPTY_VARG_INITIALIZATION #undef EMPTY_STRUCT_DECLARATION #undef EMPTY_STRUCT_INITIALIZATION + #define EMPTY_VARG_INITIALIZATION #define EMPTY_STRUCT_DECLARATION char _dummy #define EMPTY_STRUCT_INITIALIZATION 0 #undef EMPTY_ARRAY_OF_ELEMS @@ -75,8 +76,7 @@ const ( // for __offset_of #ifndef __offsetof - #define __offsetof(s,memb) \\ - ((size_t)((char *)&((s *)0)->memb - (char *)0)) + #define __offsetof(s,memb) ((size_t)((char *)&((s *)0)->memb - (char *)0)) #endif #define OPTION_CAST(x) (x) @@ -93,7 +93,7 @@ const ( #endif #endif ' - c_headers = ' + c_headers = ' // c_headers typedef int (*qsort_callback_func)(const void*, const void*); #include // TODO remove all these includes, define all function signatures and types manually @@ -429,7 +429,7 @@ static voidptr memfreedup(voidptr ptr, voidptr src, int sz) { return memdup(src, sz); } ' - c_builtin_types = ' + c_builtin_types = ' //================================== builtin types ================================*/ typedef int64_t i64; typedef int16_t i16; @@ -458,7 +458,7 @@ typedef struct sync__Channel* chan; #endif #endif ' - bare_c_headers = ' + bare_c_headers = ' $c_common_macros #ifndef exit diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 7057c2216f..017585a657 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -836,7 +836,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) { } } } else { - g.write('0') + // NB: tcc can not handle 0 here, while msvc needs it + g.write('EMPTY_VARG_INITIALIZATION') } g.write('}}') } diff --git a/vlib/v/tests/vargs_empty_param_test.v b/vlib/v/tests/vargs_empty_param_test.v new file mode 100644 index 0000000000..c89eceeb09 --- /dev/null +++ b/vlib/v/tests/vargs_empty_param_test.v @@ -0,0 +1,20 @@ +struct Config { + token string +} + +struct Client { + x u64 + y u64 +} + +fn new(config Config, shard_count ...int) ?&Client { + return &Client{1, 2} +} + +fn test_can_compile_an_empty_var_arg() { + x := new(Config{ + token: 'xyz' + }) or { panic(err) } + assert x.x == 1 + assert x.y == 2 +}