diff --git a/src/V3Control.cpp b/src/V3Control.cpp index d715cd2fc..3e432be8d 100644 --- a/src/V3Control.cpp +++ b/src/V3Control.cpp @@ -445,12 +445,11 @@ public: bool waive(V3ErrorCode code, const string& message) { if (code.hardError()) return false; for (const auto& itr : m_waivers) { - if ((code.isUnder(itr.m_code) || (itr.m_code == V3ErrorCode::I_LINT))) - if ((code.isUnder(itr.m_code) || (itr.m_code == V3ErrorCode::I_LINT)) - && VString::wildmatch(message, itr.m_match) - && WildcardContents::resolve(itr.m_contents)) { - return true; - } + if ((code.isUnder(itr.m_code) || (itr.m_code == V3ErrorCode::I_LINT)) + && VString::wildmatch(message, itr.m_match) + && WildcardContents::resolve(itr.m_contents)) { + return true; + } } return false; } diff --git a/src/V3Error.cpp b/src/V3Error.cpp index fcbc4d8ed..fc6e684b2 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -301,8 +301,9 @@ void V3ErrorGuarded::v3errorEndGuts(const std::ostringstream& sstr, const string void V3Error::init() { for (int i = 0; i < V3ErrorCode::_ENUM_MAX; i++) { - describedEachWarn(static_cast(i), false); - pretendError(static_cast(i), V3ErrorCode{i}.pretendError()); + const V3ErrorCode code{i}; + describedEachWarn(code, false); + pretendError(code, code.pretendError()); } // Not an UASSERT as failure would call V3Error and it's broken due to this assert(std::string{V3ErrorCode{V3ErrorCode::_ENUM_MAX}.ascii()} == " MAX"); diff --git a/src/V3Error.h b/src/V3Error.h index 5b083a3c6..44bc12dfc 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -197,6 +197,8 @@ public: constexpr V3ErrorCode(en _e) : m_e{_e} {} explicit V3ErrorCode(const char* msgp); // Matching code or ERROR + explicit V3ErrorCode(const std::string& msg) + : V3ErrorCode{msg.c_str()} {} explicit V3ErrorCode(int _e) : m_e(static_cast(_e)) {} // Need () or GCC 4.8 false warning constexpr operator en() const VL_MT_SAFE { return m_e; } @@ -427,7 +429,7 @@ public: bool isErrorOrWarn() VL_REQUIRES(m_mutex) { return errorCount() || (warnFatal() && warnCount()); } - bool pretendError(int errorCode) VL_REQUIRES(m_mutex) { return m_pretendError[errorCode]; } + bool pretendError(V3ErrorCode code) VL_REQUIRES(m_mutex) { return m_pretendError[code]; } void pretendError(V3ErrorCode code, bool flag) VL_REQUIRES(m_mutex) { if (code == V3ErrorCode::WIDTH) { m_pretendError[V3ErrorCode::WIDTHTRUNC] = flag; @@ -504,9 +506,9 @@ public: const V3RecursiveLockGuard guard{s().m_mutex}; return s().errorCount(); } - static bool pretendError(int errorCode) VL_MT_SAFE_EXCLUDES(s().m_mutex) { + static bool pretendError(V3ErrorCode code) VL_MT_SAFE_EXCLUDES(s().m_mutex) { const V3RecursiveLockGuard guard{s().m_mutex}; - return s().pretendError(errorCode); + return s().pretendError(code); } static int warnCount() VL_MT_SAFE_EXCLUDES(s().m_mutex) { const V3RecursiveLockGuard guard{s().m_mutex}; diff --git a/src/V3FileLine.cpp b/src/V3FileLine.cpp index b02559de9..d9c8d1df9 100644 --- a/src/V3FileLine.cpp +++ b/src/V3FileLine.cpp @@ -126,7 +126,7 @@ FileLineSingleton::msgEnSetIdx_t FileLineSingleton::addMsgEnBitSet(const MsgEnBi FileLineSingleton::msgEnSetIdx_t FileLineSingleton::defaultMsgEnIndex() VL_MT_SAFE { MsgEnBitSet msgEnBitSet; for (int i = V3ErrorCode::EC_MIN; i < V3ErrorCode::_ENUM_MAX; ++i) { - // "-Wall" and the like only adjsut the code subset, so use default enablement there + // "-Wall" and the like only adjust the code subset, so use default enablement there msgEnBitSet.set(MsgEnBitSet::Subset::CODE, i, !V3ErrorCode{i}.defaultsOff()); // The control file subset is only adjusted by the control files, everything enabled by // default @@ -374,22 +374,22 @@ std::ostream& operator<<(std::ostream& os, FileLine* fileline) { return (os); } -string FileLine::warnOffParse(const string& msgs, bool flag) { +string FileLine::warnOffParse(const string& msgs, bool turnOff) { 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); + warnOff(V3ErrorCode::UNUSEDGENVAR, turnOff); + warnOff(V3ErrorCode::UNUSEDLOOP, turnOff); + warnOff(V3ErrorCode::UNUSEDPARAM, turnOff); + warnOff(V3ErrorCode::UNUSEDSIGNAL, turnOff); continue; } - const V3ErrorCode code{cmsg}; + const V3ErrorCode code{msg}; if (!code.hardError()) { - warnOff(code, flag); + warnOff(code, turnOff); continue; } @@ -399,25 +399,25 @@ string FileLine::warnOffParse(const string& msgs, bool flag) { return result; } -void FileLine::warnLintOff(bool flag) { +void FileLine::warnLintOff(bool turnOff) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { const V3ErrorCode code{codei}; - if (code.lintError()) warnOff(code, flag); + if (code.lintError()) warnOff(code, turnOff); } } -void FileLine::warnStyleOff(bool flag) { +void FileLine::warnStyleOff(bool turnOff) { for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) { const V3ErrorCode code{codei}; - if (code.styleError()) warnOff(code, flag); + if (code.styleError()) warnOff(code, turnOff); } } -void FileLine::warnUnusedOff(bool flag) { - warnOff(V3ErrorCode::UNUSEDGENVAR, flag); - warnOff(V3ErrorCode::UNUSEDLOOP, flag); - warnOff(V3ErrorCode::UNUSEDPARAM, flag); - warnOff(V3ErrorCode::UNUSEDSIGNAL, flag); +void FileLine::warnUnusedOff(bool turnOff) { + warnOff(V3ErrorCode::UNUSEDGENVAR, turnOff); + warnOff(V3ErrorCode::UNUSEDLOOP, turnOff); + warnOff(V3ErrorCode::UNUSEDPARAM, turnOff); + warnOff(V3ErrorCode::UNUSEDSIGNAL, turnOff); } bool FileLine::warnIsOff(V3ErrorCode code) const { diff --git a/src/V3FileLine.h b/src/V3FileLine.h index f04ac5d11..3bf200f36 100644 --- a/src/V3FileLine.h +++ b/src/V3FileLine.h @@ -373,7 +373,7 @@ private: warnSet(subset, V3ErrorCode::WIDTHEXPAND, flag); warnSet(subset, V3ErrorCode::WIDTHXZEXPAND, flag); } - if (code == V3ErrorCode::E_UNSUPPORTED) { warnSet(subset, V3ErrorCode::COVERIGN, flag); } + if (code == V3ErrorCode::E_UNSUPPORTED) warnSet(subset, V3ErrorCode::COVERIGN, flag); m_msgEnIdx = singleton().msgEnSetBit(m_msgEnIdx, subset, code, flag); } @@ -382,12 +382,12 @@ public: void warnOnCtrl(V3ErrorCode code, bool flag) { warnSet(MsgEnBitSet::Subset::CTRL, code, flag); } - void warnOff(V3ErrorCode code, bool flag) { warnOn(code, !flag); } - string warnOffParse(const string& msgs, bool flag); // Returns "" if ok + void warnOff(V3ErrorCode code, bool turnOff) { warnOn(code, !turnOff); } + string warnOffParse(const string& msgs, bool turnOff); // Returns "" if ok bool warnIsOff(V3ErrorCode code) const VL_MT_SAFE; - void warnLintOff(bool flag); - void warnStyleOff(bool flag); - void warnUnusedOff(bool flag); + void warnLintOff(bool turnOff); + void warnStyleOff(bool turnOff); + void warnUnusedOff(bool turnOff); void warnStateFrom(const FileLine& from) { m_msgEnIdx = from.m_msgEnIdx; } void warnResetDefault() { warnStateFrom(defaultFileLine()); } @@ -405,14 +405,14 @@ public: // and match what GCC outputs static string commandLineFilename() VL_MT_SAFE { return ""; } static string builtInFilename() VL_MT_SAFE { return ""; } - static void globalWarnLintOff(bool flag) { defaultFileLine().warnLintOff(flag); } - static void globalWarnStyleOff(bool flag) { defaultFileLine().warnStyleOff(flag); } - static void globalWarnUnusedOff(bool flag) { defaultFileLine().warnUnusedOff(flag); } - static void globalWarnOff(V3ErrorCode code, bool flag) { - defaultFileLine().warnOff(code, flag); + static void globalWarnLintOff(bool turnOff) { defaultFileLine().warnLintOff(turnOff); } + static void globalWarnStyleOff(bool turnOff) { defaultFileLine().warnStyleOff(turnOff); } + static void globalWarnUnusedOff(bool turnOff) { defaultFileLine().warnUnusedOff(turnOff); } + static void globalWarnOff(V3ErrorCode code, bool turnOff) { + defaultFileLine().warnOff(code, turnOff); } - static string globalWarnOffParse(const string& msgs, bool flag) { - return defaultFileLine().warnOffParse(msgs, flag); + static string globalWarnOffParse(const string& msgs, bool turnOff) { + return defaultFileLine().warnOffParse(msgs, turnOff); } static void fileNameNumMapDumpXml(std::ostream& os) { singleton().fileNameNumMapDumpXml(os); } static void fileNameNumMapDumpJson(std::ostream& os) { @@ -427,7 +427,7 @@ public: // Change the current fileline due to actions discovered after parsing // and may have side effects on other nodes sharing this FileLine. // Use only when this is intended - void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code, flag); } + void modifyWarnOff(V3ErrorCode code, bool turnOff) { warnOff(code, turnOff); } // OPERATORS void v3errorEnd(std::ostringstream& str, const string& extra = "") diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp index f370aaff8..bb4f96cb4 100644 --- a/src/V3ParseImp.cpp +++ b/src/V3ParseImp.cpp @@ -161,7 +161,7 @@ void V3ParseImp::lexVerilatorCmtLintRestore(FileLine* fl) { m_lexLintState.pop_back(); } -void V3ParseImp::lexVerilatorCmtLint(FileLine* fl, const char* textp, bool warnOff) { +void V3ParseImp::lexVerilatorCmtLint(FileLine* fl, const char* textp, bool turnOff) { const char* sp = textp; while (*sp && !std::isspace(*sp)) ++sp; while (*sp && std::isspace(*sp)) ++sp; @@ -171,7 +171,7 @@ 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 - const string err = parsep()->lexFileline()->warnOffParse(msg, warnOff); + const string err = parsep()->lexFileline()->warnOffParse(msg, turnOff); if (!err.empty()) fl->v3error("Unknown verilator lint message code: '" << err << "', in '" << textp << "'"); } diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index 380d84c1e..af153800d 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -196,7 +196,7 @@ public: static string lexParseTag(const char* textp) VL_MT_DISABLED; static double lexParseTimenum(const char* text) VL_MT_DISABLED; void lexPpline(const char* textp) VL_MT_DISABLED; - void lexVerilatorCmtLint(FileLine* fl, const char* textp, bool warnOff) VL_MT_DISABLED; + void lexVerilatorCmtLint(FileLine* fl, const char* textp, bool turnOff) VL_MT_DISABLED; void lexVerilatorCmtLintSave(const FileLine* fl) VL_MT_DISABLED; void lexVerilatorCmtLintRestore(FileLine* fl) VL_MT_DISABLED; static void lexVerilatorCmtBad(FileLine* fl, const char* textp) VL_MT_DISABLED; diff --git a/src/V3PreLex.h b/src/V3PreLex.h index d1fc23bc7..de0e7c8fa 100644 --- a/src/V3PreLex.h +++ b/src/V3PreLex.h @@ -211,7 +211,7 @@ public: // Used only by V3PreLex.cpp and V3PreProc.cpp } } void warnBackslashSpace(); - void verilatorCmtLint(const char* textp, bool warnOff); + void verilatorCmtLint(const char* textp, bool turnOff); void verilatorCmtLintRestore(); void verilatorCmtLintSave(); // Called by V3PreProc.cpp to inform lexer diff --git a/src/V3PreLex.l b/src/V3PreLex.l index 1fc9f61e1..21a6ea024 100644 --- a/src/V3PreLex.l +++ b/src/V3PreLex.l @@ -799,7 +799,7 @@ void V3PreLex::verilatorCmtLintRestore() { curFilelinep()->warnStateFrom(m_lexLintState.back()); m_lexLintState.pop_back(); } -void V3PreLex::verilatorCmtLint(const char* textp, bool warnOff) { +void V3PreLex::verilatorCmtLint(const char* textp, bool turnOff) { const char* sp = textp; while (*sp && std::isspace(*sp)) ++sp; while (*sp && !std::isspace(*sp)) ++sp; // "verilator" @@ -814,7 +814,7 @@ void V3PreLex::verilatorCmtLint(const char* textp, bool warnOff) { } } // No warnings on bad warning codes - the verilog.y parse will report as appropriate - curFilelinep()->warnOffParse(msg, warnOff); + curFilelinep()->warnOffParse(msg, turnOff); } /*################################################################### diff --git a/test_regress/t/t_covergroup_unsup_ign2.py b/test_regress/t/t_covergroup_unsup_ign2.py new file mode 100755 index 000000000..79faaec14 --- /dev/null +++ b/test_regress/t/t_covergroup_unsup_ign2.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# 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 + +import vltest_bootstrap + +test.scenarios('vlt') +test.top_filename = "t/t_covergroup_unsup.v" + +test.lint(verilator_flags2=[ + '--assert --coverage --Wwarn-UNSUPPORTED -Wno-fatal +define+T_COVERGROUP_UNSUP_IGN' +]) + +test.passes() diff --git a/test_regress/t/t_flag_werror_bad2.py b/test_regress/t/t_flag_werror_bad2.py index c960be889..98c683a89 100755 --- a/test_regress/t/t_flag_werror_bad2.py +++ b/test_regress/t/t_flag_werror_bad2.py @@ -12,6 +12,8 @@ import vltest_bootstrap test.scenarios('vlt') test.top_filename = "t/t_flag_werror.v" -test.lint(fails=True, verilator_flags=["-cc -Werror-WIDTH"], expect_filename=test.golden_filename) +test.lint(fails=True, + verilator_flags=["-cc -Wno-fatal -Werror-WIDTH"], + expect_filename=test.golden_filename) test.passes() diff --git a/test_regress/t/t_lint_historical.v b/test_regress/t/t_lint_historical.v index e6d085bcb..d261102db 100644 --- a/test_regress/t/t_lint_historical.v +++ b/test_regress/t/t_lint_historical.v @@ -93,6 +93,7 @@ module t; // verilator lint_off SPLITVAR // verilator lint_off STATICVAR // verilator lint_off STMTDLY + // verilator lint_off SUPERNFIRST // verilator lint_off SYMRSVDWORD // verilator lint_off SYNCASYNCNET // verilator lint_off TICKCOUNT @@ -103,6 +104,7 @@ module t; // verilator lint_off UNOPTTHREADS // verilator lint_off UNPACKED // verilator lint_off UNSIGNED + // verilator lint_off UNUSED // verilator lint_off UNUSEDGENVAR // verilator lint_off UNUSEDLOOP // verilator lint_off UNUSEDPARAM diff --git a/test_regress/t/t_lint_unused_vlt.py b/test_regress/t/t_lint_unused_vlt.py new file mode 100755 index 000000000..d2529e95b --- /dev/null +++ b/test_regress/t/t_lint_unused_vlt.py @@ -0,0 +1,19 @@ +#!/usr/bin/env python3 +# 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 + +import vltest_bootstrap + +test.scenarios('linter') +test.top_filename = 't/t_lint_unused_bad.v' + +test.lint(verilator_flags2=[ + "--lint-only --bbox-sys --bbox-unsup -Wall -Wno-DECLFILENAME", "t/t_lint_unused_vlt.vlt" +]) + +test.passes() diff --git a/test_regress/t/t_lint_unused_vlt.vlt b/test_regress/t/t_lint_unused_vlt.vlt new file mode 100644 index 000000000..8a23ae023 --- /dev/null +++ b/test_regress/t/t_lint_unused_vlt.vlt @@ -0,0 +1,10 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2025 by Wilson Snyder. +// SPDX-License-Identifier: CC0-1.0 + +`verilator_config +lint_off --rule UNDRIVEN +// Checks UNUSED delegation to UNUSEDSIGNAL etc +lint_off --rule UNUSED diff --git a/test_regress/t/t_lint_unused_werror_bad.py b/test_regress/t/t_lint_unused_werror_bad.py new file mode 100755 index 000000000..cb1332bd6 --- /dev/null +++ b/test_regress/t/t_lint_unused_werror_bad.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 +# 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 + +import vltest_bootstrap + +test.scenarios('linter') +test.top_filename = 't/t_lint_unused_bad.v' + +test.lint(verilator_flags2=["--lint-only --bbox-sys --bbox-unsup -Wall -Wno-fatal -Werror-UNUSED"], + fails=True) + +test.passes()