I am trying to understand this clang-tidy warning: altera-id-dependent-backward-branch
that seems to be triggered by this loop.
for(; first != current; ++first)
The example I have is this code, that looks almost exactly as a perfectly reasonable implementation of std::uninitialized_fill_n
.
The static analyzer complains that:
error: backward branch (for loop) is ID-dependent due to variable reference to 'current' and may cause performance degradation [altera-id-dependent-backward-branch,-warnings-as-errors]
for(; current != first; ++first) {
uninitialized_fill_n(ForwardIt first, Size n, T const& v) {
ForwardIt current = first;
try {
for(; n > 0; ++current, --n) {
new (std::addressof(*current)) T(v);
}
return current;
} catch(...) {
for(; first != current; ++first) { // clang-tidy error here
std::addressof(*first)->~T();
}
throw;
}
}
I tried different ways to rewrite the code (for example making the loop backward), to suppress this warning but I couldn't.
Is there a standard way to rewrite the fallback (catch) loop in a way that is ok with altera-id-dependent-backward-branch
?
I am using clang-tidy 13.0.0
.
I also found another instance of the same warning in my code base (this is an implementation of a hash function, by Howard Hinnart):
auto fnv1a(void const* key, std::size_t len, std::size_t h) noexcept {
auto const *p = static_cast<unsigned char const*>(key);
unsigned char const* const e = p + len;
for(; p < e; ++p) { // warning here
h = (h ^ *p) * 1099511628211U; // prime
}
return h;
}
for(int i = 0; i = N; ++i) for(int j = 0; j != i; ++j)
produces this warning. – Slouch