Add error if class types don't match (#4064)

This commit is contained in:
Ryszard Rozak 2023-03-24 18:18:20 +01:00 committed by GitHub
parent 449ac44131
commit 5b86248b54
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 18 deletions

View File

@ -6249,12 +6249,23 @@ private:
}
return false; // No change
}
bool isBaseClassRecurse(const AstClass* const cls1p, const AstClass* const cls2p) {
// Returns true if cls1p and cls2p are equal or if cls1p is a base class of cls2p
if (cls1p == cls2p) return true;
for (const AstClassExtends* cextp = cls2p->extendsp(); cextp;
cextp = VN_CAST(cextp->nextp(), ClassExtends)) {
if (isBaseClassRecurse(cls1p, cextp->classp())) return true;
}
return false;
}
void checkClassAssign(AstNode* nodep, const char* side, AstNode* rhsp,
AstNodeDType* lhsDTypep) {
if (VN_IS(lhsDTypep, ClassRefDType)
&& !(rhsp->dtypep() && VN_IS(rhsp->dtypep()->skipRefp(), ClassRefDType))) {
if (auto* const constp = VN_CAST(rhsp, Const)) {
if (AstClassRefDType* const lhsClassRefp = VN_CAST(lhsDTypep, ClassRefDType)) {
UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type");
if (AstClassRefDType* const rhsClassRefp
= VN_CAST(rhsp->dtypep()->skipRefp(), ClassRefDType)) {
if (isBaseClassRecurse(lhsClassRefp->classp(), rhsClassRefp->classp())) return;
} else if (auto* const constp = VN_CAST(rhsp, Const)) {
if (constp->num().isNull()) return;
}
nodep->v3error(side << " expects a " << lhsDTypep->prettyTypeName());

View File

@ -1,17 +1,33 @@
%Error: t/t_class_assign_bad.v:16:9: Assign RHS expects a CLASSREFDTYPE 'Cls'
%Error: t/t_class_assign_bad.v:25:9: Assign RHS expects a CLASSREFDTYPE 'Cls'
: ... In instance t
16 | c = 0;
25 | c = 0;
| ^
%Error: t/t_class_assign_bad.v:17:9: Assign RHS expects a CLASSREFDTYPE 'Cls'
%Error: t/t_class_assign_bad.v:26:9: Assign RHS expects a CLASSREFDTYPE 'Cls'
: ... In instance t
17 | c = 1;
26 | c = 1;
| ^
%Error: t/t_class_assign_bad.v:18:7: Function Argument expects a CLASSREFDTYPE 'Cls'
%Error: t/t_class_assign_bad.v:27:9: Assign RHS expects a CLASSREFDTYPE 'Cls'
: ... In instance t
18 | t(0);
27 | c = c2;
| ^
%Error: t/t_class_assign_bad.v:28:13: Assign RHS expects a CLASSREFDTYPE 'ClsExt'
: ... In instance t
28 | c_ext = c;
| ^
%Error: t/t_class_assign_bad.v:30:7: Function Argument expects a CLASSREFDTYPE 'Cls'
: ... In instance t
30 | t(0);
| ^
%Error: t/t_class_assign_bad.v:19:7: Function Argument expects a CLASSREFDTYPE 'Cls'
%Error: t/t_class_assign_bad.v:31:7: Function Argument expects a CLASSREFDTYPE 'Cls'
: ... In instance t
19 | t(1);
31 | t(1);
| ^
%Error: t/t_class_assign_bad.v:32:7: Function Argument expects a CLASSREFDTYPE 'Cls'
: ... In instance t
32 | t(c2);
| ^
%Error: t/t_class_assign_bad.v:33:7: Function Argument expects a CLASSREFDTYPE 'ClsExt'
: ... In instance t
33 | f(c);
| ^
%Error: Exiting due to

View File

@ -7,15 +7,29 @@
class Cls;
endclass : Cls
class Cls2;
endclass
class ClsExt extends Cls;
endclass
module t (/*AUTOARG*/);
Cls c;
Cls2 c2;
ClsExt c_ext;
task t(Cls c); endtask
function f(ClsExt c); endfunction
initial begin
c = 0;
c = 1;
c = c2;
c_ext = c;
t(0);
t(1);
t(c2);
f(c);
end
endmodule

View File

@ -14,11 +14,7 @@
: ... In instance t
34 | c1 = new[2];
| ^~~
%Error: t/t_class_new_bad.v:34:10: Assign RHS expects a CLASSREFDTYPE 'ClsNoArg'
: ... In instance t
34 | c1 = new[2];
| ^
%Error: Internal Error: t/t_class_new_bad.v:34:10: ../V3Width.cpp:#: Node has no type
%Error: Internal Error: t/t_class_new_bad.v:34:12: ../V3Width.cpp:#: Node has no type
: ... In instance t
34 | c1 = new[2];
| ^
| ^~~