Duplicate default function/task argument expressions

The default value for a function or task argument is elaborated once and
then used for each function invocation where no actual value is provided.

This means if a function or task is called multiple times the same NetExpr
is passed as a sub-expression to multiple statements or expressions such as
the function call.

This is causing problems because each expression or statement expects to
have exclusive ownership over its sub-expressions. It can for example
result in a double free or other undefined behavior.

To mitigate this duplicate the default argument expression before it is
given as a sub-expression to another expression or statement.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
This commit is contained in:
Lars-Peter Clausen 2023-01-07 20:33:36 -08:00
parent b74059eaa9
commit c90265351b
2 changed files with 5 additions and 5 deletions

View File

@ -2954,7 +2954,7 @@ unsigned PECallFunction::elaborate_arguments_(Design*des, NetScope*scope,
<< "requires SystemVerilog." << endl;
des->errors += 1;
}
parms[pidx] = def->port_defe(pidx);
parms[pidx] = def->port_defe(pidx)->dup_expr();
} else {
missing_parms += 1;
@ -6573,7 +6573,7 @@ NetExpr* PENewClass::elaborate_expr_constructor_(Design*des, NetScope*scope,
// Ran out of explicit arguments. Is there a default
// argument we can use?
if (NetExpr*tmp = def->port_defe(idx)) {
parms[idx] = tmp;
parms[idx] = tmp->dup_expr();
continue;
}

View File

@ -3344,7 +3344,7 @@ NetProc* PChainConstructor::elaborate(Design*des, NetScope*scope) const
}
if (NetExpr*tmp = def->port_defe(idx)) {
parms[idx] = tmp;
parms[idx] = tmp->dup_expr();
continue;
}
@ -4173,9 +4173,9 @@ NetProc* PCallTask::elaborate_build_call_(Design*des, NetScope*scope,
"requires SystemVerilog." << endl;
des->errors += 1;
}
rv = def->port_defe(idx);
rv = def->port_defe(idx)->dup_expr();
if (lv_type==IVL_VT_BOOL||lv_type==IVL_VT_LOGIC)
rv = pad_to_width(rv->dup_expr(), wid, *this);
rv = pad_to_width(rv, wid, *this);
} else {
cerr << get_fileline() << ": error: "