Tests: Better handle multiline statements in t_dist_warn_coverage

This commit is contained in:
Wilson Snyder 2025-12-21 16:15:33 -05:00
parent a6f608c616
commit ef5ca74e94
3 changed files with 116 additions and 63 deletions

View File

@ -673,8 +673,8 @@ class ForkVisitor final : public VNVisitor {
if (nodep->access().isWriteOrRW() && (!nodep->isClassHandleValue() || nodep->user2())) {
nodep->v3warn(
E_LIFETIME,
"Invalid reference: Process might outlive variable `"
<< varp->name() << "`.\n"
"Invalid reference: Process might outlive variable "
<< varp->prettyNameQ() << ".\n"
<< varp->warnMore()
<< "... Suggest use it as read-only to initialize a local copy at the "
"beginning of the process, or declare it as static. It is also "

View File

@ -126,9 +126,12 @@ private:
// Add post update if it does not exist yet
if (m_hasPostUpdate.emplace(*exprp).second) {
if (!isSupportedDType(exprp->dtypep())) {
exprp->v3warn(E_UNSUPPORTED,
"Unsupported: Cannot detect changes on expression of complex type"
" (see combinational cycles reported by UNOPTFLAT)");
exprp->v3warn(
E_UNSUPPORTED,
"Unsupported: Cannot detect changes on expression of complex type "
<< exprp->dtypep()->prettyDTypeNameQ() << "\n"
<< exprp->warnMore()
<< "... May be caused by combinational cycles reported with UNOPTFLAT");
return prevp;
}

View File

@ -18,82 +18,115 @@ Suppressed = {}
for s in [
# Cannot hit, and comment as to why
# Instead of adding here, consider adding a LCOV_EXCL_LINE/START/STOP to the sources on the message
' exited with ', # Is hit; driver.py filters out
' loading non-variable', # Instead 'storing to parameter' or syntax error
'exited with', # Is hit; driver.py filters out
'loading non-variable', # Instead 'storing to parameter' or syntax error
'does not allow '
' in the middle of literal', # Is covered, this parser misses it due to quote
'Assigned pin is neither input nor output', # Instead earlier error
'Define missing argument \'', # Instead get Define passed too many arguments
'Define or directive not defined: `', # Instead V3ParseImp will warn
'Expecting define formal arguments. Found: ', # Instead define syntax error
'Syntax error: Range \':\', \'+:\' etc are not allowed in the instance ', # Instead get syntax error
'Expecting define formal arguments. Found:', # Instead define syntax error
'Syntax error: Range \':\', \'+:\' etc are not allowed in the instance', # Instead get syntax error
'dynamic new() not expected in this context (expected under an assign)', # Instead get syntax error
# Not yet analyzed
'--pipe-filter protocol error, unexpected: ',
'$VERILATOR_ROOT needs to be in environment',
'--pipe-filter protocol error, unexpected:',
'--pipe-filter returned bad status',
'Array initialization has too few elements, need element ',
'--pipe-filter: stdin/stdout closed before pipe opened',
'--pipe-filter: write to closed file',
'Array initialization has too few elements, need element',
'Assigning >32 bit to unranged parameter (defaults to 32 bits)',
'Assignment pattern with no members',
'Can\'t find varpin scope of ',
'Can\'t read annotation file: ',
'Can\'t find varpin scope of',
'Can\'t read annotation file:',
'Can\'t resolve module reference: \'',
'Can\'t write file: ',
'Expected data type, not a ',
'Can\'t write file:',
'Circular logic when ordering code (non-cutable edge loop)',
'Expected data type, not a',
'Extern declaration\'s scope is not a defined class',
'File not found: ',
'File not found:',
'Format to $display-like function must have constant format string',
'Forward typedef used as class/package does not resolve to class/package: ',
'Illegal +: or -: select; type already selected, or bad dimension: ',
'Illegal bit or array select; type already selected, or bad dimension: ',
'Illegal range select; type already selected, or bad dimension: ',
'Interface port declaration ',
'Modport item is not a function/task: ',
'Modport item is not a variable: ',
'Forward typedef used as class/package does not resolve to class/package:',
'Illegal +: or -: select; type already selected, or bad dimension:',
'Illegal bit or array select; type already selected, or bad dimension:',
'Illegal range select; type already selected, or bad dimension:',
'Instance pin connected by name with empty reference:',
'Interface port declaration',
'Invalid reference: Process might outlive variable',
'Modport item is not a function/task:',
'Modport item is not a variable:',
'Modport not referenced as <interface>.',
'Modport not referenced from underneath an interface: ',
'Non-interface used as an interface: ',
'Parameter type pin value isn\'t a type: Param ',
'Parameter type variable isn\'t a type: Param ',
'Modport not referenced from underneath an interface:',
'Need $SYSTEMC_INCLUDE in environment or when Verilator configured,',
'Non-interface used as an interface:',
'Parameter type pin value isn\'t a type: Param',
'Parameter type variable isn\'t a type: Param',
'Pattern replication value of 0 is not legal.',
'Signals inside functions/tasks cannot be marked forceable',
'Slice size cannot be zero.',
'Slices of arrays in assignments have different unpacked dimensions, ',
'String of ',
'Symbol matching ',
'Slices of arrays in assignments have different unpacked dimensions,',
'String of',
'Symbol matching',
'Unexpected connection to arrayed port',
'Unsized numbers/parameters not allowed in streams.',
'Unsupported RHS tristate construct: ',
'Unsupported (or syntax error): Foreach on this array\'s construct',
'Unsupported LHS node type in array assignment',
'Unsupported RHS tristate construct:',
'Unsupported or syntax error: Unsized range in instance or other declaration',
'Unsupported pullup/down (weak driver) construct.',
'Unsupported tristate port expression: ',
'Unsupported tristate construct (not in propagation graph):',
'Unsupported tristate port expression:',
'Unsupported/unknown built-in queue method',
'Unsupported: $bits for queue',
'Unsupported: &&& expression',
'Unsupported: 4-state numbers in this context',
'Unsupported: Assignments with signal strength with LHS of type:',
'Unsupported: Bind with instance list',
'Unsupported: Concatenation to form ',
'Unsupported: Cannot detect changes on expression of complex type',
'Unsupported: Cast to',
'Unsupported: Concatenation to form',
'Unsupported: Creating tristate signal not underneath a module:',
'Unsupported: Default value on module inout/ref/constref:',
'Unsupported: Modport empty expression',
'Unsupported: Modport export with prototype',
'Unsupported: Modport import with prototype',
'Unsupported: Non-constant default value in missing argument',
'Unsupported: Non-constant index when passing interface to module',
'Unsupported: Only one PSL clock allowed per assertion',
'Unsupported: Per-bit array instantiations ',
'Unsupported: Public functions with >64 bit outputs; ',
'Unsupported: Replication to form ',
'Unsupported: Per-bit array instantiations',
'Unsupported: Public functions with >64 bit outputs;',
'Unsupported: Public functions with return > 64 bits wide.',
'Unsupported: Release statement argument is too complex array select',
'Unsupported: Replication to form',
'Unsupported: Shifting of by over 32-bit number isn\'t supported.',
'Unsupported: Size-changing cast on non-basic data type',
'Unsupported: Slice of non-constant bounds',
'Unsupported: Stream operation on a variable of a type',
'Unsupported: Unclocked assertion',
'Unsupported: Using --protect-ids with public function',
'Unsupported: Verilog 1995 deassign',
'Unsupported: Verilog 1995 gate primitive: ',
'Unsupported: Verilog 1995 gate primitive:',
'Unsupported: [] dimensions',
'Unsupported: \'default :/\' constraint',
'Unsupported: \'{} .* patterns',
'Unsupported: assertion items in clocking blocks',
'Unsupported: don\'t know how to deal with ',
'Unsupported: don\'t know how to deal with',
'Unsupported: extern constraint definition with class-in-class',
'Unsupported: extern forkjoin',
'Unsupported: extern task',
'Unsupported: modport export',
'Unsupported: no_inline for tasks',
'Unsupported: non-const assert directive type expression',
'Unsupported: property port \'local\'',
'Unsupported: randsequence production function variable',
'Unsupported: repeat event control',
'Unsupported: static cast to ',
'Unsupported: static cast to',
'Unsupported: super',
'Unsupported: with[] stream expression',
'expected non-complex non-double',
'is not an unpacked array, but is in an unpacked array context',
'loading other than unpacked-array variable',
'loading other than unpacked/associative-array variable',
]:
Suppressed[s] = True
@ -106,7 +139,8 @@ def read_messages():
continue
with open(filename, 'r', encoding="utf8") as fh:
lineno = 0
read_next = None
statement = ""
statement_lineno = 0
excl = False
excl_next = False
@ -118,36 +152,52 @@ def read_messages():
if re.match(r'^\s*/\*', line):
continue
excl = excl_next
# print(('C ' if (statement != "") else 'L') + line)
if 'LCOV_EXCL_START' in line:
excl = True
excl_next = True
if 'LCOV_EXCL_STOP' in line:
excl_next = False # Reenables coverage on next line, not this one
if re.search(r'\b(v3error|v3warn|v3fatal|BBUNSUP)\b\($', line):
if 'LCOV_EXCL_LINE' not in line:
read_next = True
continue
m = re.search(r'.*\b(v3error|v3warn|v3fatal|BBUNSUP)\b(.*)', line)
if m:
line = m.group(2)
if 'LCOV_EXCL_LINE' not in line:
read_next = True
if read_next:
read_next = False
if 'LCOV_EXCL_LINE' in line:
continue
excl = True
if excl:
statement = ""
continue
if "\\" in line: # \" messes up next part
line = re.sub(r'\\n', '', line)
line = re.sub(r'\s+//.*', '', line)
line = line.rstrip()
m = re.search(r'\b((v3error|v3warn|v3fatal|BBUNSUP)\b.*)', line)
if m:
statement = m.group(1)
statement_lineno = lineno
if statement == "":
continue
m = re.search(r'"([^"]*)"', line)
statement += line
if ');' not in statement:
continue # Keep reading lines until get end of statement
if '\\"' in statement:
continue # Parser messes these up
# print("SSS " + statement)
m = re.search(r'"([^"]*)"', statement)
if m:
msg = m.group(1)
fileline = filename + ":" + str(lineno)
# print("FFFF " + fileline + ": " + msg + " LL " + line)
msg = re.sub(r'\s+$', '', msg)
msg = re.sub(r'^\s+', '', msg)
fileline = filename + ":" + str(statement_lineno)
# print("FFFF " + fileline + ": " + msg + " LL " + statement)
Messages[msg] = {}
Messages[msg]['fileline'] = fileline
Messages[msg]['line'] = origline
Messages[msg]['line'] = statement
statement = ""
print("Number of messages = " + str(len(Messages)))