scanner/parser: change error msgs for `\0` and `\x00` and add error for r`byte` and c`byte` (#6436)
parent
f159163856
commit
077b597bd8
|
@ -729,6 +729,12 @@ fn test_raw() {
|
||||||
raw2 := r'Hello V\0'
|
raw2 := r'Hello V\0'
|
||||||
assert raw2[7] == `\\`
|
assert raw2[7] == `\\`
|
||||||
assert raw2[8] == `0`
|
assert raw2[8] == `0`
|
||||||
|
|
||||||
|
raw3 := r'Hello V\x00'
|
||||||
|
assert raw3[7] == `\\`
|
||||||
|
assert raw3[8] == `x`
|
||||||
|
assert raw3[9] == `0`
|
||||||
|
assert raw3[10] == `0`
|
||||||
}
|
}
|
||||||
|
|
||||||
fn test_raw_with_quotes() {
|
fn test_raw_with_quotes() {
|
||||||
|
|
|
@ -1358,7 +1358,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
||||||
return f.return_type
|
return f.return_type
|
||||||
}
|
}
|
||||||
// println can print anything
|
// println can print anything
|
||||||
if (fn_name == 'println' || fn_name == 'print') && call_expr.args.len > 0 {
|
if fn_name in ['println', 'print'] && call_expr.args.len > 0 {
|
||||||
c.expected_type = table.string_type
|
c.expected_type = table.string_type
|
||||||
call_expr.args[0].typ = c.expr(call_expr.args[0].expr)
|
call_expr.args[0].typ = c.expr(call_expr.args[0].expr)
|
||||||
// check optional argument
|
// check optional argument
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
vlib/v/checker/tests/string_char_null_err.vv:2:31: error: 0 character in a string literal
|
vlib/v/checker/tests/string_char_null_err.vv:2:31: error: cannot use `\0` (NULL character) in the string literal
|
||||||
1 | fn main() {
|
1 | fn main() {
|
||||||
2 | println('Null character: \0')
|
2 | println('Null character: \0')
|
||||||
| ^
|
| ^
|
||||||
|
|
|
@ -994,6 +994,11 @@ pub fn (mut p Parser) name_expr() ast.Expr {
|
||||||
if p.tok.lit in ['r', 'c', 'js'] && p.peek_tok.kind == .string && !p.inside_str_interp {
|
if p.tok.lit in ['r', 'c', 'js'] && p.peek_tok.kind == .string && !p.inside_str_interp {
|
||||||
return p.string_expr()
|
return p.string_expr()
|
||||||
}
|
}
|
||||||
|
// don't allow r`byte` and c`byte`
|
||||||
|
if p.tok.lit in ['r', 'c'] && p.peek_tok.kind == .chartoken {
|
||||||
|
opt := if p.tok.lit == 'r' { '`r` (raw string)' } else { '`c` (c string)' }
|
||||||
|
p.error('cannot use $opt with `byte` and `rune`')
|
||||||
|
}
|
||||||
known_var := p.mark_var_as_used(p.tok.lit)
|
known_var := p.mark_var_as_used(p.tok.lit)
|
||||||
mut is_mod_cast := false
|
mut is_mod_cast := false
|
||||||
if p.peek_tok.kind == .dot && !known_var &&
|
if p.peek_tok.kind == .dot && !known_var &&
|
||||||
|
|
|
@ -1218,14 +1218,14 @@ fn (mut s Scanner) ident_string() string {
|
||||||
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash {
|
if c == `0` && s.pos > 2 && s.text[s.pos - 1] == slash {
|
||||||
if (s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit()) || s.count_symbol_before(s.pos - 1, slash) % 2 == 0 {
|
if (s.pos < s.text.len - 1 && s.text[s.pos + 1].is_digit()) || s.count_symbol_before(s.pos - 1, slash) % 2 == 0 {
|
||||||
} else if !is_cstr && !is_raw {
|
} else if !is_cstr && !is_raw {
|
||||||
s.error('0 character in a string literal')
|
s.error(r'cannot use `\0` (NULL character) in the string literal')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Don't allow \x00
|
// Don't allow \x00
|
||||||
if c == `0` && s.pos > 5 && s.expect('\\x0', s.pos - 3) {
|
if c == `0` && s.pos > 5 && s.expect('\\x0', s.pos - 3) {
|
||||||
if s.count_symbol_before(s.pos - 3, slash) % 2 == 0 {
|
if s.count_symbol_before(s.pos - 3, slash) % 2 == 0 {
|
||||||
} else if !is_cstr && !is_raw {
|
} else if !is_cstr && !is_raw {
|
||||||
s.error('0 character in a string literal')
|
s.error(r'cannot use `\x00` (NULL character) in the string literal')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// ${var} (ignore in vfmt mode)
|
// ${var} (ignore in vfmt mode)
|
||||||
|
|
Loading…
Reference in New Issue