]> granicus.if.org Git - clang/commitdiff
[analyzer] Don't track the condition of foreach loops
authorKristof Umann <dkszelethus@gmail.com>
Thu, 22 Aug 2019 02:44:19 +0000 (02:44 +0000)
committerKristof Umann <dkszelethus@gmail.com>
Thu, 22 Aug 2019 02:44:19 +0000 (02:44 +0000)
As discussed on the mailing list, notes originating from the tracking of foreach
loop conditions are always meaningless.

Differential Revision: https://reviews.llvm.org/D66131

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@369613 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
test/Analysis/track-control-dependency-conditions.cpp

index 20af02842c1afbeace329f8b5eaf05d162eecfbf..b223c6fb496b79c0155f67dc709421bdd715b78d 100644 (file)
@@ -1800,6 +1800,11 @@ PathDiagnosticPieceRef TrackControlDependencyCondBRVisitor::VisitNode(
     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<CXXForRangeStmt>(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 e95cc7cbb1ec5c6427995c162e724d85ac4cdedd..bd391abdcc0c7edc983c0b505336b2d155fd3c57 100644 (file)
@@ -407,6 +407,39 @@ void f() {
 }
 } // 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-re{{{{^}}'x' initialized to a null pointer value{{$}}}}
+  for (int i : Cont)
+    if (i) // expected-note-re   {{{{^}}Assuming 'i' is not equal to 0{{$}}}}
+           // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
+           // debug-note-re@-2{{{{^}}Tracking condition 'i'{{$}}}}
+      flag = i;
+
+  if (flag) // expected-note-re{{{{^}}'flag' is not equal to 0{{$}}}}
+            // expected-note-re@-1{{{{^}}Taking true branch{{$}}}}
+            // debug-note-re@-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 condition_lambda_capture_by_reference_last_write {
 int getInt();