diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b99943f6c9..596c39daaa 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -3266,8 +3266,15 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { is_decl := node.op == .decl_assign for i, left in node.left { if left is ast.CallExpr { + // ban `foo() = 10` c.error('cannot call function `${left.name}()` on the left side of an assignment', left.pos) + } else if left is ast.PrefixExpr { + // ban `*foo() = 10` + if left.right is ast.CallExpr && left.op == .mul { + c.error('cannot dereference a function call on the left side of an assignment, use a temporary variable', + left.pos) + } } else if left is ast.IndexExpr { if left.index is ast.RangeExpr { c.error('cannot reassign using range expression on the left side of an assignment', diff --git a/vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.out b/vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.out new file mode 100644 index 0000000000..d26ab1b0fd --- /dev/null +++ b/vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.vv:8:2: error: cannot dereference a function call on the left side of an assignment, use a temporary variable + 6 | + 7 | fn main() { + 8 | *foo('s') = 1 + | ^ + 9 | } diff --git a/vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.vv b/vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.vv new file mode 100644 index 0000000000..50aa22b283 --- /dev/null +++ b/vlib/v/checker/tests/assign_deref_fn_call_on_left_side_err.vv @@ -0,0 +1,9 @@ +struct Foo{} + +fn foo(s string) &Foo { + return &Foo{} +} + +fn main() { + *foo('s') = 1 +} diff --git a/vlib/v/gen/c/cheaders.v b/vlib/v/gen/c/cheaders.v index ccbfd2619a..4b1092ccfb 100644 --- a/vlib/v/gen/c/cheaders.v +++ b/vlib/v/gen/c/cheaders.v @@ -50,6 +50,7 @@ static inline void __sort_ptr(uintptr_t a[], bool b[], int l) { ' const c_common_macros = ' +typedef unsigned char u8; #define EMPTY_VARG_INITIALIZATION 0 #define EMPTY_STRUCT_DECLARATION #define EMPTY_STRUCT_INITIALIZATION @@ -194,7 +195,7 @@ const c_helper_macros = '//============================== HELPER C MACROS ====== //#define tos4(s, slen) ((string){.str=(s), .len=(slen)}) // _SLIT0 is used as NULL string for literal arguments // `"" s` is used to enforce a string literal argument -#define _SLIT0 (string){.len=0} +#define _SLIT0 (string){.len=0} #define _SLIT(s) ((string){.str=(byteptr)("" s), .len=(sizeof(s)-1), .is_lit=1}) //#define _SLIT(s) ((string){.str=(byteptr)("" s), .len=(sizeof(s)-1), .is_lit=1}) // take the address of an rvalue