Add error when trying to assign class object to variable of non-class types (#6237)

This commit is contained in:
Igor Zaworski 2025-07-30 09:48:02 +02:00 committed by GitHub
parent 0da9f6eb03
commit 2b62f5a625
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 67 additions and 9 deletions

View File

@ -7329,21 +7329,26 @@ class WidthVisitor final : public VNVisitor {
}
return false;
}
void checkClassAssign(AstNode* nodep, const char* side, AstNode* rhsp,
void checkClassAssign(const AstNode* nodep, const char* side, AstNode* rhsp,
AstNodeDType* const lhsDTypep) {
if (AstClassRefDType* const lhsClassRefp = VN_CAST(lhsDTypep->skipRefp(), ClassRefDType)) {
UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type");
AstNodeDType* const rhsDtypep = rhsp->dtypep()->skipRefp();
if (AstClassRefDType* const rhsClassRefp = VN_CAST(rhsDtypep, ClassRefDType)) {
UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type");
const AstNodeDType* const lhsRawDTypep = lhsDTypep->skipRefp();
const AstNodeDType* const rhsRawDTypep = rhsp->dtypep()->skipRefp();
if (const AstClassRefDType* const lhsClassRefp = VN_CAST(lhsRawDTypep, ClassRefDType)) {
if (const AstClassRefDType* const rhsClassRefp
= VN_CAST(rhsRawDTypep, ClassRefDType)) {
if (isBaseClassRecurse(lhsClassRefp->classp(), rhsClassRefp->classp())) return;
} else if (rhsp->isNull()) {
return;
}
nodep->v3error(side << " expects a " << lhsClassRefp->prettyTypeName() << ", got "
<< rhsDtypep->prettyTypeName());
<< rhsRawDTypep->prettyTypeName());
} else if (VN_IS(rhsRawDTypep, ClassRefDType)) {
nodep->v3error(side << " " << rhsRawDTypep->prettyDTypeNameQ()
<< " cannot be assigned to non-class "
<< lhsDTypep->prettyDTypeNameQ());
}
if (VN_IS(lhsDTypep->skipRefp(), DynArrayDType)
&& VN_IS(rhsp->dtypep()->skipRefp(), UnpackArrayDType)) {
if (VN_IS(lhsRawDTypep, DynArrayDType) && VN_IS(rhsRawDTypep, UnpackArrayDType)) {
VNRelinker relinker;
rhsp->unlinkFrBack(&relinker);
relinker.relink(

View File

@ -0,0 +1,5 @@
%Error: t/t_class_to_basic_assignment_bad.v:26:29: Assign RHS 'class{}Foo' cannot be assigned to non-class 'int'
26 | new_node.phase_done = get();
| ^
... See the manual at https://verilator.org/verilator_doc.html?v=latest for more assistance.
%Error: Exiting due to

View File

@ -0,0 +1,16 @@
#!/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('linter')
test.lint(fails=True, expect_filename=test.golden_filename)
test.passes()

View File

@ -0,0 +1,32 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2025 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
class Foo;
int phase_done;
static function Foo get();
Foo ans = new;
return ans;
endfunction
static function int create ();
return 3;
endfunction
function string get_name ();
return "bar";
endfunction
function void add(Foo phase);
Foo new_node;
if (new_node.get_name() == "run") begin
new_node.phase_done = get();
end
else begin
new_node.phase_done = create();
end
endfunction
endclass

View File

@ -7,7 +7,7 @@
class Cls;
int x = 1;
function new();
int p = process::self();
process p = process::self();
endfunction
endclass