Fix initialization order of initial static after function/task (#4159)

This commit is contained in:
Kamil Rakoczy 2023-05-02 17:50:57 +02:00 committed by GitHub
parent 128186ea68
commit 49d2eb9a08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 20 deletions

View File

@ -40,6 +40,39 @@ VL_DEFINE_DEBUG_FUNCTIONS;
//######################################################################
class RenameStaticVisitor final : public VNVisitor {
private:
// STATE
const std::set<AstVar*>& m_staticFuncVarsr; // Static variables from m_ftaskp
AstNodeFTask* const m_ftaskp; // Current function/task
// VISITORS
void visit(AstVarRef* nodep) override {
const auto it = m_staticFuncVarsr.find(nodep->varp());
if (it != m_staticFuncVarsr.end()) nodep->name((*it)->name());
iterateChildren(nodep);
}
void visit(AstInitialStatic* nodep) override {
iterateChildren(nodep);
nodep->unlinkFrBack();
m_ftaskp->addHereThisAsNext(nodep);
}
void visit(AstNode* nodep) override { iterateChildren(nodep); }
public:
// CONSTRUCTORS
RenameStaticVisitor(std::set<AstVar*>& staticFuncVars, AstNodeFTask* ftaskp, AstNode* nodep)
: m_staticFuncVarsr(staticFuncVars)
, m_ftaskp(ftaskp) {
iterateChildren(nodep);
}
~RenameStaticVisitor() override = default;
};
//######################################################################
class BeginState final {
private:
// NODE STATE
@ -123,25 +156,6 @@ private:
}
}
void renameAndStaticsRecurse(AstNode* const nodep) {
// Rename references and move InitialStatic items
if (AstVarRef* const varrefp = VN_CAST(nodep, VarRef)) {
const auto it = m_staticFuncVars.find(varrefp->varp());
if (it != m_staticFuncVars.end()) varrefp->name((*it)->name());
}
if (nodep->op1p()) renameAndStaticsRecurse(nodep->op1p());
if (nodep->op2p()) renameAndStaticsRecurse(nodep->op2p());
if (nodep->op3p()) renameAndStaticsRecurse(nodep->op3p());
if (nodep->op4p()) renameAndStaticsRecurse(nodep->op4p());
if (nodep->nextp()) renameAndStaticsRecurse(nodep->nextp());
if (VN_IS(nodep, InitialStatic)) {
nodep->unlinkFrBack();
m_ftaskp->addHereThisAsNext(nodep);
}
}
// VISITORS
void visit(AstFork* nodep) override {
// Keep begins in forks to group their statements together
@ -197,7 +211,7 @@ private:
m_ftaskp = nodep;
m_liftedp = nullptr;
iterateChildren(nodep);
renameAndStaticsRecurse(nodep);
RenameStaticVisitor{m_staticFuncVars, m_ftaskp, nodep};
if (m_liftedp) {
// Place lifted nodes at beginning of stmtsp, so Var nodes appear before referenced
if (AstNode* const stmtsp = nodep->stmtsp()) {

View File

@ -16,6 +16,7 @@ compile(
execute(
check_finished => 1,
all_run_flags => ['+plusarg=value'],
);
ok(1);

View File

@ -52,10 +52,17 @@ module t (/*AUTOARG*/
function automatic int f_au_au ();
automatic int au = 2; au++; return au;
endfunction
string plusarg = "";
bit has_plusarg = |($value$plusargs("plusarg=%s", plusarg));
int v;
initial begin
if (has_plusarg) begin
if (plusarg == "") begin
$fatal(1, "%m: +plusarg must not be empty");
end
end
v = f_no_no(); `checkh(v, 3);
v = f_no_no(); `checkh(v, 4);
v = f_no_st(); `checkh(v, 3);