Add NORETURN warning on functions without return values (#6534).

This commit is contained in:
Wilson Snyder 2025-10-07 21:06:11 -04:00
parent f979e459e8
commit 165622a9e9
43 changed files with 509 additions and 264 deletions

View File

@ -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).

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -1100,7 +1100,8 @@ private:
bool visitNext);
template <typename T_Arg, bool N_Default, typename T_Callable>
inline static bool predicateImpl(ConstCorrectAstNode<T_Arg>* nodep, const T_Callable& p);
inline static bool predicateImpl(ConstCorrectAstNode<T_Arg>* 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<T_Node>(this, f, /* visitNext: */ false);
}
// Same as above, but for 'const' nodes
template <typename T_Callable>
void foreach(T_Callable&& f) const {
@ -1131,7 +1131,6 @@ public:
"with 'T_Node' being a subtype of 'AstNode'");
foreachImpl<const T_Node>(this, f, /* visitNext: */ false);
}
// Same as 'foreach' but also traverses 'this->nextp()' transitively
template <typename T_Callable>
void foreachAndNext(T_Callable&& f) {
@ -1142,7 +1141,6 @@ public:
"with 'T_Node' being a subtype of 'AstNode'");
foreachImpl<T_Node>(this, f, /* visitNext: */ true);
}
// Same as above, but for 'const' nodes
template <typename T_Callable>
void foreachAndNext(T_Callable&& f) const {
@ -1167,9 +1165,8 @@ public:
&& std::is_base_of<AstNode, T_Node>::value,
"Predicate 'p' must have a signature compatible with 'bool(T_Node*)', "
"with 'T_Node' being a subtype of 'AstNode'");
return predicateImpl<T_Node, /* N_Default: */ false>(this, p);
return predicateImpl<T_Node, /* N_Default: */ false>(this, p, /* visitNext: */ false);
}
// Same as above, but for 'const' nodes
template <typename T_Callable>
bool exists(T_Callable&& p) const {
@ -1178,7 +1175,28 @@ public:
&& std::is_base_of<AstNode, T_Node>::value,
"Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', "
"with 'T_Node' being a subtype of 'AstNode'");
return predicateImpl<const T_Node, /* N_Default: */ false>(this, p);
return predicateImpl<const T_Node, /* N_Default: */ false>(this, p,
/* visitNext: */ false);
}
// Same as 'exists' but also traverses 'this->nextp()' transitively
template <typename T_Callable>
bool existsAndNext(T_Callable&& p) {
using T_Node = typename FunctionArgNoPointerNoCV<T_Callable, 0>::type;
static_assert(vlstd::is_invocable_r<bool, T_Callable, const T_Node*>::value
&& std::is_base_of<AstNode, T_Node>::value,
"Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', "
"with 'T_Node' being a subtype of 'AstNode'");
return predicateImpl<T_Node, /* N_Default: */ false>(this, p, /* visitNext: */ true);
}
// Same as above, but for 'const' nodes
template <typename T_Callable>
bool existsAndNext(T_Callable&& p) const {
using T_Node = typename FunctionArgNoPointerNoCV<T_Callable, 0>::type;
static_assert(vlstd::is_invocable_r<bool, T_Callable, const T_Node*>::value
&& std::is_base_of<AstNode, T_Node>::value,
"Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', "
"with 'T_Node' being a subtype of 'AstNode'");
return predicateImpl<const T_Node, /* N_Default: */ false>(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<AstNode, T_Node>::value,
"Predicate 'p' must have a signature compatible with 'bool(T_Node*)', "
"with 'T_Node' being a subtype of 'AstNode'");
return predicateImpl<T_Node, /* N_Default: */ true>(this, p);
return predicateImpl<T_Node, /* N_Default: */ true>(this, p, /* visitNext: */ false);
}
// Same as above, but for 'const' nodes
template <typename T_Callable>
bool forall(T_Callable&& p) const {
@ -1203,7 +1220,7 @@ public:
&& std::is_base_of<AstNode, T_Node>::value,
"Predicate 'p' must have a signature compatible with 'bool(const T_Node*)', "
"with 'T_Node' being a subtype of 'AstNode'");
return predicateImpl<const T_Node, /* N_Default: */ true>(this, p);
return predicateImpl<const T_Node, /* N_Default: */ true>(this, p, /* visitNext: */ false);
}
int nodeCount() const {
@ -1365,7 +1382,8 @@ void AstNode::foreachImpl(ConstCorrectAstNode<T_Arg>* nodep, const T_Callable& f
// predicate implementation
template <typename T_Arg, bool N_Default, typename T_Callable>
bool AstNode::predicateImpl(ConstCorrectAstNode<T_Arg>* nodep, const T_Callable& p) {
bool AstNode::predicateImpl(ConstCorrectAstNode<T_Arg>* 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<T_Arg>::type;
using Node = ConstCorrectAstNode<T_Arg>;
@ -1410,6 +1428,9 @@ bool AstNode::predicateImpl(ConstCorrectAstNode<T_Arg>* 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;

View File

@ -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",

View File

@ -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());

View File

@ -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);

View File

@ -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<AstVar*> ports;
std::vector<AstAttrOf*> protos;

View File

@ -6721,6 +6721,7 @@ covergroup_declaration<nodep>: // ==IEEE: covergroup_declaration
/*cont*/ yENDGROUP endLabelE
{ AstClass *cgClassp = new AstClass{$<fl>2, *$2, PARSEP->libname()};
AstFunc* const newp = new AstFunc{$<fl>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<nodep>: // ==IEEE: covergroup_declaration
/*cont*/ yENDGROUP endLabelE
{ AstClass *cgClassp = new AstClass{$<fl>3, *$3, PARSEP->libname()};
AstFunc* const newp = new AstFunc{$<fl>1, "new", nullptr, nullptr};
newp->fileline()->warnOff(V3ErrorCode::NORETURN, true);
newp->classMethod(true);
newp->isConstructor(true);
newp->dtypep(cgClassp->dtypep());

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -12,7 +12,7 @@ class base #(
endclass
class ext extends base;
function fext();
function void fext();
super.fbase();
endfunction
endclass

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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": []}
]}
]}
]}

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -5,7 +5,7 @@
module t;
function do_stuff();
function void do_stuff();
static int some_int;
begin: block0
static int some_int;

