From bb9f0a2c478cbfabf9741acaed89f18099489709 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 7 Oct 2026 22:54:59 +0100 Subject: [PATCH] Prefix the atomic analysis procedures with `check_atomic_` --- src/check_atomics.cpp | 194 +++++++++++++++++++++--------------------- src/check_builtin.cpp | 4 +- src/check_expr.cpp | 4 +- src/check_stmt.cpp | 2 +- src/checker.hpp | 4 +- 5 files changed, 104 insertions(+), 104 deletions(-) diff --git a/src/check_atomics.cpp b/src/check_atomics.cpp index 4d9a95ee3..1941fd4d2 100644 --- a/src/check_atomics.cpp +++ b/src/check_atomics.cpp @@ -37,7 +37,7 @@ gb_global PtrMap atomic_uses; // what an atomic operation on `&expr` is on, if anything -gb_internal Entity *atomic_location(Ast *expr) { +gb_internal Entity *check_atomic_location(Ast *expr) { for (;;) { expr = unparen_expr(expr); switch (expr->kind) { @@ -98,17 +98,17 @@ gb_internal Entity *atomic_location(Ast *expr) { } } -gb_internal void atomic_first(Ast **site, Ast *call) { +gb_internal void check_atomic_first(Ast **site, Ast *call) { if (*site == nullptr || token_pos_cmp(ast_token(call).pos, ast_token(*site).pos) < 0) { *site = call; } } -gb_internal OdinAtomicMemoryOrder atomic_order_of(Ast *expr) { +gb_internal OdinAtomicMemoryOrder check_atomic_order_of(Ast *expr) { return cast(OdinAtomicMemoryOrder)exact_value_to_i64(expr->tav.value); } -gb_internal bool atomic_order_acquires(OdinAtomicMemoryOrder order) { +gb_internal bool check_atomic_order_acquires(OdinAtomicMemoryOrder order) { switch (order) { case OdinAtomicMemoryOrder_consume: case OdinAtomicMemoryOrder_acquire: @@ -119,7 +119,7 @@ gb_internal bool atomic_order_acquires(OdinAtomicMemoryOrder order) { return false; } -gb_internal bool atomic_order_releases(OdinAtomicMemoryOrder order) { +gb_internal bool check_atomic_order_releases(OdinAtomicMemoryOrder order) { switch (order) { case OdinAtomicMemoryOrder_release: case OdinAtomicMemoryOrder_acq_rel: @@ -129,14 +129,14 @@ gb_internal bool atomic_order_releases(OdinAtomicMemoryOrder order) { return false; } -gb_internal int atomic_report_cmp(void const *a, void const *b) { +gb_internal int check_atomic_report_cmp(void const *a, void const *b) { AtomicReport const *x = cast(AtomicReport const *)a; AtomicReport const *y = cast(AtomicReport const *)b; return token_pos_cmp(ast_token(x->site).pos, ast_token(y->site).pos); } // the plain reads within a statement or an expression, of which only the address is used when `addr` -gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { +gb_internal void check_atomic_scan(AtomicScan *s, Ast *node, bool addr) { if (node == nullptr || node->tav.mode == Addressing_Constant || node->tav.mode == Addressing_Type) { return; } @@ -145,7 +145,7 @@ gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { case Ast_SelectorExpr: case Ast_IndexExpr: if (!addr) { - Entity *e = atomic_location(node); + Entity *e = check_atomic_location(node); if (e != nullptr && map_get(&atomic_uses, e) != nullptr) { array_add(&s->reads, node); } @@ -155,16 +155,16 @@ gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { switch (node->kind) { case_ast_node(pe, ParenExpr, node); - atomic_scan(s, pe->expr, addr); + check_atomic_scan(s, pe->expr, addr); case_end; case_ast_node(ue, UnaryExpr, node); - atomic_scan(s, ue->expr, ue->op.kind == Token_And); + check_atomic_scan(s, ue->expr, ue->op.kind == Token_And); case_end; case_ast_node(be, BinaryExpr, node); - atomic_scan(s, be->left, false); - atomic_scan(s, be->right, false); + check_atomic_scan(s, be->left, false); + check_atomic_scan(s, be->right, false); case_end; case_ast_node(se, SelectorExpr, node); @@ -174,36 +174,36 @@ gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { } // reading a field reads only it, of what it is within if (is_type_pointer(se->expr->tav.type)) { - atomic_scan(s, se->expr, false); + check_atomic_scan(s, se->expr, false); } else { - atomic_scan(s, se->expr, addr || se->swizzle_count == 0); + check_atomic_scan(s, se->expr, addr || se->swizzle_count == 0); } case_end; case_ast_node(ie, IndexExpr, node); Type *t = base_type(ie->expr->tav.type); if (t != nullptr && (t->kind == Type_Array || t->kind == Type_EnumeratedArray || t->kind == Type_FixedCapacityDynamicArray || t->kind == Type_Matrix || t->kind == Type_Struct)) { - atomic_scan(s, ie->expr, true); + check_atomic_scan(s, ie->expr, true); } else { - atomic_scan(s, ie->expr, false); + check_atomic_scan(s, ie->expr, false); } - atomic_scan(s, ie->index, false); + check_atomic_scan(s, ie->index, false); case_end; case_ast_node(mie, MatrixIndexExpr, node); - atomic_scan(s, mie->expr, true); - atomic_scan(s, mie->row_index, false); - atomic_scan(s, mie->column_index, false); + check_atomic_scan(s, mie->expr, true); + check_atomic_scan(s, mie->row_index, false); + check_atomic_scan(s, mie->column_index, false); case_end; case_ast_node(de, DerefExpr, node); - atomic_scan(s, de->expr, false); + check_atomic_scan(s, de->expr, false); case_end; case_ast_node(se, SliceExpr, node); - atomic_scan(s, se->expr, is_type_array_like(se->expr->tav.type)); - atomic_scan(s, se->low, false); - atomic_scan(s, se->high, false); + check_atomic_scan(s, se->expr, is_type_array_like(se->expr->tav.type)); + check_atomic_scan(s, se->low, false); + check_atomic_scan(s, se->high, false); case_end; case_ast_node(ce, CallExpr, node); @@ -218,127 +218,127 @@ gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { (string_contains_string(e->token.string, str_lit("lock")) || string_contains_string(e->token.string, str_lit("guard")))) { s->locks = true; } - atomic_scan(s, proc, false); + check_atomic_scan(s, proc, false); } for (Ast *arg : ce->args) { - atomic_scan(s, arg, false); + check_atomic_scan(s, arg, false); } case_end; case_ast_node(sce, SelectorCallExpr, node); - atomic_scan(s, sce->call, false); + check_atomic_scan(s, sce->call, false); case_end; case_ast_node(cl, CompoundLit, node); for (Ast *elem : cl->elems) { - atomic_scan(s, elem, false); + check_atomic_scan(s, elem, false); } case_end; case_ast_node(fv, FieldValue, node); - atomic_scan(s, fv->value, false); + check_atomic_scan(s, fv->value, false); case_end; case_ast_node(te, TernaryIfExpr, node); - atomic_scan(s, te->cond, false); - atomic_scan(s, te->x, false); - atomic_scan(s, te->y, false); + check_atomic_scan(s, te->cond, false); + check_atomic_scan(s, te->x, false); + check_atomic_scan(s, te->y, false); case_end; case_ast_node(te, TernaryWhenExpr, node); if (te->cond != nullptr && te->cond->tav.value.kind == ExactValue_Bool) { if (te->cond->tav.value.value_bool) { - atomic_scan(s, te->x, false); + check_atomic_scan(s, te->x, false); } else { - atomic_scan(s, te->y, false); + check_atomic_scan(s, te->y, false); } } case_end; case_ast_node(oe, OrElseExpr, node); - atomic_scan(s, oe->x, false); - atomic_scan(s, oe->y, false); + check_atomic_scan(s, oe->x, false); + check_atomic_scan(s, oe->y, false); case_end; case_ast_node(re, OrReturnExpr, node); - atomic_scan(s, re->expr, false); + check_atomic_scan(s, re->expr, false); case_end; case_ast_node(be, OrBranchExpr, node); - atomic_scan(s, be->expr, false); + check_atomic_scan(s, be->expr, false); case_end; case_ast_node(ta, TypeAssertion, node); - atomic_scan(s, ta->expr, false); + check_atomic_scan(s, ta->expr, false); case_end; case_ast_node(tc, TypeCast, node); - atomic_scan(s, tc->expr, false); + check_atomic_scan(s, tc->expr, false); case_end; case_ast_node(ac, AutoCast, node); - atomic_scan(s, ac->expr, false); + check_atomic_scan(s, ac->expr, false); case_end; case_ast_node(te, TagExpr, node); - atomic_scan(s, te->expr, false); + check_atomic_scan(s, te->expr, false); case_end; case_ast_node(es, ExprStmt, node); - atomic_scan(s, es->expr, false); + check_atomic_scan(s, es->expr, false); case_end; case_ast_node(vd, ValueDecl, node); if (vd->is_mutable) { for (Ast *value : vd->values) { - atomic_scan(s, value, false); + check_atomic_scan(s, value, false); } } case_end; case_ast_node(as, AssignStmt, node); for (Ast *rhs : as->rhs) { - atomic_scan(s, rhs, false); + check_atomic_scan(s, rhs, false); } for (Ast *lhs : as->lhs) { - atomic_scan(s, lhs, as->op.kind == Token_Eq); + check_atomic_scan(s, lhs, as->op.kind == Token_Eq); } case_end; case_ast_node(bs, BlockStmt, node); for (Ast *stmt : bs->stmts) { - atomic_scan(s, stmt, false); + check_atomic_scan(s, stmt, false); } case_end; case_ast_node(is, IfStmt, node); - atomic_scan(s, is->init, false); - atomic_scan(s, is->cond, false); - atomic_scan(s, is->body, false); - atomic_scan(s, is->else_stmt, false); + check_atomic_scan(s, is->init, false); + check_atomic_scan(s, is->cond, false); + check_atomic_scan(s, is->body, false); + check_atomic_scan(s, is->else_stmt, false); case_end; case_ast_node(ws, WhenStmt, node); if (ws->is_cond_determined) { if (ws->determined_cond) { - atomic_scan(s, ws->body, false); + check_atomic_scan(s, ws->body, false); } else { - atomic_scan(s, ws->else_stmt, false); + check_atomic_scan(s, ws->else_stmt, false); } } case_end; case_ast_node(rs, ReturnStmt, node); for (Ast *result : rs->results) { - atomic_scan(s, result, false); + check_atomic_scan(s, result, false); } case_end; case_ast_node(fs, ForStmt, node); - atomic_scan(s, fs->init, false); - atomic_scan(s, fs->cond, false); - atomic_scan(s, fs->post, false); - atomic_scan(s, fs->body, false); + check_atomic_scan(s, fs->init, false); + check_atomic_scan(s, fs->cond, false); + check_atomic_scan(s, fs->post, false); + check_atomic_scan(s, fs->body, false); case_end; case_ast_node(rs, RangeStmt, node); @@ -346,8 +346,8 @@ gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { for (Ast *val : rs->vals) { by_ref |= val->kind == Ast_UnaryExpr && val->UnaryExpr.op.kind == Token_And; } - atomic_scan(s, rs->expr, by_ref && is_type_array_like(rs->expr->tav.type)); - atomic_scan(s, rs->body, false); + check_atomic_scan(s, rs->expr, by_ref && is_type_array_like(rs->expr->tav.type)); + check_atomic_scan(s, rs->body, false); case_end; case_ast_node(rs, UnrollRangeStmt, node); @@ -356,42 +356,42 @@ gb_internal void atomic_scan(AtomicScan *s, Ast *node, bool addr) { for (Ast *val : vals) { by_ref |= val != nullptr && val->kind == Ast_UnaryExpr && val->UnaryExpr.op.kind == Token_And; } - atomic_scan(s, rs->init, false); - atomic_scan(s, rs->expr, by_ref && is_type_array_like(rs->expr->tav.type)); - atomic_scan(s, rs->body, false); + check_atomic_scan(s, rs->init, false); + check_atomic_scan(s, rs->expr, by_ref && is_type_array_like(rs->expr->tav.type)); + check_atomic_scan(s, rs->body, false); case_end; case_ast_node(ss, SwitchStmt, node); - atomic_scan(s, ss->init, false); - atomic_scan(s, ss->tag, false); - atomic_scan(s, ss->body, false); + check_atomic_scan(s, ss->init, false); + check_atomic_scan(s, ss->tag, false); + check_atomic_scan(s, ss->body, false); case_end; case_ast_node(ss, TypeSwitchStmt, node); if (ss->tag != nullptr && ss->tag->kind == Ast_AssignStmt) { for (Ast *rhs : ss->tag->AssignStmt.rhs) { - atomic_scan(s, rhs, false); + check_atomic_scan(s, rhs, false); } } - atomic_scan(s, ss->body, false); + check_atomic_scan(s, ss->body, false); case_end; case_ast_node(cc, CaseClause, node); for (Ast *expr : cc->list) { - atomic_scan(s, expr, false); + check_atomic_scan(s, expr, false); } for (Ast *stmt : cc->stmts) { - atomic_scan(s, stmt, false); + check_atomic_scan(s, stmt, false); } case_end; case_ast_node(ds, DeferStmt, node); - atomic_scan(s, ds->stmt, false); + check_atomic_scan(s, ds->stmt, false); case_end; } } -gb_internal void atomic_check_bodies(ProcInfo **procs, isize count) { +gb_internal void check_atomic_bodies(ProcInfo **procs, isize count) { TEMPORARY_ALLOCATOR_GUARD(); for (isize i = 0; i < count; i++) { ProcInfo *pi = procs[i]; @@ -401,7 +401,7 @@ gb_internal void atomic_check_bodies(ProcInfo **procs, isize count) { } AtomicScan s = {}; s.reads = array_make(temporary_allocator(), 0, 0); - atomic_scan(&s, body, false); + check_atomic_scan(&s, body, false); if (s.locks || s.reads.count == 0) { continue; } @@ -409,7 +409,7 @@ gb_internal void atomic_check_bodies(ProcInfo **procs, isize count) { ErrorInstantiations prev_instantiations = global_error_context.instantiations; global_error_context.instantiations = {pi->generated_from_polymorphic ? pi : pi->poly_parent, nullptr}; for (Ast *read : s.reads) { - AtomicUses *uses = map_get(&atomic_uses, atomic_location(read)); + AtomicUses *uses = map_get(&atomic_uses, check_atomic_location(read)); ERROR_BLOCK(); gbString str = expr_to_string(read); error(read, "'%s' is read plainly, but it is accessed atomically, e.g. at %s", str, token_pos_to_string(ast_token(uses->first).pos)); @@ -443,13 +443,13 @@ gb_internal void check_atomics(Checker *c) { if (a.id != BuiltinProc_atomic_thread_fence || a.decl == nullptr) { continue; } - OdinAtomicMemoryOrder order = atomic_order_of(a.call->CallExpr.args[0]); + OdinAtomicMemoryOrder order = check_atomic_order_of(a.call->CallExpr.args[0]); AtomicFences f = {}; if (AtomicFences *found = map_get(&fences, a.decl)) { f = *found; } - f.acquire |= atomic_order_acquires(order); - f.release |= atomic_order_releases(order); + f.acquire |= check_atomic_order_acquires(order); + f.release |= check_atomic_order_releases(order); map_set(&fences, a.decl, f); } @@ -462,12 +462,12 @@ gb_internal void check_atomics(Checker *c) { continue; } Ast *call = a.call; - Ast *ptr = atomic_address_of(call->CallExpr.args[0]); + Ast *ptr = check_atomic_address_of(call->CallExpr.args[0]); if (ptr == nullptr) { continue; } ptr_set_add(&operated, ptr); - Entity *e = atomic_location(ptr->UnaryExpr.expr); + Entity *e = check_atomic_location(ptr->UnaryExpr.expr); if (e == nullptr) { continue; } @@ -484,7 +484,7 @@ gb_internal void check_atomics(Checker *c) { reads = false; break; case BuiltinProc_atomic_store_explicit: - order = atomic_order_of(call->CallExpr.args[2]); + order = check_atomic_order_of(call->CallExpr.args[2]); reads = false; break; case BuiltinProc_atomic_load: @@ -492,7 +492,7 @@ gb_internal void check_atomics(Checker *c) { writes = false; break; case BuiltinProc_atomic_load_explicit: - order = atomic_order_of(call->CallExpr.args[1]); + order = check_atomic_order_of(call->CallExpr.args[1]); writes = false; break; case BuiltinProc_atomic_add_explicit: @@ -502,12 +502,12 @@ gb_internal void check_atomics(Checker *c) { case BuiltinProc_atomic_or_explicit: case BuiltinProc_atomic_xor_explicit: case BuiltinProc_atomic_exchange_explicit: - order = atomic_order_of(call->CallExpr.args[2]); + order = check_atomic_order_of(call->CallExpr.args[2]); break; case BuiltinProc_atomic_compare_exchange_strong_explicit: case BuiltinProc_atomic_compare_exchange_weak_explicit: - order = atomic_order_of(call->CallExpr.args[3]); - failure = atomic_order_of(call->CallExpr.args[4]); + order = check_atomic_order_of(call->CallExpr.args[3]); + failure = check_atomic_order_of(call->CallExpr.args[4]); break; default: explicit_order = false; @@ -530,23 +530,23 @@ gb_internal void check_atomics(Checker *c) { } // seq_cst, by default or not, is not asked for as acquire or release ordering is, so it is never reported bool reported = explicit_order && order != OdinAtomicMemoryOrder_seq_cst && ast_file_analysis(call->file(), AnalysisFlag_Atomic); - atomic_first(&uses.first, call); + check_atomic_first(&uses.first, call); if (reads && !writes) { - atomic_first(&uses.load, call); + check_atomic_first(&uses.load, call); } if (writes && !reads) { - atomic_first(&uses.store, call); + check_atomic_first(&uses.store, call); } if (reads) { - uses.acquires |= atomic_order_acquires(order) || atomic_order_acquires(failure) || f.acquire; - if (reported && atomic_order_acquires(order)) { - atomic_first(&uses.asks_acquire, call); + uses.acquires |= check_atomic_order_acquires(order) || check_atomic_order_acquires(failure) || f.acquire; + if (reported && check_atomic_order_acquires(order)) { + check_atomic_first(&uses.asks_acquire, call); } } if (writes) { - uses.releases |= atomic_order_releases(order) || f.release; - if (reported && atomic_order_releases(order)) { - atomic_first(&uses.asks_release, call); + uses.releases |= check_atomic_order_releases(order) || f.release; + if (reported && check_atomic_order_releases(order)) { + check_atomic_first(&uses.asks_release, call); } } map_set(&atomic_uses, e, uses); @@ -579,7 +579,7 @@ gb_internal void check_atomics(Checker *c) { } } // in order, and once for what is at the same place in each instantiation of a polymorphic procedure - array_sort(reports, atomic_report_cmp); + array_sort(reports, check_atomic_report_cmp); TokenPos last = {}; for (AtomicReport const &r : reports) { TokenPos pos = ast_token(r.site).pos; @@ -589,7 +589,7 @@ gb_internal void check_atomics(Checker *c) { last = pos; ERROR_BLOCK(); - gbString str = expr_to_string(atomic_address_of(r.site->CallExpr.args[0])->UnaryExpr.expr); + gbString str = expr_to_string(check_atomic_address_of(r.site->CallExpr.args[0])->UnaryExpr.expr); char const *other = token_pos_to_string(ast_token(r.other).pos); if (r.release) { warning(r.site, "'%s' is written with release ordering, but it is only loaded with relaxed ordering, so the release orders nothing", str); @@ -618,8 +618,8 @@ gb_internal void check_atomics(Checker *c) { array_add_elems(&procs, slot.array.data, slot.array.count); } if (!build_context.no_threaded_checker && build_context.thread_count > 1) { - thread_pool_for_chunks(procs.data, procs.count, 1024, atomic_check_bodies); + thread_pool_for_chunks(procs.data, procs.count, 1024, check_atomic_bodies); } else { - atomic_check_bodies(procs.data, procs.count); + check_atomic_bodies(procs.data, procs.count); } } diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 7f2f955f8..64926f97d 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -2170,7 +2170,7 @@ gb_internal bool is_valid_type_for_load(Type *type) { } // the `&x` an atomic operation's pointer is, through any conversions of it, unless it is a pointer from elsewhere -gb_internal Ast *atomic_address_of(Ast *ptr) { +gb_internal Ast *check_atomic_address_of(Ast *ptr) { ptr = unparen_expr(ptr); for (;;) { if (ptr->kind == Ast_CallExpr && ptr->CallExpr.proc->tav.mode == Addressing_Type && ptr->CallExpr.args.count == 1) { @@ -2205,7 +2205,7 @@ gb_internal bool check_atomic_ptr_argument(Operand *operand, String const &built return false; } - Ast *ptr = atomic_address_of(operand->expr); + Ast *ptr = check_atomic_address_of(operand->expr); if (ptr == nullptr) { return true; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index d9af5b1a9..91a4bcd0a 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3067,7 +3067,7 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast * return; } if (analysis_in_use(AnalysisFlag_Atomic)) { - if (Entity *e = atomic_location(o->expr)) { + if (Entity *e = check_atomic_location(o->expr)) { per_thread_array_add(&c->info->checked_addresses_queue, CheckedAddress{node, e}); } } @@ -12897,7 +12897,7 @@ gb_internal ExprKind check_slice_expr(CheckerContext *c, Operand *o, Ast *node, return kind; } if (analysis_in_use(AnalysisFlag_Atomic) && !is_type_pointer(o->type)) { - if (Entity *e = atomic_location(node->SliceExpr.expr)) { + if (Entity *e = check_atomic_location(node->SliceExpr.expr)) { per_thread_array_add(&c->info->checked_addresses_queue, CheckedAddress{node, e}); } } diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index baae52f4e..d170cb7ef 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -2110,7 +2110,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) if (is_possibly_addressable && i == addressable_index) { entity->flags &= ~EntityFlag_Value; if (analysis_in_use(AnalysisFlag_Atomic)) { - if (Entity *e = atomic_location(expr)) { + if (Entity *e = check_atomic_location(expr)) { per_thread_array_add(&ctx->info->checked_addresses_queue, CheckedAddress{node, e}); } } diff --git a/src/checker.hpp b/src/checker.hpp index 05db715e4..51992a4ad 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -290,7 +290,7 @@ struct CheckedAtomic { struct CheckedAddress { Ast * node; // `&x`, or what is sliced or iterated by reference - Entity *location; // see `atomic_location` + Entity *location; // see `check_atomic_location` }; @@ -966,7 +966,7 @@ gb_internal isize type_info_index (CheckerInfo *info, TypeInfoPair // Will return nullptr if not found gb_internal Entity *entity_of_node(Ast *expr); -gb_internal Entity *atomic_location(Ast *expr); +gb_internal Entity *check_atomic_location(Ast *expr); // gb_internal Entity *scope_lookup_current(Scope *s, String const &name, u32 hash=0);