From 5089eb4a8450a540a77cb5eaac94bdf23dd0722f Mon Sep 17 00:00:00 2001 From: crthpl <56052645+crthpl@users.noreply.github.com> Date: Tue, 13 Jul 2021 02:01:24 -0700 Subject: [PATCH] parser: fix pointer cast expressions hack (#10777) --- cmd/tools/vast/vast.v | 1 - vlib/net/address.v | 3 +-- vlib/sync/channels.v | 3 +-- vlib/v/ast/ast.v | 1 - vlib/v/checker/checker.v | 16 +++++----------- vlib/v/checker/tests/fixed_array_conv.out | 4 ++-- .../tests/warnings_for_string_c2v_calls.out | 11 ++--------- .../tests/warnings_for_string_c2v_calls.vv | 5 ++--- vlib/v/parser/expr.v | 9 ++++++--- 9 files changed, 19 insertions(+), 34 deletions(-) diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index 4934b7c7da..96cd724f02 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -1230,7 +1230,6 @@ fn (t Tree) cast_expr(node ast.CastExpr) &Node { obj.add('typname', t.string_node(node.typname)) obj.add('expr_type', t.type_node(node.expr_type)) obj.add('has_arg', t.bool_node(node.has_arg)) - obj.add('in_prexpr', t.bool_node(node.in_prexpr)) obj.add('pos', t.position(node.pos)) return obj } diff --git a/vlib/net/address.v b/vlib/net/address.v index 47166167c6..ecc65c6fa8 100644 --- a/vlib/net/address.v +++ b/vlib/net/address.v @@ -185,8 +185,7 @@ pub fn resolve_ipaddrs(addr string, family AddrFamily, typ SocketType) ?[]Addr { // This might look silly but is recommended by MSDN $if windows { - socket_error(0 - C.getaddrinfo(&char(address.str), &char(sport.str), &hints, - &results)) ? + socket_error(0 - C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results)) ? } $else { x := C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results) wrap_error(x) ? diff --git a/vlib/sync/channels.v b/vlib/sync/channels.v index 74d88a70bc..8acd6d326b 100644 --- a/vlib/sync/channels.v +++ b/vlib/sync/channels.v @@ -637,8 +637,7 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo } subscr[i].prev = unsafe { &ch.read_subscriber } unsafe { - subscr[i].nxt = C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber), - &subscr[i]) + subscr[i].nxt = C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber), &subscr[i]) } if voidptr(subscr[i].nxt) != voidptr(0) { subscr[i].nxt.prev = unsafe { &subscr[i].nxt } diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index cd6e5896af..031334d32d 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1106,7 +1106,6 @@ pub mut: typname string // TypeSymbol.name expr_type Type // `byteptr` has_arg bool - in_prexpr bool // is the parent node a PrefixExpr } pub struct AsmStmt { diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 955abdc8ed..a9da1f71cf 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -5131,20 +5131,14 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type { if to_type_sym.language != .c { c.ensure_type_exists(node.typ, node.pos) or {} } - n_e_t_idx := node.expr_type.idx() - expr_is_ptr := node.expr_type.is_ptr() || n_e_t_idx in ast.pointer_type_idxs + if from_type_sym.kind == .byte && node.expr_type.is_ptr() && to_type_sym.kind == .string + && !node.typ.is_ptr() { + c.error('to convert a C string buffer pointer to a V string, use x.vstring() instead of string(x)', + node.pos) + } if node.expr_type == ast.void_type { c.error('expression does not return a value so it cannot be cast', node.expr.position()) } - if expr_is_ptr && to_type_sym.kind == .string && !node.in_prexpr { - if node.has_arg { - c.warn('to convert a C string buffer pointer to a V string, use x.vstring_with_len(len) instead of string(x,len)', - node.pos) - } else { - c.warn('to convert a C string buffer pointer to a V string, use x.vstring() instead of string(x)', - node.pos) - } - } if node.expr_type == ast.byte_type && to_type_sym.kind == .string { c.error('can not cast type `byte` to string, use `${node.expr.str()}.str()` instead.', node.pos) diff --git a/vlib/v/checker/tests/fixed_array_conv.out b/vlib/v/checker/tests/fixed_array_conv.out index 7cc36f1b29..211f4b5ff7 100644 --- a/vlib/v/checker/tests/fixed_array_conv.out +++ b/vlib/v/checker/tests/fixed_array_conv.out @@ -12,11 +12,11 @@ vlib/v/checker/tests/fixed_array_conv.vv:5:4: error: mismatched types `&int` and | ^ 6 | _ = &int(arr) 7 | _ = p -vlib/v/checker/tests/fixed_array_conv.vv:6:6: error: cannot cast a fixed array (use e.g. `&arr[0]` instead) +vlib/v/checker/tests/fixed_array_conv.vv:6:5: error: cannot cast a fixed array (use e.g. `&arr[0]` instead) 4 | mut ip := &int(0) 5 | ip = arr 6 | _ = &int(arr) - | ~~~~~~~~ + | ~~~~~~~~~ 7 | _ = p 8 | _ = ip vlib/v/checker/tests/fixed_array_conv.vv:11:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup` diff --git a/vlib/v/checker/tests/warnings_for_string_c2v_calls.out b/vlib/v/checker/tests/warnings_for_string_c2v_calls.out index bdf6320010..f570847a42 100644 --- a/vlib/v/checker/tests/warnings_for_string_c2v_calls.out +++ b/vlib/v/checker/tests/warnings_for_string_c2v_calls.out @@ -3,12 +3,5 @@ vlib/v/checker/tests/warnings_for_string_c2v_calls.vv:8:7: error: to convert a C 7 | } 8 | x := string(p) | ~~~~~~~~~ - 9 | y := string(p, 10) - 10 | eprintln('x: $x | y: $y') -vlib/v/checker/tests/warnings_for_string_c2v_calls.vv:9:7: error: to convert a C string buffer pointer to a V string, use x.vstring_with_len(len) instead of string(x,len) - 7 | } - 8 | x := string(p) - 9 | y := string(p, 10) - | ~~~~~~~~~~~~~ - 10 | eprintln('x: $x | y: $y') - 11 | eprintln('x.len: $x.len | y.len: $y.len') + 9 | eprintln('x: $x') + 10 | eprintln('x.len: $x.len') diff --git a/vlib/v/checker/tests/warnings_for_string_c2v_calls.vv b/vlib/v/checker/tests/warnings_for_string_c2v_calls.vv index e85313803c..7f4daded86 100644 --- a/vlib/v/checker/tests/warnings_for_string_c2v_calls.vv +++ b/vlib/v/checker/tests/warnings_for_string_c2v_calls.vv @@ -6,7 +6,6 @@ fn main() { p[2] = `z` } x := string(p) - y := string(p, 10) - eprintln('x: $x | y: $y') - eprintln('x.len: $x.len | y.len: $y.len') + eprintln('x: $x') + eprintln('x.len: $x.len') } diff --git a/vlib/v/parser/expr.v b/vlib/v/parser/expr.v index 09849f7e7a..862eb062de 100644 --- a/vlib/v/parser/expr.v +++ b/vlib/v/parser/expr.v @@ -560,7 +560,7 @@ fn (p &Parser) fileis(s string) bool { return p.file_name.contains(s) } -fn (mut p Parser) prefix_expr() ast.PrefixExpr { +fn (mut p Parser) prefix_expr() ast.Expr { mut pos := p.tok.position() op := p.tok.kind if op == .amp { @@ -576,8 +576,11 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr { p.next() mut right := p.expr(int(token.Precedence.prefix)) p.is_amp = false - if mut right is ast.CastExpr { - right.in_prexpr = true + if mut right is ast.CastExpr && op == .amp { + return ast.CastExpr{ + ...right + pos: pos.extend(right.pos) + } } mut or_stmts := []ast.Stmt{} mut or_kind := ast.OrKind.absent