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('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
}

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
$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) ?

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 }
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 }

View File

@ -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 {

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 {
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)

View File

@ -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`

View File

@ -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')

View File

@ -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')
}

View File

@ -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