checker: allow mut arg on C functions (#11430)
parent
5b619b99c2
commit
ccf6285f82
|
@ -2938,7 +2938,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr) ast.Type {
|
||||||
c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block',
|
c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block',
|
||||||
call_arg.pos)
|
call_arg.pos)
|
||||||
}
|
}
|
||||||
if call_arg.is_mut && func.language == .v {
|
if call_arg.is_mut {
|
||||||
to_lock, pos := c.fail_if_immutable(call_arg.expr)
|
to_lock, pos := c.fail_if_immutable(call_arg.expr)
|
||||||
if !call_arg.expr.is_lvalue() {
|
if !call_arg.expr.is_lvalue() {
|
||||||
c.error('cannot pass expression as `mut`', call_arg.expr.position())
|
c.error('cannot pass expression as `mut`', call_arg.expr.position())
|
||||||
|
|
|
@ -216,6 +216,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
} else if p.tok.kind == .name && p.tok.lit == 'JS' {
|
} else if p.tok.kind == .name && p.tok.lit == 'JS' {
|
||||||
language = .js
|
language = .js
|
||||||
}
|
}
|
||||||
|
p.fn_language = language
|
||||||
if language != .v {
|
if language != .v {
|
||||||
for fna in p.attrs {
|
for fna in p.attrs {
|
||||||
if fna.name == 'export' {
|
if fna.name == 'export' {
|
||||||
|
@ -249,6 +250,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
// rec.language was initialized with language variable.
|
// rec.language was initialized with language variable.
|
||||||
// So language is changed only if rec.language has been changed.
|
// So language is changed only if rec.language has been changed.
|
||||||
language = rec.language
|
language = rec.language
|
||||||
|
p.fn_language = language
|
||||||
}
|
}
|
||||||
mut name := ''
|
mut name := ''
|
||||||
name_pos := p.tok.position()
|
name_pos := p.tok.position()
|
||||||
|
@ -994,6 +996,9 @@ fn (mut p Parser) check_fn_mutable_arguments(typ ast.Type, pos token.Position) {
|
||||||
p.check_fn_mutable_arguments(atyp, pos)
|
p.check_fn_mutable_arguments(atyp, pos)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if p.fn_language == .c {
|
||||||
|
return
|
||||||
|
}
|
||||||
p.error_with_pos(
|
p.error_with_pos(
|
||||||
'mutable arguments are only allowed for arrays, interfaces, maps, pointers, structs or their aliases\n' +
|
'mutable arguments are only allowed for arrays, interfaces, maps, pointers, structs or their aliases\n' +
|
||||||
'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`',
|
'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`',
|
||||||
|
|
|
@ -33,6 +33,7 @@ mut:
|
||||||
peek_tok token.Token
|
peek_tok token.Token
|
||||||
table &ast.Table
|
table &ast.Table
|
||||||
language ast.Language
|
language ast.Language
|
||||||
|
fn_language ast.Language // .c for `fn C.abcd()` declarations
|
||||||
inside_test_file bool // when inside _test.v or _test.vv file
|
inside_test_file bool // when inside _test.v or _test.vv file
|
||||||
inside_if bool
|
inside_if bool
|
||||||
inside_if_expr bool
|
inside_if_expr bool
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
void mut_arg(const byte *_key, size_t *val) {
|
||||||
|
*val = 5;
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
module main
|
||||||
|
|
||||||
|
#include "@VMODROOT/code.c"
|
||||||
|
|
||||||
|
fn C.mut_arg(key &byte, mut val usize)
|
||||||
|
|
||||||
|
fn test_c_function_mut_param() {
|
||||||
|
key := &byte(1)
|
||||||
|
mut val := usize(1)
|
||||||
|
C.mut_arg(key, mut &val)
|
||||||
|
assert val == usize(5)
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
Module {
|
||||||
|
name: 'c_function_mut_param'
|
||||||
|
description: ''
|
||||||
|
version: ''
|
||||||
|
license: ''
|
||||||
|
dependencies: []
|
||||||
|
}
|
Loading…
Reference in New Issue