Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -1830,6 +1830,11 @@ return nullptr; if (ControlDeps.isControlDependent(OriginB, NB)) { + // We don't really want to explain for range loops. Evidence suggests that + // the only thing that leads to is the addition of calls to operator!=. + if (isa(NB->getTerminator())) + return nullptr; + if (const Expr *Condition = NB->getLastCondition()) { // Keeping track of the already tracked conditions on a visitor level // isn't sufficient, because a new visitor is created for each tracked Index: clang/test/Analysis/track-control-dependency-conditions.cpp =================================================================== --- clang/test/Analysis/track-control-dependency-conditions.cpp +++ clang/test/Analysis/track-control-dependency-conditions.cpp @@ -407,6 +407,40 @@ } } // end of namespace condition_written_in_nested_stackframe_before_assignment +namespace dont_explain_foreach_loops { + +struct Iterator { + int *pos; + bool operator!=(Iterator other) const { + return pos && other.pos && pos != other.pos; + } + int operator*(); + Iterator operator++(); +}; + +struct Container { + Iterator begin(); + Iterator end(); +}; + +void f(Container Cont) { + int flag = 0; + int *x = 0; // expected-note{{'x' initialized to a null pointer value}} + for (int i : Cont) + if (i) // expected-note {{Assuming 'i' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'i'}} + flag = i; + + if (flag) // expected-note{{'flag' is not equal to 0}} + // expected-note@-1{{Taking true branch}} + // debug-note@-2{{Tracking condition 'flag'}} + *x = 5; // expected-warning{{Dereference of null pointer}} + // expected-note@-1{{Dereference of null pointer}} +} + +} // end of namespace dont_explain_foreach_loops + namespace collapse_point_not_in_condition_bool { [[noreturn]] void halt();