cgen: fix compiling call expressions with no varargs (tcc bug)

pull/7525/head
Delyan Angelov 2020-12-23 20:53:56 +02:00
parent 4dfb7dbffa
commit 36dcace0a7
3 changed files with 31 additions and 10 deletions

View File

@ -3,10 +3,9 @@ module gen
// NB: @@@ here serve as placeholders. // NB: @@@ here serve as placeholders.
// They will be replaced with correct strings // They will be replaced with correct strings
// for each constant, during C code generation. // for each constant, during C code generation.
const ( const (
// V_COMMIT_HASH is generated by cmd/tools/gen_vc.v . // V_COMMIT_HASH is generated by cmd/tools/gen_vc.v .
c_commit_hash_default = ' c_commit_hash_default = '
#ifndef V_COMMIT_HASH #ifndef V_COMMIT_HASH
#define V_COMMIT_HASH "@@@" #define V_COMMIT_HASH "@@@"
#endif #endif
@ -17,8 +16,8 @@ const (
#define V_CURRENT_COMMIT_HASH "@@@" #define V_CURRENT_COMMIT_HASH "@@@"
#endif #endif
' '
c_common_macros = '
c_common_macros = ' #define EMPTY_VARG_INITIALIZATION 0
#define EMPTY_STRUCT_DECLARATION #define EMPTY_STRUCT_DECLARATION
#define EMPTY_STRUCT_INITIALIZATION 0 #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... // 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 #endif
#ifdef __TINYC__ #ifdef __TINYC__
#undef EMPTY_VARG_INITIALIZATION
#undef EMPTY_STRUCT_DECLARATION #undef EMPTY_STRUCT_DECLARATION
#undef EMPTY_STRUCT_INITIALIZATION #undef EMPTY_STRUCT_INITIALIZATION
#define EMPTY_VARG_INITIALIZATION
#define EMPTY_STRUCT_DECLARATION char _dummy #define EMPTY_STRUCT_DECLARATION char _dummy
#define EMPTY_STRUCT_INITIALIZATION 0 #define EMPTY_STRUCT_INITIALIZATION 0
#undef EMPTY_ARRAY_OF_ELEMS #undef EMPTY_ARRAY_OF_ELEMS
@ -75,8 +76,7 @@ const (
// for __offset_of // for __offset_of
#ifndef __offsetof #ifndef __offsetof
#define __offsetof(s,memb) \\ #define __offsetof(s,memb) ((size_t)((char *)&((s *)0)->memb - (char *)0))
((size_t)((char *)&((s *)0)->memb - (char *)0))
#endif #endif
#define OPTION_CAST(x) (x) #define OPTION_CAST(x) (x)
@ -93,7 +93,7 @@ const (
#endif #endif
#endif #endif
' '
c_headers = ' c_headers = '
// c_headers // c_headers
typedef int (*qsort_callback_func)(const void*, const void*); typedef int (*qsort_callback_func)(const void*, const void*);
#include <stdio.h> // TODO remove all these includes, define all function signatures and types manually #include <stdio.h> // 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); return memdup(src, sz);
} }
' '
c_builtin_types = ' c_builtin_types = '
//================================== builtin types ================================*/ //================================== builtin types ================================*/
typedef int64_t i64; typedef int64_t i64;
typedef int16_t i16; typedef int16_t i16;
@ -458,7 +458,7 @@ typedef struct sync__Channel* chan;
#endif #endif
#endif #endif
' '
bare_c_headers = ' bare_c_headers = '
$c_common_macros $c_common_macros
#ifndef exit #ifndef exit

View File

@ -836,7 +836,8 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
} }
} }
} else { } else {
g.write('0') // NB: tcc can not handle 0 here, while msvc needs it
g.write('EMPTY_VARG_INITIALIZATION')
} }
g.write('}}') g.write('}}')
} }

View File

@ -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
}