MCPcopy Create free account
hub / github.com/Serial-Studio/Serial-Studio / _scan_body_lines

Function _scan_body_lines

scripts/code_verify_rules.py:670–716  ·  view source on GitHub ↗

Run a list of `(regex, kind, message)` triples over each line of a function body. First-match wins per line so a single problematic expression doesn't fire every pattern. Lines skipped (all driven by AST walks for multi-line statements): - `constexpr` / `static const` declarations

(body, src: bytes, fname: str, fenced, patterns)

Source from the content-addressed store, hash-verified

668
669
670def _scan_body_lines(body, src: bytes, fname: str, fenced, patterns) -> list:
671 """Run a list of `(regex, kind, message)` triples over each line of a
672 function body. First-match wins per line so a single problematic
673 expression doesn't fire every pattern.
674
675 Lines skipped (all driven by AST walks for multi-line statements):
676 - `constexpr` / `static const` declarations -- init code, not per-call
677 - `[[unlikely]]`-attributed substatement bodies -- cold path
678 - `catch_clause` bodies -- error / exception path, not steady-state
679
680 Lines skipped per-pattern: reciprocal-cache declarations
681 (`const T inv = 1.0 / x;`) bypass the divide rule -- they ARE the
682 recommended fix for runtime-divisor cost."""
683 if body is None:
684 return []
685 findings: list = []
686 body_text = _node_text(body, src)
687 body_start = body.start_point[0] + 1
688 exempt_lines = _init_only_decl_line_span(body, src) | _cold_branch_line_span(
689 body, src
690 )
691 constexpr_names = _compile_time_constants_in_scope(body, src)
692 for j, line in enumerate(body_text.split("\n")):
693 abs_line = body_start + j
694 if fenced(abs_line) or abs_line in exempt_lines:
695 continue
696 scrubbed = _strip_strings_and_line_comments(line)
697 is_recip_cache = _is_reciprocal_cache_line(scrubbed)
698 # If every divisor / modulo on this line resolves to a constexpr
699 # name we know is in scope, the compiler folds them. Skip the
700 # divide/modulo runtime rules for this line.
701 divisors = _DIV_OR_MOD_DIVISOR_RE.findall(scrubbed)
702 all_compile_time = bool(divisors) and all(
703 d in constexpr_names for d in divisors
704 )
705 for pat, kind, msg in patterns:
706 if is_recip_cache and kind == "perf-divide-runtime-divisor":
707 continue
708 if all_compile_time and kind in (
709 "perf-divide-runtime-divisor",
710 "perf-modulo-runtime-divisor",
711 ):
712 continue
713 if pat.search(scrubbed):
714 findings.append(Finding(abs_line, kind, msg))
715 break
716 return findings
717
718
719def _recursion_findings(func_node, fname: str, body, src: bytes, fenced) -> list:

Callers 1

_cpp_rulesFunction · 0.85

Calls 10

_node_textFunction · 0.85
_cold_branch_line_spanFunction · 0.85
fencedFunction · 0.85
FindingClass · 0.70
searchMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected