Fix virtual interface function calls binding to wrong instance (#7363)

This commit is contained in:
Yilou Wang
2026-04-02 10:53:01 -04:00
committed by GitHub
parent 32672deb6f
commit 1e5c93cc51
3 changed files with 70 additions and 2 deletions
+11 -2
View File
@@ -251,6 +251,13 @@ private:
if (nodep->dpiImport()) m_curVxp->noInline(true);
if (nodep->classMethod()) m_curVxp->noInline(true); // Until V3Task supports it
if (nodep->recursive()) m_curVxp->noInline(true);
// V3Scope resolves virtual-interface MethodCalls via user2p (last-wins),
// so inlining would bake in the wrong instance's VarScope refs.
if (v3Global.hasVirtIfaces()) {
if (const AstScope* const scopep = VN_CAST(nodep->user3p(), Scope)) {
if (VN_IS(scopep->modp(), Iface)) m_curVxp->noInline(true);
}
}
if (nodep->isConstructor()) {
m_curVxp->noInline(true);
m_ctorp = nodep;
@@ -1690,10 +1697,12 @@ class TaskVisitor final : public VNVisitor {
}
const bool noInline = m_statep->ftaskNoInline(nodep);
// Warn if not inlining an impure ftask (unless method or recursvie).
// Warn if not inlining an impure ftask (unless method, recursive,
// or interface function -- interface member access is not truly external).
// Will likely not schedule correctly.
// TODO: Why not if recursive? It will not work ...
if (noInline && !nodep->classMethod() && !nodep->recursive()) {
if (noInline && !nodep->classMethod() && !nodep->recursive()
&& !VN_IS(m_modp, Iface)) {
if (AstNode* const impurep = m_statep->checkImpure(nodep)) {
nodep->v3warn(
IMPURE,