balazske created this revision.
Herald added subscribers: manas, steakhal, ASDenysPetrov, martong, gamesh411, 
dkrupp, donat.nagy, Szelethus, mikhail.ramalho, a.sidorin, szepet, 
baloghadamsoftware, xazax.hun, whisperity.
Herald added a reviewer: Szelethus.
balazske requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

The multiple note tag functions are replaced with one that
works for all cases.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D106262

Files:
  clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
  clang/test/Analysis/stream-note.c

Index: clang/test/Analysis/stream-note.c
===================================================================
--- clang/test/Analysis/stream-note.c
+++ clang/test/Analysis/stream-note.c
@@ -33,12 +33,12 @@
 // expected-note@-2 {{Opened stream never closed. Potential resource leak}}
 
 void check_note_freopen() {
-  FILE *F = fopen("file", "r"); // expected-note {{Stream opened here}}
+  FILE *F = fopen("file", "r");
   if (!F)
     // expected-note@-1 {{'F' is non-null}}
     // expected-note@-2 {{Taking false branch}}
     return;
-  F = freopen(0, "w", F); // expected-note {{Stream reopened here}}
+  F = freopen(0, "w", F); // expected-note {{Stream opened here}}
   if (!F)
     // expected-note@-1 {{'F' is non-null}}
     // expected-note@-2 {{Taking false branch}}
Index: clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
+++ clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
@@ -231,8 +231,6 @@
   /// If true, evaluate special testing stream functions.
   bool TestMode = false;
 
-  const BugType *getBT_StreamEof() const { return &BT_StreamEof; }
-
 private:
   CallDescriptionMap<FnDescription> FnDescriptions = {
       {{"fopen"}, {nullptr, &StreamChecker::evalFopen, ArgNone}},
@@ -376,37 +374,29 @@
     return FnDescriptions.lookup(Call);
   }
 
-  /// Generate a message for BugReporterVisitor if the stored symbol is
-  /// marked as interesting by the actual bug report.
-  // FIXME: Use lambda instead.
-  struct NoteFn {
-    const BugType *BT_ResourceLeak;
-    SymbolRef StreamSym;
-    std::string Message;
-
-    std::string operator()(PathSensitiveBugReport &BR) const {
-      if (BR.isInteresting(StreamSym) && &BR.getBugType() == BT_ResourceLeak)
-        return Message;
-
-      return "";
-    }
-  };
-
   const NoteTag *constructNoteTag(CheckerContext &C, SymbolRef StreamSym,
-                                  const std::string &Message) const {
-    return C.getNoteTag(NoteFn{&BT_ResourceLeak, StreamSym, Message});
-  }
-
-  const NoteTag *constructSetEofNoteTag(CheckerContext &C,
-                                        SymbolRef StreamSym) const {
-    return C.getNoteTag([this, StreamSym](PathSensitiveBugReport &BR) {
-      if (!BR.isInteresting(StreamSym) ||
-          &BR.getBugType() != this->getBT_StreamEof())
+                                  const BugType *BT) const {
+    const char *Message;
+    if (BT == &BT_UseAfterClose)
+      Message = "Stream closed here";
+    else if (BT == &BT_UseAfterOpenFailed)
+      Message = "Assuming opening the stream fails here";
+    else if (BT == &BT_IndeterminatePosition)
+      Message = "Assuming this stream operation fails";
+    else if (BT == &BT_StreamEof)
+      Message = "Assuming stream reaches end-of-file here";
+    else if (BT == &BT_ResourceLeak)
+      Message = "Stream opened here";
+    else
+      llvm_unreachable("Invalid bug type for note tag");
+
+    return C.getNoteTag([StreamSym, BT, Message](PathSensitiveBugReport &BR) {
+      if (!BR.isInteresting(StreamSym) || &BR.getBugType() != BT)
         return "";
 
       BR.markNotInteresting(StreamSym);
 
-      return "Assuming stream reaches end-of-file here";
+      return Message;
     });
   }
 
@@ -499,8 +489,7 @@
   StateNull =
       StateNull->set<StreamMap>(RetSym, StreamState::getOpenFailed(Desc));
 
-  C.addTransition(StateNotNull,
-                  constructNoteTag(C, RetSym, "Stream opened here"));
+  C.addTransition(StateNotNull, constructNoteTag(C, RetSym, &BT_ResourceLeak));
   C.addTransition(StateNull);
 }
 
@@ -557,7 +546,7 @@
       StateRetNull->set<StreamMap>(StreamSym, StreamState::getOpenFailed(Desc));
 
   C.addTransition(StateRetNotNull,
-                  constructNoteTag(C, StreamSym, "Stream reopened here"));
+                  constructNoteTag(C, StreamSym, &BT_ResourceLeak));
   C.addTransition(StateRetNull);
 }
 
@@ -705,7 +694,7 @@
   StreamState NewSS = StreamState::getOpened(Desc, NewES, !NewES.isFEof());
   StateFailed = StateFailed->set<StreamMap>(StreamSym, NewSS);
   if (IsFread && OldSS->ErrorState != ErrorFEof)
-    C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
+    C.addTransition(StateFailed, constructNoteTag(C, StreamSym, &BT_StreamEof));
   else
     C.addTransition(StateFailed);
 }
@@ -766,7 +755,7 @@
       StreamState::getOpened(Desc, ErrorNone | ErrorFEof | ErrorFError, true));
 
   C.addTransition(StateNotFailed);
-  C.addTransition(StateFailed, constructSetEofNoteTag(C, StreamSym));
+  C.addTransition(StateFailed, constructNoteTag(C, StreamSym, &BT_StreamEof));
 }
 
 void StreamChecker::evalClearerr(const FnDescription *Desc,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to