From 21bfe06b3316cd5bb96e4658dfddf9ec80bcc36d Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Mon, 10 Aug 2026 22:24:18 -0700 Subject: [PATCH] Add tests for named type expression lookup Check that lookup chooses the nearest visible type or value when an identifier can denote either. Cover lexical ordering, inherited properties, and a bracket suffix that must remain a value select after lookup. Check typed expression and l-value contexts where a type must be rejected instead of binding an outer value. Check that a hierarchical type reference is rejected with the type-specific diagnostic. Check that probing an invalid hierarchical type parameter does not elaborate its signal prefix and report a false circular dependency. Signed-off-by: Lars-Peter Clausen --- ..._identifier_hier_fail-iverilog-stderr.gold | 3 ++ ...er_shadow_lvalue_fail-iverilog-stderr.gold | 4 +++ ...hadow_typed_expr_fail-iverilog-stderr.gold | 3 ++ ..._type_param_hier_fail-iverilog-stderr.gold | 2 ++ .../ivltests/sv_type_identifier_hier_fail.v | 7 ++++ ...ype_identifier_inherited_property_shadow.v | 35 +++++++++++++++++++ .../sv_type_identifier_reference_order.v | 31 ++++++++++++++++ ivtest/ivltests/sv_type_identifier_shadow.v | 33 +++++++++++++++++ .../sv_type_identifier_shadow_lvalue_fail.v | 16 +++++++++ ...v_type_identifier_shadow_typed_expr_fail.v | 16 +++++++++ .../sv_type_identifier_type_param_hier_fail.v | 6 ++++ ivtest/regress-vvp.list | 7 ++++ .../sv_type_identifier_hier_fail.json | 6 ++++ ..._identifier_inherited_property_shadow.json | 9 +++++ .../sv_type_identifier_reference_order.json | 5 +++ .../vvp_tests/sv_type_identifier_shadow.json | 5 +++ ...sv_type_identifier_shadow_lvalue_fail.json | 6 ++++ ...ype_identifier_shadow_typed_expr_fail.json | 6 ++++ ..._type_identifier_type_param_hier_fail.json | 6 ++++ 19 files changed, 206 insertions(+) create mode 100644 ivtest/gold/sv_type_identifier_hier_fail-iverilog-stderr.gold create mode 100644 ivtest/gold/sv_type_identifier_shadow_lvalue_fail-iverilog-stderr.gold create mode 100644 ivtest/gold/sv_type_identifier_shadow_typed_expr_fail-iverilog-stderr.gold create mode 100644 ivtest/gold/sv_type_identifier_type_param_hier_fail-iverilog-stderr.gold create mode 100644 ivtest/ivltests/sv_type_identifier_hier_fail.v create mode 100644 ivtest/ivltests/sv_type_identifier_inherited_property_shadow.v create mode 100644 ivtest/ivltests/sv_type_identifier_reference_order.v create mode 100644 ivtest/ivltests/sv_type_identifier_shadow.v create mode 100644 ivtest/ivltests/sv_type_identifier_shadow_lvalue_fail.v create mode 100644 ivtest/ivltests/sv_type_identifier_shadow_typed_expr_fail.v create mode 100644 ivtest/ivltests/sv_type_identifier_type_param_hier_fail.v create mode 100644 ivtest/vvp_tests/sv_type_identifier_hier_fail.json create mode 100644 ivtest/vvp_tests/sv_type_identifier_inherited_property_shadow.json create mode 100644 ivtest/vvp_tests/sv_type_identifier_reference_order.json create mode 100644 ivtest/vvp_tests/sv_type_identifier_shadow.json create mode 100644 ivtest/vvp_tests/sv_type_identifier_shadow_lvalue_fail.json create mode 100644 ivtest/vvp_tests/sv_type_identifier_shadow_typed_expr_fail.json create mode 100644 ivtest/vvp_tests/sv_type_identifier_type_param_hier_fail.json diff --git a/ivtest/gold/sv_type_identifier_hier_fail-iverilog-stderr.gold b/ivtest/gold/sv_type_identifier_hier_fail-iverilog-stderr.gold new file mode 100644 index 000000000..fa24d9822 --- /dev/null +++ b/ivtest/gold/sv_type_identifier_hier_fail-iverilog-stderr.gold @@ -0,0 +1,3 @@ +ivltests/sv_type_identifier_hier_fail.v:5: error: Type name `test.T' cannot be referenced through a hierarchical path. +ivltests/sv_type_identifier_hier_fail.v:3: : The type was declared here. +1 error(s) during elaboration. diff --git a/ivtest/gold/sv_type_identifier_shadow_lvalue_fail-iverilog-stderr.gold b/ivtest/gold/sv_type_identifier_shadow_lvalue_fail-iverilog-stderr.gold new file mode 100644 index 000000000..150a2a5f2 --- /dev/null +++ b/ivtest/gold/sv_type_identifier_shadow_lvalue_fail-iverilog-stderr.gold @@ -0,0 +1,4 @@ +ivltests/sv_type_identifier_shadow_lvalue_fail.v:13: error: Type name `value' cannot be used as a procedural l-value. +ivltests/sv_type_identifier_shadow_lvalue_fail.v:12: : The type was declared here. +ivltests/sv_type_identifier_shadow_lvalue_fail.v:13: error: I give up on task port 1 expression: value +1 error(s) during elaboration. diff --git a/ivtest/gold/sv_type_identifier_shadow_typed_expr_fail-iverilog-stderr.gold b/ivtest/gold/sv_type_identifier_shadow_typed_expr_fail-iverilog-stderr.gold new file mode 100644 index 000000000..046fc823c --- /dev/null +++ b/ivtest/gold/sv_type_identifier_shadow_typed_expr_fail-iverilog-stderr.gold @@ -0,0 +1,3 @@ +ivltests/sv_type_identifier_shadow_typed_expr_fail.v:13: error: Type name `value' cannot be used in an expression. +ivltests/sv_type_identifier_shadow_typed_expr_fail.v:12: : The type was declared here. +1 error(s) during elaboration. diff --git a/ivtest/gold/sv_type_identifier_type_param_hier_fail-iverilog-stderr.gold b/ivtest/gold/sv_type_identifier_type_param_hier_fail-iverilog-stderr.gold new file mode 100644 index 000000000..679e95016 --- /dev/null +++ b/ivtest/gold/sv_type_identifier_type_param_hier_fail-iverilog-stderr.gold @@ -0,0 +1,2 @@ +ivltests/sv_type_identifier_type_param_hier_fail.v:3: error: Type parameter `T` value `value.invalid` is not a type. +1 error(s) during elaboration. diff --git a/ivtest/ivltests/sv_type_identifier_hier_fail.v b/ivtest/ivltests/sv_type_identifier_hier_fail.v new file mode 100644 index 000000000..e00aeab89 --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_hier_fail.v @@ -0,0 +1,7 @@ +// Check that a type cannot be referenced through a hierarchical path. + +module test #(parameter type T = logic); + + localparam integer WIDTH = $bits(test.T); + +endmodule diff --git a/ivtest/ivltests/sv_type_identifier_inherited_property_shadow.v b/ivtest/ivltests/sv_type_identifier_inherited_property_shadow.v new file mode 100644 index 000000000..a8bec49c1 --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_inherited_property_shadow.v @@ -0,0 +1,35 @@ +// Check that an inherited property hides a compilation-unit type. + +typedef logic [2:0] T; + +class Base; + logic [7:0] T; +endclass + +class Derived extends Base; + function integer width; + width = $bits(T); + endfunction + + function integer slice_width; + slice_width = $bits(T[3:0]); + endfunction +endclass + +module test; + + Derived object; + + initial begin + object = new; + + if (object.width() !== 8) begin + $display("FAILED: expected 8, got %0d", object.width()); + end else if (object.slice_width() !== 4) begin + $display("FAILED: expected 4, got %0d", object.slice_width()); + end else begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_type_identifier_reference_order.v b/ivtest/ivltests/sv_type_identifier_reference_order.v new file mode 100644 index 000000000..a47acc1d2 --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_reference_order.v @@ -0,0 +1,31 @@ +// Check lexical ordering when an identifier can be a type or a value. + +integer value; +typedef logic [7:0] type_name; + +module test; + + reg failed; + + `define check(val, exp) \ + if (val !== exp) begin \ + $display("FAILED(%0d). '%s' expected %0d, got %0d", `__LINE__, \ + `"val`", exp, val); \ + failed = 1'b1; \ + end + + initial begin + failed = 1'b0; + + `check($bits(value), 32); + `check($bits(type_name), 8); + + if (!failed) begin + $display("PASSED"); + end + end + + typedef logic [3:0] value; + integer type_name; + +endmodule diff --git a/ivtest/ivltests/sv_type_identifier_shadow.v b/ivtest/ivltests/sv_type_identifier_shadow.v new file mode 100644 index 000000000..aae43b999 --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_shadow.v @@ -0,0 +1,33 @@ +// Check shadowing between type and value declarations. + +typedef logic [15:0] type_name; +integer value_name; + +module test; + + integer type_name; + typedef logic [7:0] value_name; + reg failed; + + `define check(value, expected) \ + if ((value) !== (expected)) begin \ + $display("FAILED(%0d). Expected %0d, got %0d", `__LINE__, \ + expected, value); \ + failed = 1'b1; \ + end + + initial begin + failed = 1'b0; + + // A nearer value declaration hides an outer type declaration. + `check($bits(type_name), 32); + + // A nearer type declaration hides an outer value declaration. + `check($bits(value_name), 8); + + if (!failed) begin + $display("PASSED"); + end + end + +endmodule diff --git a/ivtest/ivltests/sv_type_identifier_shadow_lvalue_fail.v b/ivtest/ivltests/sv_type_identifier_shadow_lvalue_fail.v new file mode 100644 index 000000000..123b65e0e --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_shadow_lvalue_fail.v @@ -0,0 +1,16 @@ +// Check that a typedef prevents an l-value from binding an outer variable. + +module test; + + integer value; + + task set_value(output integer result); + result = 1; + endtask + + initial begin : inner + typedef logic value; + set_value(value); + end + +endmodule diff --git a/ivtest/ivltests/sv_type_identifier_shadow_typed_expr_fail.v b/ivtest/ivltests/sv_type_identifier_shadow_typed_expr_fail.v new file mode 100644 index 000000000..44651625d --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_shadow_typed_expr_fail.v @@ -0,0 +1,16 @@ +// Check that a typedef shadows an outer value in a typed expression. + +class C; +endclass + +module test; + + C value; + C result; + + initial begin : inner + typedef logic value; + result = value; + end + +endmodule diff --git a/ivtest/ivltests/sv_type_identifier_type_param_hier_fail.v b/ivtest/ivltests/sv_type_identifier_type_param_hier_fail.v new file mode 100644 index 000000000..6fee06d57 --- /dev/null +++ b/ivtest/ivltests/sv_type_identifier_type_param_hier_fail.v @@ -0,0 +1,6 @@ +// Check that testing an invalid type parameter does not elaborate its prefix. + +module test; + wire [$bits(T)-1:0] value; + parameter type T = value.invalid; +endmodule diff --git a/ivtest/regress-vvp.list b/ivtest/regress-vvp.list index 41b21f62a..41812ce18 100644 --- a/ivtest/regress-vvp.list +++ b/ivtest/regress-vvp.list @@ -509,6 +509,8 @@ sv_type_identifier_fork_prefix_label_name vvp_tests/sv_type_identifier_fork_pref sv_type_identifier_function_name vvp_tests/sv_type_identifier_function_name.json sv_type_identifier_generate_label_name vvp_tests/sv_type_identifier_generate_label_name.json sv_type_identifier_genvar_name vvp_tests/sv_type_identifier_genvar_name.json +sv_type_identifier_hier_fail vvp_tests/sv_type_identifier_hier_fail.json +sv_type_identifier_inherited_property_shadow vvp_tests/sv_type_identifier_inherited_property_shadow.json sv_type_identifier_modport_name vvp_tests/sv_type_identifier_modport_name.json sv_type_identifier_modport_named_port vvp_tests/sv_type_identifier_modport_named_port.json sv_type_identifier_module_name vvp_tests/sv_type_identifier_module_name.json @@ -528,14 +530,19 @@ sv_type_identifier_parameter_type_param_name vvp_tests/sv_type_identifier_parame sv_type_identifier_port_name vvp_tests/sv_type_identifier_port_name.json sv_type_identifier_procedural_lvalue vvp_tests/sv_type_identifier_procedural_lvalue.json sv_type_identifier_procedural_lvalue_fail vvp_tests/sv_type_identifier_procedural_lvalue_fail.json +sv_type_identifier_reference_order vvp_tests/sv_type_identifier_reference_order.json +sv_type_identifier_shadow vvp_tests/sv_type_identifier_shadow.json sv_type_identifier_shadow_function_call_fail vvp_tests/sv_type_identifier_shadow_function_call_fail.json sv_type_identifier_shadow_function_statement_fail vvp_tests/sv_type_identifier_shadow_function_statement_fail.json sv_type_identifier_shadow_implicit_port_fail vvp_tests/sv_type_identifier_shadow_implicit_port_fail.json +sv_type_identifier_shadow_lvalue_fail vvp_tests/sv_type_identifier_shadow_lvalue_fail.json sv_type_identifier_shadow_task_call_fail vvp_tests/sv_type_identifier_shadow_task_call_fail.json +sv_type_identifier_shadow_typed_expr_fail vvp_tests/sv_type_identifier_shadow_typed_expr_fail.json sv_type_identifier_shadow_wildcard_port_fail vvp_tests/sv_type_identifier_shadow_wildcard_port_fail.json sv_type_identifier_specparam_name vvp_tests/sv_type_identifier_specparam_name.json sv_type_identifier_task_function_argument_name vvp_tests/sv_type_identifier_task_function_argument_name.json sv_type_identifier_task_name vvp_tests/sv_type_identifier_task_name.json +sv_type_identifier_type_param_hier_fail vvp_tests/sv_type_identifier_type_param_hier_fail.json sv_type_identifier_typed_expression vvp_tests/sv_type_identifier_typed_expression.json sv_type_identifier_typed_expression_fail vvp_tests/sv_type_identifier_typed_expression_fail.json sv_type_identifier_udp_ansi_name vvp_tests/sv_type_identifier_udp_ansi_name.json diff --git a/ivtest/vvp_tests/sv_type_identifier_hier_fail.json b/ivtest/vvp_tests/sv_type_identifier_hier_fail.json new file mode 100644 index 000000000..51f989ecd --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_hier_fail.json @@ -0,0 +1,6 @@ +{ + "type" : "CE", + "source" : "sv_type_identifier_hier_fail.v", + "gold" : "sv_type_identifier_hier_fail", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_type_identifier_inherited_property_shadow.json b/ivtest/vvp_tests/sv_type_identifier_inherited_property_shadow.json new file mode 100644 index 000000000..7230498cd --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_inherited_property_shadow.json @@ -0,0 +1,9 @@ +{ + "type" : "normal", + "source" : "sv_type_identifier_inherited_property_shadow.v", + "iverilog-args" : [ "-g2005-sv" ], + "vlog95" : { + "__comment" : "Classes are not supported", + "type" : "CE" + } +} diff --git a/ivtest/vvp_tests/sv_type_identifier_reference_order.json b/ivtest/vvp_tests/sv_type_identifier_reference_order.json new file mode 100644 index 000000000..325d19516 --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_reference_order.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_type_identifier_reference_order.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_type_identifier_shadow.json b/ivtest/vvp_tests/sv_type_identifier_shadow.json new file mode 100644 index 000000000..4da9b5438 --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_shadow.json @@ -0,0 +1,5 @@ +{ + "type" : "normal", + "source" : "sv_type_identifier_shadow.v", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_type_identifier_shadow_lvalue_fail.json b/ivtest/vvp_tests/sv_type_identifier_shadow_lvalue_fail.json new file mode 100644 index 000000000..b13180a6c --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_shadow_lvalue_fail.json @@ -0,0 +1,6 @@ +{ + "type" : "CE", + "source" : "sv_type_identifier_shadow_lvalue_fail.v", + "gold" : "sv_type_identifier_shadow_lvalue_fail", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_type_identifier_shadow_typed_expr_fail.json b/ivtest/vvp_tests/sv_type_identifier_shadow_typed_expr_fail.json new file mode 100644 index 000000000..a70afbbd4 --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_shadow_typed_expr_fail.json @@ -0,0 +1,6 @@ +{ + "type" : "CE", + "source" : "sv_type_identifier_shadow_typed_expr_fail.v", + "gold" : "sv_type_identifier_shadow_typed_expr_fail", + "iverilog-args" : [ "-g2005-sv" ] +} diff --git a/ivtest/vvp_tests/sv_type_identifier_type_param_hier_fail.json b/ivtest/vvp_tests/sv_type_identifier_type_param_hier_fail.json new file mode 100644 index 000000000..030947044 --- /dev/null +++ b/ivtest/vvp_tests/sv_type_identifier_type_param_hier_fail.json @@ -0,0 +1,6 @@ +{ + "type" : "CE", + "source" : "sv_type_identifier_type_param_hier_fail.v", + "gold" : "sv_type_identifier_type_param_hier_fail", + "iverilog-args" : [ "-g2005-sv" ] +}