From 165622a9e9626fa3f8b1c83b20b4060215636185 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 7 Oct 2025 21:06:11 -0400 Subject: [PATCH] Add NORETURN warning on functions without return values (#6534). --- Changes | 1 + docs/gen/ex_NORETURN_faulty.rst | 7 ++ docs/gen/ex_NORETURN_msg.rst | 4 + docs/guide/warnings.rst | 21 +++++ src/V3Ast.h | 43 ++++++--- src/V3Error.h | 5 +- src/V3ParseGrammar.h | 1 + src/V3Randomize.cpp | 1 + src/V3Width.cpp | 7 ++ src/verilog.y | 2 + test_regress/t/t_class_assign_bad.v | 2 +- test_regress/t/t_class_defaultparams.v | 1 + test_regress/t/t_class_extends.v | 2 + test_regress/t/t_class_extern_args_bad.out | 32 +++---- test_regress/t/t_class_extern_args_bad.v | 3 + test_regress/t/t_class_hier_construction.v | 91 ++++++++++---------- test_regress/t/t_class_misstatic_bad.out | 18 ++-- test_regress/t/t_class_misstatic_bad.v | 64 +++++++------- test_regress/t/t_class_param_extends3.v | 1 + test_regress/t/t_class_param_super.v | 2 +- test_regress/t/t_covergroup_args.v | 2 +- test_regress/t/t_fork_func2_bad.out | 6 +- test_regress/t/t_fork_func2_bad.v | 19 ++-- test_regress/t/t_func_const_bad.out | 64 +++++++------- test_regress/t/t_func_const_bad.v | 82 +++++++++--------- test_regress/t/t_func_no_paren.v | 29 ++++--- test_regress/t/t_func_ref_noparen.v | 16 ++-- test_regress/t/t_func_uninit.v | 1 + test_regress/t/t_interface_virtual_unused2.v | 2 +- test_regress/t/t_json_only_tag.out | 65 +++++++------- test_regress/t/t_json_only_tag.v | 2 +- test_regress/t/t_lint_noreturn.py | 18 ++++ test_regress/t/t_lint_noreturn.v | 22 +++++ test_regress/t/t_lint_noreturn_bad.out | 7 ++ test_regress/t/t_lint_noreturn_bad.py | 27 ++++++ test_regress/t/t_lint_noreturn_param.py | 18 ++++ test_regress/t/t_lint_noreturn_param.v | 21 +++++ test_regress/t/t_lint_noreturn_param_bad.out | 12 +++ test_regress/t/t_lint_noreturn_param_bad.py | 18 ++++ test_regress/t/t_lint_noreturn_param_bad.v | 21 +++++ test_regress/t/t_static_dup_name.v | 2 +- test_regress/t/t_xml_tag.out | 9 +- test_regress/t/t_xml_tag.v | 2 +- 43 files changed, 509 insertions(+), 264 deletions(-) create mode 100644 docs/gen/ex_NORETURN_faulty.rst create mode 100644 docs/gen/ex_NORETURN_msg.rst create mode 100755 test_regress/t/t_lint_noreturn.py create mode 100644 test_regress/t/t_lint_noreturn.v create mode 100644 test_regress/t/t_lint_noreturn_bad.out create mode 100755 test_regress/t/t_lint_noreturn_bad.py create mode 100755 test_regress/t/t_lint_noreturn_param.py create mode 100644 test_regress/t/t_lint_noreturn_param.v create mode 100644 test_regress/t/t_lint_noreturn_param_bad.out create mode 100755 test_regress/t/t_lint_noreturn_param_bad.py create mode 100644 test_regress/t/t_lint_noreturn_param_bad.v diff --git a/Changes b/Changes index 9ff7dc354..ddd2b76d2 100644 --- a/Changes +++ b/Changes @@ -24,6 +24,7 @@ Verilator 5.041 devel * Add FUNCTIMCTL error on function invoking task or time-controlling statements (#6385). * Add error on `virtual new` (#6486). [Alex Solomatnikov] * Add error on ranges with tristate values (#6534). [Alex Solomatnikov] +* Add NORETURN warning on functions without return values (#6534). [Alex Solomatnikov] * Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore] * Deprecate clocker attribute and --clk option (#6463). [Geza Lore] * Change default `--expand-limit` to 256 (#3419). diff --git a/docs/gen/ex_NORETURN_faulty.rst b/docs/gen/ex_NORETURN_faulty.rst new file mode 100644 index 000000000..bf5bc5d8f --- /dev/null +++ b/docs/gen/ex_NORETURN_faulty.rst @@ -0,0 +1,7 @@ +.. comment: generated by t_lint_noreturn_bad +.. code-block:: sv + :linenos: + :emphasize-lines: 1 + + function int no_rtn(); // <--- Warning: No return + endfunction diff --git a/docs/gen/ex_NORETURN_msg.rst b/docs/gen/ex_NORETURN_msg.rst new file mode 100644 index 000000000..e91a51594 --- /dev/null +++ b/docs/gen/ex_NORETURN_msg.rst @@ -0,0 +1,4 @@ +.. comment: generated by t_lint_noreturn_bad +.. code-block:: + + %Warning-NORETURN: example.v:1:16 Non-void function 'no_rtn' has no return value diff --git a/docs/guide/warnings.rst b/docs/guide/warnings.rst index 0bdde1e5a..d724a834e 100644 --- a/docs/guide/warnings.rst +++ b/docs/guide/warnings.rst @@ -1439,6 +1439,27 @@ List Of Warnings simulate correctly. +.. option:: NORETURN + + Warns that a non-void function has no return statement, nor sets the + output result of the function. + + Faulty example: + + .. include:: ../../docs/gen/ex_NORETURN_faulty.rst + + Results in: + + .. include:: ../../docs/gen/ex_NORETURN_msg.rst + + To fix the issue, add a :code:`return` statement, or set the output + variable of the function, or make the function of data type + :code:`void`. + + Ignoring this warning will only suppress the lint check; it will + simulate correctly. + + .. option:: NOTIMING Error when a timing-related construct that requires :vlopt:`--timing` has diff --git a/src/V3Ast.h b/src/V3Ast.h index 5f0cb5df4..e404cf5cf 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1100,7 +1100,8 @@ private: bool visitNext); template - inline static bool predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& p); + inline static bool predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& p, + bool visitNext); public: // Given a callable 'f' that takes a single argument of some AstNode subtype 'T_Node', traverse @@ -1119,7 +1120,6 @@ public: "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ false); } - // Same as above, but for 'const' nodes template void foreach(T_Callable&& f) const { @@ -1131,7 +1131,6 @@ public: "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ false); } - // Same as 'foreach' but also traverses 'this->nextp()' transitively template void foreachAndNext(T_Callable&& f) { @@ -1142,7 +1141,6 @@ public: "with 'T_Node' being a subtype of 'AstNode'"); foreachImpl(this, f, /* visitNext: */ true); } - // Same as above, but for 'const' nodes template void foreachAndNext(T_Callable&& f) const { @@ -1167,9 +1165,8 @@ public: && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p, /* visitNext: */ false); } - // Same as above, but for 'const' nodes template bool exists(T_Callable&& p) const { @@ -1178,7 +1175,28 @@ public: && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p, + /* visitNext: */ false); + } + // Same as 'exists' but also traverses 'this->nextp()' transitively + template + bool existsAndNext(T_Callable&& p) { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable_r::value + && std::is_base_of::value, + "Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', " + "with 'T_Node' being a subtype of 'AstNode'"); + return predicateImpl(this, p, /* visitNext: */ true); + } + // Same as above, but for 'const' nodes + template + bool existsAndNext(T_Callable&& p) const { + using T_Node = typename FunctionArgNoPointerNoCV::type; + static_assert(vlstd::is_invocable_r::value + && std::is_base_of::value, + "Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', " + "with 'T_Node' being a subtype of 'AstNode'"); + return predicateImpl(this, p, /* visitNext: */ true); } // Given a predicate 'p' that takes a single argument of some AstNode subtype 'T_Node', return @@ -1192,9 +1210,8 @@ public: && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p, /* visitNext: */ false); } - // Same as above, but for 'const' nodes template bool forall(T_Callable&& p) const { @@ -1203,7 +1220,7 @@ public: && std::is_base_of::value, "Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', " "with 'T_Node' being a subtype of 'AstNode'"); - return predicateImpl(this, p); + return predicateImpl(this, p, /* visitNext: */ false); } int nodeCount() const { @@ -1365,7 +1382,8 @@ void AstNode::foreachImpl(ConstCorrectAstNode* nodep, const T_Callable& f // predicate implementation template -bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& p) { +bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& p, + bool visitNext) { // Implementation similar to foreach, but abort traversal as soon as result is determined using T_Arg_NonConst = typename std::remove_const::type; using Node = ConstCorrectAstNode; @@ -1410,6 +1428,9 @@ bool AstNode::predicateImpl(ConstCorrectAstNode* nodep, const T_Callable& return false; }; + // Enqueue the next of the root node, if required + if (visitNext && nodep->nextp()) *topp++ = nodep->nextp(); + // Visit the root node if (visit(nodep)) return !N_Default; diff --git a/src/V3Error.h b/src/V3Error.h index b98f354fb..655dd6e2c 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -133,6 +133,7 @@ public: NOEFFECT, // Statement has no effect NOLATCH, // No latch detected in always_latch block NONSTD, // Non-standard feature present in other sims + NORETURN, // Function with no return NULLPORT, // Null port detected in module definition PARAMNODEFAULT, // Parameter without default PINCONNECTEMPTY,// Cell pin connected by name with empty reference @@ -219,8 +220,8 @@ public: "IMPERFECTSCH", "IMPLICIT", "IMPLICITSTATIC", "IMPORTSTAR", "IMPURE", "INCABSPATH", "INFINITELOOP", "INITIALDLY", "INSECURE", "LATCH", "LITENDIAN", "MINTYPMAXDLY", "MISINDENT", "MODDUP", "MODMISSING", "MULTIDRIVEN", "MULTITOP", "NEWERSTD", "NOEFFECT", - "NOLATCH", "NONSTD", "NULLPORT", "PARAMNODEFAULT", "PINCONNECTEMPTY", "PINMISSING", - "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT", + "NOLATCH", "NONSTD", "NORETURN", "NULLPORT", "PARAMNODEFAULT", "PINCONNECTEMPTY", + "PINMISSING", "PINNOCONNECT", "PINNOTFOUND", "PKGNODECL", "PREPROCZERO", "PROCASSINIT", "PROCASSWIRE", "PROFOUTOFDATE", "PROTECTED", "PROTOTYPEMIS", "RANDC", "REALCVT", "REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN", "SPLITVAR", "STATICVAR", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET", "TICKCOUNT", diff --git a/src/V3ParseGrammar.h b/src/V3ParseGrammar.h index 0c391f5a9..fc1f8239c 100644 --- a/src/V3ParseGrammar.h +++ b/src/V3ParseGrammar.h @@ -118,6 +118,7 @@ public: // IEEE: function real get_inst_coverage(optional ref int, optional ref int) for (const string& name : {"get_coverage"s, "get_inst_coverage"s}) { AstFunc* const funcp = new AstFunc{nodep->fileline(), name, nullptr, nullptr}; + funcp->fileline()->warnOff(V3ErrorCode::NORETURN, true); funcp->isStatic(name == "get_coverage"); funcp->classMethod(true); funcp->dtypep(funcp->findVoidDType()); diff --git a/src/V3Randomize.cpp b/src/V3Randomize.cpp index 409d7d448..64525ccfd 100644 --- a/src/V3Randomize.cpp +++ b/src/V3Randomize.cpp @@ -2554,6 +2554,7 @@ AstFunc* V3Randomize::newRandomizeFunc(VMemberMap& memberMap, AstClass* nodep, ? new AstVar{nodep->fileline(), VVarType::MEMBER, name, VFlagChildDType{}, dtypep} : new AstVar{nodep->fileline(), VVarType::MEMBER, name, dtypep}; + fvarp->fileline()->warnOff(V3ErrorCode::NORETURN, true); fvarp->lifetime(VLifetime::AUTOMATIC_EXPLICIT); fvarp->funcLocal(true); fvarp->funcReturn(true); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index babe67c01..3cbf67edc 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -6324,6 +6324,13 @@ class WidthVisitor final : public VNVisitor { nodep->dpiOpenParentInc(); // Mark so V3Task will wait for a child to build calling // func } + if (nodep->fvarp() && !nodep->dpiImport() && !nodep->pureVirtual() + && (!nodep->stmtsp() || !nodep->stmtsp()->existsAndNext([&](const AstVarRef* varrefp) { + return varrefp->varp() == nodep->fvarp(); + }))) { + nodep->v3warn(NORETURN, + "Non-void function " << nodep->prettyNameQ() << " has no return value"); + } std::vector ports; std::vector protos; diff --git a/src/verilog.y b/src/verilog.y index 002f14db7..d833fb098 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -6721,6 +6721,7 @@ covergroup_declaration: // ==IEEE: covergroup_declaration /*cont*/ yENDGROUP endLabelE { AstClass *cgClassp = new AstClass{$2, *$2, PARSEP->libname()}; AstFunc* const newp = new AstFunc{$1, "new", nullptr, nullptr}; + newp->fileline()->warnOff(V3ErrorCode::NORETURN, true); newp->classMethod(true); newp->isConstructor(true); newp->dtypep(cgClassp->dtypep()); @@ -6737,6 +6738,7 @@ covergroup_declaration: // ==IEEE: covergroup_declaration /*cont*/ yENDGROUP endLabelE { AstClass *cgClassp = new AstClass{$3, *$3, PARSEP->libname()}; AstFunc* const newp = new AstFunc{$1, "new", nullptr, nullptr}; + newp->fileline()->warnOff(V3ErrorCode::NORETURN, true); newp->classMethod(true); newp->isConstructor(true); newp->dtypep(cgClassp->dtypep()); diff --git a/test_regress/t/t_class_assign_bad.v b/test_regress/t/t_class_assign_bad.v index 97dec5f9e..bf79a2b17 100644 --- a/test_regress/t/t_class_assign_bad.v +++ b/test_regress/t/t_class_assign_bad.v @@ -22,7 +22,7 @@ module t; ClsExt c_ext; task t(Cls c); endtask - function f(ClsExt c); endfunction + function void f(ClsExt c); endfunction initial begin c = 0; diff --git a/test_regress/t/t_class_defaultparams.v b/test_regress/t/t_class_defaultparams.v index 76cfd7cb8..0d95a5aa5 100644 --- a/test_regress/t/t_class_defaultparams.v +++ b/test_regress/t/t_class_defaultparams.v @@ -4,6 +4,7 @@ // any use, without warranty, 2025 by Antmicro. // SPDX-License-Identifier: CC0-1.0 +// verilator lint_off NORETURN class c0 #(type T= real); static function T f(); endfunction diff --git a/test_regress/t/t_class_extends.v b/test_regress/t/t_class_extends.v index 0df8dfc09..387fd50a9 100644 --- a/test_regress/t/t_class_extends.v +++ b/test_regress/t/t_class_extends.v @@ -27,6 +27,7 @@ endclass : Cls class uvm_object_wrapper; function int create (); + return 0; endfunction endclass @@ -35,6 +36,7 @@ class uvm__registry #(type T=int) extends uvm_object_wrapper; // under the extend's symbol table function int create (); T obj; + return 0; endfunction endclass diff --git a/test_regress/t/t_class_extern_args_bad.out b/test_regress/t/t_class_extern_args_bad.out index facf52cdb..25980be22 100644 --- a/test_regress/t/t_class_extern_args_bad.out +++ b/test_regress/t/t_class_extern_args_bad.out @@ -14,8 +14,8 @@ : ... Declaration data type: 'bit' 9 | extern function int f1_bad(); | ^~~ - t/t_class_extern_args_bad.v:22:10: ... Location of out-of-block declaration - 22 | function bit Cls::f1_bad(); + t/t_class_extern_args_bad.v:23:10: ... Location of out-of-block declaration + 23 | function bit Cls::f1_bad(); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:10:19: In prototype for 'f2_bad', return data type does not match out-of-block declaration data-type (IEEE 1800-2023 8.24) : ... note: In instance 't' @@ -23,8 +23,8 @@ : ... Declaration data type: 'VOIDDTYPE' 10 | extern function int f2_bad(); | ^~~ - t/t_class_extern_args_bad.v:24:15: ... Location of out-of-block declaration - 24 | function void Cls::f2_bad(); + t/t_class_extern_args_bad.v:26:15: ... Location of out-of-block declaration + 26 | function void Cls::f2_bad(); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:11:24: In prototype for 'f3_bad', return data type does not match out-of-block declaration data-type (IEEE 1800-2023 8.24) : ... note: In instance 't' @@ -32,8 +32,8 @@ : ... Declaration data type: 'bit' 11 | extern function void f3_bad(); | ^~~~~~ - t/t_class_extern_args_bad.v:26:10: ... Location of out-of-block declaration - 26 | function bit Cls::f3_bad(); + t/t_class_extern_args_bad.v:28:10: ... Location of out-of-block declaration + 28 | function bit Cls::f3_bad(); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:12:34: In prototype for 'f1bit_bad', argument 'a' data-type does not match out-of-block declaration's data-type (IEEE 1800-2023 8.24) : ... note: In instance 't' @@ -41,35 +41,35 @@ : ... Declaration data type: 'bit' 12 | extern function void f1bit_bad(int a); | ^~~ - t/t_class_extern_args_bad.v:29:30: ... Location of out-of-block declaration - 29 | function void Cls::f1bit_bad(bit a); + t/t_class_extern_args_bad.v:32:30: ... Location of out-of-block declaration + 32 | function void Cls::f1bit_bad(bit a); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:13:24: In prototype for 'f2args1_bad', the argumement counts do not match the out-of-block declaration (IEEE 1800-2023 8.24) : ... note: In instance 't' 13 | extern function void f2args1_bad(bit a); | ^~~~~~~~~~~ - t/t_class_extern_args_bad.v:32:15: ... Location of out-of-block declaration - 32 | function void Cls::f2args1_bad(bit a, bit b); + t/t_class_extern_args_bad.v:35:15: ... Location of out-of-block declaration + 35 | function void Cls::f2args1_bad(bit a, bit b); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:14:24: In prototype for 'f2args2', the argumement counts do not match the out-of-block declaration (IEEE 1800-2023 8.24) : ... note: In instance 't' 14 | extern function void f2args2(bit a); | ^~~~~~~ - t/t_class_extern_args_bad.v:35:15: ... Location of out-of-block declaration - 35 | function void Cls::f2args2(bit a, bit b); + t/t_class_extern_args_bad.v:38:15: ... Location of out-of-block declaration + 38 | function void Cls::f2args2(bit a, bit b); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:15:24: In prototype for 'f2args3_bad', the argumement counts do not match the out-of-block declaration (IEEE 1800-2023 8.24) : ... note: In instance 't' 15 | extern function void f2args3_bad(bit a, bit b, bit c); | ^~~~~~~~~~~ - t/t_class_extern_args_bad.v:38:15: ... Location of out-of-block declaration - 38 | function void Cls::f2args3_bad(bit a, bit b); + t/t_class_extern_args_bad.v:41:15: ... Location of out-of-block declaration + 41 | function void Cls::f2args3_bad(bit a, bit b); | ^~~ %Error-PROTOTYPEMIS: t/t_class_extern_args_bad.v:16:38: In prototype for 'farg_name_bad', argument 1 named 'declnamebad' mismatches out-of-block argument name 'declname' (IEEE 1800-2023 8.24) : ... note: In instance 't' 16 | extern function void farg_name_bad(bit declnamebad); | ^~~ - t/t_class_extern_args_bad.v:41:34: ... Location of out-of-block declaration - 41 | function void Cls::farg_name_bad(bit declname); + t/t_class_extern_args_bad.v:44:34: ... Location of out-of-block declaration + 44 | function void Cls::farg_name_bad(bit declname); | ^~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_extern_args_bad.v b/test_regress/t/t_class_extern_args_bad.v index a969abb06..16e04d7ae 100644 --- a/test_regress/t/t_class_extern_args_bad.v +++ b/test_regress/t/t_class_extern_args_bad.v @@ -17,13 +17,16 @@ class Cls; endclass function bit Cls::func_bad(); + return 1'b0; endfunction function bit Cls::f1_bad(); + return 1'b0; endfunction function void Cls::f2_bad(); endfunction function bit Cls::f3_bad(); + return 1'b0; endfunction function void Cls::f1bit_bad(bit a); diff --git a/test_regress/t/t_class_hier_construction.v b/test_regress/t/t_class_hier_construction.v index a3f60a566..e62488136 100644 --- a/test_regress/t/t_class_hier_construction.v +++ b/test_regress/t/t_class_hier_construction.v @@ -9,80 +9,81 @@ `define checks(gotv,expv) do if ((gotv) != (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); `stop; end while(0); interface class IBottomMid; - pure virtual function void moo(int i); + pure virtual function void moo(int i); endclass interface class IBottom; - pure virtual function bit foo(); + pure virtual function bit foo(); endclass interface class IMid extends IBottomMid; - pure virtual function string bar(); + pure virtual function string bar(); endclass class bottom_class implements IBottom; - string name; + string name; - function new(string name); - this.name = name; - endfunction + function new(string name); + this.name = name; + endfunction - virtual function bit foo(); - $display("%s", name); - endfunction + virtual function bit foo(); + $display("%s", name); + return 1'b0; + endfunction endclass class middle_class extends bottom_class implements IMid, IBottom; - function new(string name); - super.new($sformatf("middle %0s", name)); - endfunction + function new(string name); + super.new($sformatf("middle %0s", name)); + endfunction - virtual function bit foo(); - $display("%s", name); - return 0; - endfunction + virtual function bit foo(); + $display("%s", name); + return 0; + endfunction - virtual function void moo(int i); - $display("moo: %d", i); - endfunction + virtual function void moo(int i); + $display("moo: %d", i); + endfunction - virtual function string bar(); - return name; - endfunction + virtual function string bar(); + return name; + endfunction endclass class top_class extends middle_class; - int i; - function new(string name, int i); - super.new($sformatf("%0s %0d", name, i)); - this.i = i; - endfunction + int i; + function new(string name, int i); + super.new($sformatf("%0s %0d", name, i)); + this.i = i; + endfunction endclass class sky_class extends top_class; - function new(string name); - super.new(name, 42); - endfunction + function new(string name); + super.new(name, 42); + endfunction endclass module t; - initial begin - sky_class s = new("ahoj"); - bottom_class b = s; - top_class t = s; - IMid im; + initial begin + sky_class s = new("ahoj"); + bottom_class b = s; + top_class t = s; + IMid im; - `checks( b.name, "middle ahoj 42" ); - `checks( s.name, "middle ahoj 42" ); - `checks( t.name, "middle ahoj 42" ); - `checkh( t.i, 42); - `checks(s.bar(), "middle ahoj 42"); - im = s; - im.moo(42); + `checks( b.name, "middle ahoj 42" ); + `checks( s.name, "middle ahoj 42" ); + `checks( t.name, "middle ahoj 42" ); + `checkh( t.i, 42); + `checks(s.bar(), "middle ahoj 42"); + im = s; + im.moo(42); - $finish; - end + $finish; + end endmodule diff --git a/test_regress/t/t_class_misstatic_bad.out b/test_regress/t/t_class_misstatic_bad.out index d6deb0936..368cfffae 100644 --- a/test_regress/t/t_class_misstatic_bad.out +++ b/test_regress/t/t_class_misstatic_bad.out @@ -1,14 +1,14 @@ -%Error: t/t_class_misstatic_bad.v:31:7: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10) +%Error: t/t_class_misstatic_bad.v:31:5: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10) : ... note: In instance 't' - 31 | nonstatic(); - | ^~~~~~~~~ + 31 | nonstatic(); + | ^~~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_class_misstatic_bad.v:38:12: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10) +%Error: t/t_class_misstatic_bad.v:38:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10) : ... note: In instance 't' - 38 | Cls::nonstatic(); - | ^~~~~~~~~ -%Error: t/t_class_misstatic_bad.v:44:12: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10) + 38 | Cls::nonstatic(); + | ^~~~~~~~~ +%Error: t/t_class_misstatic_bad.v:44:10: Cannot call non-static member function 'nonstatic' without object (IEEE 1800-2023 8.10) : ... note: In instance 't' - 44 | Cls::nonstatic(); - | ^~~~~~~~~ + 44 | Cls::nonstatic(); + | ^~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_class_misstatic_bad.v b/test_regress/t/t_class_misstatic_bad.v index 3d4b0b0cd..3f0cbca1c 100644 --- a/test_regress/t/t_class_misstatic_bad.v +++ b/test_regress/t/t_class_misstatic_bad.v @@ -5,45 +5,45 @@ // SPDX-License-Identifier: CC0-1.0 class Cls; - int m_field = get_ok(); - function int get_ok(); - return 1; - endfunction - function void nonstatic(); - endfunction - static function void isst(); - endfunction + int m_field = get_ok(); + function int get_ok(); + return 1; + endfunction + function void nonstatic(); + endfunction + static function void isst(); + endfunction endclass class Bar; - function void bar(); - Cls::nonstatic(); // <--- bad static ref - Cls::isst(); - endfunction + function void bar(); + Cls::nonstatic(); // <--- bad static ref + Cls::isst(); + endfunction endclass class Extends extends Cls; - function void ok(); - nonstatic(); - isst(); - endfunction - static function extstatic(); - nonstatic(); // <--- bad static ref - isst(); - endfunction + function void ok(); + nonstatic(); + isst(); + endfunction + static function void extstatic(); + nonstatic(); // <--- bad static ref + isst(); + endfunction endclass module t; - function nonclassfunc(); - Cls::nonstatic(); // <--- bad static ref - Cls::isst(); - endfunction - initial begin - Bar obj = new(); - obj.bar(); - Cls::nonstatic(); // <--- bad static ref - Cls::isst(); - Extends::isst(); - $stop; - end + function void nonclassfunc(); + Cls::nonstatic(); // <--- bad static ref + Cls::isst(); + endfunction + initial begin + Bar obj = new(); + obj.bar(); + Cls::nonstatic(); // <--- bad static ref + Cls::isst(); + Extends::isst(); + $stop; + end endmodule diff --git a/test_regress/t/t_class_param_extends3.v b/test_regress/t/t_class_param_extends3.v index 3447076ec..9fcf788ab 100644 --- a/test_regress/t/t_class_param_extends3.v +++ b/test_regress/t/t_class_param_extends3.v @@ -28,6 +28,7 @@ package u_pkg; class u_callbacks #(type T=u_object, type CB=u_callback) extends u_typed_callbacks#(T); static function bit m_register_pair(); + return 1'b0; endfunction static function void add(u_callback cb); u_queue#(u_callback) qr; diff --git a/test_regress/t/t_class_param_super.v b/test_regress/t/t_class_param_super.v index a61004533..9f90de633 100644 --- a/test_regress/t/t_class_param_super.v +++ b/test_regress/t/t_class_param_super.v @@ -12,7 +12,7 @@ class base #( endclass class ext extends base; - function fext(); + function void fext(); super.fbase(); endfunction endclass diff --git a/test_regress/t/t_covergroup_args.v b/test_regress/t/t_covergroup_args.v index d72b9c23f..dad391a7e 100644 --- a/test_regress/t/t_covergroup_args.v +++ b/test_regress/t/t_covergroup_args.v @@ -16,7 +16,7 @@ module t; int i, j; real r; - function x(); + function void x(); cov1.set_inst_name("the_inst_name"); cov1.start(); cov1.sample(); diff --git a/test_regress/t/t_fork_func2_bad.out b/test_regress/t/t_fork_func2_bad.out index 1f3c49e98..f3707d884 100644 --- a/test_regress/t/t_fork_func2_bad.out +++ b/test_regress/t/t_fork_func2_bad.out @@ -1,6 +1,6 @@ -%Error: t/t_fork_func2_bad.v:10:7: Only fork .. join_none is legal in functions. (IEEE 1800-2023 13.4.4) +%Error: t/t_fork_func2_bad.v:10:5: Only fork .. join_none is legal in functions. (IEEE 1800-2023 13.4.4) : ... note: In instance 't' - 10 | fork - | ^~~~ + 10 | fork + | ^~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. %Error: Exiting due to diff --git a/test_regress/t/t_fork_func2_bad.v b/test_regress/t/t_fork_func2_bad.v index 1b5e29d65..5627dca5f 100644 --- a/test_regress/t/t_fork_func2_bad.v +++ b/test_regress/t/t_fork_func2_bad.v @@ -6,16 +6,17 @@ module t; - function int f; - fork - ; - join_any // Illegal 13.4.4 - endfunction + function int f; + fork + ; + join_any // Illegal 13.4.4 + return 0; + endfunction - int i; + int i; - initial begin - i = f(); - end + initial begin + i = f(); + end endmodule diff --git a/test_regress/t/t_func_const_bad.out b/test_regress/t/t_func_const_bad.out index 036d35222..d1d52f71d 100644 --- a/test_regress/t/t_func_const_bad.out +++ b/test_regress/t/t_func_const_bad.out @@ -1,48 +1,48 @@ -%Error: t/t_func_const_bad.v:12:20: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_output' +%Error: t/t_func_const_bad.v:12:19: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_output' : ... note: In instance 't' - t/t_func_const_bad.v:13:64: ... Location of non-constant VAR 'o': Language violation: Outputs/refs not allowed in constant functions - 12 | localparam B1 = f_bad_output(1,2); - | ^~~~~~~~~~~~ + t/t_func_const_bad.v:13:63: ... Location of non-constant VAR 'o': Language violation: Outputs/refs not allowed in constant functions + 12 | localparam B1 = f_bad_output(1, 2); + | ^~~~~~~~~~~~ ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. -%Error: t/t_func_const_bad.v:21:20: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_dotted' +%Error: t/t_func_const_bad.v:21:19: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_dotted' : ... note: In instance 't' - t/t_func_const_bad.v:23:24: ... Location of non-constant VARXREF 'EIGHT': Language violation: Dotted hierarchical references not allowed in constant functions - t/t_func_const_bad.v:21:20: ... Called from 'f_bad_dotted()' with parameters: + t/t_func_const_bad.v:23:22: ... Location of non-constant VARXREF 'EIGHT': Language violation: Dotted hierarchical references not allowed in constant functions + t/t_func_const_bad.v:21:19: ... Called from 'f_bad_dotted()' with parameters: a = ?32?h2 - 21 | localparam B2 = f_bad_dotted(2); - | ^~~~~~~~~~~~ -%Error: t/t_func_const_bad.v:28:20: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_nonparam' + 21 | localparam B2 = f_bad_dotted(2); + | ^~~~~~~~~~~~ +%Error: t/t_func_const_bad.v:28:19: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_nonparam' : ... note: In instance 't' - t/t_func_const_bad.v:30:24: ... Location of non-constant VARREF 'modvar': Language violation: reference to non-function-local variable - t/t_func_const_bad.v:28:20: ... Called from 'f_bad_nonparam()' with parameters: + t/t_func_const_bad.v:30:22: ... Location of non-constant VARREF 'modvar': Language violation: reference to non-function-local variable + t/t_func_const_bad.v:28:19: ... Called from 'f_bad_nonparam()' with parameters: a = ?32?h3 - 28 | localparam B3 = f_bad_nonparam(3); - | ^~~~~~~~~~~~~~ -%Error: t/t_func_const_bad.v:36:20: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_infinite' + 28 | localparam B3 = f_bad_nonparam(3); + | ^~~~~~~~~~~~~~ +%Error: t/t_func_const_bad.v:36:19: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_infinite' : ... note: In instance 't' - t/t_func_const_bad.v:38:7: ... Location of non-constant LOOP: Loop unrolling took too long; probably this is aninfinite loop, or use /*verilator unroll_full*/, or set --unroll-count above 16386 - t/t_func_const_bad.v:36:20: ... Called from 'f_bad_infinite()' with parameters: + t/t_func_const_bad.v:38:5: ... Location of non-constant LOOP: Loop unrolling took too long; probably this is aninfinite loop, or use /*verilator unroll_full*/, or set --unroll-count above 16386 + t/t_func_const_bad.v:36:19: ... Called from 'f_bad_infinite()' with parameters: a = ?32?h3 - 36 | localparam B4 = f_bad_infinite(3); - | ^~~~~~~~~~~~~~ -%Error: t/t_func_const_bad.v:44:23: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_stop' + 36 | localparam B4 = f_bad_infinite(3); + | ^~~~~~~~~~~~~~ +%Error: t/t_func_const_bad.v:44:22: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_stop' : ... note: In instance 't' - t/t_func_const_bad.v:46:7: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing - t/t_func_const_bad.v:44:23: ... Called from 'f_bad_stop()' with parameters: + t/t_func_const_bad.v:46:5: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing + t/t_func_const_bad.v:44:22: ... Called from 'f_bad_stop()' with parameters: a = ?32?h3 - 44 | localparam BSTOP = f_bad_stop(3); - | ^~~~~~~~~~ --Info: "Printing in loop: 0" --Info: "Printing in loop: 1" --Info: "Printing in loop: 2" + 44 | localparam BSTOP = f_bad_stop(3); + | ^~~~~~~~~~ +-Info: "Printing in loop: 0" +-Info: "Printing in loop: 1" +-Info: "Printing in loop: 2" %Warning-USERFATAL: "Fatal Error" ... For warning description see https://verilator.org/warn/USERFATAL?v=latest ... Use "/* verilator lint_off USERFATAL */" and lint_on around source to disable this message. -%Error: t/t_func_const_bad.v:50:24: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_fatal' +%Error: t/t_func_const_bad.v:51:23: Expecting expression to be constant, but can't determine constant for FUNCREF 'f_bad_fatal' : ... note: In instance 't' - t/t_func_const_bad.v:55:7: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing - t/t_func_const_bad.v:50:24: ... Called from 'f_bad_fatal()' with parameters: + t/t_func_const_bad.v:56:5: ... Location of non-constant STOP: $stop executed during function constification; maybe indicates assertion firing + t/t_func_const_bad.v:51:23: ... Called from 'f_bad_fatal()' with parameters: a = ?32?h3 - 50 | localparam BFATAL = f_bad_fatal(3); - | ^~~~~~~~~~~ + 51 | localparam BFATAL = f_bad_fatal(3); + | ^~~~~~~~~~~ %Error: Exiting due to diff --git a/test_regress/t/t_func_const_bad.v b/test_regress/t/t_func_const_bad.v index 0334e46fa..1ebe7c765 100644 --- a/test_regress/t/t_func_const_bad.v +++ b/test_regress/t/t_func_const_bad.v @@ -6,52 +6,54 @@ module t; - // Speced ignored: system calls. I think this is nasty, so we error instead. + // Speced ignored: system calls. I think this is nasty, so we error instead. - // Speced Illegal: inout/output/ref not allowed - localparam B1 = f_bad_output(1,2); - function integer f_bad_output(input [31:0] a, output [31:0] o); - f_bad_output = 0; - endfunction + // Speced Illegal: inout/output/ref not allowed + localparam B1 = f_bad_output(1, 2); + function integer f_bad_output(input [31:0] a, output [31:0] o); + f_bad_output = 0; + endfunction - // Speced Illegal: void + // Speced Illegal: void - // Speced Illegal: dotted - localparam EIGHT = 8; - localparam B2 = f_bad_dotted(2); - function integer f_bad_dotted(input [31:0] a); - f_bad_dotted = t.EIGHT; - endfunction + // Speced Illegal: dotted + localparam EIGHT = 8; + localparam B2 = f_bad_dotted(2); + function integer f_bad_dotted(input [31:0] a); + f_bad_dotted = t.EIGHT; + endfunction - // Speced Illegal: ref to non-local var - integer modvar; - localparam B3 = f_bad_nonparam(3); - function integer f_bad_nonparam(input [31:0] a); - f_bad_nonparam = modvar; - endfunction + // Speced Illegal: ref to non-local var + integer modvar; + localparam B3 = f_bad_nonparam(3); + function integer f_bad_nonparam(input [31:0] a); + f_bad_nonparam = modvar; + endfunction - // Speced Illegal: needs constant function itself + // Speced Illegal: needs constant function itself - // Our own - infinite loop - localparam B4 = f_bad_infinite(3); - function integer f_bad_infinite(input [31:0] a); - while (1) begin - f_bad_infinite = 0; - end - endfunction + // Our own - infinite loop + localparam B4 = f_bad_infinite(3); + function integer f_bad_infinite(input [31:0] a); + while (1) begin + f_bad_infinite = 0; + end + endfunction - // Our own - stop - localparam BSTOP = f_bad_stop(3); - function integer f_bad_stop(input [31:0] a); - $stop; - endfunction + // Our own - stop + localparam BSTOP = f_bad_stop(3); + function integer f_bad_stop(input [31:0] a); + $stop; + return 0; + endfunction - // Verify $fatal works with sformatf as argument - localparam BFATAL = f_bad_fatal(3); - function integer f_bad_fatal(input [31:0] a); - for (integer i=0;i<3;i++) begin - $display("Printing in loop: %s", $sformatf("%d", i)); - end - $fatal(2, "%s", $sformatf("Fatal Error")); - endfunction + // Verify $fatal works with sformatf as argument + localparam BFATAL = f_bad_fatal(3); + function integer f_bad_fatal(input [31:0] a); + for (integer i = 0; i < 3; i++) begin + $display("Printing in loop: %s", $sformatf("%0d", i)); + end + $fatal(2, "%s", $sformatf("Fatal Error")); + return 0; + endfunction endmodule diff --git a/test_regress/t/t_func_no_paren.v b/test_regress/t/t_func_no_paren.v index 5a65f3dd5..13a56eff9 100644 --- a/test_regress/t/t_func_no_paren.v +++ b/test_regress/t/t_func_no_paren.v @@ -5,18 +5,23 @@ // SPDX-License-Identifier: CC0-1.0 package pkg; - class tb_cpu_seq_item; - virtual function void uvm_report_error(string message); - $display("%s", message); - endfunction - virtual function string get_type_name(); - return "GTN"; - endfunction - virtual function bit do_compare( tb_cpu_seq_item rhs, int comparer); - uvm_report_error($sformatf("this is of type %s, rhs is of type %s", this.get_type_name(), rhs.get_type_name())); - uvm_report_error($sformatf("this is of type %s, rhs is of type %s", this.get_type_name, rhs.get_type_name)); - endfunction - endclass + class tb_cpu_seq_item; + virtual function void uvm_report_error(string message); + $display("%s", message); + endfunction + virtual function string get_type_name(); + return "GTN"; + endfunction + virtual function bit do_compare(tb_cpu_seq_item rhs, int comparer); + uvm_report_error( + $sformatf( + "this is of type %s, rhs is of type %s", this.get_type_name(), rhs.get_type_name())); + uvm_report_error( + $sformatf("this is of type %s, rhs is of type %s", this.get_type_name, rhs.get_type_name + )); + return 1'b0; + endfunction + endclass endpackage module t; diff --git a/test_regress/t/t_func_ref_noparen.v b/test_regress/t/t_func_ref_noparen.v index 75ab8e934..b006b9d1f 100644 --- a/test_regress/t/t_func_ref_noparen.v +++ b/test_regress/t/t_func_ref_noparen.v @@ -5,13 +5,15 @@ // SPDX-License-Identifier: CC0-1.0 class c; - function f(); - endfunction + function bit f(); + return 1'b0; + endfunction endclass module t; - c cinst; - initial begin - cinst = new(); - if(cinst.f) begin end - end + c cinst; + initial begin + cinst = new(); + if (cinst.f) begin + end + end endmodule diff --git a/test_regress/t/t_func_uninit.v b/test_regress/t/t_func_uninit.v index 8e1653fdb..1e688c113 100644 --- a/test_regress/t/t_func_uninit.v +++ b/test_regress/t/t_func_uninit.v @@ -4,6 +4,7 @@ // any use, without warranty, 2021 by Wilson Snyder. // SPDX-License-Identifier: CC0-1.0 +// verilator lint_off NORETURN function int zeroed; endfunction diff --git a/test_regress/t/t_interface_virtual_unused2.v b/test_regress/t/t_interface_virtual_unused2.v index 5a0a08099..7feb732ce 100644 --- a/test_regress/t/t_interface_virtual_unused2.v +++ b/test_regress/t/t_interface_virtual_unused2.v @@ -11,7 +11,7 @@ endinterface class cls; virtual QBus vif1; - function foo(virtual QBus vif2); + function void foo(virtual QBus vif2); vif2.data = 1; endfunction endclass diff --git a/test_regress/t/t_json_only_tag.out b/test_regress/t/t_json_only_tag.out index b73c21345..a2da57b98 100644 --- a/test_regress/t/t_json_only_tag.out +++ b/test_regress/t/t_json_only_tag.out @@ -17,31 +17,28 @@ "lhsp": [ {"type":"VARREF","name":"dotted","addr":"(X)","loc":"d,33:16,33:22","dtypep":"(S)","access":"WR","varp":"(R)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"timingControlp": [],"strengthSpecp": []}, - {"type":"FUNC","name":"f","addr":"(Y)","loc":"d,35:13,35:14","dtypep":"(G)","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f", - "fvarp": [ - {"type":"VAR","name":"f","addr":"(Z)","loc":"d,35:13,35:14","dtypep":"(G)","origName":"f","isSc":false,"isPrimaryIO":false,"isPrimaryClock":false,"direction":"OUTPUT","isConst":false,"isPullup":false,"isPulldown":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":true,"isFuncLocal":true,"lifetime":"VAUTOM","varType":"VAR","dtypeName":"logic","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"ignorePostWrite":false,"ignoreSchedWrite":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []} - ],"classOrPackagep": [], + {"type":"TASK","name":"f","addr":"(Y)","loc":"d,35:18,35:19","method":false,"dpiExport":false,"dpiImport":false,"dpiOpenChild":false,"dpiOpenParent":false,"isExternDef":false,"isExternProto":false,"prototype":false,"recursive":false,"taskPublic":false,"cname":"f","fvarp": [],"classOrPackagep": [], "stmtsp": [ - {"type":"VAR","name":"m","addr":"(AB)","loc":"d,35:28,35:29","dtypep":"(BB)","origName":"m","isSc":false,"isPrimaryIO":false,"isPrimaryClock":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"ignorePostWrite":false,"ignoreSchedWrite":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"DISPLAY","name":"","addr":"(CB)","loc":"d,36:7,36:15", + {"type":"VAR","name":"m","addr":"(Z)","loc":"d,35:33,35:34","dtypep":"(AB)","origName":"m","isSc":false,"isPrimaryIO":false,"isPrimaryClock":false,"direction":"INPUT","isConst":false,"isPullup":false,"isPulldown":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":true,"lifetime":"VAUTOMI","varType":"PORT","dtypeName":"string","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"ignorePostWrite":false,"ignoreSchedWrite":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, + {"type":"DISPLAY","name":"","addr":"(BB)","loc":"d,36:7,36:15", "fmtp": [ - {"type":"SFORMATF","name":"%@","addr":"(DB)","loc":"d,36:7,36:15","dtypep":"(BB)", + {"type":"SFORMATF","name":"%@","addr":"(CB)","loc":"d,36:7,36:15","dtypep":"(AB)", "exprsp": [ - {"type":"VARREF","name":"m","addr":"(EB)","loc":"d,36:22,36:23","dtypep":"(BB)","access":"RD","varp":"(AB)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} + {"type":"VARREF","name":"m","addr":"(DB)","loc":"d,36:22,36:23","dtypep":"(AB)","access":"RD","varp":"(Z)","varScopep":"UNLINKED","classOrPackagep":"UNLINKED"} ],"scopeNamep": []} ],"filep": []} ],"scopeNamep": []}, - {"type":"INITIAL","name":"","addr":"(FB)","loc":"d,39:4,39:11","isSuspendable":false,"needProcess":false, + {"type":"INITIAL","name":"","addr":"(EB)","loc":"d,39:4,39:11","isSuspendable":false,"needProcess":false, "stmtsp": [ - {"type":"BEGIN","name":"","addr":"(GB)","loc":"d,39:12,39:17","implied":false,"needProcess":false,"unnamed":true, + {"type":"BEGIN","name":"","addr":"(FB)","loc":"d,39:12,39:17","implied":false,"needProcess":false,"unnamed":true, "stmtsp": [ - {"type":"STMTEXPR","name":"","addr":"(HB)","loc":"d,41:7,41:8", + {"type":"STMTEXPR","name":"","addr":"(GB)","loc":"d,41:7,41:8", "exprp": [ - {"type":"TASKREF","name":"f","addr":"(IB)","loc":"d,41:7,41:8","dtypep":"(JB)","dotted":"","taskp":"(Y)","classOrPackagep":"UNLINKED","namep": [], + {"type":"TASKREF","name":"f","addr":"(HB)","loc":"d,41:7,41:8","dtypep":"(IB)","dotted":"","taskp":"(Y)","classOrPackagep":"UNLINKED","namep": [], "pinsp": [ - {"type":"ARG","name":"","addr":"(KB)","loc":"d,41:9,41:736", + {"type":"ARG","name":"","addr":"(JB)","loc":"d,41:9,41:736", "exprp": [ - {"type":"CONST","name":"\\\"\\001\\002\\003\\004\\005\\006\\007\\010\\t\\n\\013\\014\\r\\016\\017\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037 !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\177\\200\\201\\202\\203\\204\\205\\206\\207\\210\\211\\212\\213\\214\\215\\216\\217\\220\\221\\222\\223\\224\\225\\226\\227\\230\\231\\232\\233\\234\\235\\236\\237\\240\\241\\242\\243\\244\\245\\246\\247\\250\\251\\252\\253\\254\\255\\256\\257\\260\\261\\262\\263\\264\\265\\266\\267\\270\\271\\272\\273\\274\\275\\276\\277\\300\\301\\302\\303\\304\\305\\306\\307\\310\\311\\312\\313\\314\\315\\316\\317\\320\\321\\322\\323\\324\\325\\326\\327\\330\\331\\332\\333\\334\\335\\336\\337\\340\\341\\342\\343\\344\\345\\346\\347\\350\\351\\352\\353\\354\\355\\356\\357\\360\\361\\362\\363\\364\\365\\366\\367\\370\\371\\372\\373\\374\\375\\376\\377\\\"","addr":"(LB)","loc":"d,41:9,41:736","dtypep":"(BB)"} + {"type":"CONST","name":"\\\"\\001\\002\\003\\004\\005\\006\\007\\010\\t\\n\\013\\014\\r\\016\\017\\020\\021\\022\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037 !\\\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`abcdefghijklmnopqrstuvwxyz{|}~\\177\\200\\201\\202\\203\\204\\205\\206\\207\\210\\211\\212\\213\\214\\215\\216\\217\\220\\221\\222\\223\\224\\225\\226\\227\\230\\231\\232\\233\\234\\235\\236\\237\\240\\241\\242\\243\\244\\245\\246\\247\\250\\251\\252\\253\\254\\255\\256\\257\\260\\261\\262\\263\\264\\265\\266\\267\\270\\271\\272\\273\\274\\275\\276\\277\\300\\301\\302\\303\\304\\305\\306\\307\\310\\311\\312\\313\\314\\315\\316\\317\\320\\321\\322\\323\\324\\325\\326\\327\\330\\331\\332\\333\\334\\335\\336\\337\\340\\341\\342\\343\\344\\345\\346\\347\\350\\351\\352\\353\\354\\355\\356\\357\\360\\361\\362\\363\\364\\365\\366\\367\\370\\371\\372\\373\\374\\375\\376\\377\\\"","addr":"(KB)","loc":"d,41:9,41:736","dtypep":"(AB)"} ]} ],"scopeNamep": []} ]} @@ -51,49 +48,49 @@ {"type":"IFACE","name":"ifc","addr":"(M)","loc":"d,7:11,7:14","origName":"ifc","level":3,"modPublic":false,"inLibrary":true,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"1ps","inlinesp": [], "stmtsp": [ {"type":"VAR","name":"value","addr":"(W)","loc":"d,8:12,8:17","dtypep":"(V)","origName":"value","isSc":false,"isPrimaryIO":false,"isPrimaryClock":false,"direction":"NONE","isConst":false,"isPullup":false,"isPulldown":false,"isSigPublic":false,"isLatched":false,"isUsedLoopIdx":false,"noReset":false,"attrIsolateAssign":false,"attrFileDescr":false,"isDpiOpenArray":false,"isFuncReturn":false,"isFuncLocal":false,"lifetime":"VSTATICI","varType":"VAR","dtypeName":"integer","isSigUserRdPublic":false,"isSigUserRWPublic":false,"isGParam":false,"isParam":false,"attrScBv":false,"attrSFormat":false,"ignorePostWrite":false,"ignoreSchedWrite":false,"sensIfacep":"UNLINKED","childDTypep": [],"delayp": [],"valuep": [],"attrsp": []}, - {"type":"MODPORT","name":"out_modport","addr":"(MB)","loc":"d,9:12,9:23", + {"type":"MODPORT","name":"out_modport","addr":"(LB)","loc":"d,9:12,9:23", "varsp": [ - {"type":"MODPORTVARREF","name":"value","addr":"(NB)","loc":"d,9:32,9:37","direction":"OUTPUT","varp":"(W)"} + {"type":"MODPORTVARREF","name":"value","addr":"(MB)","loc":"d,9:32,9:37","direction":"OUTPUT","varp":"(W)"} ]} ]} ],"filesp": [], "miscsp": [ - {"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(JB)", + {"type":"TYPETABLE","name":"","addr":"(C)","loc":"a,0:0,0:0","constraintRefp":"UNLINKED","emptyQueuep":"UNLINKED","queueIndexp":"UNLINKED","streamp":"UNLINKED","voidp":"(IB)", "typesp": [ - {"type":"VOIDDTYPE","name":"","addr":"(JB)","loc":"d,41:7,41:8","dtypep":"(JB)","generic":false}, + {"type":"VOIDDTYPE","name":"","addr":"(IB)","loc":"d,41:7,41:8","dtypep":"(IB)","generic":false}, {"type":"BASICDTYPE","name":"integer","addr":"(V)","loc":"d,8:4,8:11","dtypep":"(V)","keyword":"integer","range":"31:0","generic":true,"rangep": []}, {"type":"BASICDTYPE","name":"logic","addr":"(G)","loc":"d,14:11,14:17","dtypep":"(G)","keyword":"logic","generic":true,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(OB)","loc":"d,21:7,21:12","dtypep":"(OB)","keyword":"logic","generic":false,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(PB)","loc":"d,22:7,22:12","dtypep":"(PB)","keyword":"logic","generic":false,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(QB)","loc":"d,23:7,23:12","dtypep":"(QB)","keyword":"logic","generic":false,"rangep": []}, - {"type":"BASICDTYPE","name":"logic","addr":"(RB)","loc":"d,24:7,24:12","dtypep":"(RB)","keyword":"logic","generic":false,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(NB)","loc":"d,21:7,21:12","dtypep":"(NB)","keyword":"logic","generic":false,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(OB)","loc":"d,22:7,22:12","dtypep":"(OB)","keyword":"logic","generic":false,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(PB)","loc":"d,23:7,23:12","dtypep":"(PB)","keyword":"logic","generic":false,"rangep": []}, + {"type":"BASICDTYPE","name":"logic","addr":"(QB)","loc":"d,24:7,24:12","dtypep":"(QB)","keyword":"logic","generic":false,"rangep": []}, {"type":"STRUCTDTYPE","name":"m.my_struct","addr":"(K)","loc":"d,20:12,20:18","dtypep":"(K)","packed":true,"isFourstate":true,"generic":false,"classOrPackagep":"UNLINKED", "membersp": [ - {"type":"MEMBERDTYPE","name":"clk","addr":"(SB)","loc":"d,21:19,21:22","dtypep":"(OB)","isConstrainedRand":false,"name":"clk","tag":"this is clk","generic":false,"refDTypep":"(OB)","childDTypep": [],"valuep": []}, - {"type":"MEMBERDTYPE","name":"k","addr":"(TB)","loc":"d,22:19,22:20","dtypep":"(PB)","isConstrainedRand":false,"name":"k","tag":"","generic":false,"refDTypep":"(PB)","childDTypep": [],"valuep": []}, - {"type":"MEMBERDTYPE","name":"enable","addr":"(UB)","loc":"d,23:19,23:25","dtypep":"(QB)","isConstrainedRand":false,"name":"enable","tag":"enable","generic":false,"refDTypep":"(QB)","childDTypep": [],"valuep": []}, - {"type":"MEMBERDTYPE","name":"data","addr":"(VB)","loc":"d,24:19,24:23","dtypep":"(RB)","isConstrainedRand":false,"name":"data","tag":"data","generic":false,"refDTypep":"(RB)","childDTypep": [],"valuep": []} + {"type":"MEMBERDTYPE","name":"clk","addr":"(RB)","loc":"d,21:19,21:22","dtypep":"(NB)","isConstrainedRand":false,"name":"clk","tag":"this is clk","generic":false,"refDTypep":"(NB)","childDTypep": [],"valuep": []}, + {"type":"MEMBERDTYPE","name":"k","addr":"(SB)","loc":"d,22:19,22:20","dtypep":"(OB)","isConstrainedRand":false,"name":"k","tag":"","generic":false,"refDTypep":"(OB)","childDTypep": [],"valuep": []}, + {"type":"MEMBERDTYPE","name":"enable","addr":"(TB)","loc":"d,23:19,23:25","dtypep":"(PB)","isConstrainedRand":false,"name":"enable","tag":"enable","generic":false,"refDTypep":"(PB)","childDTypep": [],"valuep": []}, + {"type":"MEMBERDTYPE","name":"data","addr":"(UB)","loc":"d,24:19,24:23","dtypep":"(QB)","isConstrainedRand":false,"name":"data","tag":"data","generic":false,"refDTypep":"(QB)","childDTypep": [],"valuep": []} ]}, {"type":"IFACEREFDTYPE","name":"","addr":"(O)","loc":"d,29:8,29:12","dtypep":"(O)","isPortDecl":false,"isVirtual":false,"cellName":"itop","ifaceName":"ifc","modportName":"","generic":false,"ifacep":"UNLINKED","cellp":"(L)","modportp":"UNLINKED","paramsp": []}, {"type":"BASICDTYPE","name":"logic","addr":"(S)","loc":"d,31:27,31:28","dtypep":"(S)","keyword":"logic","range":"31:0","generic":true,"rangep": []}, - {"type":"REFDTYPE","name":"my_struct","addr":"(WB)","loc":"d,31:4,31:13","dtypep":"(K)","generic":false,"typedefp":"UNLINKED","refDTypep":"(K)","classOrPackagep":"UNLINKED","typeofp": [],"classOrPackageOpp": [],"paramsp": []}, - {"type":"UNPACKARRAYDTYPE","name":"","addr":"(Q)","loc":"d,31:26,31:27","dtypep":"(Q)","isCompound":false,"declRange":"[0:1]","generic":false,"refDTypep":"(WB)","childDTypep": [], + {"type":"REFDTYPE","name":"my_struct","addr":"(VB)","loc":"d,31:4,31:13","dtypep":"(K)","generic":false,"typedefp":"UNLINKED","refDTypep":"(K)","classOrPackagep":"UNLINKED","typeofp": [],"classOrPackageOpp": [],"paramsp": []}, + {"type":"UNPACKARRAYDTYPE","name":"","addr":"(Q)","loc":"d,31:26,31:27","dtypep":"(Q)","isCompound":false,"declRange":"[0:1]","generic":false,"refDTypep":"(VB)","childDTypep": [], "rangep": [ - {"type":"RANGE","name":"","addr":"(XB)","loc":"d,31:26,31:27","ascending":true,"fromBracket":true, + {"type":"RANGE","name":"","addr":"(WB)","loc":"d,31:26,31:27","ascending":true,"fromBracket":true, "leftp": [ - {"type":"CONST","name":"32'h0","addr":"(YB)","loc":"d,31:27,31:28","dtypep":"(S)"} + {"type":"CONST","name":"32'h0","addr":"(XB)","loc":"d,31:27,31:28","dtypep":"(S)"} ], "rightp": [ - {"type":"CONST","name":"32'h1","addr":"(ZB)","loc":"d,31:27,31:28","dtypep":"(S)"} + {"type":"CONST","name":"32'h1","addr":"(YB)","loc":"d,31:27,31:28","dtypep":"(S)"} ]} ]}, - {"type":"BASICDTYPE","name":"string","addr":"(BB)","loc":"d,35:21,35:27","dtypep":"(BB)","keyword":"string","generic":true,"rangep": []} + {"type":"BASICDTYPE","name":"string","addr":"(AB)","loc":"d,35:26,35:32","dtypep":"(AB)","keyword":"string","generic":true,"rangep": []} ]}, {"type":"CONSTPOOL","name":"","addr":"(D)","loc":"a,0:0,0:0", "modulep": [ - {"type":"MODULE","name":"@CONST-POOL@","addr":"(AC)","loc":"a,0:0,0:0","isChecker":false,"isProgram":false,"hasGenericIface":false,"origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [], + {"type":"MODULE","name":"@CONST-POOL@","addr":"(ZB)","loc":"a,0:0,0:0","isChecker":false,"isProgram":false,"hasGenericIface":false,"origName":"@CONST-POOL@","level":0,"modPublic":false,"inLibrary":false,"dead":false,"recursiveClone":false,"recursive":false,"timeunit":"NONE","inlinesp": [], "stmtsp": [ - {"type":"SCOPE","name":"@CONST-POOL@","addr":"(BC)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(AC)","varsp": [],"blocksp": [],"inlinesp": []} + {"type":"SCOPE","name":"@CONST-POOL@","addr":"(AC)","loc":"a,0:0,0:0","aboveScopep":"UNLINKED","aboveCellp":"UNLINKED","modp":"(ZB)","varsp": [],"blocksp": [],"inlinesp": []} ]} ]} ]} diff --git a/test_regress/t/t_json_only_tag.v b/test_regress/t/t_json_only_tag.v index 736942cbf..a47cd18d7 100644 --- a/test_regress/t/t_json_only_tag.v +++ b/test_regress/t/t_json_only_tag.v @@ -32,7 +32,7 @@ module m wire [31:0] dotted = itop.value; - function f(input string m); + function void f(input string m); $display("%s", m); endfunction diff --git a/test_regress/t/t_lint_noreturn.py b/test_regress/t/t_lint_noreturn.py new file mode 100755 index 000000000..506c4f8b2 --- /dev/null +++ b/test_regress/t/t_lint_noreturn.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator_st') + +test.compile(verilator_flags2=['-Wall -Wno-DECLFILENAME -Wno-NORETURN']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_lint_noreturn.v b/test_regress/t/t_lint_noreturn.v new file mode 100644 index 000000000..62d2d02fa --- /dev/null +++ b/test_regress/t/t_lint_noreturn.v @@ -0,0 +1,22 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + // verilator lint_off UNDRIVEN + + function int no_rtn(); // <--- Warning: No return + endfunction + + int i; + + initial begin + i = no_rtn(); + if (i !== 0) $stop; + $finish; + end + +endmodule diff --git a/test_regress/t/t_lint_noreturn_bad.out b/test_regress/t/t_lint_noreturn_bad.out new file mode 100644 index 000000000..757b095aa --- /dev/null +++ b/test_regress/t/t_lint_noreturn_bad.out @@ -0,0 +1,7 @@ +%Warning-NORETURN: t/t_lint_noreturn.v:11:16: Non-void function 'no_rtn' has no return value + : ... note: In instance 't' + 11 | function int no_rtn(); + | ^~~~~~ + ... For warning description see https://verilator.org/warn/NORETURN?v=latest + ... Use "/* verilator lint_off NORETURN */" and lint_on around source to disable this message. +%Error: Exiting due to diff --git a/test_regress/t/t_lint_noreturn_bad.py b/test_regress/t/t_lint_noreturn_bad.py new file mode 100755 index 000000000..cd6a0720b --- /dev/null +++ b/test_regress/t/t_lint_noreturn_bad.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = "t/t_lint_noreturn.v" + +test.lint(verilator_flags2=['-Wall -Wno-DECLFILENAME'], + fails=True, + expect_filename=test.golden_filename) + +test.extract(in_filename=test.top_filename, + out_filename=test.root + "/docs/gen/ex_NORETURN_faulty.rst", + lines="11-12") + +test.extract(in_filename=test.golden_filename, + out_filename=test.root + "/docs/gen/ex_NORETURN_msg.rst", + lines="1-1") + +test.passes() diff --git a/test_regress/t/t_lint_noreturn_param.py b/test_regress/t/t_lint_noreturn_param.py new file mode 100755 index 000000000..506c4f8b2 --- /dev/null +++ b/test_regress/t/t_lint_noreturn_param.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator_st') + +test.compile(verilator_flags2=['-Wall -Wno-DECLFILENAME -Wno-NORETURN']) + +test.execute() + +test.passes() diff --git a/test_regress/t/t_lint_noreturn_param.v b/test_regress/t/t_lint_noreturn_param.v new file mode 100644 index 000000000..f8855f158 --- /dev/null +++ b/test_regress/t/t_lint_noreturn_param.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + // verilator lint_off UNDRIVEN + + function integer log2m1(); // <--- Warning: No return + endfunction + + localparam WIDTH = log2m1(); + + initial begin + if (WIDTH !== {32{1'bx}}) $stop; + $finish; + end + +endmodule diff --git a/test_regress/t/t_lint_noreturn_param_bad.out b/test_regress/t/t_lint_noreturn_param_bad.out new file mode 100644 index 000000000..5ca1a3f07 --- /dev/null +++ b/test_regress/t/t_lint_noreturn_param_bad.out @@ -0,0 +1,12 @@ +%Warning-NORETURN: t/t_lint_noreturn_param_bad.v:14:20: Non-void function 'no_rtn' has no return value + : ... note: In instance 't' + 14 | function integer no_rtn(); + | ^~~~~~ + ... For warning description see https://verilator.org/warn/NORETURN?v=latest + ... Use "/* verilator lint_off NORETURN */" and lint_on around source to disable this message. +%Error: t/t_lint_noreturn_param_bad.v:19:16: left side of bit range isn't a two-state constant (IEEE 1800-2023 6.9.1) + : ... note: In instance 't' + 19 | output [WIDTH-1:0] o; + | ^ + ... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance. +%Error: Exiting due to diff --git a/test_regress/t/t_lint_noreturn_param_bad.py b/test_regress/t/t_lint_noreturn_param_bad.py new file mode 100755 index 000000000..5f286b96d --- /dev/null +++ b/test_regress/t/t_lint_noreturn_param_bad.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('vlt') + +test.lint(verilator_flags2=['-Wall -Wno-DECLFILENAME'], + fails=True, + expect_filename=test.golden_filename) + +test.passes() diff --git a/test_regress/t/t_lint_noreturn_param_bad.v b/test_regress/t/t_lint_noreturn_param_bad.v new file mode 100644 index 000000000..b6e217d10 --- /dev/null +++ b/test_regress/t/t_lint_noreturn_param_bad.v @@ -0,0 +1,21 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Outputs + o + ); + + // verilator lint_off UNDRIVEN + + function integer no_rtn(); // <--- Warning: No return + endfunction + + localparam WIDTH = no_rtn(); + + output [WIDTH-1:0] o; + +endmodule diff --git a/test_regress/t/t_static_dup_name.v b/test_regress/t/t_static_dup_name.v index 9d3765238..e4155526e 100644 --- a/test_regress/t/t_static_dup_name.v +++ b/test_regress/t/t_static_dup_name.v @@ -5,7 +5,7 @@ module t; - function do_stuff(); + function void do_stuff(); static int some_int; begin: block0 static int some_int; diff --git a/test_regress/t/t_xml_tag.out b/test_regress/t/t_xml_tag.out index c342d280c..c07c60593 100644 --- a/test_regress/t/t_xml_tag.out +++ b/test_regress/t/t_xml_tag.out @@ -29,15 +29,14 @@ - - - + + - + @@ -79,7 +78,7 @@ - + diff --git a/test_regress/t/t_xml_tag.v b/test_regress/t/t_xml_tag.v index 736942cbf..a47cd18d7 100644 --- a/test_regress/t/t_xml_tag.v +++ b/test_regress/t/t_xml_tag.v @@ -32,7 +32,7 @@ module m wire [31:0] dotted = itop.value; - function f(input string m); + function void f(input string m); $display("%s", m); endfunction