Improve `lint_off` to allow multiple messages and comments (#2755 partial).
This commit is contained in:
parent
2631af977a
commit
1a8f9f0483
1
Changes
1
Changes
|
|
@ -33,6 +33,7 @@ Verilator 5.041 devel
|
|||
* Support digits in `$sscanf` field width formats (#6083). [Iztok Jeras]
|
||||
* Support pure functions in sensitivity lists (#6393). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support simple alias statements (#6339) (#6501). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Improve `lint_off` to allow multiple messages and comments (#2755).
|
||||
* Improve automatic selection of logic for DFG synthesis (#6370). [Geza Lore]
|
||||
* Improve `covergroup with function sample` handling (#6387). [Jakub Wasilewski]
|
||||
* Improve DFG type system (#6390). [Geza Lore]
|
||||
|
|
|
|||
|
|
@ -362,15 +362,20 @@ or "`ifdef`"'s may break other tools.
|
|||
|
||||
Same as :option:`isolate_assignments` control file option.
|
||||
|
||||
.. option:: /*verilator&32;lint_off <msg>*/
|
||||
.. option:: /*verilator&32;lint_off <msgs>*/
|
||||
|
||||
Disable the specified warning message for any warnings following the
|
||||
comment.
|
||||
Disable the specified warning message(s) for any warnings following the
|
||||
comment. Multiple messages may be specified, separated with commas.
|
||||
|
||||
.. option:: /*verilator&32;lint_on <msg>*/
|
||||
If a one-line slash-slash-format comment is used, then the metacomment
|
||||
ends at the newline or at an earlier next slash-slash. This allow
|
||||
commenting the reason for the disable, e.g. :code:`// verilator lint_off
|
||||
MSG // Because...`.
|
||||
|
||||
Re-enable the specified warning message for any warnings following the
|
||||
comment.
|
||||
.. option:: /*verilator&32;lint_on <msgs>*/
|
||||
|
||||
Re-enable the specified warning message(s) for any warnings following
|
||||
the comment. Multiple messages may be specified, separated with commas.
|
||||
|
||||
.. option:: /*verilator&32;lint_restore*/
|
||||
|
||||
|
|
|
|||
|
|
@ -368,23 +368,29 @@ std::ostream& operator<<(std::ostream& os, FileLine* fileline) {
|
|||
return (os);
|
||||
}
|
||||
|
||||
bool FileLine::warnOff(const string& msg, bool flag) {
|
||||
const char* cmsg = msg.c_str();
|
||||
// Backward compatibility with msg="UNUSED"
|
||||
if (V3ErrorCode::unusedMsg(cmsg)) {
|
||||
warnOff(V3ErrorCode::UNUSEDGENVAR, flag);
|
||||
warnOff(V3ErrorCode::UNUSEDLOOP, flag);
|
||||
warnOff(V3ErrorCode::UNUSEDPARAM, flag);
|
||||
warnOff(V3ErrorCode::UNUSEDSIGNAL, flag);
|
||||
return true;
|
||||
}
|
||||
const V3ErrorCode code{cmsg};
|
||||
if (code.hardError()) {
|
||||
return false;
|
||||
} else {
|
||||
warnOff(code, flag);
|
||||
return true;
|
||||
string FileLine::warnOffParse(const string& msgs, bool flag) {
|
||||
string result;
|
||||
for (const string& msg : VString::split(msgs, ',')) {
|
||||
const char* cmsg = msg.c_str();
|
||||
// Backward compatibility with msg="UNUSED"
|
||||
if (V3ErrorCode::unusedMsg(cmsg)) {
|
||||
warnOff(V3ErrorCode::UNUSEDGENVAR, flag);
|
||||
warnOff(V3ErrorCode::UNUSEDLOOP, flag);
|
||||
warnOff(V3ErrorCode::UNUSEDPARAM, flag);
|
||||
warnOff(V3ErrorCode::UNUSEDSIGNAL, flag);
|
||||
continue;
|
||||
}
|
||||
|
||||
const V3ErrorCode code{cmsg};
|
||||
if (!code.hardError()) {
|
||||
warnOff(code, flag);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Error if not suppressed
|
||||
if (!v3Global.opt.isFuture(msg)) result = VString::dot(result, ",", cmsg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void FileLine::warnLintOff(bool flag) {
|
||||
|
|
|
|||
|
|
@ -322,7 +322,7 @@ public:
|
|||
m_msgEnIdx = singleton().msgEnSetBit(m_msgEnIdx, code, flag);
|
||||
}
|
||||
void warnOff(V3ErrorCode code, bool flag) { warnOn(code, !flag); }
|
||||
bool warnOff(const string& msg, bool flag); // Returns 1 if ok
|
||||
string warnOffParse(const string& msgs, bool flag); // Returns "" if ok
|
||||
bool warnIsOff(V3ErrorCode code) const VL_MT_SAFE;
|
||||
void warnLintOff(bool flag);
|
||||
void warnStyleOff(bool flag);
|
||||
|
|
@ -350,8 +350,8 @@ public:
|
|||
static void globalWarnOff(V3ErrorCode code, bool flag) {
|
||||
defaultFileLine().warnOff(code, flag);
|
||||
}
|
||||
static bool globalWarnOff(const string& code, bool flag) {
|
||||
return defaultFileLine().warnOff(code, flag);
|
||||
static string globalWarnOffParse(const string& msgs, bool flag) {
|
||||
return defaultFileLine().warnOffParse(msgs, flag);
|
||||
}
|
||||
static void fileNameNumMapDumpXml(std::ostream& os) { singleton().fileNameNumMapDumpXml(os); }
|
||||
static void fileNameNumMapDumpJson(std::ostream& os) {
|
||||
|
|
|
|||
|
|
@ -1807,7 +1807,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
addFuture(optp);
|
||||
});
|
||||
DECL_OPTION("-Wno-", CbPartialMatch, [fl, &parser](const char* optp) VL_MT_DISABLED {
|
||||
if (!FileLine::globalWarnOff(optp, true)) {
|
||||
const string err = FileLine::globalWarnOffParse(optp, true);
|
||||
if (!err.empty()) {
|
||||
const string fullopt = "-Wno-"s + optp;
|
||||
fl->v3fatal("Unknown warning specified: " << fullopt
|
||||
<< parser.getSuggestion(fullopt.c_str()));
|
||||
|
|
|
|||
|
|
@ -171,12 +171,9 @@ void V3ParseImp::lexVerilatorCmtLint(FileLine* fl, const char* textp, bool warnO
|
|||
string::size_type pos;
|
||||
if ((pos = msg.find('*')) != string::npos) msg.erase(pos);
|
||||
// Use parsep()->lexFileline() as want to affect later FileLine's warnings
|
||||
if (!(parsep()->lexFileline()->warnOff(msg, warnOff))) {
|
||||
if (!v3Global.opt.isFuture(msg)) {
|
||||
fl->v3error("Unknown verilator lint message code: '" << msg << "', in '" << textp
|
||||
<< "'");
|
||||
}
|
||||
}
|
||||
const string err = parsep()->lexFileline()->warnOffParse(msg, warnOff);
|
||||
if (!err.empty())
|
||||
fl->v3error("Unknown verilator lint message code: '" << err << "', in '" << textp << "'");
|
||||
}
|
||||
|
||||
void V3ParseImp::lexVerilatorCmtBad(FileLine* fl, const char* textp) {
|
||||
|
|
|
|||
|
|
@ -438,10 +438,10 @@ bom [\357\273\277]
|
|||
<ARGMODE>. { FL_FWDC; appendDefValue(yytext, yyleng); FL_BRK; }
|
||||
|
||||
/* Pragma comments. */
|
||||
<INITIAL>"//"{ws}*"verilator lint_off"[^\n\r]* { FL_FWDC; LEXP->verilatorCmtLint(yytext + 2, true); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_on"[^\n\r]* { FL_FWDC; LEXP->verilatorCmtLint(yytext + 2, false); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_restore"[^\n\r]* { FL_FWDC; LEXP->verilatorCmtLintRestore(); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_save"[^\n\r]* { FL_FWDC; LEXP->verilatorCmtLintSave(); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_off"[^\n\r/]* { FL_FWDC; LEXP->verilatorCmtLint(yytext + 2, true); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_on"[^\n\r/]* { FL_FWDC; LEXP->verilatorCmtLint(yytext + 2, false); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_restore"[^\n\r/]* { FL_FWDC; LEXP->verilatorCmtLintRestore(); return VP_COMMENT; }
|
||||
<INITIAL>"//"{ws}*"verilator lint_save"[^\n\r/]* { FL_FWDC; LEXP->verilatorCmtLintSave(); return VP_COMMENT; }
|
||||
<INITIAL>"/*"{ws}*"verilator lint_off"[^*]*"*/" { FL_FWDC; LEXP->verilatorCmtLint(yytext + 2, true); return VP_COMMENT; }
|
||||
<INITIAL>"/*"{ws}*"verilator lint_on"[^*]*"*/" { FL_FWDC; LEXP->verilatorCmtLint(yytext + 2, false); return VP_COMMENT; }
|
||||
<INITIAL>"/*"{ws}*"verilator lint_restore"[^*]*"*/" { FL_FWDC; LEXP->verilatorCmtLintRestore(); return VP_COMMENT; }
|
||||
|
|
@ -788,7 +788,7 @@ void V3PreLex::verilatorCmtLint(const char* textp, bool warnOff) {
|
|||
}
|
||||
}
|
||||
// No warnings on bad warning codes - the verilog.y parse will report as appropriate
|
||||
curFilelinep()->warnOff(msg, warnOff);
|
||||
curFilelinep()->warnOffParse(msg, warnOff);
|
||||
}
|
||||
|
||||
/*###################################################################
|
||||
|
|
|
|||
|
|
@ -327,6 +327,14 @@ string VString::replaceWord(const string& str, const string& from, const string&
|
|||
return result;
|
||||
}
|
||||
|
||||
std::deque<string> VString::split(const string& str, char delimiter) {
|
||||
std::deque<std::string> results;
|
||||
std::istringstream is{str};
|
||||
std::string token;
|
||||
while (std::getline(is, token, delimiter)) results.push_back(token);
|
||||
return results;
|
||||
}
|
||||
|
||||
bool VString::endsWith(const string& str, const string& suffix) {
|
||||
if (str.length() < suffix.length()) return false;
|
||||
return str.compare(str.length() - suffix.length(), suffix.length(), suffix) == 0;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
// No V3 headers here - this is a base class for Vlc etc
|
||||
|
||||
#include <deque>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
|
@ -138,6 +139,8 @@ public:
|
|||
// to be a consecutive sequence of the characters [a-zA-Z0-9_]. Sub-words are not replaced.
|
||||
// e.g.: replaceWords("one apple bad_apple", "apple", "banana") -> "one banana bad_apple"
|
||||
static string replaceWord(const string& str, const string& from, const string& to);
|
||||
// Return deque of strings split by the given delimiter
|
||||
static std::deque<string> split(const string& str, char delimiter = ',');
|
||||
// Predicate to check if 'str' starts with 'prefix'
|
||||
static bool startsWith(const string& str, const char* prefixp) {
|
||||
return !str.rfind(prefixp, 0); // Faster than .find(_) == 0
|
||||
|
|
|
|||
|
|
@ -46,12 +46,7 @@
|
|||
//END_MODULE_NAME--------------------------------------------------------------
|
||||
|
||||
//See also: https://github.com/twosigma/verilator_support
|
||||
// verilator lint_off COMBDLY
|
||||
// verilator lint_off INITIALDLY
|
||||
// verilator lint_off MULTIDRIVEN
|
||||
// verilator lint_off UNSIGNED
|
||||
// verilator lint_off WIDTH
|
||||
// verilator lint_off LATCH
|
||||
// verilator lint_off COMBDLY,INITIALDLY,LATCH,MULTIDRIVEN,UNSIGNED,WIDTH
|
||||
|
||||
// BEGINNING OF MODULE
|
||||
`timescale 1 ps / 1 ps
|
||||
|
|
|
|||
|
|
@ -154,11 +154,9 @@ module t #(parameter GATED_CLK = 0) (/*AUTOARG*/
|
|||
logic possibly_gated_clk;
|
||||
if (GATED_CLK != 0) begin: yes_gated_clock
|
||||
logic clk_en_latch;
|
||||
/* verilator lint_off COMBDLY */
|
||||
/* verilator lint_off LATCH */
|
||||
// verilator lint_off COMBDLY,LATCH
|
||||
always_comb if (clk == '0) clk_en_latch <= clk_en;
|
||||
/* verilator lint_on LATCH */
|
||||
/* verilator lint_on COMBDLY */
|
||||
// verilator lint_on COMBDLY,LATCH
|
||||
assign possibly_gated_clk = clk & clk_en_latch;
|
||||
end else begin: no_gated_clock
|
||||
assign possibly_gated_clk = clk;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
#!/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('vlt')
|
||||
|
||||
test.lint()
|
||||
|
||||
test.passes()
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// 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 (
|
||||
input [3:1] i3,
|
||||
input [4:1] i4,
|
||||
output [3:1] o3,
|
||||
output [4:1] o4
|
||||
);
|
||||
|
||||
// verilator lint_off WIDTHTRUNC,WIDTHEXPAND // after slashes ignored
|
||||
assign o3 = i4;
|
||||
assign o4 = i3;
|
||||
|
||||
endmodule
|
||||
Loading…
Reference in New Issue