diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 778784ba0..d7ed985dc 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -2942,9 +2942,13 @@ bool AstNodeFTask::getPurityRecurse() const { if (varp->isInoutOrRef()) return false; } if (!stmtp->isPure()) return false; - if (stmtp->exists([](const AstNodeVarRef* const varrefp) { - return (!varrefp->varp()->isFuncLocal() || varrefp->varp()->lifetime().isStatic()) - && varrefp->access().isWriteOrRW(); + if (stmtp->exists([](AstNode* const nodep) { + if (AstNodeVarRef* const varrefp = VN_CAST(nodep, VarRef)) { + return (!varrefp->varp()->isFuncLocal() + || varrefp->varp()->lifetime().isStatic()) + && varrefp->access().isWriteOrRW(); + } + return !nodep->isPure(); })) return false; } diff --git a/test_regress/t/t_expr_shortcircuit.py b/test_regress/t/t_expr_shortcircuit.py new file mode 100755 index 000000000..f989a35fb --- /dev/null +++ b/test_regress/t/t_expr_shortcircuit.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2025 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +import vltest_bootstrap + +test.scenarios('simulator') + +test.compile() + +test.execute() + +test.passes() diff --git a/test_regress/t/t_expr_shortcircuit.v b/test_regress/t/t_expr_shortcircuit.v new file mode 100644 index 000000000..f3960ce4c --- /dev/null +++ b/test_regress/t/t_expr_shortcircuit.v @@ -0,0 +1,30 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + + int cyc = 0; + + function automatic logic is_odd(int value); + logic odd = value % 2 == 1; + if (!odd) $error($sformatf("%0d is not odd", value)); + return odd; + endfunction + + always_ff @(posedge clk) begin + if (cyc[0] == 1'b0 || is_odd(cyc)) + cyc <= cyc + 1; + if (cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end +endmodule