From 5ee938fd1cee415075ced9551199e45f3191df52 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Fri, 8 Mar 2024 17:33:51 -0500 Subject: [PATCH] Fix assignment of null into struct member (#4952). --- Changes | 3 ++- src/V3Cast.cpp | 5 ++-- test_regress/t/t_class_null_struct.pl | 20 ++++++++++++++ test_regress/t/t_class_null_struct.v | 39 +++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100755 test_regress/t/t_class_null_struct.pl create mode 100644 test_regress/t/t_class_null_struct.v diff --git a/Changes b/Changes index af031e8e1..a47207a0c 100644 --- a/Changes +++ b/Changes @@ -23,11 +23,12 @@ Verilator 5.023 devel * Support public packed struct / union (#860) (#4878). [Kefa Chen] * Change installation to be relocatable (#4927). [Geza Lore] * Fix __Vlip undefined error in --freloop (#4824). [Justin Yao Du] -* Fix invalid cast on string structure creation (#4921). [esynr3z] +* Fix invalid cast on string structure creation (#4921). * Fix try-lock spuriously fails (#4931) (#4938). [Kamil Rakoczy] * Fix V3Unknown unpacked struct x-assign (#4934). [Yan Xu] * Fix DFG removing forceable signals (#4942). [Geza Lore] * Fix null characters in shortened identifiers (#4946). [Abdul Hameed] +* Fix assignment of null into struct member (#4952). Verilator 5.022 2024-02-24 diff --git a/src/V3Cast.cpp b/src/V3Cast.cpp index b6a79353e..8a6df2876 100644 --- a/src/V3Cast.cpp +++ b/src/V3Cast.cpp @@ -82,7 +82,8 @@ class CastVisitor final : public VNVisitor { } void ensureCast(AstNodeExpr* nodep) { if (castSize(nodep->backp()) != castSize(nodep) || !nodep->user1()) { - insertCast(nodep, castSize(nodep->backp())); + const AstConst* const constp = VN_CAST(nodep, Const); + if (!(constp && constp->num().isNull())) insertCast(nodep, castSize(nodep->backp())); } } void ensureLower32Cast(AstCCast* nodep) { @@ -201,7 +202,7 @@ class CastVisitor final : public VNVisitor { // Constants are of unknown size if smaller than 33 bits, because // we're too lazy to wrap every constant in the universe in // ((IData)#). - nodep->user1(nodep->isQuad() || nodep->isWide()); + nodep->user1(nodep->isQuad() || nodep->isWide() || nodep->num().isNull()); } // Null dereference protection diff --git a/test_regress/t/t_class_null_struct.pl b/test_regress/t/t_class_null_struct.pl new file mode 100755 index 000000000..49330a5fe --- /dev/null +++ b/test_regress/t/t_class_null_struct.pl @@ -0,0 +1,20 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2020 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_class_null_struct.v b/test_regress/t/t_class_null_struct.v new file mode 100644 index 000000000..c68a382f8 --- /dev/null +++ b/test_regress/t/t_class_null_struct.v @@ -0,0 +1,39 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// 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 + +class Cls; +endclass : Cls + +typedef struct { + Cls obj; + int number; +} str_t; + +module t (/*AUTOARG*/); + function automatic str_t func_null(); + return '{null, 42}; + endfunction + + function automatic str_t func_obj(); + Cls c; + c = new; + return '{c, 43}; + endfunction + + initial begin + str_t result; + result = func_null(); + if (result.obj != null) $stop; + if (result.number != 42) $stop; + + result = func_obj(); + if (result.obj == null) $stop; + if (result.number != 43) $stop; + + $write("*-* All Finished *-*\n"); + $finish; + end +endmodule