Severity: low
Domain: analysis
Status: VERIFIED — read against a210d34 on 2026-08-10
Suggested labels: policy-violation, analysis
Summary
Log2() calls itself, violating the no-recursion rule in AGENTS.md. It is also a
non-static member function, so it cannot be used in a constant expression without an object.
Location
numerical/analysis/FastFourierTransform.hpp
Evidence
constexpr std::size_t Log2(std::size_t n)
{
return (n <= 1) ? 0 : 1 + Log2(n >> 1);
}
Why it matters
Deterministic stack usage is a hard requirement for the target platforms. Although the depth here is
bounded by log₂(SIZE_MAX) and the compiler will usually fold it at -O3, the rule exists so that
stack bounds are provable without relying on optimiser behaviour.
Suggested fix
Iterative form, and make it static:
static constexpr std::size_t Log2(std::size_t n) noexcept
{
std::size_t result{ 0 };
while (n > 1)
{
n >>= 1;
++result;
}
return result;
}
Or use std::bit_width(n) - 1 from <bit> (C++20) for power-of-two inputs.
Notes
Consider a repository-wide grep for self-recursive functions as part of the same change.
Severity: low
Domain: analysis
Status: VERIFIED — read against
a210d34on 2026-08-10Suggested labels:
policy-violation,analysisSummary
Log2()calls itself, violating the no-recursion rule in AGENTS.md. It is also anon-static member function, so it cannot be used in a constant expression without an object.
Location
numerical/analysis/FastFourierTransform.hpp
Evidence
Why it matters
Deterministic stack usage is a hard requirement for the target platforms. Although the depth here is
bounded by
log₂(SIZE_MAX)and the compiler will usually fold it at-O3, the rule exists so thatstack bounds are provable without relying on optimiser behaviour.
Suggested fix
Iterative form, and make it
static:Or use
std::bit_width(n) - 1from<bit>(C++20) for power-of-two inputs.Notes
Consider a repository-wide grep for self-recursive functions as part of the same change.