From 530ab17c8bc3ddf2a1f38392788e2e01007c9e54 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Mon, 4 Nov 2019 21:51:20 -0500 Subject: [PATCH] Fix bad-syntax crashes, bug1586, bug1587. --- Changes | 2 +- src/V3Slice.cpp | 68 +++++++++++++++++------------- test_regress/t/t_fuzz_eqne_bad.out | 5 +++ test_regress/t/t_fuzz_eqne_bad.pl | 18 ++++++++ test_regress/t/t_fuzz_eqne_bad.v | 12 ++++++ 5 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 test_regress/t/t_fuzz_eqne_bad.out create mode 100755 test_regress/t/t_fuzz_eqne_bad.pl create mode 100644 test_regress/t/t_fuzz_eqne_bad.v diff --git a/Changes b/Changes index 85f7f900c..99b8be577 100644 --- a/Changes +++ b/Changes @@ -27,7 +27,7 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix multithreaded yield behavior when no work. [Patrick Stewart] **** Fix bad-syntax crashes, bug1548, bug1550-1553, bug1557-1560, bug1563, - bug1573-1577, bug1582-1585, bug1589-1591. [Eric Rippey] + bug1573-1577, bug1582-1591. [Eric Rippey] **** Fix false CMPCONST/UNSIGNED warnings on "inside", bug1581. [Mitch Hayenga] diff --git a/src/V3Slice.cpp b/src/V3Slice.cpp index 063ec6d7e..ad997c830 100644 --- a/src/V3Slice.cpp +++ b/src/V3Slice.cpp @@ -173,38 +173,48 @@ class SliceVisitor : public AstNVisitor { UINFO(9, " Bi-Eq/Neq expansion "<rangep()->elementsConst(); ++index) { - // EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1]) - AstNodeBiop* clonep - = VN_CAST(nodep->cloneType - (new AstArraySel(nodep->fileline(), - nodep->lhsp()->cloneTree(false), - index), - new AstArraySel(nodep->fileline(), - nodep->rhsp()->cloneTree(false), - index)), - NodeBiop); - if (!logp) logp = clonep; - else { - switch (nodep->type()) { - case AstType::atEq: // FALLTHRU - case AstType::atEqCase: - logp = new AstLogAnd(nodep->fileline(), logp, clonep); - break; - case AstType::atNeq: // FALLTHRU - case AstType::atNeqCase: - logp = new AstLogOr(nodep->fileline(), logp, clonep); - break; - default: - nodep->v3fatalSrc("Unknown node type processing array slice"); - break; + if (!VN_IS(nodep->lhsp()->dtypep()->skipRefp(), NodeArrayDType)) { + nodep->lhsp()->v3error("Slice operatator "<lhsp()->prettyTypeName() + <<" on non-slicable (e.g. non-vector) left-hand-side operand"); + } + else if (!VN_IS(nodep->rhsp()->dtypep()->skipRefp(), NodeArrayDType)) { + nodep->rhsp()->v3error("Slice operatator "<rhsp()->prettyTypeName() + <<" on non-slicable (e.g. non-vector) right-hand-side operand"); + } + else { + for (int index = 0; index < adtypep->rangep()->elementsConst(); ++index) { + // EQ(a,b) -> LOGAND(EQ(ARRAYSEL(a,0), ARRAYSEL(b,0)), ...[1]) + AstNodeBiop* clonep + = VN_CAST(nodep->cloneType + (new AstArraySel(nodep->fileline(), + nodep->lhsp()->cloneTree(false), + index), + new AstArraySel(nodep->fileline(), + nodep->rhsp()->cloneTree(false), + index)), + NodeBiop); + if (!logp) logp = clonep; + else { + switch (nodep->type()) { + case AstType::atEq: // FALLTHRU + case AstType::atEqCase: + logp = new AstLogAnd(nodep->fileline(), logp, clonep); + break; + case AstType::atNeq: // FALLTHRU + case AstType::atNeqCase: + logp = new AstLogOr(nodep->fileline(), logp, clonep); + break; + default: + nodep->v3fatalSrc("Unknown node type processing array slice"); + break; + } } } + UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range"); + nodep->replaceWith(logp); + pushDeletep(nodep); VL_DANGLING(nodep); + nodep = logp; } - UASSERT_OBJ(logp, nodep, "Unpacked array with empty indices range"); - nodep->replaceWith(logp); - pushDeletep(nodep); VL_DANGLING(nodep); - nodep = logp; } iterateChildren(nodep); } diff --git a/test_regress/t/t_fuzz_eqne_bad.out b/test_regress/t/t_fuzz_eqne_bad.out new file mode 100644 index 000000000..599558e7f --- /dev/null +++ b/test_regress/t/t_fuzz_eqne_bad.out @@ -0,0 +1,5 @@ +%Error: t/t_fuzz_eqne_bad.v:11: Slice operatator VARREF 't.b' on non-slicable (e.g. non-vector) right-hand-side operand + : ... In instance t.b + initial c = (a != &b); + ^ +%Error: Exiting due to diff --git a/test_regress/t/t_fuzz_eqne_bad.pl b/test_regress/t/t_fuzz_eqne_bad.pl new file mode 100755 index 000000000..b09f43e8b --- /dev/null +++ b/test_regress/t/t_fuzz_eqne_bad.pl @@ -0,0 +1,18 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +scenarios(linter => 1); + +lint( + fails => 1, + expect_filename => $Self->{golden_filename}, + ); + +ok(1); +1; diff --git a/test_regress/t/t_fuzz_eqne_bad.v b/test_regress/t/t_fuzz_eqne_bad.v new file mode 100644 index 000000000..bef8e3548 --- /dev/null +++ b/test_regress/t/t_fuzz_eqne_bad.v @@ -0,0 +1,12 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +//bug1587 +module t; + reg a[0]; + reg b; + reg c; + initial c = (a != &b); +endmodule