diff --git a/elab_expr.cc b/elab_expr.cc index 464b549e7..77ef3f609 100644 --- a/elab_expr.cc +++ b/elab_expr.cc @@ -1642,6 +1642,9 @@ unsigned PECallFunction::test_width(Design*des, NetScope*scope, return 0; } + if (def->is_void()) + return 0; + NetScope*dscope = def->scope(); assert(dscope); @@ -2706,8 +2709,7 @@ NetExpr* PECallFunction::elaborate_expr_(Design*des, NetScope*scope, } // If the symbol is found, but is not a _function_ scope... - NetFuncDef*def = search_results.scope->func_def(); - if (def == 0) { + if (search_results.scope->type() != NetScope::FUNC) { // Not a user defined function. Maybe it is an access // function for a nature? If so then elaborate it that // way. @@ -2722,6 +2724,7 @@ NetExpr* PECallFunction::elaborate_expr_(Design*des, NetScope*scope, des->errors += 1; return 0; } + NetFuncDef*def = search_results.scope->func_def(); ivl_assert(*this, def); ivl_assert(*this, def->scope() == search_results.scope); @@ -2860,6 +2863,14 @@ NetExpr* PECallFunction::elaborate_base_(Design*des, NetScope*scope, NetScope*ds if (parm_errors) return 0; + if (def->is_void()) { + cerr << get_fileline() << ": error: void function `" + << dscope->basename() << "` can not be called in an expression." + << endl; + des->errors++; + return nullptr; + } + /* Look for the return value signal for the called function. This return value is a magic signal in the scope of the function, that has the name of the function. The diff --git a/ivtest/ivltests/func_void_in_expr_fail.v b/ivtest/ivltests/func_void_in_expr_fail.v new file mode 100644 index 000000000..8b065f2e7 --- /dev/null +++ b/ivtest/ivltests/func_void_in_expr_fail.v @@ -0,0 +1,14 @@ +// Check that an error is reported when a void function is used in an expression + +module test; + + function void f; + endfunction + + initial begin + int x; + x = f() + 1; // This should fail, void function can not be used in expression + $display("FAILED"); + end + +endmodule diff --git a/ivtest/ivltests/task_in_expr_fail.v b/ivtest/ivltests/task_in_expr_fail.v new file mode 100644 index 000000000..4ff3e8ff0 --- /dev/null +++ b/ivtest/ivltests/task_in_expr_fail.v @@ -0,0 +1,14 @@ +// Check that an error is reported when a task is used in an expression + +module test; + + task t; + endtask + + initial begin + int x; + x = t() + 1; // This should fail, task can not be used in expression + $display("FAILED"); + end + +endmodule diff --git a/ivtest/regress-sv.list b/ivtest/regress-sv.list index c04b1ca67..d002e84a3 100644 --- a/ivtest/regress-sv.list +++ b/ivtest/regress-sv.list @@ -312,6 +312,7 @@ fr49 normal,-g2009 ivltests func_init_var1 normal,-g2009 ivltests func_init_var2 normal,-g2009 ivltests func_init_var3 normal,-g2009 ivltests +func_void_in_expr_fail CE,-g2005-sv ivltests function10 CO,-g2005-sv ivltests function11 CE,-g2005-sv ivltests function12 normal,-g2005-sv ivltests gold=function12.gold diff --git a/ivtest/regress-vlg.list b/ivtest/regress-vlg.list index c6c70a513..57f82c2e2 100644 --- a/ivtest/regress-vlg.list +++ b/ivtest/regress-vlg.list @@ -1650,6 +1650,7 @@ task3.14D normal ivltests task3.14E normal ivltests task3.14F normal ivltests task_bypath normal ivltests # task enabled by complete path name. +task_in_expr_fail CE ivltests task_inpad normal ivltests # Validates input of task should pad w/ 0 task_iotypes normal ivltests # task ports with types. task_iotypes2 normal ivltests # task ports with types.