From eaa719760274a8e2157e86cfa3cd40ef059dcd3d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 21 Jun 2026 14:28:00 -0700 Subject: [PATCH 1/2] Handle bogus member l-value paths Currently the procedural l-value path asserts if symbol lookup leaves a member tail for a variable that is not a struct or class. For example, `r.bad = 1'b1;` where `r` is a scalar variable aborts during elaboration instead of reporting a normal error. Report an error for the leftover member path before the assertion. This matches the r-value path behavior for the same kind of invalid member access. Signed-off-by: Lars-Peter Clausen --- elab_lval.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/elab_lval.cc b/elab_lval.cc index 1068954d1..526b15d5b 100644 --- a/elab_lval.cc +++ b/elab_lval.cc @@ -298,6 +298,15 @@ NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope, // Past this point, we should have taken care of the cases // where the name is a member/method of a struct/class. // XXXX ivl_assert(*this, method_name.nil()); + if (!tail_path.empty()) { + cerr << get_fileline() << ": error: Variable " + << reg->name() + << " does not have a field named: " + << tail_path << "." << endl; + des->errors += 1; + return nullptr; + } + ivl_assert(*this, tail_path.empty()); bool need_const_idx = is_cassign || is_force; From 3c7250eb5173bac8d2f73dfc452cb22c6ebc079f Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sun, 21 Jun 2026 14:29:32 -0700 Subject: [PATCH 2/2] Add regression test for bogus member l-values Check that bogus member access on a procedural l-value is rejected with a normal compile error instead of aborting during elaboration. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_bad_member_lval_proc_fail.v | 9 +++++++++ ivtest/regress-vvp.list | 1 + ivtest/vvp_tests/sv_bad_member_lval_proc_fail.json | 5 +++++ 3 files changed, 15 insertions(+) create mode 100644 ivtest/ivltests/sv_bad_member_lval_proc_fail.v create mode 100644 ivtest/vvp_tests/sv_bad_member_lval_proc_fail.json diff --git a/ivtest/ivltests/sv_bad_member_lval_proc_fail.v b/ivtest/ivltests/sv_bad_member_lval_proc_fail.v new file mode 100644 index 000000000..5b43b7afe --- /dev/null +++ b/ivtest/ivltests/sv_bad_member_lval_proc_fail.v @@ -0,0 +1,9 @@ +// Check that bogus member access on procedural l-values reports an error. + +module test; + logic r; + + initial begin + r.bad = 1'b1; + end +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index b66ada6b5..3ad3643f1 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -254,6 +254,7 @@ sv_array_cassign10 vvp_tests/sv_array_cassign10.json sv_array_cassign_single vvp_tests/sv_array_cassign_single.json sv_array_cassign_single_fail1 vvp_tests/sv_array_cassign_single_fail1.json sv_automatic_2state vvp_tests/sv_automatic_2state.json +sv_bad_member_lval_proc_fail vvp_tests/sv_bad_member_lval_proc_fail.json sv_byte_array_string1 vvp_tests/sv_byte_array_string1.json sv_byte_array_string2 vvp_tests/sv_byte_array_string2.json sv_byte_array_string3 vvp_tests/sv_byte_array_string3.json diff --git a/ivtest/vvp_tests/sv_bad_member_lval_proc_fail.json b/ivtest/vvp_tests/sv_bad_member_lval_proc_fail.json new file mode 100644 index 000000000..dc312633a --- /dev/null +++ b/ivtest/vvp_tests/sv_bad_member_lval_proc_fail.json @@ -0,0 +1,5 @@ +{ + "type" : "CE", + "source" : "sv_bad_member_lval_proc_fail.v", + "iverilog-args" : [ "-g2005-sv" ] +}