From aaa5c5e857d111d3c84de91260e618d77bf68fea Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 3 Feb 2026 19:51:23 -0500 Subject: [PATCH] Tests: t_dist_warn_coverage.py: Understand wildcards (#6994 comment) --- test_regress/t/t_dist_warn_coverage.py | 92 ++++++++++++++++---------- 1 file changed, 58 insertions(+), 34 deletions(-) diff --git a/test_regress/t/t_dist_warn_coverage.py b/test_regress/t/t_dist_warn_coverage.py index 54414b76d..e2696ba51 100755 --- a/test_regress/t/t_dist_warn_coverage.py +++ b/test_regress/t/t_dist_warn_coverage.py @@ -14,6 +14,7 @@ test.scenarios('dist') Messages = {} Outputs = {} Suppressed = {} +Used_Suppressed = {} for s in [ # Cannot hit, and comment as to why @@ -109,6 +110,7 @@ for s in [ 'Slices of arrays in assignments have different unpacked dimensions,', 'String of', 'Symbol matching', + 'Thread scheduler is unable to provide requested', 'Unexpected connection to arrayed port', 'Unsized numbers/parameters not allowed in streams.', 'Unsupported (or syntax error): Foreach on this array\'s construct', @@ -120,7 +122,6 @@ for s in [ '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', @@ -149,7 +150,6 @@ for s in [ '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: extern constraint definition with class-in-class', @@ -253,16 +253,69 @@ def read_outputs(): test.glob_some(test.root + "/docs/gen/*.rst")): if "t_dist_warn_coverage" in filename: # Avoid our own suppressions continue + is_python = re.search(r'\.py$', filename) with open(filename, 'r', encoding="latin-1") as fh: for line in fh: - if re.match(r'^\$date', line): # Assume it is a VCD file + # File suppressions based on magic content + if re.match(r'^\$version', line): # Assume it is a VCD file break + if re.match(r'^# SystemC::Coverage', line): # Coverage data + break + if re.match(r'^//.*verilator_coverage annotation', line): # Coverage data + break + if re.match(r'^{"type":"NETLIST"', line): # JSON + break + if re.match(r'^// *Generated by verilated_saif', line): # SAIF + break + # Line suppressions + if is_python and re.match(r'^#', line): # Assume it is a VCD file + continue line = line.lstrip().rstrip() Outputs[line] = True print("Number of outputs = " + str(len(Outputs))) +def check_msg(msg): + fileline = Messages[msg]['fileline'] + # Fast first - exact match + for output in Outputs: + if msg in output: + # print(fileline+": M '" + msg + "' HIT '" + output) + return + + # Try regexp, with %s in message changed to .*? + if re.search(r'%[a-z]', msg): + msg_re = re.escape(msg) + msg_re = re.sub(r'^%[a-z]', r'', msg_re) + msg_re = re.sub(r'%[a-z]$', r'', msg_re) + msg_re = re.sub(r'%[a-z]', r'.*?', msg_re) + # print("msg_re='%s'" % (msg_re)) + m = re.compile(msg_re) + for output in Outputs: + if re.search(m, output): + # print(fileline+": M '" + msg + "' HIT '" + output) + return + + # Some exceptions + if re.match(r'internal:', msg, re.IGNORECASE): + return + + line = Messages[msg]['line'] + line = line.lstrip().rstrip() + + if msg in Suppressed: + Used_Suppressed[msg] = True + if test.verbose: + print(fileline + ": Suppressed check for message in source: '" + msg + "'") + else: + test.error_keep_going(fileline + + ": Missing test_regress/t/*.out test for message in source: '" + + msg + "'") + if test.verbose: + print(" Line is: " + line) + + def check(): read_messages() read_outputs() @@ -277,41 +330,12 @@ def check(): print("UASSERT or v3fatalSrc instead of v3error)") print() - used_suppressed = {} - for msg in sorted(Messages.keys()): - fileline = Messages[msg]['fileline'] - next_msg = False - for output in Outputs: - if msg in output: - # print(fileline+": M '" + msg + "' HIT '" + output) - next_msg = True - break - - if next_msg: - continue - - # Some exceptions - if re.match(r'internal:', msg, re.IGNORECASE): - continue - - line = Messages[msg]['line'] - line = line.lstrip().rstrip() - - if msg in Suppressed: - used_suppressed[msg] = True - if test.verbose: - print(fileline + ": Suppressed check for message in source: '" + msg + "'") - else: - test.error_keep_going(fileline + - ": Missing test_regress/t/*.out test for message in source: '" + - msg + "'") - if test.verbose: - print(" Line is: " + line) + check_msg(msg) print() for msg in sorted(Suppressed.keys()): - if msg not in used_suppressed: + if msg not in Used_Suppressed: print("Suppression not used: '" + msg + "'") print()