Found while implementing #591. Filed rather than folded in: it is a
repository-wide tooling question, not part of that change.
What
clang-tidy 22.1.8 reports a finding on include/morph/render/locale_format.hpp
that this repository's own .clang-tidy asks for, and that nothing in the tree
suppresses. The header was otherwise untouched by any in-flight work when I
measured it.
Verification status
Reproduced, on master @ 0e3b8823, by running clang-tidy directly over a
one-line translation unit that includes the header. Not inferred from reading.
$ cat /tmp/tu.cpp
#include <morph/render/locale_format.hpp>
$ clang-tidy --version | head -3
LLVM (http://llvm.org/):
LLVM version 22.1.8
Optimized build.
$ clang-tidy --config-file=.clang-tidy /tmp/tu.cpp -- -std=c++23 -I include
include/morph/render/locale_format.hpp:457:29: error: possibly unsafe 'operator[]', consider bounds-safe alternatives [cppcoreguidelines-pro-bounds-avoid-unchecked-container-access,-warnings-as-errors]
Line 457 on that revision is the display loop in formatCanonicalNumber:
cppcoreguidelines-* is in the Checks list and WarningsAsErrors is "*",
so this is an error by the repository's own configuration, not a check I
enabled.
One methodological note, because it changes how to reproduce this. The
finding only appears when the header's path matches HeaderFilterRegex
(include/morph/.*). Pointing clang-tidy at a copy of the header under some
other path reports nothing at all, silently — which is how I initially
convinced myself a different check was not firing when it was.
What I did not verify
- Which clang-tidy version CI runs, and whether it reports this. This is the
load-bearing unknown. The check
cppcoreguidelines-pro-bounds-avoid-unchecked-container-access is recent; an
older clang-tidy does not have it, which would explain why a green CI has been
sitting on top of this. I did not read the workflow to find the pinned version
and I did not run CI's toolchain locally.
- Whether the rest of the tree has the same finding. I measured one header,
because it is the one I was working in. A tree-wide sweep is exactly what
would size this, and I am told a separate lane is already running one — this
issue should be reconciled with that lane's result rather than duplicated by
it.
- Whether this is a real safety problem.
i is bounded by the loop condition
three lines above, so the access is in fact in range. This is a suppression /
policy question, not a defect report.
Why it matters
Not because the indexing is wrong — it is not. It matters because the
repository has decided it wants clang-tidy as strict as possible (#580), and a
check that the configuration enables and that fires on first-party code is
either a finding to fix, a check to disable deliberately, or a suppression to
write with a reason. Which of the three it is has not been recorded anywhere,
and the difference only shows up when someone upgrades the compiler on the CI
image.
The existing code already knows about this check: the same header carries
// i is bounded by the loop condition.
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-avoid-unchecked-container-access)
twice, in groupingIsWellPlaced and in normalizeLocaleNumber. So it fires in
CI at least sometimes, or did once — and formatCanonicalNumber's identical
pattern simply never got the same treatment.
Incidental note
PR #630 rewrites that loop for unrelated reasons (#591 needed the digits mapped
through a base rather than copied), and the rewrite happens to use a range-for
with a separate index counter, so the finding is gone on that branch. That
is a side effect of the rewrite, not a fix, and it says nothing about the rest
of the tree. This issue is about the policy and the sweep, not about that line.
What would change the verdict
- Close as fixed when a tree-wide clang-tidy run at the version CI pins
reports no
cppcoreguidelines-pro-bounds-avoid-unchecked-container-access outside
suppressions that state a reason.
- Close as invalid if CI's pinned clang-tidy does not implement this check
and the project decides not to move to a version that does — in which case the
two existing NOLINTNEXTLINEs for it in this same header are dead weight and
should go, which is a finding in itself.
- Re-open / widen if the tree-wide sweep finds this in more than a handful
of places, which would make it a configuration decision rather than a few
annotations.
Found while implementing #591. Filed rather than folded in: it is a
repository-wide tooling question, not part of that change.
What
clang-tidy22.1.8 reports a finding oninclude/morph/render/locale_format.hppthat this repository's own
.clang-tidyasks for, and that nothing in the treesuppresses. The header was otherwise untouched by any in-flight work when I
measured it.
Verification status
Reproduced, on
master@0e3b8823, by running clang-tidy directly over aone-line translation unit that includes the header. Not inferred from reading.
Line 457 on that revision is the display loop in
formatCanonicalNumber:cppcoreguidelines-*is in theCheckslist andWarningsAsErrorsis"*",so this is an error by the repository's own configuration, not a check I
enabled.
One methodological note, because it changes how to reproduce this. The
finding only appears when the header's path matches
HeaderFilterRegex(
include/morph/.*). Pointing clang-tidy at a copy of the header under someother path reports nothing at all, silently — which is how I initially
convinced myself a different check was not firing when it was.
What I did not verify
load-bearing unknown. The check
cppcoreguidelines-pro-bounds-avoid-unchecked-container-accessis recent; anolder clang-tidy does not have it, which would explain why a green CI has been
sitting on top of this. I did not read the workflow to find the pinned version
and I did not run CI's toolchain locally.
because it is the one I was working in. A tree-wide sweep is exactly what
would size this, and I am told a separate lane is already running one — this
issue should be reconciled with that lane's result rather than duplicated by
it.
iis bounded by the loop conditionthree lines above, so the access is in fact in range. This is a suppression /
policy question, not a defect report.
Why it matters
Not because the indexing is wrong — it is not. It matters because the
repository has decided it wants clang-tidy as strict as possible (#580), and a
check that the configuration enables and that fires on first-party code is
either a finding to fix, a check to disable deliberately, or a suppression to
write with a reason. Which of the three it is has not been recorded anywhere,
and the difference only shows up when someone upgrades the compiler on the CI
image.
The existing code already knows about this check: the same header carries
twice, in
groupingIsWellPlacedand innormalizeLocaleNumber. So it fires inCI at least sometimes, or did once — and
formatCanonicalNumber's identicalpattern simply never got the same treatment.
Incidental note
PR #630 rewrites that loop for unrelated reasons (#591 needed the digits mapped
through a base rather than copied), and the rewrite happens to use a range-
forwith a separate index counter, so the finding is gone on that branch. That
is a side effect of the rewrite, not a fix, and it says nothing about the rest
of the tree. This issue is about the policy and the sweep, not about that line.
What would change the verdict
reports no
cppcoreguidelines-pro-bounds-avoid-unchecked-container-accessoutsidesuppressions that state a reason.
and the project decides not to move to a version that does — in which case the
two existing
NOLINTNEXTLINEs for it in this same header are dead weight andshould go, which is a finding in itself.
of places, which would make it a configuration decision rather than a few
annotations.