Internals: Check and enforce member brace initialization. No functional change intended

This commit is contained in:
Wilson Snyder 2025-08-17 13:20:52 -04:00
parent 7126293086
commit b14539569f
7 changed files with 40 additions and 28 deletions

View File

@ -693,7 +693,7 @@ struct reverse_wrapper final {
const T& m_v;
explicit reverse_wrapper(const T& a_v)
: m_v(a_v) {}
: m_v(a_v) {} // Need () constructor
auto begin() -> decltype(m_v.rbegin()) { return m_v.rbegin(); }
auto end() -> decltype(m_v.rend()) { return m_v.rend(); }
};

View File

@ -940,26 +940,26 @@ class AstConst final : public AstNodeExpr {
public:
AstConst(FileLine* fl, const V3Number& num)
: ASTGEN_SUPER_Const(fl)
, m_num(num) {
, m_num{num} {
initWithNumber();
}
class WidthedValue {}; // for creator type-overload selection
AstConst(FileLine* fl, WidthedValue, int width, uint32_t value)
: ASTGEN_SUPER_Const(fl)
, m_num(this, width, value) {
, m_num(this, width, value) { // Need () constructor
initWithNumber();
}
class DTyped {}; // for creator type-overload selection
// Zero/empty constant with a type matching nodetypep
AstConst(FileLine* fl, DTyped, const AstNodeDType* nodedtypep)
: ASTGEN_SUPER_Const(fl)
, m_num(this, nodedtypep) {
, m_num{this, nodedtypep} {
initWithNumber();
}
class StringToParse {}; // for creator type-overload selection
AstConst(FileLine* fl, StringToParse, const char* sourcep)
: ASTGEN_SUPER_Const(fl)
, m_num(this, sourcep) {
, m_num{this, sourcep} {
initWithNumber();
}
class VerilogStringLiteral {}; // for creator type-overload selection
@ -970,41 +970,41 @@ public:
}
AstConst(FileLine* fl, uint32_t num)
: ASTGEN_SUPER_Const(fl)
, m_num(this, 32, num) {
, m_num(this, 32, num) { // Need () constructor
dtypeSetLogicUnsized(m_num.width(), 0, VSigning::UNSIGNED);
}
class Unsized32 {}; // for creator type-overload selection
AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value
: ASTGEN_SUPER_Const(fl)
, m_num(this, 32, num) {
, m_num(this, 32, num) { // Need () constructor
m_num.width(32, false);
dtypeSetLogicUnsized(32, m_num.widthToFit(), VSigning::UNSIGNED);
}
class Signed32 {}; // for creator type-overload selection
AstConst(FileLine* fl, Signed32, int32_t num) // Signed 32-bit integer of specified value
: ASTGEN_SUPER_Const(fl)
, m_num(this, 32, num) {
, m_num(this, 32, num) { // Need () constructor
m_num.width(32, true);
dtypeSetLogicUnsized(32, m_num.widthToFit(), VSigning::SIGNED);
}
class Unsized64 {}; // for creator type-overload selection
AstConst(FileLine* fl, Unsized64, uint64_t num)
: ASTGEN_SUPER_Const(fl)
, m_num(this, 64, 0) {
, m_num(this, 64, 0) { // Need () constructor
m_num.setQuad(num);
dtypeSetLogicSized(64, VSigning::UNSIGNED);
}
class SizedEData {}; // for creator type-overload selection
AstConst(FileLine* fl, SizedEData, uint64_t num)
: ASTGEN_SUPER_Const(fl)
, m_num(this, VL_EDATASIZE, 0) {
, m_num(this, VL_EDATASIZE, 0) { // Need () constructor
m_num.setQuad(num);
dtypeSetLogicSized(VL_EDATASIZE, VSigning::UNSIGNED);
}
class RealDouble {}; // for creator type-overload selection
AstConst(FileLine* fl, RealDouble, double num)
: ASTGEN_SUPER_Const(fl)
, m_num(this, 64) {
, m_num(this, 64) { // Need () constructor
m_num.setDouble(num);
dtypeSetDouble();
}
@ -1017,27 +1017,27 @@ public:
class BitFalse {};
AstConst(FileLine* fl, BitFalse) // Shorthand const 0, dtype should be a logic of size 1
: ASTGEN_SUPER_Const(fl)
, m_num(this, 1, 0) {
, m_num(this, 1, 0) { // Need () constructor
dtypeSetBit();
}
// Shorthand const 1 (or with argument 0/1), dtype should be a logic of size 1
class BitTrue {};
AstConst(FileLine* fl, BitTrue, bool on = true)
: ASTGEN_SUPER_Const(fl)
, m_num(this, 1, on) {
, m_num(this, 1, on) { // Need () constructor
dtypeSetBit();
}
class All0 {};
AstConst(FileLine* fl, All0)
: ASTGEN_SUPER_Const(fl)
, m_num(this, "'0") {
, m_num(this, "'0") { // Need () constructor
initWithNumber();
fl->warnOff(V3ErrorCode::NEWERSTD, true);
}
class All1 {};
AstConst(FileLine* fl, All1)
: ASTGEN_SUPER_Const(fl)
, m_num(this, "'1") {
, m_num(this, "'1") { // Need () constructor
initWithNumber();
fl->warnOff(V3ErrorCode::NEWERSTD, true);
}

View File

@ -126,7 +126,7 @@ class V3OptionParser::Impl::ActionCbVal<int> final : public ActionBase<en::VALUE
public:
using CbType = std::function<void(int)>;
explicit ActionCbVal(CbType cb)
: m_cb(std::move(cb)) {}
: m_cb{std::move(cb)} {}
void exec(const char* optp, const char* argp) override { m_cb(std::atoi(argp)); }
};
@ -137,7 +137,7 @@ class V3OptionParser::Impl::ActionCbVal<const char*> final : public ActionBase<e
public:
using CbType = std::function<void(const char*)>;
explicit ActionCbVal(CbType cb)
: m_cb(std::move(cb)) {}
: m_cb{std::move(cb)} {}
void exec(const char* optp, const char* argp) override { m_cb(argp); }
};

View File

@ -92,9 +92,9 @@ class ParameterizedHierBlocks final {
public:
ParameterizedHierBlocks(const V3HierBlockOptSet& hierOpts, AstNetlist* nodep)
: m_hierSubRun((!v3Global.opt.hierBlocks().empty() || v3Global.opt.hierChild())
: m_hierSubRun{(!v3Global.opt.hierBlocks().empty() || v3Global.opt.hierChild())
// Exclude consolidation
&& !v3Global.opt.hierParamFile().empty()) {
&& !v3Global.opt.hierParamFile().empty()} {
for (const auto& hierOpt : hierOpts) {
m_hierBlockOptsByOrigName.emplace(hierOpt.second.origName(), &hierOpt.second);
const V3HierarchicalBlockOption::ParamStrMap& params = hierOpt.second.params();

View File

@ -159,8 +159,8 @@ class VirtIfaceTriggers final {
const AstVar* m_memberVarp; // pointer to member field
IfaceMember(const AstIface* ifacep, const AstVar* memberVarp)
: m_ifacep(ifacep)
, m_memberVarp(memberVarp) {}
: m_ifacep{ifacep}
, m_memberVarp{memberVarp} {}
bool operator<(const IfaceMember& other) const {
if (m_ifacep != other.m_ifacep) return m_ifacep < other.m_ifacep;

View File

@ -25,11 +25,11 @@ class TestVpiHandle {
public:
TestVpiHandle()
: m_handle(NULL)
, m_freeit(true) {}
: m_handle(NULL) // Need (), not C++11
, m_freeit(true) {} // Need (), not C++11
TestVpiHandle(vpiHandle h)
: m_handle(h)
, m_freeit(true) {}
: m_handle(h) // Need (), not C++11
, m_freeit(true) {} // Need (), not C++11
~TestVpiHandle() { release(); }
operator vpiHandle() const { return m_handle; }
TestVpiHandle& operator=(vpiHandle h) {

View File

@ -29,9 +29,12 @@ def get_source_files(root):
def check_pattern(filename, contents, pattern, not_pattern, message):
# Pattern uses match, so must include skipping leading whitespace if necessary
lineno = 0
buffer_lineno = 0
buffer = "\n"
for line in contents.splitlines():
lineno += 1
if buffer == "\n":
buffer_lineno = lineno
if line != "":
# Don't do whole file at once - see issue #4085
# Build a buffer until a newline so we check a block at a time.
@ -40,7 +43,8 @@ def check_pattern(filename, contents, pattern, not_pattern, message):
m = re.search(r"\n" + pattern, buffer)
if m:
if not not_pattern or not re.search(not_pattern, buffer):
test.error_keep_going(filename + ":" + str(lineno) + ": " + message + m.group(0))
test.error_keep_going(filename + ":" + str(buffer_lineno) + ": " + message +
m.group(0))
buffer = "\n"
@ -77,8 +81,16 @@ for filename in sorted(files.keys()):
contents,
r'.*[( ]new [a-zA-Z0-9]+\([^\n]*',
# Ignore common ok narrowing conversions, on int vs uint32_t arguments
r'(Need \(\) constructor|new AstArraySel|new AstConst|new AstRange)',
"Use brace instead of parenthesis-style constructors e.g. 'new ...{...}'")
r'(Need \(\)|new AstArraySel|new AstConst|new AstRange)',
"Use brace instead of parenthesis-style new constructors e.g. 'new ...{...}'")
check_pattern(
filename,
contents,
r'.*(\n *:|,\n) +m_[a-zA-Z0-9]+\(',
# Ignore common m_e enum constructors
r'.*(Need \(\)|: m_e\()|V3OPTION_PARSER_DEF',
"Use brace instead of parenthesis-style constructors e.g. ': m_...{...}'")
if re.search(r'\.(c|cpp)', filename):
check_pattern(filename, contents, r'(\w+\s+)*(inline)[^\n]*', None,