I am not clear with what strategy static analyzer takes to report warnings, but it seems not appropriate here.
BTW, is there any options to let clang not report warnings which lack sufficient evidience?
Basically that’s the default behavior, that’s why there’s no warning in the second case, but due to our old choice of the fundamental technique behind the analyzer, we have to detect this after the fact and we do that imperfectly
It works out pretty well on a lot of real-world code but it’s very easy to build simple examples on which it fails in embarrassing ways, and it can totally happen that your specific project is disproportionally affected by similar failures in these heuristics.
So if you run into a lot of these, you might want to disable these checks.
Normally the strategy is fully expressed by “path notes” attached to the warning. Basically every time you see a
note: Assuming ...
this means that the analyzer doesn’t have enough information to conclude that a certain branch is taken, so it has to consider both possibilities. Looks like there’s a separate bug with that: Compiler Explorer - it displays the “Assuming…” note correctly in the raw loop case but not in your range-based for-loop case