From e7d3e7440d27aa203d649b361b2c6b2204426397 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 25 Sep 2022 13:08:10 +0200 Subject: [PATCH] Prevent non-blocking writes to fields of automatic structs The `PEIdent::has_aa_term()` method still uses the old `symbol_search()` and will fail to find the variable if part of the identifier path is a member select of a variable. As a result such writes to fields of automatic structs can be classified as static and it is possible to do non-blocking assignments to them. E.g. ``` task automatic t; struct packed { logic x; } s; s <= ...; // This fails s.x <= ...; // This works, but should fail endtask ``` Switch to the new symbol search to make sure this case is handled correctly. The new symbol search will correctly handle identifier paths that have a trailing item after the variable, while the old symbol search will always return an error in that case. Note that while it is not allowed to do a non-blocking write to a class object automatic variable, it is allowed to do a non-blocking write to a property of a class object that is stored in an automatic variable, as the non-blocking write is supposed to capture a reference to the object and not reference the variable. E.g. ``` class C; int x; endclass task automatic t; C c; c <= ...; // Not allowed c.x <= ...; // Allowed endtask ``` Non-blocking access to class properties is not yet support in Icarus in general, but the error handling for that needs to be done somewhere else. Signed-off-by: Lars-Peter Clausen --- PExpr.cc | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/PExpr.cc b/PExpr.cc index 2bd2b78d6..ff67da5e0 100644 --- a/PExpr.cc +++ b/PExpr.cc @@ -446,19 +446,17 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type) bool PEIdent::has_aa_term(Design*des, NetScope*scope) const { - NetNet* net = 0; - ivl_type_t cls_val; - const NetExpr*par = 0; - ivl_type_t par_type; - NetEvent* eve = 0; + symbol_search_results sr; + if (!symbol_search(this, des, scope, path_, &sr)) + return false; - scope = symbol_search(this, des, scope, path_, net, par, eve, - par_type, cls_val); + // Class properties are not considered automatic since a non-blocking + // assignment to an object stored in an automatic variable is supposed to + // capture a reference to the object, not the variable. + if (!sr.path_tail.empty() && sr.net && sr.net->class_type()) + return false; - if (scope) - return scope->is_auto(); - else - return false; + return sr.scope->is_auto(); } PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)