Fix the error message when the type of ref argument is wrong (#4490)

This commit is contained in:
Ryszard Rozak 2023-09-15 13:17:24 +02:00 committed by GitHub
parent 131eb319e0
commit 96857c5f95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 14 additions and 11 deletions

View File

@ -5577,12 +5577,14 @@ private:
const AstArg* const argp = tconnect.second; const AstArg* const argp = tconnect.second;
AstNode* const pinp = argp->exprp(); AstNode* const pinp = argp->exprp();
if (!pinp) continue; // Argument error we'll find later if (!pinp) continue; // Argument error we'll find later
AstNodeDType* const portDTypep = portp->dtypep()->skipRefToEnump();
const AstNodeDType* const pinDTypep = pinp->dtypep()->skipRefToEnump();
if (portp->direction() == VDirection::REF if (portp->direction() == VDirection::REF
&& !similarDTypeRecurse(portp->dtypep(), pinp->dtypep())) { && !similarDTypeRecurse(portDTypep, pinDTypep)) {
pinp->v3error("Ref argument requires matching types;" pinp->v3error("Ref argument requires matching types;"
<< " port " << portp->prettyNameQ() << " requires " << " port " << portp->prettyNameQ() << " requires "
<< portp->prettyTypeName() << " but connection is " << portDTypep->prettyDTypeName() << " but connection is "
<< pinp->prettyTypeName() << "."); << pinDTypep->prettyDTypeName() << ".");
} else if (portp->isWritable() && pinp->width() != portp->width()) { } else if (portp->isWritable() && pinp->width() != portp->width()) {
pinp->v3warn(E_UNSUPPORTED, "Unsupported: Function output argument " pinp->v3warn(E_UNSUPPORTED, "Unsupported: Function output argument "
<< portp->prettyNameQ() << " requires " << portp->prettyNameQ() << " requires "
@ -5593,10 +5595,10 @@ private:
// (get an ASSIGN with EXTEND on the lhs instead of rhs) // (get an ASSIGN with EXTEND on the lhs instead of rhs)
} }
if (!portp->basicp() || portp->basicp()->isOpaque()) { if (!portp->basicp() || portp->basicp()->isOpaque()) {
checkClassAssign(nodep, "Function Argument", pinp, portp->dtypep()); checkClassAssign(nodep, "Function Argument", pinp, portDTypep);
userIterate(pinp, WidthVP{portp->dtypep(), FINAL}.p()); userIterate(pinp, WidthVP{portDTypep, FINAL}.p());
} else { } else {
iterateCheckAssign(nodep, "Function Argument", pinp, FINAL, portp->dtypep()); iterateCheckAssign(nodep, "Function Argument", pinp, FINAL, portDTypep);
} }
} }
} }
@ -6402,7 +6404,7 @@ private:
return false; return false;
} }
void checkClassAssign(AstNode* nodep, const char* side, AstNode* rhsp, void checkClassAssign(AstNode* nodep, const char* side, AstNode* rhsp,
AstNodeDType* lhsDTypep) { const AstNodeDType* const lhsDTypep) {
if (AstClassRefDType* const lhsClassRefp = VN_CAST(lhsDTypep->skipRefp(), ClassRefDType)) { if (AstClassRefDType* const lhsClassRefp = VN_CAST(lhsDTypep->skipRefp(), ClassRefDType)) {
UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type"); UASSERT_OBJ(rhsp->dtypep(), rhsp, "Node has no type");
AstNodeDType* const rhsDtypep = rhsp->dtypep()->skipRefp(); AstNodeDType* const rhsDtypep = rhsp->dtypep()->skipRefp();
@ -6415,7 +6417,8 @@ private:
<< rhsDtypep->prettyTypeName()); << rhsDtypep->prettyTypeName());
} }
} }
static bool similarDTypeRecurse(AstNodeDType* node1p, AstNodeDType* node2p) { static bool similarDTypeRecurse(const AstNodeDType* const node1p,
const AstNodeDType* const node2p) {
return node1p->skipRefp()->similarDType(node2p->skipRefp()); return node1p->skipRefp()->similarDType(node2p->skipRefp());
} }
void iterateCheckFileDesc(AstNode* nodep, AstNode* underp, Stage stage) { void iterateCheckFileDesc(AstNode* nodep, AstNode* underp, Stage stage) {

View File

@ -2,7 +2,7 @@
: ... In instance t : ... In instance t
20 | Converter#(bit) conv2 = conv1; 20 | Converter#(bit) conv2 = conv1;
| ^~~~~ | ^~~~~
%Error-ENUMVALUE: t/t_class_param_enum_bad.v:21:19: Implicit conversion to enum 'T' from 'logic[31:0]' (IEEE 1800-2017 6.19.3) %Error-ENUMVALUE: t/t_class_param_enum_bad.v:21:19: Implicit conversion to enum 'ENUMDTYPE '$unit::enum_t'' from 'logic[31:0]' (IEEE 1800-2017 6.19.3)
: ... In instance t : ... In instance t
: ... Suggest use enum's mnemonic, or static cast : ... Suggest use enum's mnemonic, or static cast
21 | conv1.toInt(0); 21 | conv1.toInt(0);

View File

@ -1,4 +1,4 @@
%Error: t/t_func_refio_bad.v:16:17: Ref argument requires matching types; port 'q' requires VAR 'q' but connection is CONST '?32?sh2a'. %Error: t/t_func_refio_bad.v:16:17: Ref argument requires matching types; port 'q' requires integer[$] but connection is logic[31:0].
: ... In instance t : ... In instance t
16 | queue_set(42); 16 | queue_set(42);
| ^~ | ^~

View File

@ -2,7 +2,7 @@
: ... In instance t : ... In instance t
13 | bad_const_set = 32'h4567; 13 | bad_const_set = 32'h4567;
| ^~~~~~~~~~~~~ | ^~~~~~~~~~~~~
%Error: t/t_var_ref_bad2.v:23:17: Ref argument requires matching types; port 'int_ref' requires VAR 'int_ref' but connection is VARREF 'bad_non_int'. %Error: t/t_var_ref_bad2.v:23:17: Ref argument requires matching types; port 'int_ref' requires int but connection is byte.
: ... In instance t : ... In instance t
23 | checkset2(bad_non_int); 23 | checkset2(bad_non_int);
| ^~~~~~~~~~~ | ^~~~~~~~~~~