checker: check number of C function arguments for some cases (#8444)
parent
2cadb3e4d8
commit
64d12cdc8d
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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 | }
|
|
@ -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()
|
||||
}
|
Loading…
Reference in New Issue