Index: clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp =================================================================== --- clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -452,6 +452,58 @@ CallEventRef<> Call = BR.getStateManager().getCallEventManager().getCaller(SCtx, State); + if (Call->isInSystemHeader()) + return nullptr; + + if (const auto *MC = dyn_cast(Call)) { + // If we failed to construct a piece for self, we still want to check + // whether the entity of interest is in a parameter. + if (PathDiagnosticPieceRef Piece = maybeEmitNoteForObjCSelf(R, *MC, N)) + return Piece; + } + + if (const auto *CCall = dyn_cast(Call)) { + // Do not generate diagnostics for not modified parameters in + // constructors. + return maybeEmitNoteForCXXThis(R, *CCall, N); + } + + return maybeEmitNoteForParameters(R, *Call, N); +} + +//===----------------------------------------------------------------------===// +// Implementation of SuppressSystemHeaderWarningVistor. +//===----------------------------------------------------------------------===// + +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(); + + // No diagnostic if region was modified inside the frame. + if (!CallExitLoc) + return nullptr; + + CallEventRef<> Call = + BRC.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. @@ -469,27 +521,13 @@ // 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()) { + + if (!Succ->getStackFrame()->getCFG()->isLinear()) { static int i = 0; - R.markInvalid(&i, nullptr); + BR.markInvalid(&i, nullptr); } - return nullptr; - } - - if (const auto *MC = dyn_cast(Call)) { - // If we failed to construct a piece for self, we still want to check - // whether the entity of interest is in a parameter. - if (PathDiagnosticPieceRef Piece = maybeEmitNoteForObjCSelf(R, *MC, N)) - return Piece; - } - - if (const auto *CCall = dyn_cast(Call)) { - // Do not generate diagnostics for not modified parameters in - // constructors. - return maybeEmitNoteForCXXThis(R, *CCall, N); } - - return maybeEmitNoteForParameters(R, *Call, N); + return nullptr; } //===----------------------------------------------------------------------===// @@ -2350,7 +2388,7 @@ // Mark both the variable region and its contents as interesting. SVal V = LVState->getRawSVal(loc::MemRegionVal(R)); Report.addVisitor(cast(R), Opts.Kind); - + Report.addVisitor(); // When we got here, we do have something to track, and we will // interrupt. Result.FoundSomethingToTrack = true;