From 74efd2621b347d578856634ae20388e6d5881884 Mon Sep 17 00:00:00 2001 From: shove Date: Thu, 17 Nov 2022 15:20:42 +0800 Subject: [PATCH] checker: fix struct field unsign type check (fix #16457) (#16458) --- vlib/v/checker/assign.v | 8 ++++++++ vlib/v/checker/struct.v | 16 +++++++++++++++ .../struct_field_unsign_type_check_err.out | 20 +++++++++++++++++++ .../struct_field_unsign_type_check_err.vv | 12 +++++++++++ 4 files changed, 56 insertions(+) create mode 100644 vlib/v/checker/tests/struct_field_unsign_type_check_err.out create mode 100644 vlib/v/checker/tests/struct_field_unsign_type_check_err.vv diff --git a/vlib/v/checker/assign.v b/vlib/v/checker/assign.v index 937198c8c3..da198c674d 100644 --- a/vlib/v/checker/assign.v +++ b/vlib/v/checker/assign.v @@ -321,6 +321,14 @@ pub fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) { left.expr.is_setter = true } } + if left_type in ast.unsigned_integer_type_idxs { + if mut right is ast.IntegerLiteral { + if right.val[0] == `-` { + c.error('Cannot assign negative value to unsigned integer type', + right.pos) + } + } + } } else { if mut left is ast.IndexExpr { diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 988376ff5a..82192c3496 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -124,6 +124,14 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) { } continue } + if field.typ in ast.unsigned_integer_type_idxs { + if field.default_expr is ast.IntegerLiteral { + if field.default_expr.val[0] == `-` { + c.error('Cannot assign negative value to unsigned integer type', + field.default_expr.pos) + } + } + } if field.default_expr is ast.UnsafeExpr { if field.default_expr.expr is ast.Nil && !field.typ.is_ptr() && c.table.sym(field.typ).kind != .function && !field.typ.is_pointer() { @@ -482,6 +490,14 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type { } } } + if field_info.typ in ast.unsigned_integer_type_idxs { + if mut field.expr is ast.IntegerLiteral { + if field.expr.val[0] == `-` { + c.error('Cannot assign negative value to unsigned integer type', + field.expr.pos) + } + } + } } // Check uninitialized refs/sum types // The variable `fields` contains two parts, the first part is the same as info.fields, diff --git a/vlib/v/checker/tests/struct_field_unsign_type_check_err.out b/vlib/v/checker/tests/struct_field_unsign_type_check_err.out new file mode 100644 index 0000000000..9695fa2281 --- /dev/null +++ b/vlib/v/checker/tests/struct_field_unsign_type_check_err.out @@ -0,0 +1,20 @@ +vlib/v/checker/tests/struct_field_unsign_type_check_err.vv:3:10: error: Cannot assign negative value to unsigned integer type + 1 | struct Foo { + 2 | mut: + 3 | n u32 = -1 + | ~~ + 4 | } + 5 | +vlib/v/checker/tests/struct_field_unsign_type_check_err.vv:8:6: error: Cannot assign negative value to unsigned integer type + 6 | fn main() { + 7 | mut foo := Foo{ + 8 | n: -1 + | ~~ + 9 | } + 10 | +vlib/v/checker/tests/struct_field_unsign_type_check_err.vv:11:10: error: Cannot assign negative value to unsigned integer type + 9 | } + 10 | + 11 | foo.n = -1 + | ~~ + 12 | } diff --git a/vlib/v/checker/tests/struct_field_unsign_type_check_err.vv b/vlib/v/checker/tests/struct_field_unsign_type_check_err.vv new file mode 100644 index 0000000000..379f9174cc --- /dev/null +++ b/vlib/v/checker/tests/struct_field_unsign_type_check_err.vv @@ -0,0 +1,12 @@ +struct Foo { +mut: + n u32 = -1 +} + +fn main() { + mut foo := Foo{ + n: -1 + } + + foo.n = -1 +}