Internals: Refactor V3Error, and handle UNDRIVEN/UNSUPPORTED/WIDTH consistently (#6874)
This commit is contained in:
parent
aa94219531
commit
2025b81614
|
|
@ -2301,6 +2301,8 @@ List Of Warnings
|
|||
make the design simulate incorrectly and is only intended for lint
|
||||
usage; see the details under :vlopt:`--bbox-unsup`.
|
||||
|
||||
Disabling this error also disables :option:`COVERIGN` and
|
||||
:option:`SPECIFYIGN`.
|
||||
|
||||
.. option:: UNUSED
|
||||
|
||||
|
|
|
|||
|
|
@ -166,9 +166,9 @@ void V3ErrorGuarded::v3errorEndGuts(const std::ostringstream& sstr, const string
|
|||
if (m_errorSuppressed) {
|
||||
// On debug, show only non default-off warning to prevent pages of warnings
|
||||
if (m_message.code().defaultsOff()) return;
|
||||
if (!debug() || debug() < 3 || (debug() < 9 && m_showedSuppressed[m_message.code()]))
|
||||
if (!debug() || debug() < 3 || (debug() < 9 && m_showedSuppressed.test(m_message.code())))
|
||||
return;
|
||||
m_showedSuppressed[m_message.code()] = true;
|
||||
m_showedSuppressed.set(m_message.code(), true);
|
||||
}
|
||||
string msg
|
||||
= V3Error::warnContextBegin() + msgPrefix() + V3Error::warnContextEnd() + sstr.str();
|
||||
|
|
@ -223,8 +223,8 @@ void V3ErrorGuarded::v3errorEndGuts(const std::ostringstream& sstr, const string
|
|||
const bool anError = isError(m_message.code(), m_errorSuppressed);
|
||||
if (m_message.code()
|
||||
!= V3ErrorCode::EC_FATALMANY // Not verbose on final too-many-errors error
|
||||
&& !m_describedEachWarn[m_message.code()]) {
|
||||
m_describedEachWarn[m_message.code()] = true;
|
||||
&& !m_describedEachWarn.test(m_message.code())) {
|
||||
m_describedEachWarn.set(m_message.code(), true);
|
||||
if (m_message.code() >= V3ErrorCode::EC_FIRST_NAMED) {
|
||||
text += warnMoreSpaces() + "... For " + (anError ? "error" : "warning")
|
||||
+ " description see " + m_message.code().url() + '\n';
|
||||
|
|
@ -238,7 +238,7 @@ void V3ErrorGuarded::v3errorEndGuts(const std::ostringstream& sstr, const string
|
|||
text += warnMoreSpaces() + "... See the manual at " + m_message.code().url()
|
||||
+ " for more assistance.\n";
|
||||
}
|
||||
if (!m_pretendError[m_message.code()] && !m_message.code().hardError()) {
|
||||
if (!m_pretendError.test(m_message.code()) && !m_message.code().hardError()) {
|
||||
text += warnMoreSpaces() + "... Use \"/* verilator lint_off "
|
||||
+ m_message.code().ascii()
|
||||
+ " */\" and lint_on around source to disable this message.\n";
|
||||
|
|
|
|||
116
src/V3Error.h
116
src/V3Error.h
|
|
@ -20,6 +20,7 @@
|
|||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "V3Hash.h"
|
||||
#include "V3Mutex.h"
|
||||
|
||||
// Limited V3 headers here - this is a base class for Vlc etc
|
||||
|
|
@ -56,9 +57,9 @@ public:
|
|||
I_COVERAGE, // Coverage is on/off from /*verilator coverage_on/off*/
|
||||
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
|
||||
I_LINT, // All lint messages
|
||||
I_STYLE, // All style messages
|
||||
I_TIMING, // Enable timing from /*verilator timing_on/off*/
|
||||
I_TRACING, // Tracing is on/off from /*verilator tracing_on/off*/
|
||||
I_UNUSED, // Unused genvar, parameter or signal message (Backward Compatibility)
|
||||
// Error codes:
|
||||
E_CONSTWRITTEN, // Error: Const variable being written.
|
||||
E_LIFETIME, // Error: Reference to a variable might outlive the variable.
|
||||
|
|
@ -169,6 +170,7 @@ public:
|
|||
UNOPTTHREADS, // Thread partitioner unable to fill all requested threads
|
||||
UNPACKED, // Unsupported unpacked
|
||||
UNSIGNED, // Comparison is constant due to unsigned arithmetic
|
||||
UNUSED, // Unused genvar, parameter or signal message (Backward Compatibility)
|
||||
UNUSEDGENVAR, // No receivers for genvar
|
||||
UNUSEDLOOP, // Loop is unused
|
||||
UNUSEDPARAM, // No receivers for parameters
|
||||
|
|
@ -207,8 +209,8 @@ public:
|
|||
// Leading spaces indicate it can't be disabled.
|
||||
" MIN", " INFO", " FATAL", " FATALMANY", " FATALSRC", " ERROR", " FIRST_NAMED",
|
||||
// Boolean
|
||||
" I_CELLDEFINE", " I_COVERAGE", " I_DEF_NETTYPE_WIRE", " I_LINT", " I_TIMING",
|
||||
" I_TRACING", " I_UNUSED",
|
||||
" I_CELLDEFINE", " I_COVERAGE", " I_DEF_NETTYPE_WIRE", " I_LINT", " I_STYLE",
|
||||
" I_TIMING", " I_TRACING",
|
||||
// Errors
|
||||
"CONSTWRITTEN", "LIFETIME", "NEEDTIMINGOPT", "NOTIMING", "PORTSHORT", "TASKNSVAR",
|
||||
"UNSUPPORTED",
|
||||
|
|
@ -229,10 +231,10 @@ public:
|
|||
"REDEFMACRO", "RISEFALLDLY", "SELRANGE", "SHORTREAL", "SIDEEFFECT", "SPECIFYIGN",
|
||||
"SPLITVAR", "STATICVAR", "STMTDLY", "SUPERNFIRST", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"TICKCOUNT", "TIMESCALEMOD", "UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNOPTTHREADS",
|
||||
"UNPACKED", "UNSIGNED", "UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM", "UNUSEDSIGNAL",
|
||||
"USERERROR", "USERFATAL", "USERINFO", "USERWARN", "VARHIDDEN", "WAITCONST", "WIDTH",
|
||||
"WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND", "ZERODLY", "ZEROREPL",
|
||||
" MAX"};
|
||||
"UNPACKED", "UNSIGNED", "UNUSED", "UNUSEDGENVAR", "UNUSEDLOOP", "UNUSEDPARAM",
|
||||
"UNUSEDSIGNAL", "USERERROR", "USERFATAL", "USERINFO", "USERWARN", "VARHIDDEN",
|
||||
"WAITCONST", "WIDTH", "WIDTHCONCAT", "WIDTHEXPAND", "WIDTHTRUNC", "WIDTHXZEXPAND",
|
||||
"ZERODLY", "ZEROREPL", " MAX"};
|
||||
return names[m_e];
|
||||
}
|
||||
// Warnings that default to off
|
||||
|
|
@ -267,8 +269,8 @@ public:
|
|||
}
|
||||
// Warnings to mention manual
|
||||
bool mentionManual() const VL_MT_SAFE {
|
||||
return (m_e == EC_FATALSRC || m_e == SIDEEFFECT || m_e == SYMRSVDWORD || m_e == ZERODLY
|
||||
|| pretendError());
|
||||
return (pretendError() || m_e == EC_FATALSRC || m_e == SIDEEFFECT || m_e == SYMRSVDWORD
|
||||
|| m_e == ZERODLY);
|
||||
}
|
||||
// Warnings that are lint only
|
||||
bool lintError() const VL_MT_SAFE {
|
||||
|
|
@ -290,33 +292,56 @@ public:
|
|||
|| m_e == UNUSEDLOOP || m_e == UNUSEDPARAM || m_e == UNUSEDSIGNAL
|
||||
|| m_e == VARHIDDEN);
|
||||
}
|
||||
// Warnings that are unused only
|
||||
bool unusedError() const VL_MT_SAFE {
|
||||
return (m_e == UNUSEDGENVAR || m_e == UNUSEDLOOP || m_e == UNUSEDPARAM
|
||||
|| m_e == UNUSEDSIGNAL);
|
||||
}
|
||||
bool isNamed() const { return m_e >= EC_FIRST_NAMED; }
|
||||
|
||||
private:
|
||||
V3ErrorCode renamedTo() const {
|
||||
// Return a new error this error has been renamed to
|
||||
if (m_e == LITENDIAN) return V3ErrorCode{ASCRANGE};
|
||||
return V3ErrorCode{EC_MIN}; // Not renamed; see isRenamed()
|
||||
}
|
||||
bool isNamed() const { return m_e >= EC_FIRST_NAMED; }
|
||||
bool isRenamed() const { return renamedTo() != V3ErrorCode{EC_MIN}; }
|
||||
bool isUnder(V3ErrorCode other) {
|
||||
// backwards compatibility inheritance-like warnings
|
||||
if (m_e == other) return true;
|
||||
if (other == V3ErrorCode::WIDTH) {
|
||||
return (m_e == WIDTHEXPAND || m_e == WIDTHTRUNC || m_e == WIDTHXZEXPAND);
|
||||
|
||||
public:
|
||||
// Call given callable on all error codes that result from given code.
|
||||
// Deals with codes which imply disabling multiple other codes.
|
||||
void forDelegateCodes(std::function<void(V3ErrorCode code)> action) const {
|
||||
// If add to this switch, also update isUnder()
|
||||
switch (m_e) {
|
||||
case V3ErrorCode::E_UNSUPPORTED:
|
||||
action(V3ErrorCode{E_UNSUPPORTED});
|
||||
action(V3ErrorCode{COVERIGN});
|
||||
action(V3ErrorCode{SPECIFYIGN});
|
||||
return;
|
||||
case V3ErrorCode::UNUSED:
|
||||
action(V3ErrorCode{UNUSEDGENVAR});
|
||||
action(V3ErrorCode{UNUSEDLOOP});
|
||||
action(V3ErrorCode{UNUSEDPARAM});
|
||||
action(V3ErrorCode{UNUSEDSIGNAL});
|
||||
return;
|
||||
case V3ErrorCode::WIDTH:
|
||||
action(V3ErrorCode{WIDTHEXPAND});
|
||||
action(V3ErrorCode{WIDTHTRUNC});
|
||||
action(V3ErrorCode{WIDTHXZEXPAND});
|
||||
return;
|
||||
default: action(*this);
|
||||
}
|
||||
if (other == V3ErrorCode::I_UNUSED) {
|
||||
return (m_e == UNUSEDGENVAR || m_e == UNUSEDLOOP || m_e == UNUSEDPARAM
|
||||
|| m_e == UNUSEDSIGNAL);
|
||||
}
|
||||
bool isUnder(V3ErrorCode other) const {
|
||||
// Reverse of forDelegateCodes, return true if this' code is under another
|
||||
if (VL_LIKELY(other == m_e)) return true;
|
||||
switch (other) {
|
||||
case V3ErrorCode::E_UNSUPPORTED:
|
||||
return m_e == E_UNSUPPORTED || m_e == COVERIGN || m_e == SPECIFYIGN;
|
||||
case V3ErrorCode::UNUSED:
|
||||
return m_e == UNUSEDGENVAR || m_e == UNUSEDLOOP || m_e == UNUSEDPARAM
|
||||
|| m_e == UNUSEDSIGNAL;
|
||||
case V3ErrorCode::WIDTH:
|
||||
return m_e == WIDTHEXPAND || m_e == WIDTHTRUNC || m_e == WIDTHXZEXPAND;
|
||||
default: return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
string url() const;
|
||||
static bool unusedMsg(const char* msgp) { return 0 == VL_STRCASECMP(msgp, "UNUSED"); }
|
||||
};
|
||||
constexpr bool operator==(const V3ErrorCode& lhs, const V3ErrorCode& rhs) {
|
||||
return lhs.m_e == rhs.m_e;
|
||||
|
|
@ -329,6 +354,27 @@ inline std::ostream& operator<<(std::ostream& os, const V3ErrorCode& rhs) {
|
|||
|
||||
// ######################################################################
|
||||
|
||||
// Store a single bit for each error code
|
||||
class VErrorBitSet final {
|
||||
std::bitset<V3ErrorCode::_ENUM_MAX> m_bitset; // Enable for each code
|
||||
VErrorBitSet(const VErrorBitSet& lhs, const VErrorBitSet& rhs)
|
||||
: m_bitset{lhs.m_bitset & rhs.m_bitset} {}
|
||||
|
||||
public:
|
||||
VErrorBitSet() {}
|
||||
~VErrorBitSet() = default;
|
||||
bool test(V3ErrorCode code) const { return m_bitset[code]; }
|
||||
void set(V3ErrorCode code, bool flag) { m_bitset[code] = flag; }
|
||||
V3Hash hash() const {
|
||||
const size_t hashCode = std::hash<std::bitset<V3ErrorCode::_ENUM_MAX>>()(m_bitset);
|
||||
return V3Hash{static_cast<uint64_t>(hashCode)};
|
||||
}
|
||||
VErrorBitSet operator&(const VErrorBitSet& rhs) const { return VErrorBitSet{*this, rhs}; }
|
||||
bool operator==(const VErrorBitSet& rhs) const { return m_bitset == rhs.m_bitset; }
|
||||
};
|
||||
|
||||
// ######################################################################
|
||||
|
||||
class VErrorMessage final {
|
||||
// TYPES
|
||||
using FileLines = std::deque<const FileLine*>;
|
||||
|
|
@ -391,11 +437,11 @@ private:
|
|||
int m_warnCount VL_GUARDED_BY(m_mutex) = 0; // Warning count
|
||||
int m_errCount VL_GUARDED_BY(m_mutex) = 0; // Error count
|
||||
// Pretend this warning is an error
|
||||
std::array<bool, V3ErrorCode::_ENUM_MAX> m_pretendError VL_GUARDED_BY(m_mutex);
|
||||
VErrorBitSet m_pretendError VL_GUARDED_BY(m_mutex);
|
||||
// Told user specifics about this warning
|
||||
std::array<bool, V3ErrorCode::_ENUM_MAX> m_describedEachWarn VL_GUARDED_BY(m_mutex);
|
||||
VErrorBitSet m_describedEachWarn VL_GUARDED_BY(m_mutex);
|
||||
// Debug about suppressed this warning
|
||||
std::array<bool, V3ErrorCode::_ENUM_MAX> m_showedSuppressed VL_GUARDED_BY(m_mutex);
|
||||
VErrorBitSet m_showedSuppressed VL_GUARDED_BY(m_mutex);
|
||||
int m_debugDefault = 0; // Option: --debugi Default debugging level
|
||||
int m_errorLimit VL_GUARDED_BY(m_mutex)
|
||||
= MAX_ERRORS; // Option: --error-limit Number of errors before exit
|
||||
|
|
@ -429,14 +475,10 @@ public:
|
|||
bool isErrorOrWarn() VL_REQUIRES(m_mutex) {
|
||||
return errorCount() || (warnFatal() && warnCount());
|
||||
}
|
||||
bool pretendError(V3ErrorCode code) VL_REQUIRES(m_mutex) { return m_pretendError[code]; }
|
||||
bool pretendError(V3ErrorCode code) VL_REQUIRES(m_mutex) { return m_pretendError.test(code); }
|
||||
void pretendError(V3ErrorCode code, bool flag) VL_REQUIRES(m_mutex) {
|
||||
if (code == V3ErrorCode::WIDTH) {
|
||||
m_pretendError[V3ErrorCode::WIDTHTRUNC] = flag;
|
||||
m_pretendError[V3ErrorCode::WIDTHEXPAND] = flag;
|
||||
m_pretendError[V3ErrorCode::WIDTHXZEXPAND] = flag;
|
||||
}
|
||||
m_pretendError[code] = flag;
|
||||
code.forDelegateCodes([this, flag](V3ErrorCode subcode)
|
||||
VL_REQUIRES(m_mutex) { m_pretendError.set(subcode, flag); });
|
||||
}
|
||||
int debugDefault() VL_MT_SAFE { return m_debugDefault; }
|
||||
void debugDefault(int level) VL_MT_UNSAFE { m_debugDefault = level; }
|
||||
|
|
@ -450,10 +492,10 @@ public:
|
|||
bool errorSuppressed() VL_REQUIRES(m_mutex) { return m_errorSuppressed; }
|
||||
void errorSuppressed(bool flag) VL_REQUIRES(m_mutex) { m_errorSuppressed = flag; }
|
||||
bool describedEachWarn(V3ErrorCode code) VL_REQUIRES(m_mutex) {
|
||||
return m_describedEachWarn[code];
|
||||
return m_describedEachWarn.test(code);
|
||||
}
|
||||
void describedEachWarn(V3ErrorCode code, bool flag) VL_REQUIRES(m_mutex) {
|
||||
m_describedEachWarn[code] = flag;
|
||||
m_describedEachWarn.set(code, flag);
|
||||
}
|
||||
void suppressThisWarning() VL_REQUIRES(m_mutex);
|
||||
string warnRelated(const FileLine* fl) VL_REQUIRES(m_mutex) {
|
||||
|
|
|
|||
|
|
@ -126,21 +126,28 @@ 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) {
|
||||
const V3ErrorCode code{i};
|
||||
// "-Wall" and the like only adjust the code subset, so use default enablement there
|
||||
msgEnBitSet.set(MsgEnBitSet::Subset::CODE, i, !V3ErrorCode{i}.defaultsOff());
|
||||
msgEnBitSet.set(MsgEnBitSet::Subset::CODE, code, !code.defaultsOff());
|
||||
// The control file subset is only adjusted by the control files, everything enabled by
|
||||
// default
|
||||
msgEnBitSet.set(MsgEnBitSet::Subset::CTRL, i, true);
|
||||
msgEnBitSet.set(MsgEnBitSet::Subset::CTRL, code, true);
|
||||
}
|
||||
return addMsgEnBitSet(msgEnBitSet);
|
||||
}
|
||||
|
||||
FileLineSingleton::msgEnSetIdx_t FileLineSingleton::msgEnSetBit(msgEnSetIdx_t setIdx,
|
||||
MsgEnBitSet::Subset subset,
|
||||
size_t bitIdx, bool value) {
|
||||
if (msgEn(setIdx).test(subset, bitIdx) == value) return setIdx;
|
||||
V3ErrorCode code, bool value) {
|
||||
// See if state matches existing
|
||||
bool same = true;
|
||||
code.forDelegateCodes([&](V3ErrorCode subcode) {
|
||||
if (msgEn(setIdx).test(subset, subcode) != value) same = false;
|
||||
});
|
||||
if (same) return setIdx;
|
||||
// Make new mask of all delegated codes at once (to avoid extra indicies if looped above this)
|
||||
MsgEnBitSet msgEnBitSet{msgEn(setIdx)};
|
||||
msgEnBitSet.set(subset, bitIdx, value);
|
||||
code.forDelegateCodes([&](V3ErrorCode subcode) { msgEnBitSet.set(subset, subcode, value); });
|
||||
return addMsgEnBitSet(msgEnBitSet);
|
||||
}
|
||||
|
||||
|
|
@ -377,24 +384,13 @@ std::ostream& operator<<(std::ostream& os, FileLine* fileline) {
|
|||
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, turnOff);
|
||||
warnOff(V3ErrorCode::UNUSEDLOOP, turnOff);
|
||||
warnOff(V3ErrorCode::UNUSEDPARAM, turnOff);
|
||||
warnOff(V3ErrorCode::UNUSEDSIGNAL, turnOff);
|
||||
continue;
|
||||
}
|
||||
|
||||
const V3ErrorCode code{msg};
|
||||
if (!code.hardError()) {
|
||||
warnOff(code, turnOff);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Error if not suppressed
|
||||
if (!v3Global.opt.isFuture(msg)) result = VString::dot(result, ",", cmsg);
|
||||
if (!v3Global.opt.isFuture(msg)) result = VString::dot(result, ",", msg);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -413,20 +409,12 @@ void FileLine::warnStyleOff(bool turnOff) {
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
if (!msgEn().enabled(code)) return true;
|
||||
if (!defaultFileLine().msgEn().enabled(code)) return true; // Global overrides local
|
||||
if ((code.lintError() || code.styleError()) && !msgEn().enabled(V3ErrorCode::I_LINT)) {
|
||||
return true;
|
||||
}
|
||||
if ((code.unusedError()) && !msgEn().enabled(V3ErrorCode::I_UNUSED)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
#include "V3Mutex.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <bitset>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
|
|
@ -50,8 +49,8 @@ class FileLineSingleton final {
|
|||
using fileNameIdx_t = uint16_t; // Increase width if 64K input files are not enough
|
||||
using msgEnSetIdx_t = uint16_t; // Increase width if 64K unique message sets are not enough
|
||||
class MsgEnBitSet final {
|
||||
std::bitset<V3ErrorCode::_ENUM_MAX> m_codeEn; // Enabeld by code directives/metacomments
|
||||
std::bitset<V3ErrorCode::_ENUM_MAX> m_ctrlEn; // Enabled by control file
|
||||
VErrorBitSet m_codeEn; // Enabled by code directives/metacomments
|
||||
VErrorBitSet m_ctrlEn; // Enabled by control file
|
||||
|
||||
public:
|
||||
enum class Subset {
|
||||
|
|
@ -68,12 +67,8 @@ class FileLineSingleton final {
|
|||
|
||||
struct Hash final {
|
||||
size_t operator()(const MsgEnBitSet& item) const {
|
||||
const size_t hashCode
|
||||
= std::hash<std::bitset<V3ErrorCode::_ENUM_MAX>>()(item.m_codeEn);
|
||||
const size_t hashCtrl
|
||||
= std::hash<std::bitset<V3ErrorCode::_ENUM_MAX>>()(item.m_ctrlEn);
|
||||
V3Hash hash{static_cast<uint64_t>(hashCode)};
|
||||
hash += static_cast<uint64_t>(hashCtrl);
|
||||
V3Hash hash{item.m_codeEn.hash()};
|
||||
hash += item.m_ctrlEn.hash();
|
||||
return hash.value();
|
||||
}
|
||||
};
|
||||
|
|
@ -86,11 +81,10 @@ class FileLineSingleton final {
|
|||
return m_codeEn == other.m_codeEn && m_ctrlEn == other.m_ctrlEn;
|
||||
}
|
||||
|
||||
bool test(Subset subset, size_t code) const {
|
||||
bool test(Subset subset, V3ErrorCode code) const {
|
||||
return subset == Subset::CODE ? m_codeEn.test(code) : m_ctrlEn.test(code);
|
||||
}
|
||||
|
||||
void set(Subset subset, size_t code, bool value) {
|
||||
void set(Subset subset, V3ErrorCode code, bool value) {
|
||||
if (subset == Subset::CODE) {
|
||||
m_codeEn.set(code, value);
|
||||
} else {
|
||||
|
|
@ -139,8 +133,8 @@ class FileLineSingleton final {
|
|||
msgEnSetIdx_t addMsgEnBitSet(const MsgEnBitSet& bitSet) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
// Add index of default bitset
|
||||
msgEnSetIdx_t defaultMsgEnIndex() VL_MT_SAFE;
|
||||
// Set bitIdx to value in bitset at interned index setIdx, return interned index of result
|
||||
msgEnSetIdx_t msgEnSetBit(msgEnSetIdx_t setIdx, MsgEnBitSet::Subset subset, size_t bitIdx,
|
||||
// Set code to value in bitset at interned index setIdx, return interned index of result
|
||||
msgEnSetIdx_t msgEnSetBit(msgEnSetIdx_t setIdx, MsgEnBitSet::Subset subset, V3ErrorCode code,
|
||||
bool value);
|
||||
// Return index to intersection set
|
||||
msgEnSetIdx_t msgEnAnd(msgEnSetIdx_t lhsIdx, msgEnSetIdx_t rhsIdx);
|
||||
|
|
@ -368,12 +362,6 @@ public:
|
|||
// Turn on/off warning messages on this line.
|
||||
private:
|
||||
void warnSet(MsgEnBitSet::Subset subset, V3ErrorCode code, bool flag) {
|
||||
if (code == V3ErrorCode::WIDTH) {
|
||||
warnSet(subset, V3ErrorCode::WIDTHTRUNC, flag);
|
||||
warnSet(subset, V3ErrorCode::WIDTHEXPAND, flag);
|
||||
warnSet(subset, V3ErrorCode::WIDTHXZEXPAND, flag);
|
||||
}
|
||||
if (code == V3ErrorCode::E_UNSUPPORTED) warnSet(subset, V3ErrorCode::COVERIGN, flag);
|
||||
m_msgEnIdx = singleton().msgEnSetBit(m_msgEnIdx, subset, code, flag);
|
||||
}
|
||||
|
||||
|
|
@ -387,7 +375,6 @@ public:
|
|||
bool warnIsOff(V3ErrorCode code) const VL_MT_SAFE;
|
||||
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()); }
|
||||
|
||||
|
|
@ -407,7 +394,6 @@ public:
|
|||
static string builtInFilename() VL_MT_SAFE { return "<built-in>"; }
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1863,12 +1863,6 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
FileLine::globalWarnLintOff(false);
|
||||
FileLine::globalWarnStyleOff(false);
|
||||
});
|
||||
DECL_OPTION("-Werror-UNUSED", CbCall, []() {
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDGENVAR, true);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDLOOP, true);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDPARAM, true);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDSIGNAL, true);
|
||||
});
|
||||
DECL_OPTION("-Werror-", CbPartialMatch, [this, fl](const char* optp) {
|
||||
const V3ErrorCode code{optp};
|
||||
if (code == V3ErrorCode::EC_ERROR) {
|
||||
|
|
@ -1901,8 +1895,6 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
FileLine::globalWarnStyleOff(true);
|
||||
});
|
||||
DECL_OPTION("-Wno-style", CbCall, []() { FileLine::globalWarnStyleOff(true); });
|
||||
DECL_OPTION("-Wno-UNUSED", CbCall, []() { FileLine::globalWarnUnusedOff(true); });
|
||||
DECL_OPTION("-Wno-WIDTH", CbCall, []() { FileLine::globalWarnOff(V3ErrorCode::WIDTH, true); });
|
||||
DECL_OPTION("-work", Set, &m_work);
|
||||
DECL_OPTION("-Wpedantic", CbCall, [this]() {
|
||||
m_pedantic = true;
|
||||
|
|
@ -1923,25 +1915,6 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc,
|
|||
});
|
||||
DECL_OPTION("-Wwarn-lint", CbCall, []() { FileLine::globalWarnLintOff(false); });
|
||||
DECL_OPTION("-Wwarn-style", CbCall, []() { FileLine::globalWarnStyleOff(false); });
|
||||
DECL_OPTION("-Wwarn-UNUSED", CbCall, []() {
|
||||
FileLine::globalWarnUnusedOff(false);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDGENVAR, false);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDLOOP, false);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDSIGNAL, false);
|
||||
V3Error::pretendError(V3ErrorCode::UNUSEDPARAM, false);
|
||||
});
|
||||
DECL_OPTION("-Wwarn-UNSUPPORTED", CbCall, []() {
|
||||
FileLine::globalWarnOff(V3ErrorCode::E_UNSUPPORTED, false);
|
||||
FileLine::globalWarnOff(V3ErrorCode::COVERIGN, false);
|
||||
FileLine::globalWarnOff(V3ErrorCode::SPECIFYIGN, false);
|
||||
V3Error::pretendError(V3ErrorCode::E_UNSUPPORTED, false);
|
||||
V3Error::pretendError(V3ErrorCode::COVERIGN, false);
|
||||
V3Error::pretendError(V3ErrorCode::SPECIFYIGN, false);
|
||||
});
|
||||
DECL_OPTION("-Wwarn-WIDTH", CbCall, []() {
|
||||
FileLine::globalWarnOff(V3ErrorCode::WIDTH, false);
|
||||
V3Error::pretendError(V3ErrorCode::WIDTH, false);
|
||||
});
|
||||
DECL_OPTION("-waiver-multiline", OnOff, &m_waiverMultiline);
|
||||
DECL_OPTION("-waiver-output", Set, &m_waiverOutput);
|
||||
|
||||
|
|
|
|||
|
|
@ -8129,10 +8129,8 @@ vltOffFront<errcodeen>:
|
|||
| yVLT_TRACING_OFF { $$ = V3ErrorCode::I_TRACING; }
|
||||
| yVLT_LINT_OFF { $$ = V3ErrorCode::I_LINT; }
|
||||
| yVLT_LINT_OFF yVLT_D_RULE idAny
|
||||
{ const char *codemsg = (*$3).c_str();
|
||||
if (V3ErrorCode::unusedMsg(codemsg)) $$ = V3ErrorCode::I_UNUSED;
|
||||
else {$$ = V3ErrorCode{codemsg}; }
|
||||
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown error code: '" << *$3 << "'"); } }
|
||||
{ $$ = V3ErrorCode{*$3};
|
||||
if ($$ == V3ErrorCode::EC_ERROR) $1->v3error("Unknown error code: '" << *$3 << "'"); }
|
||||
;
|
||||
|
||||
vltOnFront<errcodeen>:
|
||||
|
|
@ -8141,10 +8139,8 @@ vltOnFront<errcodeen>:
|
|||
| yVLT_TRACING_ON { $$ = V3ErrorCode::I_TRACING; }
|
||||
| yVLT_LINT_ON { $$ = V3ErrorCode::I_LINT; }
|
||||
| yVLT_LINT_ON yVLT_D_RULE idAny
|
||||
{ const char *codemsg = (*$3).c_str();
|
||||
if (V3ErrorCode::unusedMsg(codemsg)) $$ = V3ErrorCode::I_UNUSED;
|
||||
else {$$ = V3ErrorCode{codemsg}; }
|
||||
if ($$ == V3ErrorCode::EC_ERROR) { $1->v3error("Unknown error code: '" << *$3 << "'"); } }
|
||||
{ $$ = V3ErrorCode{*$3};
|
||||
if ($$ == V3ErrorCode::EC_ERROR) $1->v3error("Unknown error code: '" << *$3 << "'"); }
|
||||
;
|
||||
|
||||
vltDBlock<strp>: // --block <arg>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import vltest_bootstrap
|
|||
|
||||
test.scenarios('linter')
|
||||
|
||||
test.lint(verilator_flags2=["-Wwarn-lint"], fails=True, expect_filename=test.golden_filename)
|
||||
test.lint(verilator_flags2=["-Wwarn-lint -Wno-style"],
|
||||
fails=True,
|
||||
expect_filename=test.golden_filename)
|
||||
|
||||
test.passes()
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
|
||||
|
||||
|
||||
module t;
|
||||
reg width_warn_var_line18 = 2'b11; // Width warning - must be line 18
|
||||
reg width_warn2_var_line19 = 2'b11; // Width warning - must be line 19
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
lint_off -rule DEPRECATED -file "t/t_vlt_warn.vlt" -lines 14
|
||||
lint_off -rule CASEINCOMPLETE -file "t/t_vlt_warn.v"
|
||||
lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 19
|
||||
lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 18
|
||||
lint_off -rule DECLFILENAME -file "*/t_vlt_warn.v"
|
||||
// Test wildcard filenames
|
||||
lint_off -rule WIDTH -file "*/t_vlt_warn.v" -lines 20-20
|
||||
// Test wildcard filenames, and WIDTH delegating to WIDTHTRUNC
|
||||
lint_off -rule WIDTH -file "*/t_vlt_warn.v" -lines 19-19
|
||||
// Test global disables
|
||||
lint_off -file "*/t_vlt_warn.v" -lines 21-21
|
||||
lint_off -file "*/t_vlt_warn.v" -lines 20-20
|
||||
// Test match
|
||||
lint_off -rule UNUSED -file "*/t_vlt_warn.v" -match "Signal is not used: 'width_warn*'"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
%Warning-WIDTHTRUNC: t/t_vlt_warn.v:21:33: Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits.
|
||||
%Warning-WIDTHTRUNC: t/t_vlt_warn.v:20:33: Operator ASSIGN expects 1 bits on the Assign RHS, but Assign RHS's CONST '2'h3' generates 2 bits.
|
||||
: ... note: In instance 't'
|
||||
21 | reg width_warn3_var_line20 = 2'b11;
|
||||
20 | reg width_warn3_var_line20 = 2'b11;
|
||||
| ^~~~~
|
||||
... For warning description see https://verilator.org/warn/WIDTHTRUNC?v=latest
|
||||
... Use "/* verilator lint_off WIDTHTRUNC */" and lint_on around source to disable this message.
|
||||
|
|
|
|||
|
|
@ -10,8 +10,6 @@ lint_off -rule CASEINCOMPLETE -file "t/t_vlt_warn.v"
|
|||
lint_off -rule WIDTH -file "t/t_vlt_warn.v" -lines 18
|
||||
// Test wildcard filenames
|
||||
lint_off -rule WIDTH -file "*/t_vlt_warn.v" -lines 19-19
|
||||
// Test global disables
|
||||
lint_off -file "*/t_vlt_warn.v" -lines 20-20
|
||||
|
||||
coverage_off -file "t/t_vlt_warn.v"
|
||||
// Test --flag is also accepted
|
||||
|
|
|
|||
Loading…
Reference in New Issue