diff --git a/Changes b/Changes index 79495183c..cc83c659d 100644 --- a/Changes +++ b/Changes @@ -16,6 +16,8 @@ The contributors that suggested a given feature are shown in []. Thanks! **** Fix multithreaded yield behavior when no work. [Patrick Stewart] +**** Fix misc bad-syntax crashes, bug1548, bug1550-1553. [Eric Rippey] + * Verilator 4.020 2019-10-06 diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp index c0b53eab5..f1c3a120a 100644 --- a/src/V3LinkDot.cpp +++ b/src/V3LinkDot.cpp @@ -1125,8 +1125,8 @@ class LinkDotFindVisitor : public AstNVisitor { && !foundp->imported()) { // and not from package nodep->v3error("Duplicate declaration of enum value: "<prettyName()<warnContextPrimary()<warnOther()<<"... Location of original declaration\n" - <warnContextSecondary()); + <nodep()->warnOther()<<"... Location of original declaration\n" + <nodep()->warnContextSecondary()); } else { // User can disable the message at either point if (!nodep->fileline()->warnIsOff(V3ErrorCode::VARHIDDEN) diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp index 249f73821..51e490286 100644 --- a/src/V3PreProc.cpp +++ b/src/V3PreProc.cpp @@ -136,6 +136,7 @@ public: std::stack m_states; ///< Current state of parser int m_off; ///< If non-zero, ifdef level is turned off, don't dump text + bool m_incError; ///< Include error found string m_lastSym; ///< Last symbol name found. string m_formals; ///< Last formals found @@ -250,6 +251,7 @@ public: m_debug = 0; m_states.push(ps_TOP); m_off = 0; + m_incError = false; m_lineChars = ""; m_lastSym = ""; m_lineAdd = 0; @@ -748,6 +750,7 @@ string V3PreProcImp::defineSubst(VDefineRef* refp) { void V3PreProcImp::openFile(FileLine* fl, VInFilter* filterp, const string& filename) { // Open a new file, possibly overriding the current one which is active. + if (m_incError) return; V3File::addSrcDepend(filename); // Read a list with the whole file. @@ -761,8 +764,11 @@ void V3PreProcImp::openFile(FileLine* fl, VInFilter* filterp, const string& file if (!m_preprocp->isEof()) { // IE not the first file. // We allow the same include file twice, because occasionally it pops // up, with guards preventing a real recursion. - if (m_lexp->m_streampStack.size()>V3PreProc::INCLUDE_DEPTH_MAX) { + if (m_lexp->m_streampStack.size() > V3PreProc::INCLUDE_DEPTH_MAX) { error("Recursive inclusion of file: "+filename); + // Include might be a tree of includes that is O(n^2) or worse. + // Once hit this error then, ignore all further includes so can unwind. + m_incError = true; return; } // There's already a file active. Push it to work on the new one. diff --git a/src/verilog.y b/src/verilog.y index d7f1f9bd3..b2f3bdab6 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1125,7 +1125,7 @@ anonymous_program_item: // ==IEEE: anonymous_program_item //UNSUP class_declaration { $$ = $1; } //UNSUP covergroup_declaration { $$ = $1; } // // class_constructor_declaration is part of function_declaration - | ';' { } + | ';' { $$ = NULL; } ; program_declaration: // IEEE: program_declaration + program_nonansi_header + program_ansi_header: @@ -3400,7 +3400,7 @@ exprOkLvalue: // expression that's also OK to use as a variable_lvalue // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type] // // We allow more here than the spec requires //UNSUP ~l~exprScope assignment_pattern { UNSUP } - | data_type assignment_pattern { $$ = $2; $2->childDTypep($1); } + | data_type assignment_pattern { $$ = $2; if ($2) $2->childDTypep($1); } | assignment_pattern { $$ = $1; } // | streaming_concatenation { $$ = $1; } @@ -3749,7 +3749,7 @@ combinational_body: // IEEE: combinational_body + sequential_body tableEntryList: // IEEE: { combinational_entry | sequential_entry } tableEntry { $$ = $1; } - | tableEntryList tableEntry { $$ = $1->addNext($2); } + | tableEntryList tableEntry { $$ = $1->addNextNull($2); } ; tableEntry: // IEEE: combinational_entry + sequential_entry diff --git a/test_regress/t/t_preproc_inc_recurse_bad.out b/test_regress/t/t_preproc_inc_recurse_bad.out new file mode 100644 index 000000000..a4ac2808b --- /dev/null +++ b/test_regress/t/t_preproc_inc_recurse_bad.out @@ -0,0 +1,4 @@ +%Error: t/t_preproc_inc_recurse_bad.v:6: Recursive inclusion of file: t/t_preproc_inc_recurse_bad.v +`include "t_preproc_inc_recurse_bad.v" + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%Error: Exiting due to diff --git a/test_regress/t/t_preproc_inc_recurse_bad.pl b/test_regress/t/t_preproc_inc_recurse_bad.pl new file mode 100755 index 000000000..b09f43e8b --- /dev/null +++ b/test_regress/t/t_preproc_inc_recurse_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_preproc_inc_recurse_bad.v b/test_regress/t/t_preproc_inc_recurse_bad.v new file mode 100644 index 000000000..da097aeaf --- /dev/null +++ b/test_regress/t/t_preproc_inc_recurse_bad.v @@ -0,0 +1,6 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2019 by Wilson Snyder. + +`include "t_preproc_inc_recurse_bad.v"