Skip to content

Commit b099107

Browse files
committed
Document Coverity Scan triage and pin Cython for stable scans
Backport of IntelPython/mkl_umath#266, adapted to mkl_fft. - Pin cython==3.3.0 in the Coverity workflow (only there, not in pyproject.toml) so the generated _pydfti.c stays byte-stable between scans and Coverity CIDs plus their triage survive. Works because the scan build uses --no-build-isolation. - Add coverity/README.md: where findings come from across mkl_fft's two translation units (template-generated mklfft.c, which is our DFTI logic and stays in scope, and Cython-generated _pydfti.c), the Cython-pin rationale, an opt-in Project Component, a review checklist, and the one verified Cython-boilerplate false positive that applies to mkl_fft (a DEADCODE in the tp_traverse slot of Cython genexpr scope structs). mkl_umath's other documented false positives (the __umath_generated.c InitOperators DEADCODE, the with-statement and __Pyx__Import DEADCODE, and the _patch_impl FORWARD_NULL) do not occur in mkl_fft and are deliberately omitted.
1 parent d87b5c5 commit b099107

3 files changed

Lines changed: 90 additions & 1 deletion

File tree

‎.github/workflows/coverity.yml‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ jobs:
3232
architecture: x64
3333

3434
- name: Install mkl_fft dependencies
35-
run: pip install meson-python ninja cmake cython "numpy>=2" mkl-devel
35+
# Cython is pinned here only (not in pyproject.toml) to keep the generated
36+
# code stable between scans, so Coverity CIDs and their triage survive
37+
run: pip install meson-python ninja cmake "cython==3.3.0" "numpy>=2" mkl-devel
3638

