mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: disallow 'small_unsigned == signed' (#13967)
This commit is contained in:
parent
6718958058
commit
c780de6282
@ -161,7 +161,7 @@ fn test_bf_from_str() {
|
||||
output := bitfield.from_str(input)
|
||||
mut result := 1
|
||||
for i in 0 .. len {
|
||||
if input[i] != output.get_bit(i) + 48 {
|
||||
if input[i] != byte(output.get_bit(i)) + 48 {
|
||||
result = 0
|
||||
}
|
||||
}
|
||||
|
@ -775,7 +775,7 @@ fn test_byte_keys() {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == byte_max
|
||||
assert m.len == int(byte_max)
|
||||
keys := m.keys()
|
||||
for i in byte(0) .. byte_max {
|
||||
assert keys[i] == i
|
||||
@ -827,7 +827,7 @@ fn test_u16_keys() {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
assert m.len == int(end)
|
||||
keys := m.keys()
|
||||
for i in u16(0) .. end {
|
||||
assert keys[i] == i
|
||||
|
@ -763,7 +763,7 @@ fn test_byte_keys() {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == byte_max
|
||||
assert m.len == int(byte_max)
|
||||
keys := m.keys()
|
||||
for i in byte(0) .. byte_max {
|
||||
assert keys[i] == i
|
||||
@ -815,7 +815,7 @@ fn test_u16_keys() {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
assert m.len == int(end)
|
||||
keys := m.keys()
|
||||
for i in u16(0) .. end {
|
||||
assert keys[i] == i
|
||||
|
@ -1937,7 +1937,7 @@ pub fn (name string) match_glob(pattern string) bool {
|
||||
mut is_inverted := false
|
||||
mut inner_match := false
|
||||
mut inner_idx := bstart + 1
|
||||
mut inner_c := 0
|
||||
mut inner_c := byte(0)
|
||||
if inner_idx < plen {
|
||||
inner_c = pattern[inner_idx]
|
||||
if inner_c == `^` {
|
||||
|
@ -173,7 +173,7 @@ pub fn (mut zentry Zip) crc32() u32 {
|
||||
|
||||
// write_entry compresses an input buffer for the current zip entry.
|
||||
pub fn (mut zentry Zip) write_entry(data []byte) ? {
|
||||
if (data[0] & 0xff) == -1 {
|
||||
if int(data[0] & 0xff) == -1 {
|
||||
return error('szip: cannot write entry')
|
||||
}
|
||||
res := C.zip_entry_write(zentry, data.data, data.len)
|
||||
|
@ -288,8 +288,8 @@ fn (mut ctx Context) parse_events() {
|
||||
if !C.GetConsoleScreenBufferInfo(ctx.stdout_handle, &sb) {
|
||||
panic('could not get screenbuffer info')
|
||||
}
|
||||
w := sb.srWindow.Right - sb.srWindow.Left + 1
|
||||
h := sb.srWindow.Bottom - sb.srWindow.Top + 1
|
||||
w := int(sb.srWindow.Right - sb.srWindow.Left + 1)
|
||||
h := int(sb.srWindow.Bottom - sb.srWindow.Top + 1)
|
||||
utf8 := '($ctx.window_width, $ctx.window_height) -> ($w, $h)'
|
||||
if w != ctx.window_width || h != ctx.window_height {
|
||||
ctx.window_width, ctx.window_height = w, h
|
||||
|
@ -9,7 +9,7 @@ import toml.util
|
||||
|
||||
pub const (
|
||||
digit_extras = [`_`, `.`, `x`, `o`, `b`, `e`, `E`]
|
||||
end_of_text = 4294967295
|
||||
end_of_text = u32(~0)
|
||||
)
|
||||
|
||||
// Scanner contains the necessary fields for the state of the scan process.
|
||||
|
@ -374,6 +374,23 @@ pub fn (typ Type) is_unsigned() bool {
|
||||
return typ.idx() in ast.unsigned_integer_type_idxs
|
||||
}
|
||||
|
||||
pub fn (typ Type) flip_signedness() Type {
|
||||
r := match typ {
|
||||
ast.i8_type { ast.byte_type }
|
||||
ast.i16_type { ast.u16_type }
|
||||
ast.int_type { ast.u32_type }
|
||||
ast.isize_type { ast.usize_type }
|
||||
ast.i64_type { ast.u64_type }
|
||||
ast.byte_type { ast.i8_type }
|
||||
ast.u16_type { ast.i16_type }
|
||||
ast.u32_type { ast.int_type }
|
||||
ast.usize_type { ast.isize_type }
|
||||
ast.u64_type { ast.i64_type }
|
||||
else { typ }
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
[inline]
|
||||
pub fn (typ Type) is_int_literal() bool {
|
||||
return int(typ) == ast.int_literal_type_idx
|
||||
@ -442,6 +459,9 @@ pub const (
|
||||
i64_type_idx, isize_type_idx]
|
||||
unsigned_integer_type_idxs = [byte_type_idx, u8_type_idx, u16_type_idx, u32_type_idx,
|
||||
u64_type_idx, usize_type_idx]
|
||||
// C will promote any type smaller than int to int in an expression
|
||||
int_promoted_type_idxs = [char_type_idx, i8_type_idx, i16_type_idx, byte_type_idx,
|
||||
u8_type_idx, u16_type_idx]
|
||||
float_type_idxs = [f32_type_idx, f64_type_idx, float_literal_type_idx]
|
||||
number_type_idxs = [i8_type_idx, i16_type_idx, int_type_idx, i64_type_idx,
|
||||
byte_type_idx, char_type_idx, u16_type_idx, u32_type_idx, u64_type_idx, isize_type_idx,
|
||||
|
@ -79,3 +79,9 @@ fn test_derive() {
|
||||
assert t2.has_flag(ast.TypeFlag.generic) == true
|
||||
assert t2.nr_muls() == 10
|
||||
}
|
||||
|
||||
fn test_flip_signedness() {
|
||||
assert ast.i8_type.flip_signedness() == ast.byte_type
|
||||
assert ast.u16_type.flip_signedness() == ast.i16_type
|
||||
assert ast.isize_type.flip_signedness() == ast.usize_type
|
||||
}
|
||||
|
@ -626,6 +626,29 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
if is_mismatch {
|
||||
c.error('possible type mismatch of compared values of `$node.op` operation',
|
||||
left_right_pos)
|
||||
} else if left_type in ast.integer_type_idxs && right_type in ast.integer_type_idxs {
|
||||
is_left_type_signed := left_type in ast.signed_integer_type_idxs
|
||||
is_right_type_signed := right_type in ast.signed_integer_type_idxs
|
||||
if !is_left_type_signed && mut node.right is ast.IntegerLiteral {
|
||||
if node.right.val.int() < 0 && left_type in ast.int_promoted_type_idxs {
|
||||
lt := c.table.sym(left_type).name
|
||||
c.error('`$lt` cannot be compared with negative value', node.right.pos)
|
||||
}
|
||||
} else if !is_right_type_signed && mut node.left is ast.IntegerLiteral {
|
||||
if node.left.val.int() < 0 && right_type in ast.int_promoted_type_idxs {
|
||||
rt := c.table.sym(right_type).name
|
||||
c.error('negative value cannot be compared with `$rt`', node.left.pos)
|
||||
}
|
||||
} else if is_left_type_signed != is_right_type_signed
|
||||
&& left_type.flip_signedness() != right_type {
|
||||
// prevent e.g. `u16(-1) == int(-1)` which is false in C
|
||||
if (is_right_type_signed && left_type in ast.int_promoted_type_idxs)
|
||||
|| (is_left_type_signed && right_type in ast.int_promoted_type_idxs) {
|
||||
lt := c.table.sym(left_type).name
|
||||
rt := c.table.sym(right_type).name
|
||||
c.error('`$lt` cannot be compared with `$rt`', node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.key_in, .not_in {
|
||||
|
40
vlib/v/checker/tests/compare_unsigned_signed.out
Normal file
40
vlib/v/checker/tests/compare_unsigned_signed.out
Normal file
@ -0,0 +1,40 @@
|
||||
vlib/v/checker/tests/compare_unsigned_signed.vv:2:14: error: unsigned integer cannot be compared with negative value
|
||||
1 | fn main() {
|
||||
2 | if u32(1) < -1 {
|
||||
| ~~
|
||||
3 | println('unexpected')
|
||||
4 | }
|
||||
vlib/v/checker/tests/compare_unsigned_signed.vv:6:5: error: unsigned integer cannot be compared with negative value
|
||||
4 | }
|
||||
5 |
|
||||
6 | if -1 > u32(1) {
|
||||
| ~~
|
||||
7 | println('unexpected')
|
||||
8 | }
|
||||
vlib/v/checker/tests/compare_unsigned_signed.vv:10:18: error: `byte` cannot be compared with negative value
|
||||
8 | }
|
||||
9 | // unsigned == literal
|
||||
10 | _ = byte(-1) == -1 // false!
|
||||
| ~~
|
||||
11 | _ = -1 == u16(-1) // false!
|
||||
12 |
|
||||
vlib/v/checker/tests/compare_unsigned_signed.vv:11:6: error: negative value cannot be compared with `u16`
|
||||
9 | // unsigned == literal
|
||||
10 | _ = byte(-1) == -1 // false!
|
||||
11 | _ = -1 == u16(-1) // false!
|
||||
| ~~
|
||||
12 |
|
||||
13 | // unsigned == signed
|
||||
vlib/v/checker/tests/compare_unsigned_signed.vv:14:14: error: `u16` cannot be compared with `int`
|
||||
12 |
|
||||
13 | // unsigned == signed
|
||||
14 | _ = u16(-1) == int(-1)
|
||||
| ~~
|
||||
15 | _ = int(-1) != byte(-1)
|
||||
16 | }
|
||||
vlib/v/checker/tests/compare_unsigned_signed.vv:15:14: error: `int` cannot be compared with `byte`
|
||||
13 | // unsigned == signed
|
||||
14 | _ = u16(-1) == int(-1)
|
||||
15 | _ = int(-1) != byte(-1)
|
||||
| ~~
|
||||
16 | }
|
16
vlib/v/checker/tests/compare_unsigned_signed.vv
Normal file
16
vlib/v/checker/tests/compare_unsigned_signed.vv
Normal file
@ -0,0 +1,16 @@
|
||||
fn main() {
|
||||
if u32(1) < -1 {
|
||||
println('unexpected')
|
||||
}
|
||||
|
||||
if -1 > u32(1) {
|
||||
println('unexpected')
|
||||
}
|
||||
// unsigned == literal
|
||||
_ = byte(-1) == -1 // false!
|
||||
_ = -1 == u16(-1) // false!
|
||||
|
||||
// unsigned == signed
|
||||
_ = u16(-1) == int(-1)
|
||||
_ = int(-1) != byte(-1)
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
vlib/v/checker/tests/infix_unsigned_and_signed_int_err.vv:2:14: error: unsigned integer cannot be compared with negative value
|
||||
1 | fn main() {
|
||||
2 | if u32(1) < -1 {
|
||||
| ~~
|
||||
3 | println('unexpected')
|
||||
4 | }
|
||||
vlib/v/checker/tests/infix_unsigned_and_signed_int_err.vv:6:5: error: unsigned integer cannot be compared with negative value
|
||||
4 | }
|
||||
5 |
|
||||
6 | if -1 > u32(1) {
|
||||
| ~~
|
||||
7 | println('unexpected')
|
||||
8 | }
|
@ -1,9 +0,0 @@
|
||||
fn main() {
|
||||
if u32(1) < -1 {
|
||||
println('unexpected')
|
||||
}
|
||||
|
||||
if -1 > u32(1) {
|
||||
println('unexpected')
|
||||
}
|
||||
}
|
@ -778,7 +778,7 @@ pub fn (mut bmp BitMap) draw_glyph(index u16) (int, int) {
|
||||
}
|
||||
}
|
||||
|
||||
if count == glyph.contour_ends[c] {
|
||||
if count == int(glyph.contour_ends[c]) {
|
||||
// dprintln("count == glyph.contour_ends[count]")
|
||||
if s == 2 { // final point was off-curve. connect to start
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user