From 6ca60429ce01fb1f60dcb24d897b7bbbdb62559e Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Sun, 4 Feb 2024 14:19:54 +0000 Subject: [PATCH] Fix incorrect temporary insertion in loop conditions with statements (#4873) When the condition of an AstWhile loop contains a statement (e.g. through an AstExprStmt), temporaries inserted in that statement need to go before that statement, not in the AstWhile precondition. --- src/V3Premit.cpp | 4 +++- test_regress/t/t_while_cond_is_stmt.pl | 18 ++++++++++++++++ test_regress/t/t_while_cond_is_stmt.v | 29 ++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_while_cond_is_stmt.pl create mode 100644 test_regress/t/t_while_cond_is_stmt.v diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp index b313df5c9..44036735c 100644 --- a/src/V3Premit.cpp +++ b/src/V3Premit.cpp @@ -176,8 +176,10 @@ class PremitVisitor final : public VNVisitor { if (stmtp->user1SetOnce()) return; \ VL_RESTORER(m_assignLhs); \ VL_RESTORER(m_stmtp); \ + VL_RESTORER(m_inWhileCondp); \ m_assignLhs = false; \ - m_stmtp = stmtp + m_stmtp = stmtp; \ + m_inWhileCondp = nullptr void visit(AstWhile* nodep) override { UINFO(4, " WHILE " << nodep << endl); diff --git a/test_regress/t/t_while_cond_is_stmt.pl b/test_regress/t/t_while_cond_is_stmt.pl new file mode 100755 index 000000000..b3335ee60 --- /dev/null +++ b/test_regress/t/t_while_cond_is_stmt.pl @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2024 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 + +scenarios(simulator => 1); + +compile(); + +execute(); + +ok(1); +1; diff --git a/test_regress/t/t_while_cond_is_stmt.v b/test_regress/t/t_while_cond_is_stmt.v new file mode 100644 index 000000000..9e7289d05 --- /dev/null +++ b/test_regress/t/t_while_cond_is_stmt.v @@ -0,0 +1,29 @@ +// DESCRIPTION: Verilator: Test of select from constant +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2024 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +module t; + + function int unsigned nth_power_of_2(input int unsigned n); + nth_power_of_2 = 1; + while (n != 0) begin + n = n - 1; + nth_power_of_2 = nth_power_of_2 << 1; + end + endfunction + + initial begin + // Evaluating the function call in the loop condition used + // to cause an infinite loop at run-time + while (nth_power_of_2(8) != 256) begin + $display("2**8 != 256 ?!"); + $stop; + end + + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule