From b7f2ef78b204aea0442facd38e2f2064d4b58a51 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 27 Apr 2022 18:31:21 +0300 Subject: [PATCH] all: atomic int fixes --- vlib/builtin/int.v | 5 +++++ vlib/v/ast/types.v | 6 +++++- vlib/v/checker/for.v | 3 ++- vlib/v/parser/parse_type.v | 5 ++++- vlib/v/tests/atomic_test.v | 23 +++++++++++++++++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/atomic_test.v diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 9ad1b86d0e..a387be5f4f 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -578,3 +578,8 @@ pub fn (b u8) repeat(count int) string { } return unsafe { ret.vstring_with_len(new_len) } } + +// for atomic ints, internal +fn _Atomic__int_str(x int) string { + return x.str() +} diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index f03b83afb8..2415b71aca 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -127,7 +127,7 @@ pub fn (t Type) atomic_typename() string { idx := t.idx() match idx { ast.u32_type_idx { return 'atomic_uint' } - ast.int_type_idx { return 'atomic_int' } + ast.int_type_idx { return '_Atomic int' } ast.u64_type_idx { return 'atomic_ullong' } ast.i64_type_idx { return 'atomic_llong' } else { return 'unknown_atomic' } @@ -1161,6 +1161,10 @@ pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string] nr_muls-- res = 'shared ' + res } + if typ.has_flag(.atomic_f) { + nr_muls-- + res = 'atomic ' + res + } if nr_muls > 0 && !typ.has_flag(.variadic) { res = strings.repeat(`&`, nr_muls) + res } diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index e27126935e..494ad01dbc 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -35,7 +35,8 @@ fn (mut c Checker) for_in_stmt(mut node ast.ForInStmt) { if node.is_range { high_type := c.expr(node.high) high_type_idx := high_type.idx() - if typ_idx in ast.integer_type_idxs && high_type_idx !in ast.integer_type_idxs { + if typ_idx in ast.integer_type_idxs && high_type_idx !in ast.integer_type_idxs + && high_type_idx != ast.void_type_idx { c.error('range types do not match', node.cond.pos()) } else if typ_idx in ast.float_type_idxs || high_type_idx in ast.float_type_idxs { c.error('range type can not be float', node.cond.pos()) diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 6906b5edb8..ce29321e1c 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -401,10 +401,13 @@ pub fn (mut p Parser) parse_type() ast.Type { p.error_with_pos('cannot use `mut` on struct field type', p.tok.pos()) } } - if p.tok.kind == .key_mut || is_shared || is_atomic { + if p.tok.kind == .key_mut || is_shared { // || is_atomic { nr_muls++ p.next() } + if is_atomic { + p.next() + } if p.tok.kind == .mul { p.error('use `&Type` instead of `*Type` when declaring references') return 0 diff --git a/vlib/v/tests/atomic_test.v b/vlib/v/tests/atomic_test.v new file mode 100644 index 0000000000..ba66ac29b0 --- /dev/null +++ b/vlib/v/tests/atomic_test.v @@ -0,0 +1,23 @@ +import term +import os +import runtime +import time + +struct App { +mut: + idx atomic int +} + +fn test_atomic() { + mut app := &App{} + for i in 0 .. 10 { + go app.run() + } + time.sleep(2 * time.second) + println('idx=$app.idx') + assert app.idx == 10 +} + +fn (mut app App) run() { + app.idx++ +}