From 85edd8bb182809f297a01ae3ba2f06356dfc8ccd Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 4 Oct 2022 22:01:18 +0200 Subject: [PATCH 1/2] Handle calling void function from class method Calling a void function (or a regular function and ignoring the result) from within a class method will currently result in an error unless the void function itself is a method of the same class. This is because we add the implicit `this` as an object on which to search for the function and if we do not find it print an error. Change this to only print an error if the implicit this was not added and it was a method call on an object identifier. Signed-off-by: Lars-Peter Clausen --- elaborate.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/elaborate.cc b/elaborate.cc index 6a38d8b16..f23e796c4 100644 --- a/elaborate.cc +++ b/elaborate.cc @@ -3844,10 +3844,15 @@ NetProc* PCallTask::elaborate_method_(Design*des, NetScope*scope, if (const netclass_t*class_type = net->class_type()) { NetScope*task = class_type->method_from_name(method_name); if (task == 0) { - cerr << get_fileline() << ": error: " - << "Can't find task " << method_name - << " in class " << class_type->get_name() << endl; - des->errors += 1; + // If an implicit this was added it is not an error if we + // don't find a method. It might actually be a call to a + // function outside of the class. + if (!add_this_flag) { + cerr << get_fileline() << ": error: " + << "Can't find task " << method_name + << " in class " << class_type->get_name() << endl; + des->errors += 1; + } return 0; } From 9107e298a342bda5737eb5680fb3b8de1df9951b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Sat, 8 Oct 2022 15:59:42 +0200 Subject: [PATCH 2/2] Add regression test for calling void functions from class method Check that it is possible to call a void function from a class method. Check this for both functions defined in the global scope as well as functions that are methods of the class or a base class. Signed-off-by: Lars-Peter Clausen --- ivtest/ivltests/sv_class_method_call_void.v | 46 +++++++++++++++++++++ ivtest/regress-sv.list | 1 + ivtest/regress-vlog95.list | 1 + 3 files changed, 48 insertions(+) create mode 100644 ivtest/ivltests/sv_class_method_call_void.v diff --git a/ivtest/ivltests/sv_class_method_call_void.v b/ivtest/ivltests/sv_class_method_call_void.v new file mode 100644 index 000000000..bb76540fa --- /dev/null +++ b/ivtest/ivltests/sv_class_method_call_void.v @@ -0,0 +1,46 @@ +// Check that it is possible to call void function from within a class method. +// Check this for functions defined outside the class as well as functions that +// are methods of the class or base class. + +integer sum = 0; + +function void f1(integer x); + sum += x; +endfunction + +class B; + function void f2(integer x); + sum += x; + endfunction +endclass + +class C extends B; + + function void f3(integer x); + sum += x; + endfunction + + task t; + f1(10); + f2(20); + f3(30); + endtask + +endclass + +module test; + + C c = new; + + initial begin + c.t; + c.f2(40); + c.f3(50); + if (sum === 150) begin + $display("PASSED"); + end else begin + $display("FAILED"); + end + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index e423c2a86..69695b38f 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -529,6 +529,7 @@ sv_class_new_fail1 CE,-g2009 ivltests sv_class_new_fail2 CE,-g2009 ivltests sv_class_new_init normal,-g2009 ivltests sv_class_in_module_decl normal,-g2009 ivltests +sv_class_method_call_void normal,-g2009 ivltests sv_class_method_default1 normal,-g2009 ivltests sv_class_method_default2 normal,-g2009 ivltests sv_class_method_signed1 normal,-g2009 ivltests diff --git a/ivtest/regress-vlog95.list b/ivtest/regress-vlog95.list index 97ad90d58..cde38066f 100644 --- a/ivtest/regress-vlog95.list +++ b/ivtest/regress-vlog95.list @@ -409,6 +409,7 @@ sv_class_extends_scoped CE,-g2009 ivltests sv_class_localparam CE,-g2009 ivltests sv_class_new_init CE,-g2009 ivltests sv_class_in_module_decl CE,-g2009 ivltests +sv_class_method_call_void CE,-g2009 ivltests sv_class_method_default1 CE,-g2009 ivltests sv_class_method_default2 CE,-g2009 ivltests sv_class_method_signed1 CE,-g2009,-pallowsigned=1 ivltests