View File

@ -29,15 +29,14 @@
<varxref loc="d,33,30,33,35" name="value" dtype_id="6" dotted="itop"/>
<varref loc="d,33,16,33,22" name="dotted" dtype_id="5"/>
</contassign>
<func loc="d,35,13,35,14" name="f" dtype_id="1">
<var loc="d,35,13,35,14" name="f" dtype_id="1" dir="output" vartype="logic" origName="f"/>
<var loc="d,35,28,35,29" name="m" dtype_id="7" dir="input" vartype="string" origName="m"/>
<task loc="d,35,18,35,19" name="f">
<var loc="d,35,33,35,34" name="m" dtype_id="7" dir="input" vartype="string" origName="m"/>
<display loc="d,36,7,36,15" displaytype="$display">
<sformatf loc="d,36,7,36,15" name="%@" dtype_id="7">
<varref loc="d,36,22,36,23" name="m" dtype_id="7"/>
</sformatf>
</display>
</func>
</task>
<initial loc="d,39,4,39,11">
<begin loc="d,39,12,39,17">
<stmtexpr loc="d,41,7,41,8">
@ -79,7 +78,7 @@
<const loc="d,31,27,31,28" name="32&apos;h1" dtype_id="5"/>
</range>
</unpackarraydtype>
<basicdtype loc="d,35,21,35,27" id="7" name="string"/>
<basicdtype loc="d,35,26,35,32" id="7" name="string"/>
</typetable>
</netlist>
</verilator_xml>

View File

@ -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