Add error on static access to non-static class member (#4072)

Before this patch, it was possible to access non-static class members using
static access, which resulted in C++ compilation errors. This adds
verilation-time checks for such situations.
This commit is contained in:
Krzysztof Bieganski 2023-03-27 16:46:51 +02:00 committed by GitHub
parent 947402bc57
commit 0b96789e65
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 1 deletions

View File

@ -2534,12 +2534,14 @@ private:
string expectWhat;
bool allowScope = false;
bool allowVar = false;
bool staticAccess = false;
if (m_ds.m_dotPos == DP_PACKAGE) {
// {package}::{a}
AstNodeModule* classOrPackagep = nullptr;
expectWhat = "scope/variable";
allowScope = true;
allowVar = true;
staticAccess = true;
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
"Bad package link");
AstClassOrPackageRef* const cpackagerefp
@ -2667,6 +2669,10 @@ private:
newp = refp;
}
} else {
if (staticAccess && !varp->lifetime().isStatic() && !varp->isParam()) {
nodep->v3error("Static access to non-static member variable "
<< varp->prettyNameQ() << endl);
}
AstVarRef* const refp = new AstVarRef{
nodep->fileline(), varp, VAccess::READ}; // lvalue'ness computed later
refp->classOrPackagep(foundp->classOrPackagep());
@ -2980,6 +2986,7 @@ private:
iterateChildren(nodep);
}
bool staticAccess = false;
if (m_ds.m_unresolvedClass) {
// Unable to link before V3Param
return;
@ -2995,6 +3002,7 @@ private:
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_PACKAGE) {
UASSERT_OBJ(VN_IS(m_ds.m_dotp->lhsp(), ClassOrPackageRef), m_ds.m_dotp->lhsp(),
"Bad package link");
staticAccess = true;
AstClassOrPackageRef* const cpackagerefp
= VN_AS(m_ds.m_dotp->lhsp(), ClassOrPackageRef);
if (cpackagerefp->name() == "local") {
@ -3066,6 +3074,10 @@ private:
AstNodeFTask* const taskp
= foundp ? VN_CAST(foundp->nodep(), NodeFTask) : nullptr; // Maybe nullptr
if (taskp) {
if (staticAccess && !taskp->lifetime().isStatic()) {
nodep->v3error("Static access to non-static task/function "
<< taskp->prettyNameQ() << endl);
}
nodep->taskp(taskp);
nodep->classOrPackagep(foundp->classOrPackagep());
UINFO(7, " Resolved " << nodep << endl); // Also prints taskp

View File

@ -15,7 +15,7 @@ package Pkg;
endfunction
endclass
class Fwd;
function Fwd m_uvm_get_root();
static function Fwd m_uvm_get_root();
return null;
endfunction
endclass

View File

@ -0,0 +1,7 @@
%Error: t/t_class_member_bad3.v:16:12: Static access to non-static member variable 'member'
16 | Foo::member = 1;
| ^~~~~~
%Error: t/t_class_member_bad3.v:17:12: Static access to non-static task/function 'method'
17 | Foo::method();
| ^~~~~~
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2023 by Antmicro Ltd. 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
scenarios(linter => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,19 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2023 by Antmicro Ltd.
// SPDX-License-Identifier: CC0-1.0
class Foo;
int member;
task method; endtask
endclass
module t;
initial begin
Foo foo = new;
Foo::member = 1;
Foo::method();
end
endmodule