parser: fix pointer cast expressions hack (#10777)

pull/10787/head
crthpl 2021-07-13 02:01:24 -07:00 committed by GitHub
parent 1bf6743987
commit 5089eb4a84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 19 additions and 34 deletions

View File

@ -1230,7 +1230,6 @@ fn (t Tree) cast_expr(node ast.CastExpr) &Node {
obj.add('typname', t.string_node(node.typname)) obj.add('typname', t.string_node(node.typname))
obj.add('expr_type', t.type_node(node.expr_type)) obj.add('expr_type', t.type_node(node.expr_type))
obj.add('has_arg', t.bool_node(node.has_arg)) 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)) obj.add('pos', t.position(node.pos))
return obj return obj
} }

View File

@ -185,8 +185,7 @@ pub fn resolve_ipaddrs(addr string, family AddrFamily, typ SocketType) ?[]Addr {
// This might look silly but is recommended by MSDN // This might look silly but is recommended by MSDN
$if windows { $if windows {
socket_error(0 - C.getaddrinfo(&char(address.str), &char(sport.str), &hints, socket_error(0 - C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results)) ?
&results)) ?
} $else { } $else {
x := C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results) x := C.getaddrinfo(&char(address.str), &char(sport.str), &hints, &results)
wrap_error(x) ? wrap_error(x) ?

View File

@ -637,8 +637,7 @@ pub fn channel_select(mut channels []&Channel, dir []Direction, mut objrefs []vo
} }
subscr[i].prev = unsafe { &ch.read_subscriber } subscr[i].prev = unsafe { &ch.read_subscriber }
unsafe { unsafe {
subscr[i].nxt = C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber), subscr[i].nxt = C.atomic_exchange_ptr(&voidptr(&ch.read_subscriber), &subscr[i])
&subscr[i])
} }
if voidptr(subscr[i].nxt) != voidptr(0) { if voidptr(subscr[i].nxt) != voidptr(0) {
subscr[i].nxt.prev = unsafe { &subscr[i].nxt } subscr[i].nxt.prev = unsafe { &subscr[i].nxt }

View File

@ -1106,7 +1106,6 @@ pub mut:
typname string // TypeSymbol.name typname string // TypeSymbol.name
expr_type Type // `byteptr` expr_type Type // `byteptr`
has_arg bool has_arg bool
in_prexpr bool // is the parent node a PrefixExpr
} }
pub struct AsmStmt { pub struct AsmStmt {

View File

@ -5131,20 +5131,14 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
if to_type_sym.language != .c { if to_type_sym.language != .c {
c.ensure_type_exists(node.typ, node.pos) or {} c.ensure_type_exists(node.typ, node.pos) or {}
} }
n_e_t_idx := node.expr_type.idx() if from_type_sym.kind == .byte && node.expr_type.is_ptr() && to_type_sym.kind == .string
expr_is_ptr := node.expr_type.is_ptr() || n_e_t_idx in ast.pointer_type_idxs && !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 { if node.expr_type == ast.void_type {
c.error('expression does not return a value so it cannot be cast', node.expr.position()) 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 { 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.', c.error('can not cast type `byte` to string, use `${node.expr.str()}.str()` instead.',
node.pos) node.pos)

View File

@ -12,11 +12,11 @@ vlib/v/checker/tests/fixed_array_conv.vv:5:4: error: mismatched types `&int` and
| ^ | ^
6 | _ = &int(arr) 6 | _ = &int(arr)
7 | _ = p 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) 4 | mut ip := &int(0)
5 | ip = arr 5 | ip = arr
6 | _ = &int(arr) 6 | _ = &int(arr)
| ~~~~~~~~ | ~~~~~~~~~
7 | _ = p 7 | _ = p
8 | _ = ip 8 | _ = ip
vlib/v/checker/tests/fixed_array_conv.vv:11:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup` vlib/v/checker/tests/fixed_array_conv.vv:11:13: error: cannot use `[2]int` as `voidptr` in argument 1 to `memdup`

View File

@ -3,12 +3,5 @@ vlib/v/checker/tests/warnings_for_string_c2v_calls.vv:8:7: error: to convert a C
7 | } 7 | }
8 | x := string(p) 8 | x := string(p)
| ~~~~~~~~~ | ~~~~~~~~~
9 | y := string(p, 10) 9 | eprintln('x: $x')
10 | eprintln('x: $x | y: $y') 10 | eprintln('x.len: $x.len')
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')

View File

@ -6,7 +6,6 @@ fn main() {
p[2] = `z` p[2] = `z`
} }
x := string(p) x := string(p)
y := string(p, 10) eprintln('x: $x')
eprintln('x: $x | y: $y') eprintln('x.len: $x.len')
eprintln('x.len: $x.len | y.len: $y.len')
} }

View File

@ -560,7 +560,7 @@ fn (p &Parser) fileis(s string) bool {
return p.file_name.contains(s) 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() mut pos := p.tok.position()
op := p.tok.kind op := p.tok.kind
if op == .amp { if op == .amp {
@ -576,8 +576,11 @@ fn (mut p Parser) prefix_expr() ast.PrefixExpr {
p.next() p.next()
mut right := p.expr(int(token.Precedence.prefix)) mut right := p.expr(int(token.Precedence.prefix))
p.is_amp = false p.is_amp = false
if mut right is ast.CastExpr { if mut right is ast.CastExpr && op == .amp {
right.in_prexpr = true return ast.CastExpr{
...right
pos: pos.extend(right.pos)
}
} }
mut or_stmts := []ast.Stmt{} mut or_stmts := []ast.Stmt{}
mut or_kind := ast.OrKind.absent mut or_kind := ast.OrKind.absent