diff --git a/elab_expr.cc b/elab_expr.cc index fd6954b37..12967412a 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2023 Stephen Williams (steve@icarus.com) + * Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com) * Copyright CERN 2013 / Stephen Williams (steve@icarus.com) * * This source code is free software; you can redistribute it @@ -4495,6 +4495,11 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope, if (!sr.net) { cerr << get_fileline() << ": error: Unable to bind variable `" << path_ << "' in `" << scope_path(scope) << "'" << endl; + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } des->errors++; return nullptr; } @@ -5016,6 +5021,11 @@ NetExpr* PEIdent::elaborate_expr_(Design*des, NetScope*scope, << "' is being used as a constant function, so may " "only reference local variables." << endl; } + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } des->errors += 1; return 0; } diff --git a/elab_lval.cc b/elab_lval.cc index 71054a72e..bc6ae087e 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -193,6 +193,11 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, cerr << get_fileline() << ": error: Could not find variable ``" << path_ << "'' in ``" << scope_path(scope) << "''" << endl; + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } } des->errors += 1; return 0; diff --git a/elab_net.cc b/elab_net.cc index 0ae06bf58..7d0024192 100644 --- a/elab_net.cc +++ b/elab_net.cc @@ -520,6 +520,11 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope, if (sig == 0) { cerr << get_fileline() << ": error: Net " << path_ << " is not defined in this context." << endl; + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } des->errors += 1; return 0; } @@ -1117,6 +1122,11 @@ NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const if (!sr.net) { cerr << get_fileline() << ": error: Net " << path_ << " is not defined in this context." << endl; + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } des->errors += 1; return nullptr; } diff --git a/elaborate.cc b/elaborate.cc index b1d6edda3..410e30eff 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -6041,6 +6041,11 @@ NetProc* PTrigger::elaborate(Design*des, NetScope*scope) const if (!symbol_search(this, des, scope, event_, lexical_pos_, &sr)) { cerr << get_fileline() << ": error: event <" << event_ << ">" << " not found." << endl; + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } des->errors += 1; return 0; } @@ -6065,6 +6070,11 @@ NetProc* PNBTrigger::elaborate(Design*des, NetScope*scope) const if (!symbol_search(this, des, scope, event_, lexical_pos_, &sr)) { cerr << get_fileline() << ": error: event <" << event_ << ">" << " not found." << endl; + if (sr.decl_after_use) { + cerr << sr.decl_after_use->get_fileline() << ": : " + "A symbol with that name was declared here. " + "Check for declaration after use." << endl; + } des->errors += 1; return 0; } diff --git a/ivtest/gold/decl_before_use1-iverilog-stderr.gold b/ivtest/gold/decl_before_use1-iverilog-stderr.gold index 4ac31fc85..bde09a416 100644 --- a/ivtest/gold/decl_before_use1-iverilog-stderr.gold +++ b/ivtest/gold/decl_before_use1-iverilog-stderr.gold @@ -1,3 +1,4 @@ ivltests/decl_before_use1.v:4: error: Could not find variable ``v'' in ``test'' +ivltests/decl_before_use1.v:9: : A symbol with that name was declared here. Check for declaration after use. ivltests/decl_before_use1.v:5: error: Unable to bind wire/reg/memory `v' in `test' 2 error(s) during elaboration. diff --git a/ivtest/gold/decl_before_use2-iverilog-stderr.gold b/ivtest/gold/decl_before_use2-iverilog-stderr.gold index b9c66eb78..40091a707 100644 --- a/ivtest/gold/decl_before_use2-iverilog-stderr.gold +++ b/ivtest/gold/decl_before_use2-iverilog-stderr.gold @@ -1,3 +1,4 @@ ivltests/decl_before_use2.v:3: error: Net w is not defined in this context. +ivltests/decl_before_use2.v:10: : A symbol with that name was declared here. Check for declaration after use. ivltests/decl_before_use2.v:6: error: Unable to bind wire/reg/memory `w' in `test' 2 error(s) during elaboration. diff --git a/ivtest/gold/decl_before_use3-iverilog-stderr.gold b/ivtest/gold/decl_before_use3-iverilog-stderr.gold index cca909053..b42d51989 100644 --- a/ivtest/gold/decl_before_use3-iverilog-stderr.gold +++ b/ivtest/gold/decl_before_use3-iverilog-stderr.gold @@ -1,2 +1,3 @@ ivltests/decl_before_use3.v:4: error: event not found. +ivltests/decl_before_use3.v:8: : A symbol with that name was declared here. Check for declaration after use. 1 error(s) during elaboration. diff --git a/ivtest/gold/decl_before_use4-iverilog-stderr.gold b/ivtest/gold/decl_before_use4-iverilog-stderr.gold index 0fea6bfee..1a6e3ebe3 100644 --- a/ivtest/gold/decl_before_use4-iverilog-stderr.gold +++ b/ivtest/gold/decl_before_use4-iverilog-stderr.gold @@ -1,3 +1,4 @@ ivltests/decl_before_use4.v:4: error: Unable to bind wire/reg/memory `e' in `test' +ivltests/decl_before_use4.v:8: : A symbol with that name was declared here. Check for declaration after use. ivltests/decl_before_use4.v:4: error: Failed to evaluate event expression 'e'. 2 error(s) during elaboration. diff --git a/netmisc.h b/netmisc.h index 0f87fee88..5ae10d6f9 100644 --- a/netmisc.h +++ b/netmisc.h @@ -49,6 +49,7 @@ struct symbol_search_results { par_val = 0; type = 0; eve = 0; + decl_after_use = 0; } inline bool is_scope() const { @@ -78,6 +79,11 @@ struct symbol_search_results { ivl_type_t type; // If this is a named event, ... NetEvent*eve; + // If a symbol was located but skipped because its lexical position + // is after the lexical position of the name being searched, it is + // stored here. If more than one such symbol is found, the first + // one is retained. + const LineInfo*decl_after_use; // Store bread crumbs of the search here. The path_tail is the parts // of the original path that were not found, or are after an object diff --git a/symbol_search.cc b/symbol_search.cc index 5db3405a6..8479ff268 100644 --- a/symbol_search.cc +++ b/symbol_search.cc @@ -170,6 +170,8 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, res->type = net->net_type(); res->path_head = path; return true; + } else if (!res->decl_after_use) { + res->decl_after_use = net; } } @@ -180,6 +182,8 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, res->eve = eve; res->path_head = path; return true; + } else if (!res->decl_after_use) { + res->decl_after_use = eve; } } @@ -190,6 +194,8 @@ bool symbol_search(const LineInfo*li, Design*des, NetScope*scope, res->par_val = par; res->path_head = path; return true; + } else if (!res->decl_after_use) { + res->decl_after_use = par; } }