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())) { if (nodep->access().isWriteOrRW() && (!nodep->isClassHandleValue() || nodep->user2())) {
nodep->v3warn( nodep->v3warn(
E_LIFETIME, E_LIFETIME,
"Invalid reference: Process might outlive variable `" "Invalid reference: Process might outlive variable "
<< varp->name() << "`.\n" << varp->prettyNameQ() << ".\n"
<< varp->warnMore() << varp->warnMore()
<< "... Suggest use it as read-only to initialize a local copy at the " << "... 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 " "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 // Add post update if it does not exist yet
if (m_hasPostUpdate.emplace(*exprp).second) { if (m_hasPostUpdate.emplace(*exprp).second) {
if (!isSupportedDType(exprp->dtypep())) { if (!isSupportedDType(exprp->dtypep())) {
exprp->v3warn(E_UNSUPPORTED, exprp->v3warn(
"Unsupported: Cannot detect changes on expression of complex type" E_UNSUPPORTED,
" (see combinational cycles reported by UNOPTFLAT)"); "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; return prevp;
} }

View File

@ -18,82 +18,115 @@ Suppressed = {}
for s in [ for s in [
# Cannot hit, and comment as to why # 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 # 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 'exited with', # Is hit; driver.py filters out
' loading non-variable', # Instead 'storing to parameter' or syntax error '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 'Assigned pin is neither input nor output', # Instead earlier error
'Define missing argument \'', # Instead get Define passed too many arguments 'Define missing argument \'', # Instead get Define passed too many arguments
'Define or directive not defined: `', # Instead V3ParseImp will warn 'Define or directive not defined: `', # Instead V3ParseImp will warn
'Expecting define formal arguments. Found: ', # Instead define 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 '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 'dynamic new() not expected in this context (expected under an assign)', # Instead get syntax error
# Not yet analyzed # 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', '--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', 'Assignment pattern with no members',
'Can\'t find varpin scope of ', 'Can\'t find varpin scope of',
'Can\'t read annotation file: ', 'Can\'t read annotation file:',
'Can\'t resolve module reference: \'', 'Can\'t resolve module reference: \'',
'Can\'t write file: ', 'Can\'t write file:',
'Expected data type, not a ', 'Circular logic when ordering code (non-cutable edge loop)',
'Expected data type, not a',
'Extern declaration\'s scope is not a defined class', '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', 'Format to $display-like function must have constant format string',
'Forward typedef used as class/package does not resolve to class/package: ', 'Forward typedef used as class/package does not resolve to class/package:',
'Illegal +: or -: select; type already selected, or bad dimension: ', 'Illegal +: or -: select; type already selected, or bad dimension:',
'Illegal bit or array 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: ', 'Illegal range select; type already selected, or bad dimension:',
'Interface port declaration ', 'Instance pin connected by name with empty reference:',
'Modport item is not a function/task: ', 'Interface port declaration',
'Modport item is not a variable: ', '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 as <interface>.',
'Modport not referenced from underneath an interface: ', 'Modport not referenced from underneath an interface:',
'Non-interface used as an interface: ', 'Need $SYSTEMC_INCLUDE in environment or when Verilator configured,',
'Parameter type pin value isn\'t a type: Param ', 'Non-interface used as an interface:',
'Parameter type variable isn\'t a type: Param ', '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.', 'Pattern replication value of 0 is not legal.',
'Signals inside functions/tasks cannot be marked forceable', 'Signals inside functions/tasks cannot be marked forceable',
'Slice size cannot be zero.', 'Slice size cannot be zero.',
'Slices of arrays in assignments have different unpacked dimensions, ', 'Slices of arrays in assignments have different unpacked dimensions,',
'String of ', 'String of',
'Symbol matching ', 'Symbol matching',
'Unexpected connection to arrayed port', 'Unexpected connection to arrayed port',
'Unsized numbers/parameters not allowed in streams.', '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 or syntax error: Unsized range in instance or other declaration',
'Unsupported pullup/down (weak driver) construct.', '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: $bits for queue',
'Unsupported: &&& expression', 'Unsupported: &&& expression',
'Unsupported: 4-state numbers in this context', 'Unsupported: 4-state numbers in this context',
'Unsupported: Assignments with signal strength with LHS of type:',
'Unsupported: Bind with instance list', '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 empty expression',
'Unsupported: Modport export with prototype', 'Unsupported: Modport export with prototype',
'Unsupported: Modport import 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: Only one PSL clock allowed per assertion',
'Unsupported: Per-bit array instantiations ', 'Unsupported: Per-bit array instantiations',
'Unsupported: Public functions with >64 bit outputs; ', 'Unsupported: Public functions with >64 bit outputs;',
'Unsupported: Replication to form ', '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: Size-changing cast on non-basic data type',
'Unsupported: Slice of non-constant bounds', 'Unsupported: Slice of non-constant bounds',
'Unsupported: Stream operation on a variable of a type',
'Unsupported: Unclocked assertion', 'Unsupported: Unclocked assertion',
'Unsupported: Using --protect-ids with public function',
'Unsupported: Verilog 1995 deassign', 'Unsupported: Verilog 1995 deassign',
'Unsupported: Verilog 1995 gate primitive: ', 'Unsupported: Verilog 1995 gate primitive:',
'Unsupported: [] dimensions', 'Unsupported: [] dimensions',
'Unsupported: \'default :/\' constraint', 'Unsupported: \'default :/\' constraint',
'Unsupported: \'{} .* patterns', 'Unsupported: \'{} .* patterns',
'Unsupported: assertion items in clocking blocks', '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 forkjoin',
'Unsupported: extern task', 'Unsupported: extern task',
'Unsupported: modport export', 'Unsupported: modport export',
'Unsupported: no_inline for tasks', 'Unsupported: no_inline for tasks',
'Unsupported: non-const assert directive type expression',
'Unsupported: property port \'local\'', 'Unsupported: property port \'local\'',
'Unsupported: randsequence production function variable',
'Unsupported: repeat event control', 'Unsupported: repeat event control',
'Unsupported: static cast to ', 'Unsupported: static cast to',
'Unsupported: super', 'Unsupported: super',
'Unsupported: with[] stream expression', '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 Suppressed[s] = True
@ -106,7 +139,8 @@ def read_messages():
continue continue
with open(filename, 'r', encoding="utf8") as fh: with open(filename, 'r', encoding="utf8") as fh:
lineno = 0 lineno = 0
read_next = None statement = ""
statement_lineno = 0
excl = False excl = False
excl_next = False excl_next = False
@ -118,36 +152,52 @@ def read_messages():
if re.match(r'^\s*/\*', line): if re.match(r'^\s*/\*', line):
continue continue
excl = excl_next excl = excl_next
# print(('C ' if (statement != "") else 'L') + line)
if 'LCOV_EXCL_START' in line: if 'LCOV_EXCL_START' in line:
excl = True excl = True
excl_next = True excl_next = True
if 'LCOV_EXCL_STOP' in line: if 'LCOV_EXCL_STOP' in line:
excl_next = False # Reenables coverage on next line, not this one 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' in line:
if 'LCOV_EXCL_LINE' not in line: excl = True
read_next = True if excl:
statement = ""
continue continue
m = re.search(r'.*\b(v3error|v3warn|v3fatal|BBUNSUP)\b(.*)', line)
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: if m:
line = m.group(2) statement = m.group(1)
if 'LCOV_EXCL_LINE' not in line: statement_lineno = lineno
read_next = True
if read_next: if statement == "":
read_next = False continue
if 'LCOV_EXCL_LINE' in line: statement += line
continue
if excl: if ');' not in statement:
continue continue # Keep reading lines until get end of statement
if "\\" in line: # \" messes up next part
continue if '\\"' in statement:
m = re.search(r'"([^"]*)"', line) continue # Parser messes these up
if m:
msg = m.group(1) # print("SSS " + statement)
fileline = filename + ":" + str(lineno)
# print("FFFF " + fileline + ": " + msg + " LL " + line) m = re.search(r'"([^"]*)"', statement)
Messages[msg] = {} if m:
Messages[msg]['fileline'] = fileline msg = m.group(1)
Messages[msg]['line'] = origline 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'] = statement
statement = ""
print("Number of messages = " + str(len(Messages))) print("Number of messages = " + str(len(Messages)))