diff --git a/vlib/builtin/cfns.c.v b/vlib/builtin/cfns.c.v index 20f31dc449..75fdbb8bac 100644 --- a/vlib/builtin/cfns.c.v +++ b/vlib/builtin/cfns.c.v @@ -7,7 +7,7 @@ fn C.memcmp(byteptr, byteptr, int) int fn C.memmove(byteptr, byteptr, int) voidptr -fn C.calloc(int) byteptr +fn C.calloc(int, int) byteptr fn C.malloc(int) byteptr @@ -48,16 +48,16 @@ fn C.printf(byteptr, ...byteptr) int fn C.puts(byteptr) int -fn C.fputs(byteptr) int +fn C.fputs(str byteptr, stream &C.FILE) int -fn C.fflush(byteptr) int +fn C.fflush(&C.FILE) int // TODO define args in these functions fn C.fseek() int -fn C.fopen() voidptr +fn C.fopen(filename charptr, mode charptr) &C.FILE -fn C.fileno(voidptr) int +fn C.fileno(&C.FILE) int fn C.fread(ptr voidptr, item_size size_t, items size_t, stream &C.FILE) size_t @@ -86,7 +86,7 @@ fn C.waitpid(pid int, status &int, options int) int fn C.kill(pid int, sig int) int -fn C.setenv(charptr) int +fn C.setenv(charptr, charptr, int) int fn C.unsetenv(charptr) int @@ -100,7 +100,7 @@ fn C.chdir() int fn C.rewind() int -fn C.stat(charptr) int +fn C.stat(charptr, voidptr) int fn C.lstat() int @@ -125,7 +125,7 @@ fn C.sleep(int) int fn C.usleep() int -fn C.opendir() voidptr +fn C.opendir(charptr) voidptr fn C.closedir() int diff --git a/vlib/json/json_primitives.v b/vlib/json/json_primitives.v index df7672b58c..b2fa5a153c 100644 --- a/vlib/json/json_primitives.v +++ b/vlib/json/json_primitives.v @@ -105,22 +105,22 @@ fn decode_string(root &C.cJSON) string { return tos_clone(root.valuestring) // , _strlen(root.valuestring)) } -fn C.cJSON_IsTrue() bool +fn C.cJSON_IsTrue(voidptr) bool -fn C.cJSON_CreateNumber() &C.cJSON +fn C.cJSON_CreateNumber(int) &C.cJSON -fn C.cJSON_CreateBool() &C.cJSON +fn C.cJSON_CreateBool(bool) &C.cJSON -fn C.cJSON_CreateString() &C.cJSON +fn C.cJSON_CreateString(charptr) &C.cJSON -fn C.cJSON_Parse() &C.cJSON +fn C.cJSON_Parse(charptr) &C.cJSON -fn C.cJSON_PrintUnformatted() byteptr +fn C.cJSON_PrintUnformatted(voidptr) byteptr fn decode_bool(root &C.cJSON) bool { diff --git a/vlib/os/os_c.v b/vlib/os/os_c.v index 9ad7e7d10b..fe40e3a4f8 100644 --- a/vlib/os/os_c.v +++ b/vlib/os/os_c.v @@ -16,7 +16,7 @@ fn C.ftell(fp voidptr) int fn C.sigaction(int, voidptr, int) -fn C.open(charptr, int, int) int +fn C.open(charptr, int, ...int) int fn C.fdopen(int, string) voidptr diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 21e26e5a5e..d22a1d3f91 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1781,6 +1781,15 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { call_expr.should_be_skipped = true } if f.language != .v || call_expr.language != .v { + // ignore C function of type `fn()`, assume untyped + // For now don't check C functions that are variadic, underscored, capitalized + // or have no params and return int + if f.language == .c && f.params.len != call_expr.args.len && !f.is_variadic + && f.name[2] != `_` && !f.name[2].is_capital() + && (f.params.len != 0 || f.return_type !in [table.void_type, table.int_type]) { + // change to error later + c.warn('expected $f.params.len arguments, but got $call_expr.args.len', call_expr.pos) + } for arg in call_expr.args { c.expr(arg.expr) } diff --git a/vlib/v/checker/tests/c_fn_surplus_args.out b/vlib/v/checker/tests/c_fn_surplus_args.out new file mode 100644 index 0000000000..e3aa25a967 --- /dev/null +++ b/vlib/v/checker/tests/c_fn_surplus_args.out @@ -0,0 +1,27 @@ +vlib/v/checker/tests/c_fn_surplus_args.vv:7:4: error: expected 1 arguments, but got 0 + 5 | fn main() { + 6 | C.no(1) // allowed + 7 | C.y1() + | ~~~~ + 8 | C.y1(1) // ok + 9 | C.y1(1, 2) +vlib/v/checker/tests/c_fn_surplus_args.vv:9:4: error: expected 1 arguments, but got 2 + 7 | C.y1() + 8 | C.y1(1) // ok + 9 | C.y1(1, 2) + | ~~~~~~~~ + 10 | C.ret() // ok + 11 | C.ret(1) +vlib/v/checker/tests/c_fn_surplus_args.vv:11:4: error: expected 0 arguments, but got 1 + 9 | C.y1(1, 2) + 10 | C.ret() // ok + 11 | C.ret(1) + | ~~~~~~ + 12 | // avoid cgen whilst warning, later above should error + 13 | main() +vlib/v/checker/tests/c_fn_surplus_args.vv:13:2: error: the `main` function cannot be called in the program + 11 | C.ret(1) + 12 | // avoid cgen whilst warning, later above should error + 13 | main() + | ~~~~~~ + 14 | } diff --git a/vlib/v/checker/tests/c_fn_surplus_args.vv b/vlib/v/checker/tests/c_fn_surplus_args.vv new file mode 100644 index 0000000000..7e6aa38e25 --- /dev/null +++ b/vlib/v/checker/tests/c_fn_surplus_args.vv @@ -0,0 +1,14 @@ +fn C.no() // untyped +fn C.y1(int) +fn C.ret()byte + +fn main() { + C.no(1) // allowed + C.y1() + C.y1(1) // ok + C.y1(1, 2) + C.ret() // ok + C.ret(1) + // avoid cgen whilst warning, later above should error + main() +}