3739
- name: Download Coverity Build Tool
3840
timeout-minutes: 15

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111
### Changed
1212
* Multi-iterator constructors now return a status corresponding to allocation success or failure, and raise `MemoryError` instead of `ValueError` [gh-373](https://github.com/IntelPython/mkl_fft/pull/373)
1313
* `_direct_fftnd` now also checks the status returned by the backend instead of discarding it [gh-373](https://github.com/IntelPython/mkl_fft/pull/373)
14+
* Pinned Cython in the Coverity Scan workflow so generated code stays stable between scans, and added `coverity/README.md` documenting the known Cython-boilerplate false positive and the scan review checklist [gh-365](https://github.com/IntelPython/mkl_fft/pull/365)
1415

1516
### Fixed
1617
* Declared `f_ndim` as a C `int` in `_allocate_result` so the buffer size is computed in C rather than through a Python object, resolving a Coverity out-of-bounds (OVERRUN) false positive [gh-364](https://github.com/IntelPython/mkl_fft/pull/364)

‎coverity/README.md‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Triaging Coverity Scan findings
2+
3+
Static analysis runs on [Coverity Scan](https://scan.coverity.com) via
4+
[`.github/workflows/coverity.yml`](../.github/workflows/coverity.yml) (weekly + on
5+
demand). Analysis runs on Black Duck's servers; triage is done in the Scan web UI.
6+
7+
Every finding to date is a false positive in **generated** code — the
8+
Cython-generated `_pydfti.c` — not in code we maintain. This guide records the
9+
verified findings and how to keep triage from resetting.
10+
11+
## Where findings come from
12+
13+
`cov-build` captures two C translation units (the `.h` files under
14+
`mkl_fft/src/` are `#include`d into them, not compiled on their own):
15+
16+
- **Template-generated** `mklfft.c` (from `mkl_fft/src/mklfft.c.src` via
17+
`_vendored/process_src_template.py`, wired up in `meson.build`). This is *not*
18+
Cython — it is our oneMKL DFTI descriptor/compute logic, just type-specialized
19+
for float32/float64/complex64/complex128. It pulls in the hand-written helpers
20+
in `mkl_fft/src/multi_iter.h` and `mkl_fft/src/mklfft.h`. A real bug can surface
21+
here, so treat it like hand-written code, **not** boilerplate — review every
22+
finding.
23+
- **Cython-generated** `_pydfti.c` (from `mkl_fft/_pydfti.pyx`): `__Pyx_*` /
24+
`__pyx_pw_*` / `__pyx_tp_*` helpers and wrappers are boilerplate — findings here
25+
are ~always false positives. `__pyx_pf_*` functions are the C translation of our
26+
`.pyx` bodies; a real `.pyx` bug could surface there, so keep them in scope
27+
(Coverity can't see Python-level invariants — see the `_allocate_result`
28+
OVERRUN fixed in [gh-364](https://github.com/IntelPython/mkl_fft/pull/364)).
29+
30+
## Keeping triage durable: the Cython pin
31+
32+
A Cython *version* bump regenerates `_pydfti.c` wholesale, which churns the
33+
Coverity CIDs and silently drops their triage — the same boilerplate then returns
34+
under new CIDs. So **Cython is pinned in `coverity.yml`** (not `pyproject.toml`,
35+
so shipped wheels are unaffected). The pin works only because the build runs with
36+
`--no-build-isolation`; bumping it means re-triaging the boilerplate.
37+
38+
## Reducing the noise: a Project Component
39+
40+
**Project Settings → Components** buckets defects by a path regex. Define one to
41+
group (not hide) the Cython unit so it can be filtered out of view — path-based,
42+
so it survives regeneration:
43+
44+
- **Name:** `Generated-code` **Path regex:** `.*_pydfti\.c`
45+
46+
Do **not** group `mklfft.c` (or the `mkl_fft/src/*.h` helpers) — that is our DFTI
47+
logic, not boilerplate. Group only — do **not** mark it *ignored*, as that also
48+
drops the `__pyx_pf_*` bodies (see [declined](#evaluated-and-declined)).
49+
50+
## Review checklist
51+
52+
Don't blanket-ignore the generated file — prioritise instead:
53+
54+
1. **Findings in `mklfft.c` and `mkl_fft/src/*.h`** — review every one; this is
55+
our type-specialized oneMKL DFTI code and its inlined iterator/cache helpers,
56+
not boilerplate.
57+
2. **High/Medium findings in `__pyx_pf_*`** — verify against `_pydfti.pyx`; if it's
58+
a Python-level invariant Coverity can't see, mark `False Positive` with a
59+
reason. If it's a genuine defect, fix the `.pyx` (as with the `_allocate_result`
60+
OVERRUN).
61+
3. **Known false-positive families below** — carry the recorded disposition;
62+
match on **checker + mechanism**, not CID (CIDs reset on a Cython bump or an
63+
engine upgrade).
64+
65+
## Known false-positive families
66+
67+
Match on **checker + mechanism**, not CID (CIDs reset on a Cython bump or engine
68+
upgrade). Helper names below are from Cython 3.3.0 and vary between versions.
69+
All Minor severity, no runtime or security impact.
70+
71+
| Family | Checker | Why it's a false positive |
72+
| --- | --- | --- |
73+
| `__pyx_tp_traverse_..._scope_struct_...` (Cython `tp_traverse` slot for a genexpr/closure scope, e.g. from `_get_element_strides`) | DEADCODE | Cython emits a uniform base-type traversal preamble `e = __Pyx_call_type_traverse(o, 1, v, a); if (e) return e;`. The synthesized scope object derives from `object`, whose traverse contributes nothing, so the helper returns 0 and the early-return is dead. The preamble *is* needed for scopes that derive from a GC type. |
74+
75+
The DEADCODE family marks **Intentional**, with disposition **Ignore**.
76+
77+
## Evaluated and declined
78+
79+
- **Modeling files** correct the behavior of *called* functions; our FPs are
80+
intraprocedural (dead branches, compile-time-constant guards, `#if`), which
81+
models can't reach.
82+
- **Dropping the generated unit** (hard exclude), e.g. after `cov-build`:
83+
```bash
84+
cov-manage-emit --dir cov-int --tu-pattern "file('.*_pydfti\\.c')" delete
85+
```
86+
Also drops the `__pyx_pf_*` bodies, so it's disabled in favour of the checklist.

0 commit comments

Comments
 (0)