From 2c01aff2b3900e9f9d0c9c91e3a3f612f9f13e6d Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Tue, 4 Nov 2025 10:34:58 -0500 Subject: [PATCH] Fix expression short circuiting (#6483) --- src/V3AstNodes.cpp | 10 ++++++--- test_regress/t/t_expr_shortcircuit.py | 18 ++++++++++++++++ test_regress/t/t_expr_shortcircuit.v | 30 +++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_expr_shortcircuit.py create mode 100644 test_regress/t/t_expr_shortcircuit.v 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