mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +02:00
Fix false ASSIGNIN on functions with explicit port map (#5069).
This commit is contained in:
+21
-12
@@ -1589,14 +1589,13 @@ public:
|
||||
const char* const V3Task::s_dpiTemporaryVarSuffix = "__Vcvt";
|
||||
|
||||
V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
|
||||
V3TaskConnectState* statep) {
|
||||
V3TaskConnectState* statep, bool makeChanges) {
|
||||
// Output list will be in order of the port declaration variables (so
|
||||
// func calls are made right in C)
|
||||
// Missing pin/expr? We return (pinvar, nullptr)
|
||||
// Extra pin/expr? We clean it up
|
||||
UINFO(9, "taskConnects " << nodep << endl);
|
||||
std::map<const std::string, int> nameToIndex;
|
||||
std::set<const AstVar*> argWrap; // Which ports are defaulted, forcing arg wrapper creation
|
||||
V3TaskConnects tconnects;
|
||||
UASSERT_OBJ(nodep->taskp(), nodep, "unlinked");
|
||||
|
||||
@@ -1608,7 +1607,7 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
|
||||
if (portp->isIO()) {
|
||||
tconnects.emplace_back(portp, static_cast<AstArg*>(nullptr));
|
||||
nameToIndex.emplace(portp->name(), tpinnum); // For name based connections
|
||||
tpinnum++;
|
||||
++tpinnum;
|
||||
if (portp->attrSFormat()) {
|
||||
sformatp = portp;
|
||||
} else if (sformatp) {
|
||||
@@ -1630,17 +1629,19 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
|
||||
// By name
|
||||
const auto it = nameToIndex.find(argp->name());
|
||||
if (it == nameToIndex.end()) {
|
||||
pinp->v3error("No such argument " << argp->prettyNameQ() << " in function call to "
|
||||
<< nodep->taskp()->prettyTypeName());
|
||||
// We'll just delete it; seems less error prone than making a false argument
|
||||
VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp);
|
||||
if (makeChanges) {
|
||||
pinp->v3error("No such argument " << argp->prettyNameQ()
|
||||
<< " in function call to "
|
||||
<< nodep->taskp()->prettyTypeName());
|
||||
// We'll just delete it; seems less error prone than making a false argument
|
||||
VL_DO_DANGLING(pinp->unlinkFrBack()->deleteTree(), pinp);
|
||||
}
|
||||
} else {
|
||||
if (tconnects[it->second].second) {
|
||||
if (tconnects[it->second].second && makeChanges) {
|
||||
pinp->v3error("Duplicate argument " << argp->prettyNameQ()
|
||||
<< " in function call to "
|
||||
<< nodep->taskp()->prettyTypeName());
|
||||
}
|
||||
argp->name(""); // Can forget name as will add back in pin order
|
||||
tconnects[it->second].second = argp;
|
||||
reorganize = true;
|
||||
}
|
||||
@@ -1649,8 +1650,8 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
|
||||
if (sformatp) {
|
||||
tconnects.emplace_back(sformatp, static_cast<AstArg*>(nullptr));
|
||||
tconnects[ppinnum].second = argp;
|
||||
tpinnum++;
|
||||
} else {
|
||||
++tpinnum;
|
||||
} else if (makeChanges) {
|
||||
pinp->v3error("Too many arguments in function call to "
|
||||
<< nodep->taskp()->prettyTypeName());
|
||||
// We'll just delete it; seems less error prone than making a false argument
|
||||
@@ -1660,10 +1661,13 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
|
||||
tconnects[ppinnum].second = argp;
|
||||
}
|
||||
}
|
||||
ppinnum++;
|
||||
++ppinnum;
|
||||
}
|
||||
|
||||
if (!makeChanges) return tconnects;
|
||||
|
||||
// Connect missing ones
|
||||
std::set<const AstVar*> argWrap; // Which ports are defaulted, forcing arg wrapper creation
|
||||
for (int i = 0; i < tpinnum; ++i) {
|
||||
AstVar* const portp = tconnects[i].first;
|
||||
if (!tconnects[i].second || !tconnects[i].second->exprp()) {
|
||||
@@ -1723,6 +1727,11 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp,
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& tconnect : tconnects) {
|
||||
AstArg* const argp = tconnect.second;
|
||||
argp->name(""); // Can forget name as will add back in pin order
|
||||
}
|
||||
|
||||
if (reorganize) {
|
||||
// To simplify downstream, put argument list back into pure pinnumber ordering
|
||||
while (nodep->pinsp()) {
|
||||
|
||||
Reference in New Issue
Block a user