spaits updated this revision to Diff 504062.
spaits added a comment.

As @Szelethus has mentioned in his reply I tried to improve on the comment. I 
hope now it describes correctly what the new visitor is good for.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145069/new/

https://reviews.llvm.org/D145069

Files:
  clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp

Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
+++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp
@@ -452,29 +452,8 @@
   CallEventRef<> Call =
       BR.getStateManager().getCallEventManager().getCaller(SCtx, State);
 
-  // Optimistically suppress uninitialized value bugs that result
-  // from system headers having a chance to initialize the value
-  // but failing to do so. It's too unlikely a system header's fault.
-  // It's much more likely a situation in which the function has a failure
-  // mode that the user decided not to check. If we want to hunt such
-  // omitted checks, we should provide an explicit function-specific note
-  // describing the precondition under which the function isn't supposed to
-  // initialize its out-parameter, and additionally check that such
-  // precondition can actually be fulfilled on the current path.
-  if (Call->isInSystemHeader()) {
-    // We make an exception for system header functions that have no branches.
-    // Such functions unconditionally fail to initialize the variable.
-    // If they call other functions that have more paths within them,
-    // this suppression would still apply when we visit these inner functions.
-    // One common example of a standard function that doesn't ever initialize
-    // its out parameter is operator placement new; it's up to the follow-up
-    // constructor (if any) to initialize the memory.
-    if (!N->getStackFrame()->getCFG()->isLinear()) {
-      static int i = 0;
-      R.markInvalid(&i, nullptr);
-    }
+  if (Call->isInSystemHeader())
     return nullptr;
-  }
 
   if (const auto *MC = dyn_cast<ObjCMethodCall>(Call)) {
     // If we failed to construct a piece for self, we still want to check
@@ -492,6 +471,70 @@
   return maybeEmitNoteForParameters(R, *Call, N);
 }
 
+//===----------------------------------------------------------------------===//
+// Implementation of SuppressSystemHeaderWarningVistor.
+//===----------------------------------------------------------------------===//
+
+// This visitor suppresses warnings coming from inlined system
+// headers functions when we exit the call that have no branches.
+// This is a very primitive visitor. It flat-out suppresses every report that
+// have a node that matches all the conditions above.
+// It should be used carefully!
+//
+// A good example for the usage of this visitor is when we want to suppress
+// warnings when a system header function does not initialize their arguments.
+// It's too unlikely a system header's fault.
+// It's much more likely a situation in which the function has a failure
+// mode that the user decided not to check. If we want to hunt such
+// omitted checks, we should provide an explicit function-specific note
+// describing the precondition under which the function isn't supposed to
+// initialize its out-parameter, and additionally check that such
+// precondition can actually be fulfilled on the current path.
+//
+// System header functions that have no branches unconditionally fail to
+// initialize the variable.
+// If they call other functions that have more paths within them,
+// this suppression would still apply when we visit these inner functions.
+// One common example of a standard function that doesn't ever initialize
+// its out parameter is operator placement new; it's up to the follow-up
+// constructor (if any) to initialize the memory
+namespace {
+class SuppressSystemHeaderWarningVisitor : public BugReporterVisitor {
+public:
+  virtual PathDiagnosticPieceRef VisitNode(const ExplodedNode *,
+                                           BugReporterContext &,
+                                           PathSensitiveBugReport &) override;
+  void Profile(llvm::FoldingSetNodeID &ID) const override {
+    static int Tag = 0;
+    ID.AddPointer(&Tag);
+  }
+};
+} // namespace
+
+PathDiagnosticPieceRef
+SuppressSystemHeaderWarningVisitor::VisitNode(const ExplodedNode *Succ,
+                                              BugReporterContext &BRC,
+                                              PathSensitiveBugReport &BR) {
+  const LocationContext *Ctx = Succ->getLocationContext();
+  const StackFrameContext *SCtx = Ctx->getStackFrame();
+  ProgramStateRef State = Succ->getState();
+  auto CallExitLoc = Succ->getLocationAs<CallExitBegin>();
+
+  if (!CallExitLoc)
+    return nullptr;
+
+  CallEventRef<> Call =
+      BRC.getStateManager().getCallEventManager().getCaller(SCtx, State);
+
+  if (Call->isInSystemHeader()) {
+    if (!Succ->getStackFrame()->getCFG()->isLinear()) {
+      static int i = 0;
+      BR.markInvalid(&i, nullptr);
+    }
+  }
+  return nullptr;
+}
+
 //===----------------------------------------------------------------------===//
 // Implementation of NoStoreFuncVisitor.
 //===----------------------------------------------------------------------===//
@@ -2350,7 +2393,7 @@
         // Mark both the variable region and its contents as interesting.
         SVal V = LVState->getRawSVal(loc::MemRegionVal(R));
         Report.addVisitor<NoStoreFuncVisitor>(cast<SubRegion>(R), Opts.Kind);
-
+        Report.addVisitor<SuppressSystemHeaderWarningVisitor>();
         // When we got here, we do have something to track, and we will
         // interrupt.
         Result.FoundSomethingToTrack = true;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to