1//===- BugReporterVisitors.cpp - Helpers for reporting bugs ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9//  This file defines a set of BugReporter "visitors" which can be used to
10//  enhance the diagnostics reported for a bug.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
15#include "clang/AST/ASTContext.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
18#include "clang/AST/DeclCXX.h"
19#include "clang/AST/Expr.h"
20#include "clang/AST/ExprCXX.h"
21#include "clang/AST/ExprObjC.h"
22#include "clang/AST/Stmt.h"
23#include "clang/AST/Type.h"
24#include "clang/ASTMatchers/ASTMatchFinder.h"
25#include "clang/Analysis/Analyses/Dominators.h"
26#include "clang/Analysis/AnalysisDeclContext.h"
27#include "clang/Analysis/CFG.h"
28#include "clang/Analysis/CFGStmtMap.h"
29#include "clang/Analysis/PathDiagnostic.h"
30#include "clang/Analysis/ProgramPoint.h"
31#include "clang/Basic/IdentifierTable.h"
32#include "clang/Basic/LLVM.h"
33#include "clang/Basic/SourceLocation.h"
34#include "clang/Basic/SourceManager.h"
35#include "clang/Lex/Lexer.h"
36#include "clang/StaticAnalyzer/Core/AnalyzerOptions.h"
37#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
38#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
39#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
40#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
41#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
42#include "clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h"
43#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
44#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
45#include "clang/StaticAnalyzer/Core/PathSensitive/SMTConv.h"
46#include "clang/StaticAnalyzer/Core/PathSensitive/SValBuilder.h"
47#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
48#include "llvm/ADT/ArrayRef.h"
49#include "llvm/ADT/STLExtras.h"
50#include "llvm/ADT/SmallPtrSet.h"
51#include "llvm/ADT/SmallString.h"
52#include "llvm/ADT/SmallVector.h"
53#include "llvm/ADT/StringExtras.h"
54#include "llvm/ADT/StringRef.h"
55#include "llvm/Support/Casting.h"
56#include "llvm/Support/ErrorHandling.h"
57#include "llvm/Support/raw_ostream.h"
58#include <cassert>
59#include <deque>
60#include <memory>
61#include <optional>
62#include <string>
63#include <utility>
64
65using namespace clang;
66using namespace ento;
67using namespace bugreporter;
68
69//===----------------------------------------------------------------------===//
70// Utility functions.
71//===----------------------------------------------------------------------===//
72
73static const Expr *peelOffPointerArithmetic(const BinaryOperator *B) {
74  if (B->isAdditiveOp() && B->getType()->isPointerType()) {
75    if (B->getLHS()->getType()->isPointerType()) {
76      return B->getLHS();
77    } else if (B->getRHS()->getType()->isPointerType()) {
78      return B->getRHS();
79    }
80  }
81  return nullptr;
82}
83
84/// \return A subexpression of @c Ex which represents the
85/// expression-of-interest.
86static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N);
87
88/// Given that expression S represents a pointer that would be dereferenced,
89/// try to find a sub-expression from which the pointer came from.
90/// This is used for tracking down origins of a null or undefined value:
91/// "this is null because that is null because that is null" etc.
92/// We wipe away field and element offsets because they merely add offsets.
93/// We also wipe away all casts except lvalue-to-rvalue casts, because the
94/// latter represent an actual pointer dereference; however, we remove
95/// the final lvalue-to-rvalue cast before returning from this function
96/// because it demonstrates more clearly from where the pointer rvalue was
97/// loaded. Examples:
98///   x->y.z      ==>  x (lvalue)
99///   foo()->y.z  ==>  foo() (rvalue)
100const Expr *bugreporter::getDerefExpr(const Stmt *S) {
101  const auto *E = dyn_cast<Expr>(S);
102  if (!E)
103    return nullptr;
104
105  while (true) {
106    if (const auto *CE = dyn_cast<CastExpr>(E)) {
107      if (CE->getCastKind() == CK_LValueToRValue) {
108        // This cast represents the load we're looking for.
109        break;
110      }
111      E = CE->getSubExpr();
112    } else if (const auto *B = dyn_cast<BinaryOperator>(E)) {
113      // Pointer arithmetic: '*(x + 2)' -> 'x') etc.
114      if (const Expr *Inner = peelOffPointerArithmetic(B)) {
115        E = Inner;
116      } else {
117        // Probably more arithmetic can be pattern-matched here,
118        // but for now give up.
119        break;
120      }
121    } else if (const auto *U = dyn_cast<UnaryOperator>(E)) {
122      if (U->getOpcode() == UO_Deref || U->getOpcode() == UO_AddrOf ||
123          (U->isIncrementDecrementOp() && U->getType()->isPointerType())) {
124        // Operators '*' and '&' don't actually mean anything.
125        // We look at casts instead.
126        E = U->getSubExpr();
127      } else {
128        // Probably more arithmetic can be pattern-matched here,
129        // but for now give up.
130        break;
131      }
132    }
133    // Pattern match for a few useful cases: a[0], p->f, *p etc.
134    else if (const auto *ME = dyn_cast<MemberExpr>(E)) {
135      E = ME->getBase();
136    } else if (const auto *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
137      E = IvarRef->getBase();
138    } else if (const auto *AE = dyn_cast<ArraySubscriptExpr>(E)) {
139      E = AE->getBase();
140    } else if (const auto *PE = dyn_cast<ParenExpr>(E)) {
141      E = PE->getSubExpr();
142    } else if (const auto *FE = dyn_cast<FullExpr>(E)) {
143      E = FE->getSubExpr();
144    } else {
145      // Other arbitrary stuff.
146      break;
147    }
148  }
149
150  // Special case: remove the final lvalue-to-rvalue cast, but do not recurse
151  // deeper into the sub-expression. This way we return the lvalue from which
152  // our pointer rvalue was loaded.
153  if (const auto *CE = dyn_cast<ImplicitCastExpr>(E))
154    if (CE->getCastKind() == CK_LValueToRValue)
155      E = CE->getSubExpr();
156
157  return E;
158}
159
160static const MemRegion *
161getLocationRegionIfReference(const Expr *E, const ExplodedNode *N,
162                             bool LookingForReference = true) {
163  if (const auto *DR = dyn_cast<DeclRefExpr>(E)) {
164    if (const auto *VD = dyn_cast<VarDecl>(DR->getDecl())) {
165      if (LookingForReference && !VD->getType()->isReferenceType())
166        return nullptr;
167      return N->getState()
168          ->getLValue(VD, N->getLocationContext())
169          .getAsRegion();
170    }
171  }
172
173  // FIXME: This does not handle other kinds of null references,
174  // for example, references from FieldRegions:
175  //   struct Wrapper { int &ref; };
176  //   Wrapper w = { *(int *)0 };
177  //   w.ref = 1;
178
179  return nullptr;
180}
181
182/// Comparing internal representations of symbolic values (via
183/// SVal::operator==()) is a valid way to check if the value was updated,
184/// unless it's a LazyCompoundVal that may have a different internal
185/// representation every time it is loaded from the state. In this function we
186/// do an approximate comparison for lazy compound values, checking that they
187/// are the immediate snapshots of the tracked region's bindings within the
188/// node's respective states but not really checking that these snapshots
189/// actually contain the same set of bindings.
190static bool hasVisibleUpdate(const ExplodedNode *LeftNode, SVal LeftVal,
191                             const ExplodedNode *RightNode, SVal RightVal) {
192  if (LeftVal == RightVal)
193    return true;
194
195  const auto LLCV = LeftVal.getAs<nonloc::LazyCompoundVal>();
196  if (!LLCV)
197    return false;
198
199  const auto RLCV = RightVal.getAs<nonloc::LazyCompoundVal>();
200  if (!RLCV)
201    return false;
202
203  return LLCV->getRegion() == RLCV->getRegion() &&
204    LLCV->getStore() == LeftNode->getState()->getStore() &&
205    RLCV->getStore() == RightNode->getState()->getStore();
206}
207
208static std::optional<SVal> getSValForVar(const Expr *CondVarExpr,
209                                         const ExplodedNode *N) {
210  ProgramStateRef State = N->getState();
211  const LocationContext *LCtx = N->getLocationContext();
212
213  assert(CondVarExpr);
214  CondVarExpr = CondVarExpr->IgnoreImpCasts();
215
216  // The declaration of the value may rely on a pointer so take its l-value.
217  // FIXME: As seen in VisitCommonDeclRefExpr, sometimes DeclRefExpr may
218  // evaluate to a FieldRegion when it refers to a declaration of a lambda
219  // capture variable. We most likely need to duplicate that logic here.
220  if (const auto *DRE = dyn_cast<DeclRefExpr>(CondVarExpr))
221    if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl()))
222      return State->getSVal(State->getLValue(VD, LCtx));
223
224  if (const auto *ME = dyn_cast<MemberExpr>(CondVarExpr))
225    if (const auto *FD = dyn_cast<FieldDecl>(ME->getMemberDecl()))
226      if (auto FieldL = State->getSVal(ME, LCtx).getAs<Loc>())
227        return State->getRawSVal(*FieldL, FD->getType());
228
229  return std::nullopt;
230}
231
232static std::optional<const llvm::APSInt *>
233getConcreteIntegerValue(const Expr *CondVarExpr, const ExplodedNode *N) {
234
235  if (std::optional<SVal> V = getSValForVar(CondVarExpr, N))
236    if (auto CI = V->getAs<nonloc::ConcreteInt>())
237      return &CI->getValue();
238  return std::nullopt;
239}
240
241static bool isVarAnInterestingCondition(const Expr *CondVarExpr,
242                                        const ExplodedNode *N,
243                                        const PathSensitiveBugReport *B) {
244  // Even if this condition is marked as interesting, it isn't *that*
245  // interesting if it didn't happen in a nested stackframe, the user could just
246  // follow the arrows.
247  if (!B->getErrorNode()->getStackFrame()->isParentOf(N->getStackFrame()))
248    return false;
249
250  if (std::optional<SVal> V = getSValForVar(CondVarExpr, N))
251    if (std::optional<bugreporter::TrackingKind> K =
252            B->getInterestingnessKind(*V))
253      return *K == bugreporter::TrackingKind::Condition;
254
255  return false;
256}
257
258static bool isInterestingExpr(const Expr *E, const ExplodedNode *N,
259                              const PathSensitiveBugReport *B) {
260  if (std::optional<SVal> V = getSValForVar(E, N))
261    return B->getInterestingnessKind(*V).has_value();
262  return false;
263}
264
265/// \return name of the macro inside the location \p Loc.
266static StringRef getMacroName(SourceLocation Loc,
267    BugReporterContext &BRC) {
268  return Lexer::getImmediateMacroName(
269      Loc,
270      BRC.getSourceManager(),
271      BRC.getASTContext().getLangOpts());
272}
273
274/// \return Whether given spelling location corresponds to an expansion
275/// of a function-like macro.
276static bool isFunctionMacroExpansion(SourceLocation Loc,
277                                const SourceManager &SM) {
278  if (!Loc.isMacroID())
279    return false;
280  while (SM.isMacroArgExpansion(Loc))
281    Loc = SM.getImmediateExpansionRange(Loc).getBegin();
282  std::pair<FileID, unsigned> TLInfo = SM.getDecomposedLoc(Loc);
283  SrcMgr::SLocEntry SE = SM.getSLocEntry(TLInfo.first);
284  const SrcMgr::ExpansionInfo &EInfo = SE.getExpansion();
285  return EInfo.isFunctionMacroExpansion();
286}
287
288/// \return Whether \c RegionOfInterest was modified at \p N,
289/// where \p ValueAfter is \c RegionOfInterest's value at the end of the
290/// stack frame.
291static bool wasRegionOfInterestModifiedAt(const SubRegion *RegionOfInterest,
292                                          const ExplodedNode *N,
293                                          SVal ValueAfter) {
294  ProgramStateRef State = N->getState();
295  ProgramStateManager &Mgr = N->getState()->getStateManager();
296
297  if (!N->getLocationAs<PostStore>() && !N->getLocationAs<PostInitializer>() &&
298      !N->getLocationAs<PostStmt>())
299    return false;
300
301  // Writing into region of interest.
302  if (auto PS = N->getLocationAs<PostStmt>())
303    if (auto *BO = PS->getStmtAs<BinaryOperator>())
304      if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(
305                                      N->getSVal(BO->getLHS()).getAsRegion()))
306        return true;
307
308  // SVal after the state is possibly different.
309  SVal ValueAtN = N->getState()->getSVal(RegionOfInterest);
310  if (!Mgr.getSValBuilder()
311           .areEqual(State, ValueAtN, ValueAfter)
312           .isConstrainedTrue() &&
313      (!ValueAtN.isUndef() || !ValueAfter.isUndef()))
314    return true;
315
316  return false;
317}
318
319//===----------------------------------------------------------------------===//
320// Implementation of BugReporterVisitor.
321//===----------------------------------------------------------------------===//
322
323PathDiagnosticPieceRef BugReporterVisitor::getEndPath(BugReporterContext &,
324                                                      const ExplodedNode *,
325                                                      PathSensitiveBugReport &) {
326  return nullptr;
327}
328
329void BugReporterVisitor::finalizeVisitor(BugReporterContext &,
330                                         const ExplodedNode *,
331                                         PathSensitiveBugReport &) {}
332
333PathDiagnosticPieceRef
334BugReporterVisitor::getDefaultEndPath(const BugReporterContext &BRC,
335                                      const ExplodedNode *EndPathNode,
336                                      const PathSensitiveBugReport &BR) {
337  PathDiagnosticLocation L = BR.getLocation();
338  const auto &Ranges = BR.getRanges();
339
340  // Only add the statement itself as a range if we didn't specify any
341  // special ranges for this report.
342  auto P = std::make_shared<PathDiagnosticEventPiece>(
343      L, BR.getDescription(), Ranges.begin() == Ranges.end());
344  for (SourceRange Range : Ranges)
345    P->addRange(Range);
346
347  return P;
348}
349
350//===----------------------------------------------------------------------===//
351// Implementation of NoStateChangeFuncVisitor.
352//===----------------------------------------------------------------------===//
353
354bool NoStateChangeFuncVisitor::isModifiedInFrame(const ExplodedNode *N) {
355  const LocationContext *Ctx = N->getLocationContext();
356  const StackFrameContext *SCtx = Ctx->getStackFrame();
357  if (!FramesModifyingCalculated.count(SCtx))
358    findModifyingFrames(N);
359  return FramesModifying.count(SCtx);
360}
361
362void NoStateChangeFuncVisitor::markFrameAsModifying(
363    const StackFrameContext *SCtx) {
364  while (!SCtx->inTopFrame()) {
365    auto p = FramesModifying.insert(SCtx);
366    if (!p.second)
367      break; // Frame and all its parents already inserted.
368
369    SCtx = SCtx->getParent()->getStackFrame();
370  }
371}
372
373static const ExplodedNode *getMatchingCallExitEnd(const ExplodedNode *N) {
374  assert(N->getLocationAs<CallEnter>());
375  // The stackframe of the callee is only found in the nodes succeeding
376  // the CallEnter node. CallEnter's stack frame refers to the caller.
377  const StackFrameContext *OrigSCtx = N->getFirstSucc()->getStackFrame();
378
379  // Similarly, the nodes preceding CallExitEnd refer to the callee's stack
380  // frame.
381  auto IsMatchingCallExitEnd = [OrigSCtx](const ExplodedNode *N) {
382    return N->getLocationAs<CallExitEnd>() &&
383           OrigSCtx == N->getFirstPred()->getStackFrame();
384  };
385  while (N && !IsMatchingCallExitEnd(N)) {
386    assert(N->succ_size() <= 1 &&
387           "This function is to be used on the trimmed ExplodedGraph!");
388    N = N->getFirstSucc();
389  }
390  return N;
391}
392
393void NoStateChangeFuncVisitor::findModifyingFrames(
394    const ExplodedNode *const CallExitBeginN) {
395
396  assert(CallExitBeginN->getLocationAs<CallExitBegin>());
397
398  const StackFrameContext *const OriginalSCtx =
399      CallExitBeginN->getLocationContext()->getStackFrame();
400
401  const ExplodedNode *CurrCallExitBeginN = CallExitBeginN;
402  const StackFrameContext *CurrentSCtx = OriginalSCtx;
403
404  for (const ExplodedNode *CurrN = CallExitBeginN; CurrN;
405       CurrN = CurrN->getFirstPred()) {
406    // Found a new inlined call.
407    if (CurrN->getLocationAs<CallExitBegin>()) {
408      CurrCallExitBeginN = CurrN;
409      CurrentSCtx = CurrN->getStackFrame();
410      FramesModifyingCalculated.insert(CurrentSCtx);
411      // We won't see a change in between two identical exploded nodes: skip.
412      continue;
413    }
414
415    if (auto CE = CurrN->getLocationAs<CallEnter>()) {
416      if (const ExplodedNode *CallExitEndN = getMatchingCallExitEnd(CurrN))
417        if (wasModifiedInFunction(CurrN, CallExitEndN))
418          markFrameAsModifying(CurrentSCtx);
419
420      // We exited this inlined call, lets actualize the stack frame.
421      CurrentSCtx = CurrN->getStackFrame();
422
423      // Stop calculating at the current function, but always regard it as
424      // modifying, so we can avoid notes like this:
425      //   void f(Foo &F) {
426      //     F.field = 0; // note: 0 assigned to 'F.field'
427      //                  // note: returning without writing to 'F.field'
428      //   }
429      if (CE->getCalleeContext() == OriginalSCtx) {
430        markFrameAsModifying(CurrentSCtx);
431        break;
432      }
433    }
434
435    if (wasModifiedBeforeCallExit(CurrN, CurrCallExitBeginN))
436      markFrameAsModifying(CurrentSCtx);
437  }
438}
439
440PathDiagnosticPieceRef NoStateChangeFuncVisitor::VisitNode(
441    const ExplodedNode *N, BugReporterContext &BR, PathSensitiveBugReport &R) {
442
443  const LocationContext *Ctx = N->getLocationContext();
444  const StackFrameContext *SCtx = Ctx->getStackFrame();
445  ProgramStateRef State = N->getState();
446  auto CallExitLoc = N->getLocationAs<CallExitBegin>();
447
448  // No diagnostic if region was modified inside the frame.
449  if (!CallExitLoc || isModifiedInFrame(N))
450    return nullptr;
451
452  CallEventRef<> Call =
453      BR.getStateManager().getCallEventManager().getCaller(SCtx, State);
454
455  // Optimistically suppress uninitialized value bugs that result
456  // from system headers having a chance to initialize the value
457  // but failing to do so. It's too unlikely a system header's fault.
458  // It's much more likely a situation in which the function has a failure
459  // mode that the user decided not to check. If we want to hunt such
460  // omitted checks, we should provide an explicit function-specific note
461  // describing the precondition under which the function isn't supposed to
462  // initialize its out-parameter, and additionally check that such
463  // precondition can actually be fulfilled on the current path.
464  if (Call->isInSystemHeader()) {
465    // We make an exception for system header functions that have no branches.
466    // Such functions unconditionally fail to initialize the variable.
467    // If they call other functions that have more paths within them,
468    // this suppression would still apply when we visit these inner functions.
469    // One common example of a standard function that doesn't ever initialize
470    // its out parameter is operator placement new; it's up to the follow-up
471    // constructor (if any) to initialize the memory.
472    if (!N->getStackFrame()->getCFG()->isLinear()) {
473      static int i = 0;
474      R.markInvalid(&i, nullptr);
475    }
476    return nullptr;
477  }
478
479  if (const auto *MC = dyn_cast<ObjCMethodCall>(Call)) {
480    // If we failed to construct a piece for self, we still want to check
481    // whether the entity of interest is in a parameter.
482    if (PathDiagnosticPieceRef Piece = maybeEmitNoteForObjCSelf(R, *MC, N))
483      return Piece;
484  }
485
486  if (const auto *CCall = dyn_cast<CXXConstructorCall>(Call)) {
487    // Do not generate diagnostics for not modified parameters in
488    // constructors.
489    return maybeEmitNoteForCXXThis(R, *CCall, N);
490  }
491
492  return maybeEmitNoteForParameters(R, *Call, N);
493}
494
495//===----------------------------------------------------------------------===//
496// Implementation of NoStoreFuncVisitor.
497//===----------------------------------------------------------------------===//
498
499namespace {
500/// Put a diagnostic on return statement of all inlined functions
501/// for which  the region of interest \p RegionOfInterest was passed into,
502/// but not written inside, and it has caused an undefined read or a null
503/// pointer dereference outside.
504class NoStoreFuncVisitor final : public NoStateChangeFuncVisitor {
505  const SubRegion *RegionOfInterest;
506  MemRegionManager &MmrMgr;
507  const SourceManager &SM;
508  const PrintingPolicy &PP;
509
510  /// Recursion limit for dereferencing fields when looking for the
511  /// region of interest.
512  /// The limit of two indicates that we will dereference fields only once.
513  static const unsigned DEREFERENCE_LIMIT = 2;
514
515  using RegionVector = SmallVector<const MemRegion *, 5>;
516
517public:
518  NoStoreFuncVisitor(const SubRegion *R, bugreporter::TrackingKind TKind)
519      : NoStateChangeFuncVisitor(TKind), RegionOfInterest(R),
520        MmrMgr(R->getMemRegionManager()),
521        SM(MmrMgr.getContext().getSourceManager()),
522        PP(MmrMgr.getContext().getPrintingPolicy()) {}
523
524  void Profile(llvm::FoldingSetNodeID &ID) const override {
525    static int Tag = 0;
526    ID.AddPointer(&Tag);
527    ID.AddPointer(RegionOfInterest);
528  }
529
530private:
531  /// \return Whether \c RegionOfInterest was modified at \p CurrN compared to
532  /// the value it holds in \p CallExitBeginN.
533  bool wasModifiedBeforeCallExit(const ExplodedNode *CurrN,
534                                 const ExplodedNode *CallExitBeginN) override;
535
536  /// Attempts to find the region of interest in a given record decl,
537  /// by either following the base classes or fields.
538  /// Dereferences fields up to a given recursion limit.
539  /// Note that \p Vec is passed by value, leading to quadratic copying cost,
540  /// but it's OK in practice since its length is limited to DEREFERENCE_LIMIT.
541  /// \return A chain fields leading to the region of interest or std::nullopt.
542  const std::optional<RegionVector>
543  findRegionOfInterestInRecord(const RecordDecl *RD, ProgramStateRef State,
544                               const MemRegion *R, const RegionVector &Vec = {},
545                               int depth = 0);
546
547  // Region of interest corresponds to an IVar, exiting a method
548  // which could have written into that IVar, but did not.
549  PathDiagnosticPieceRef maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
550                                                  const ObjCMethodCall &Call,
551                                                  const ExplodedNode *N) final;
552
553  PathDiagnosticPieceRef maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
554                                                 const CXXConstructorCall &Call,
555                                                 const ExplodedNode *N) final;
556
557  PathDiagnosticPieceRef
558  maybeEmitNoteForParameters(PathSensitiveBugReport &R, const CallEvent &Call,
559                             const ExplodedNode *N) final;
560
561  /// Consume the information on the no-store stack frame in order to
562  /// either emit a note or suppress the report enirely.
563  /// \return Diagnostics piece for region not modified in the current function,
564  /// if it decides to emit one.
565  PathDiagnosticPieceRef
566  maybeEmitNote(PathSensitiveBugReport &R, const CallEvent &Call,
567                const ExplodedNode *N, const RegionVector &FieldChain,
568                const MemRegion *MatchedRegion, StringRef FirstElement,
569                bool FirstIsReferenceType, unsigned IndirectionLevel);
570
571  bool prettyPrintRegionName(const RegionVector &FieldChain,
572                             const MemRegion *MatchedRegion,
573                             StringRef FirstElement, bool FirstIsReferenceType,
574                             unsigned IndirectionLevel,
575                             llvm::raw_svector_ostream &os);
576
577  StringRef prettyPrintFirstElement(StringRef FirstElement,
578                                    bool MoreItemsExpected,
579                                    int IndirectionLevel,
580                                    llvm::raw_svector_ostream &os);
581};
582} // namespace
583
584/// \return Whether the method declaration \p Parent
585/// syntactically has a binary operation writing into the ivar \p Ivar.
586static bool potentiallyWritesIntoIvar(const Decl *Parent,
587                                      const ObjCIvarDecl *Ivar) {
588  using namespace ast_matchers;
589  const char *IvarBind = "Ivar";
590  if (!Parent || !Parent->hasBody())
591    return false;
592  StatementMatcher WriteIntoIvarM = binaryOperator(
593      hasOperatorName("="),
594      hasLHS(ignoringParenImpCasts(
595          objcIvarRefExpr(hasDeclaration(equalsNode(Ivar))).bind(IvarBind))));
596  StatementMatcher ParentM = stmt(hasDescendant(WriteIntoIvarM));
597  auto Matches = match(ParentM, *Parent->getBody(), Parent->getASTContext());
598  for (BoundNodes &Match : Matches) {
599    auto IvarRef = Match.getNodeAs<ObjCIvarRefExpr>(IvarBind);
600    if (IvarRef->isFreeIvar())
601      return true;
602
603    const Expr *Base = IvarRef->getBase();
604    if (const auto *ICE = dyn_cast<ImplicitCastExpr>(Base))
605      Base = ICE->getSubExpr();
606
607    if (const auto *DRE = dyn_cast<DeclRefExpr>(Base))
608      if (const auto *ID = dyn_cast<ImplicitParamDecl>(DRE->getDecl()))
609        if (ID->getParameterKind() == ImplicitParamDecl::ObjCSelf)
610          return true;
611
612    return false;
613  }
614  return false;
615}
616
617/// Attempts to find the region of interest in a given CXX decl,
618/// by either following the base classes or fields.
619/// Dereferences fields up to a given recursion limit.
620/// Note that \p Vec is passed by value, leading to quadratic copying cost,
621/// but it's OK in practice since its length is limited to DEREFERENCE_LIMIT.
622/// \return A chain fields leading to the region of interest or std::nullopt.
623const std::optional<NoStoreFuncVisitor::RegionVector>
624NoStoreFuncVisitor::findRegionOfInterestInRecord(
625    const RecordDecl *RD, ProgramStateRef State, const MemRegion *R,
626    const NoStoreFuncVisitor::RegionVector &Vec /* = {} */,
627    int depth /* = 0 */) {
628
629  if (depth == DEREFERENCE_LIMIT) // Limit the recursion depth.
630    return std::nullopt;
631
632  if (const auto *RDX = dyn_cast<CXXRecordDecl>(RD))
633    if (!RDX->hasDefinition())
634      return std::nullopt;
635
636  // Recursively examine the base classes.
637  // Note that following base classes does not increase the recursion depth.
638  if (const auto *RDX = dyn_cast<CXXRecordDecl>(RD))
639    for (const auto &II : RDX->bases())
640      if (const RecordDecl *RRD = II.getType()->getAsRecordDecl())
641        if (std::optional<RegionVector> Out =
642                findRegionOfInterestInRecord(RRD, State, R, Vec, depth))
643          return Out;
644
645  for (const FieldDecl *I : RD->fields()) {
646    QualType FT = I->getType();
647    const FieldRegion *FR = MmrMgr.getFieldRegion(I, cast<SubRegion>(R));
648    const SVal V = State->getSVal(FR);
649    const MemRegion *VR = V.getAsRegion();
650
651    RegionVector VecF = Vec;
652    VecF.push_back(FR);
653
654    if (RegionOfInterest == VR)
655      return VecF;
656
657    if (const RecordDecl *RRD = FT->getAsRecordDecl())
658      if (auto Out =
659              findRegionOfInterestInRecord(RRD, State, FR, VecF, depth + 1))
660        return Out;
661
662    QualType PT = FT->getPointeeType();
663    if (PT.isNull() || PT->isVoidType() || !VR)
664      continue;
665
666    if (const RecordDecl *RRD = PT->getAsRecordDecl())
667      if (std::optional<RegionVector> Out =
668              findRegionOfInterestInRecord(RRD, State, VR, VecF, depth + 1))
669        return Out;
670  }
671
672  return std::nullopt;
673}
674
675PathDiagnosticPieceRef
676NoStoreFuncVisitor::maybeEmitNoteForObjCSelf(PathSensitiveBugReport &R,
677                                             const ObjCMethodCall &Call,
678                                             const ExplodedNode *N) {
679  if (const auto *IvarR = dyn_cast<ObjCIvarRegion>(RegionOfInterest)) {
680    const MemRegion *SelfRegion = Call.getReceiverSVal().getAsRegion();
681    if (RegionOfInterest->isSubRegionOf(SelfRegion) &&
682        potentiallyWritesIntoIvar(Call.getRuntimeDefinition().getDecl(),
683                                  IvarR->getDecl()))
684      return maybeEmitNote(R, Call, N, {}, SelfRegion, "self",
685                           /*FirstIsReferenceType=*/false, 1);
686  }
687  return nullptr;
688}
689
690PathDiagnosticPieceRef
691NoStoreFuncVisitor::maybeEmitNoteForCXXThis(PathSensitiveBugReport &R,
692                                            const CXXConstructorCall &Call,
693                                            const ExplodedNode *N) {
694  const MemRegion *ThisR = Call.getCXXThisVal().getAsRegion();
695  if (RegionOfInterest->isSubRegionOf(ThisR) && !Call.getDecl()->isImplicit())
696    return maybeEmitNote(R, Call, N, {}, ThisR, "this",
697                         /*FirstIsReferenceType=*/false, 1);
698
699  // Do not generate diagnostics for not modified parameters in
700  // constructors.
701  return nullptr;
702}
703
704/// \return whether \p Ty points to a const type, or is a const reference.
705static bool isPointerToConst(QualType Ty) {
706  return !Ty->getPointeeType().isNull() &&
707         Ty->getPointeeType().getCanonicalType().isConstQualified();
708}
709
710PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNoteForParameters(
711    PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N) {
712  ArrayRef<ParmVarDecl *> Parameters = Call.parameters();
713  for (unsigned I = 0; I < Call.getNumArgs() && I < Parameters.size(); ++I) {
714    const ParmVarDecl *PVD = Parameters[I];
715    SVal V = Call.getArgSVal(I);
716    bool ParamIsReferenceType = PVD->getType()->isReferenceType();
717    std::string ParamName = PVD->getNameAsString();
718
719    unsigned IndirectionLevel = 1;
720    QualType T = PVD->getType();
721    while (const MemRegion *MR = V.getAsRegion()) {
722      if (RegionOfInterest->isSubRegionOf(MR) && !isPointerToConst(T))
723        return maybeEmitNote(R, Call, N, {}, MR, ParamName,
724                             ParamIsReferenceType, IndirectionLevel);
725
726      QualType PT = T->getPointeeType();
727      if (PT.isNull() || PT->isVoidType())
728        break;
729
730      ProgramStateRef State = N->getState();
731
732      if (const RecordDecl *RD = PT->getAsRecordDecl())
733        if (std::optional<RegionVector> P =
734                findRegionOfInterestInRecord(RD, State, MR))
735          return maybeEmitNote(R, Call, N, *P, RegionOfInterest, ParamName,
736                               ParamIsReferenceType, IndirectionLevel);
737
738      V = State->getSVal(MR, PT);
739      T = PT;
740      IndirectionLevel++;
741    }
742  }
743
744  return nullptr;
745}
746
747bool NoStoreFuncVisitor::wasModifiedBeforeCallExit(
748    const ExplodedNode *CurrN, const ExplodedNode *CallExitBeginN) {
749  return ::wasRegionOfInterestModifiedAt(
750      RegionOfInterest, CurrN,
751      CallExitBeginN->getState()->getSVal(RegionOfInterest));
752}
753
754static llvm::StringLiteral WillBeUsedForACondition =
755    ", which participates in a condition later";
756
757PathDiagnosticPieceRef NoStoreFuncVisitor::maybeEmitNote(
758    PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N,
759    const RegionVector &FieldChain, const MemRegion *MatchedRegion,
760    StringRef FirstElement, bool FirstIsReferenceType,
761    unsigned IndirectionLevel) {
762
763  PathDiagnosticLocation L =
764      PathDiagnosticLocation::create(N->getLocation(), SM);
765
766  // For now this shouldn't trigger, but once it does (as we add more
767  // functions to the body farm), we'll need to decide if these reports
768  // are worth suppressing as well.
769  if (!L.hasValidLocation())
770    return nullptr;
771
772  SmallString<256> sbuf;
773  llvm::raw_svector_ostream os(sbuf);
774  os << "Returning without writing to '";
775
776  // Do not generate the note if failed to pretty-print.
777  if (!prettyPrintRegionName(FieldChain, MatchedRegion, FirstElement,
778                             FirstIsReferenceType, IndirectionLevel, os))
779    return nullptr;
780
781  os << "'";
782  if (TKind == bugreporter::TrackingKind::Condition)
783    os << WillBeUsedForACondition;
784  return std::make_shared<PathDiagnosticEventPiece>(L, os.str());
785}
786
787bool NoStoreFuncVisitor::prettyPrintRegionName(const RegionVector &FieldChain,
788                                               const MemRegion *MatchedRegion,
789                                               StringRef FirstElement,
790                                               bool FirstIsReferenceType,
791                                               unsigned IndirectionLevel,
792                                               llvm::raw_svector_ostream &os) {
793
794  if (FirstIsReferenceType)
795    IndirectionLevel--;
796
797  RegionVector RegionSequence;
798
799  // Add the regions in the reverse order, then reverse the resulting array.
800  assert(RegionOfInterest->isSubRegionOf(MatchedRegion));
801  const MemRegion *R = RegionOfInterest;
802  while (R != MatchedRegion) {
803    RegionSequence.push_back(R);
804    R = cast<SubRegion>(R)->getSuperRegion();
805  }
806  std::reverse(RegionSequence.begin(), RegionSequence.end());
807  RegionSequence.append(FieldChain.begin(), FieldChain.end());
808
809  StringRef Sep;
810  for (const MemRegion *R : RegionSequence) {
811
812    // Just keep going up to the base region.
813    // Element regions may appear due to casts.
814    if (isa<CXXBaseObjectRegion, CXXTempObjectRegion>(R))
815      continue;
816
817    if (Sep.empty())
818      Sep = prettyPrintFirstElement(FirstElement,
819                                    /*MoreItemsExpected=*/true,
820                                    IndirectionLevel, os);
821
822    os << Sep;
823
824    // Can only reasonably pretty-print DeclRegions.
825    if (!isa<DeclRegion>(R))
826      return false;
827
828    const auto *DR = cast<DeclRegion>(R);
829    Sep = DR->getValueType()->isAnyPointerType() ? "->" : ".";
830    DR->getDecl()->getDeclName().print(os, PP);
831  }
832
833  if (Sep.empty())
834    prettyPrintFirstElement(FirstElement,
835                            /*MoreItemsExpected=*/false, IndirectionLevel, os);
836  return true;
837}
838
839StringRef NoStoreFuncVisitor::prettyPrintFirstElement(
840    StringRef FirstElement, bool MoreItemsExpected, int IndirectionLevel,
841    llvm::raw_svector_ostream &os) {
842  StringRef Out = ".";
843
844  if (IndirectionLevel > 0 && MoreItemsExpected) {
845    IndirectionLevel--;
846    Out = "->";
847  }
848
849  if (IndirectionLevel > 0 && MoreItemsExpected)
850    os << "(";
851
852  for (int i = 0; i < IndirectionLevel; i++)
853    os << "*";
854  os << FirstElement;
855
856  if (IndirectionLevel > 0 && MoreItemsExpected)
857    os << ")";
858
859  return Out;
860}
861
862//===----------------------------------------------------------------------===//
863// Implementation of MacroNullReturnSuppressionVisitor.
864//===----------------------------------------------------------------------===//
865
866namespace {
867
868/// Suppress null-pointer-dereference bugs where dereferenced null was returned
869/// the macro.
870class MacroNullReturnSuppressionVisitor final : public BugReporterVisitor {
871  const SubRegion *RegionOfInterest;
872  const SVal ValueAtDereference;
873
874  // Do not invalidate the reports where the value was modified
875  // after it got assigned to from the macro.
876  bool WasModified = false;
877
878public:
879  MacroNullReturnSuppressionVisitor(const SubRegion *R, const SVal V)
880      : RegionOfInterest(R), ValueAtDereference(V) {}
881
882  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
883                                   BugReporterContext &BRC,
884                                   PathSensitiveBugReport &BR) override {
885    if (WasModified)
886      return nullptr;
887
888    auto BugPoint = BR.getErrorNode()->getLocation().getAs<StmtPoint>();
889    if (!BugPoint)
890      return nullptr;
891
892    const SourceManager &SMgr = BRC.getSourceManager();
893    if (auto Loc = matchAssignment(N)) {
894      if (isFunctionMacroExpansion(*Loc, SMgr)) {
895        std::string MacroName = std::string(getMacroName(*Loc, BRC));
896        SourceLocation BugLoc = BugPoint->getStmt()->getBeginLoc();
897        if (!BugLoc.isMacroID() || getMacroName(BugLoc, BRC) != MacroName)
898          BR.markInvalid(getTag(), MacroName.c_str());
899      }
900    }
901
902    if (wasRegionOfInterestModifiedAt(RegionOfInterest, N, ValueAtDereference))
903      WasModified = true;
904
905    return nullptr;
906  }
907
908  static void addMacroVisitorIfNecessary(
909        const ExplodedNode *N, const MemRegion *R,
910        bool EnableNullFPSuppression, PathSensitiveBugReport &BR,
911        const SVal V) {
912    AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
913    if (EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths &&
914        isa<Loc>(V))
915      BR.addVisitor<MacroNullReturnSuppressionVisitor>(R->getAs<SubRegion>(),
916                                                       V);
917  }
918
919  void* getTag() const {
920    static int Tag = 0;
921    return static_cast<void *>(&Tag);
922  }
923
924  void Profile(llvm::FoldingSetNodeID &ID) const override {
925    ID.AddPointer(getTag());
926  }
927
928private:
929  /// \return Source location of right hand side of an assignment
930  /// into \c RegionOfInterest, empty optional if none found.
931  std::optional<SourceLocation> matchAssignment(const ExplodedNode *N) {
932    const Stmt *S = N->getStmtForDiagnostics();
933    ProgramStateRef State = N->getState();
934    auto *LCtx = N->getLocationContext();
935    if (!S)
936      return std::nullopt;
937
938    if (const auto *DS = dyn_cast<DeclStmt>(S)) {
939      if (const auto *VD = dyn_cast<VarDecl>(DS->getSingleDecl()))
940        if (const Expr *RHS = VD->getInit())
941          if (RegionOfInterest->isSubRegionOf(
942                  State->getLValue(VD, LCtx).getAsRegion()))
943            return RHS->getBeginLoc();
944    } else if (const auto *BO = dyn_cast<BinaryOperator>(S)) {
945      const MemRegion *R = N->getSVal(BO->getLHS()).getAsRegion();
946      const Expr *RHS = BO->getRHS();
947      if (BO->isAssignmentOp() && RegionOfInterest->isSubRegionOf(R)) {
948        return RHS->getBeginLoc();
949      }
950    }
951    return std::nullopt;
952  }
953};
954
955} // end of anonymous namespace
956
957namespace {
958
959/// Emits an extra note at the return statement of an interesting stack frame.
960///
961/// The returned value is marked as an interesting value, and if it's null,
962/// adds a visitor to track where it became null.
963///
964/// This visitor is intended to be used when another visitor discovers that an
965/// interesting value comes from an inlined function call.
966class ReturnVisitor : public TrackingBugReporterVisitor {
967  const StackFrameContext *CalleeSFC;
968  enum {
969    Initial,
970    MaybeUnsuppress,
971    Satisfied
972  } Mode = Initial;
973
974  bool EnableNullFPSuppression;
975  bool ShouldInvalidate = true;
976  AnalyzerOptions& Options;
977  bugreporter::TrackingKind TKind;
978
979public:
980  ReturnVisitor(TrackerRef ParentTracker, const StackFrameContext *Frame,
981                bool Suppressed, AnalyzerOptions &Options,
982                bugreporter::TrackingKind TKind)
983      : TrackingBugReporterVisitor(ParentTracker), CalleeSFC(Frame),
984        EnableNullFPSuppression(Suppressed), Options(Options), TKind(TKind) {}
985
986  static void *getTag() {
987    static int Tag = 0;
988    return static_cast<void *>(&Tag);
989  }
990
991  void Profile(llvm::FoldingSetNodeID &ID) const override {
992    ID.AddPointer(ReturnVisitor::getTag());
993    ID.AddPointer(CalleeSFC);
994    ID.AddBoolean(EnableNullFPSuppression);
995  }
996
997  PathDiagnosticPieceRef visitNodeInitial(const ExplodedNode *N,
998                                          BugReporterContext &BRC,
999                                          PathSensitiveBugReport &BR) {
1000    // Only print a message at the interesting return statement.
1001    if (N->getLocationContext() != CalleeSFC)
1002      return nullptr;
1003
1004    std::optional<StmtPoint> SP = N->getLocationAs<StmtPoint>();
1005    if (!SP)
1006      return nullptr;
1007
1008    const auto *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
1009    if (!Ret)
1010      return nullptr;
1011
1012    // Okay, we're at the right return statement, but do we have the return
1013    // value available?
1014    ProgramStateRef State = N->getState();
1015    SVal V = State->getSVal(Ret, CalleeSFC);
1016    if (V.isUnknownOrUndef())
1017      return nullptr;
1018
1019    // Don't print any more notes after this one.
1020    Mode = Satisfied;
1021
1022    const Expr *RetE = Ret->getRetValue();
1023    assert(RetE && "Tracking a return value for a void function");
1024
1025    // Handle cases where a reference is returned and then immediately used.
1026    std::optional<Loc> LValue;
1027    if (RetE->isGLValue()) {
1028      if ((LValue = V.getAs<Loc>())) {
1029        SVal RValue = State->getRawSVal(*LValue, RetE->getType());
1030        if (isa<DefinedSVal>(RValue))
1031          V = RValue;
1032      }
1033    }
1034
1035    // Ignore aggregate rvalues.
1036    if (isa<nonloc::LazyCompoundVal, nonloc::CompoundVal>(V))
1037      return nullptr;
1038
1039    RetE = RetE->IgnoreParenCasts();
1040
1041    // Let's track the return value.
1042    getParentTracker().track(RetE, N, {TKind, EnableNullFPSuppression});
1043
1044    // Build an appropriate message based on the return value.
1045    SmallString<64> Msg;
1046    llvm::raw_svector_ostream Out(Msg);
1047
1048    bool WouldEventBeMeaningless = false;
1049
1050    if (State->isNull(V).isConstrainedTrue()) {
1051      if (isa<Loc>(V)) {
1052
1053        // If we have counter-suppression enabled, make sure we keep visiting
1054        // future nodes. We want to emit a path note as well, in case
1055        // the report is resurrected as valid later on.
1056        if (EnableNullFPSuppression &&
1057            Options.ShouldAvoidSuppressingNullArgumentPaths)
1058          Mode = MaybeUnsuppress;
1059
1060        if (RetE->getType()->isObjCObjectPointerType()) {
1061          Out << "Returning nil";
1062        } else {
1063          Out << "Returning null pointer";
1064        }
1065      } else {
1066        Out << "Returning zero";
1067      }
1068
1069    } else {
1070      if (auto CI = V.getAs<nonloc::ConcreteInt>()) {
1071        Out << "Returning the value " << CI->getValue();
1072      } else {
1073        // There is nothing interesting about returning a value, when it is
1074        // plain value without any constraints, and the function is guaranteed
1075        // to return that every time. We could use CFG::isLinear() here, but
1076        // constexpr branches are obvious to the compiler, not necesserily to
1077        // the programmer.
1078        if (N->getCFG().size() == 3)
1079          WouldEventBeMeaningless = true;
1080
1081        Out << (isa<Loc>(V) ? "Returning pointer" : "Returning value");
1082      }
1083    }
1084
1085    if (LValue) {
1086      if (const MemRegion *MR = LValue->getAsRegion()) {
1087        if (MR->canPrintPretty()) {
1088          Out << " (reference to ";
1089          MR->printPretty(Out);
1090          Out << ")";
1091        }
1092      }
1093    } else {
1094      // FIXME: We should have a more generalized location printing mechanism.
1095      if (const auto *DR = dyn_cast<DeclRefExpr>(RetE))
1096        if (const auto *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
1097          Out << " (loaded from '" << *DD << "')";
1098    }
1099
1100    PathDiagnosticLocation L(Ret, BRC.getSourceManager(), CalleeSFC);
1101    if (!L.isValid() || !L.asLocation().isValid())
1102      return nullptr;
1103
1104    if (TKind == bugreporter::TrackingKind::Condition)
1105      Out << WillBeUsedForACondition;
1106
1107    auto EventPiece = std::make_shared<PathDiagnosticEventPiece>(L, Out.str());
1108
1109    // If we determined that the note is meaningless, make it prunable, and
1110    // don't mark the stackframe interesting.
1111    if (WouldEventBeMeaningless)
1112      EventPiece->setPrunable(true);
1113    else
1114      BR.markInteresting(CalleeSFC);
1115
1116    return EventPiece;
1117  }
1118
1119  PathDiagnosticPieceRef visitNodeMaybeUnsuppress(const ExplodedNode *N,
1120                                                  BugReporterContext &BRC,
1121                                                  PathSensitiveBugReport &BR) {
1122    assert(Options.ShouldAvoidSuppressingNullArgumentPaths);
1123
1124    // Are we at the entry node for this call?
1125    std::optional<CallEnter> CE = N->getLocationAs<CallEnter>();
1126    if (!CE)
1127      return nullptr;
1128
1129    if (CE->getCalleeContext() != CalleeSFC)
1130      return nullptr;
1131
1132    Mode = Satisfied;
1133
1134    // Don't automatically suppress a report if one of the arguments is
1135    // known to be a null pointer. Instead, start tracking /that/ null
1136    // value back to its origin.
1137    ProgramStateManager &StateMgr = BRC.getStateManager();
1138    CallEventManager &CallMgr = StateMgr.getCallEventManager();
1139
1140    ProgramStateRef State = N->getState();
1141    CallEventRef<> Call = CallMgr.getCaller(CalleeSFC, State);
1142    for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
1143      std::optional<Loc> ArgV = Call->getArgSVal(I).getAs<Loc>();
1144      if (!ArgV)
1145        continue;
1146
1147      const Expr *ArgE = Call->getArgExpr(I);
1148      if (!ArgE)
1149        continue;
1150
1151      // Is it possible for this argument to be non-null?
1152      if (!State->isNull(*ArgV).isConstrainedTrue())
1153        continue;
1154
1155      if (getParentTracker()
1156              .track(ArgE, N, {TKind, EnableNullFPSuppression})
1157              .FoundSomethingToTrack)
1158        ShouldInvalidate = false;
1159
1160      // If we /can't/ track the null pointer, we should err on the side of
1161      // false negatives, and continue towards marking this report invalid.
1162      // (We will still look at the other arguments, though.)
1163    }
1164
1165    return nullptr;
1166  }
1167
1168  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1169                                   BugReporterContext &BRC,
1170                                   PathSensitiveBugReport &BR) override {
1171    switch (Mode) {
1172    case Initial:
1173      return visitNodeInitial(N, BRC, BR);
1174    case MaybeUnsuppress:
1175      return visitNodeMaybeUnsuppress(N, BRC, BR);
1176    case Satisfied:
1177      return nullptr;
1178    }
1179
1180    llvm_unreachable("Invalid visit mode!");
1181  }
1182
1183  void finalizeVisitor(BugReporterContext &, const ExplodedNode *,
1184                       PathSensitiveBugReport &BR) override {
1185    if (EnableNullFPSuppression && ShouldInvalidate)
1186      BR.markInvalid(ReturnVisitor::getTag(), CalleeSFC);
1187  }
1188};
1189
1190//===----------------------------------------------------------------------===//
1191//                               StoreSiteFinder
1192//===----------------------------------------------------------------------===//
1193
1194/// Finds last store into the given region,
1195/// which is different from a given symbolic value.
1196class StoreSiteFinder final : public TrackingBugReporterVisitor {
1197  const MemRegion *R;
1198  SVal V;
1199  bool Satisfied = false;
1200
1201  TrackingOptions Options;
1202  const StackFrameContext *OriginSFC;
1203
1204public:
1205  /// \param V We're searching for the store where \c R received this value.
1206  /// \param R The region we're tracking.
1207  /// \param Options Tracking behavior options.
1208  /// \param OriginSFC Only adds notes when the last store happened in a
1209  ///        different stackframe to this one. Disregarded if the tracking kind
1210  ///        is thorough.
1211  ///        This is useful, because for non-tracked regions, notes about
1212  ///        changes to its value in a nested stackframe could be pruned, and
1213  ///        this visitor can prevent that without polluting the bugpath too
1214  ///        much.
1215  StoreSiteFinder(bugreporter::TrackerRef ParentTracker, KnownSVal V,
1216                  const MemRegion *R, TrackingOptions Options,
1217                  const StackFrameContext *OriginSFC = nullptr)
1218      : TrackingBugReporterVisitor(ParentTracker), R(R), V(V), Options(Options),
1219        OriginSFC(OriginSFC) {
1220    assert(R);
1221  }
1222
1223  void Profile(llvm::FoldingSetNodeID &ID) const override;
1224
1225  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1226                                   BugReporterContext &BRC,
1227                                   PathSensitiveBugReport &BR) override;
1228};
1229} // namespace
1230
1231void StoreSiteFinder::Profile(llvm::FoldingSetNodeID &ID) const {
1232  static int tag = 0;
1233  ID.AddPointer(&tag);
1234  ID.AddPointer(R);
1235  ID.Add(V);
1236  ID.AddInteger(static_cast<int>(Options.Kind));
1237  ID.AddBoolean(Options.EnableNullFPSuppression);
1238}
1239
1240/// Returns true if \p N represents the DeclStmt declaring and initializing
1241/// \p VR.
1242static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR) {
1243  std::optional<PostStmt> P = N->getLocationAs<PostStmt>();
1244  if (!P)
1245    return false;
1246
1247  const DeclStmt *DS = P->getStmtAs<DeclStmt>();
1248  if (!DS)
1249    return false;
1250
1251  if (DS->getSingleDecl() != VR->getDecl())
1252    return false;
1253
1254  const MemSpaceRegion *VarSpace = VR->getMemorySpace();
1255  const auto *FrameSpace = dyn_cast<StackSpaceRegion>(VarSpace);
1256  if (!FrameSpace) {
1257    // If we ever directly evaluate global DeclStmts, this assertion will be
1258    // invalid, but this still seems preferable to silently accepting an
1259    // initialization that may be for a path-sensitive variable.
1260    assert(VR->getDecl()->isStaticLocal() && "non-static stackless VarRegion");
1261    return true;
1262  }
1263
1264  assert(VR->getDecl()->hasLocalStorage());
1265  const LocationContext *LCtx = N->getLocationContext();
1266  return FrameSpace->getStackFrame() == LCtx->getStackFrame();
1267}
1268
1269static bool isObjCPointer(const MemRegion *R) {
1270  if (R->isBoundable())
1271    if (const auto *TR = dyn_cast<TypedValueRegion>(R))
1272      return TR->getValueType()->isObjCObjectPointerType();
1273
1274  return false;
1275}
1276
1277static bool isObjCPointer(const ValueDecl *D) {
1278  return D->getType()->isObjCObjectPointerType();
1279}
1280
1281/// Show diagnostics for initializing or declaring a region \p R with a bad value.
1282static void showBRDiagnostics(llvm::raw_svector_ostream &OS, StoreInfo SI) {
1283  const bool HasPrefix = SI.Dest->canPrintPretty();
1284
1285  if (HasPrefix) {
1286    SI.Dest->printPretty(OS);
1287    OS << " ";
1288  }
1289
1290  const char *Action = nullptr;
1291
1292  switch (SI.StoreKind) {
1293  case StoreInfo::Initialization:
1294    Action = HasPrefix ? "initialized to " : "Initializing to ";
1295    break;
1296  case StoreInfo::BlockCapture:
1297    Action = HasPrefix ? "captured by block as " : "Captured by block as ";
1298    break;
1299  default:
1300    llvm_unreachable("Unexpected store kind");
1301  }
1302
1303  if (isa<loc::ConcreteInt>(SI.Value)) {
1304    OS << Action << (isObjCPointer(SI.Dest) ? "nil" : "a null pointer value");
1305
1306  } else if (auto CVal = SI.Value.getAs<nonloc::ConcreteInt>()) {
1307    OS << Action << CVal->getValue();
1308
1309  } else if (SI.Origin && SI.Origin->canPrintPretty()) {
1310    OS << Action << "the value of ";
1311    SI.Origin->printPretty(OS);
1312
1313  } else if (SI.StoreKind == StoreInfo::Initialization) {
1314    // We don't need to check here, all these conditions were
1315    // checked by StoreSiteFinder, when it figured out that it is
1316    // initialization.
1317    const auto *DS =
1318        cast<DeclStmt>(SI.StoreSite->getLocationAs<PostStmt>()->getStmt());
1319
1320    if (SI.Value.isUndef()) {
1321      if (isa<VarRegion>(SI.Dest)) {
1322        const auto *VD = cast<VarDecl>(DS->getSingleDecl());
1323
1324        if (VD->getInit()) {
1325          OS << (HasPrefix ? "initialized" : "Initializing")
1326             << " to a garbage value";
1327        } else {
1328          OS << (HasPrefix ? "declared" : "Declaring")
1329             << " without an initial value";
1330        }
1331      }
1332    } else {
1333      OS << (HasPrefix ? "initialized" : "Initialized") << " here";
1334    }
1335  }
1336}
1337
1338/// Display diagnostics for passing bad region as a parameter.
1339static void showBRParamDiagnostics(llvm::raw_svector_ostream &OS,
1340                                   StoreInfo SI) {
1341  const auto *VR = cast<VarRegion>(SI.Dest);
1342  const auto *D = VR->getDecl();
1343
1344  OS << "Passing ";
1345
1346  if (isa<loc::ConcreteInt>(SI.Value)) {
1347    OS << (isObjCPointer(D) ? "nil object reference" : "null pointer value");
1348
1349  } else if (SI.Value.isUndef()) {
1350    OS << "uninitialized value";
1351
1352  } else if (auto CI = SI.Value.getAs<nonloc::ConcreteInt>()) {
1353    OS << "the value " << CI->getValue();
1354
1355  } else if (SI.Origin && SI.Origin->canPrintPretty()) {
1356    SI.Origin->printPretty(OS);
1357
1358  } else {
1359    OS << "value";
1360  }
1361
1362  if (const auto *Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {
1363    // Printed parameter indexes are 1-based, not 0-based.
1364    unsigned Idx = Param->getFunctionScopeIndex() + 1;
1365    OS << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter";
1366    if (VR->canPrintPretty()) {
1367      OS << " ";
1368      VR->printPretty(OS);
1369    }
1370  } else if (const auto *ImplParam = dyn_cast<ImplicitParamDecl>(D)) {
1371    if (ImplParam->getParameterKind() ==
1372        ImplicitParamDecl::ImplicitParamKind::ObjCSelf) {
1373      OS << " via implicit parameter 'self'";
1374    }
1375  }
1376}
1377
1378/// Show default diagnostics for storing bad region.
1379static void showBRDefaultDiagnostics(llvm::raw_svector_ostream &OS,
1380                                     StoreInfo SI) {
1381  const bool HasSuffix = SI.Dest->canPrintPretty();
1382
1383  if (isa<loc::ConcreteInt>(SI.Value)) {
1384    OS << (isObjCPointer(SI.Dest) ? "nil object reference stored"
1385                                  : (HasSuffix ? "Null pointer value stored"
1386                                               : "Storing null pointer value"));
1387
1388  } else if (SI.Value.isUndef()) {
1389    OS << (HasSuffix ? "Uninitialized value stored"
1390                     : "Storing uninitialized value");
1391
1392  } else if (auto CV = SI.Value.getAs<nonloc::ConcreteInt>()) {
1393    if (HasSuffix)
1394      OS << "The value " << CV->getValue() << " is assigned";
1395    else
1396      OS << "Assigning " << CV->getValue();
1397
1398  } else if (SI.Origin && SI.Origin->canPrintPretty()) {
1399    if (HasSuffix) {
1400      OS << "The value of ";
1401      SI.Origin->printPretty(OS);
1402      OS << " is assigned";
1403    } else {
1404      OS << "Assigning the value of ";
1405      SI.Origin->printPretty(OS);
1406    }
1407
1408  } else {
1409    OS << (HasSuffix ? "Value assigned" : "Assigning value");
1410  }
1411
1412  if (HasSuffix) {
1413    OS << " to ";
1414    SI.Dest->printPretty(OS);
1415  }
1416}
1417
1418static bool isTrivialCopyOrMoveCtor(const CXXConstructExpr *CE) {
1419  if (!CE)
1420    return false;
1421
1422  const auto *CtorDecl = CE->getConstructor();
1423
1424  return CtorDecl->isCopyOrMoveConstructor() && CtorDecl->isTrivial();
1425}
1426
1427static const Expr *tryExtractInitializerFromList(const InitListExpr *ILE,
1428                                                 const MemRegion *R) {
1429
1430  const auto *TVR = dyn_cast_or_null<TypedValueRegion>(R);
1431
1432  if (!TVR)
1433    return nullptr;
1434
1435  const auto ITy = ILE->getType().getCanonicalType();
1436
1437  // Push each sub-region onto the stack.
1438  std::stack<const TypedValueRegion *> TVRStack;
1439  while (isa<FieldRegion>(TVR) || isa<ElementRegion>(TVR)) {
1440    // We found a region that matches the type of the init list,
1441    // so we assume this is the outer-most region. This can happen
1442    // if the initializer list is inside a class. If our assumption
1443    // is wrong, we return a nullptr in the end.
1444    if (ITy == TVR->getValueType().getCanonicalType())
1445      break;
1446
1447    TVRStack.push(TVR);
1448    TVR = cast<TypedValueRegion>(TVR->getSuperRegion());
1449  }
1450
1451  // If the type of the outer most region doesn't match the type
1452  // of the ILE, we can't match the ILE and the region.
1453  if (ITy != TVR->getValueType().getCanonicalType())
1454    return nullptr;
1455
1456  const Expr *Init = ILE;
1457  while (!TVRStack.empty()) {
1458    TVR = TVRStack.top();
1459    TVRStack.pop();
1460
1461    // We hit something that's not an init list before
1462    // running out of regions, so we most likely failed.
1463    if (!isa<InitListExpr>(Init))
1464      return nullptr;
1465
1466    ILE = cast<InitListExpr>(Init);
1467    auto NumInits = ILE->getNumInits();
1468
1469    if (const auto *FR = dyn_cast<FieldRegion>(TVR)) {
1470      const auto *FD = FR->getDecl();
1471
1472      if (FD->getFieldIndex() >= NumInits)
1473        return nullptr;
1474
1475      Init = ILE->getInit(FD->getFieldIndex());
1476    } else if (const auto *ER = dyn_cast<ElementRegion>(TVR)) {
1477      const auto Ind = ER->getIndex();
1478
1479      // If index is symbolic, we can't figure out which expression
1480      // belongs to the region.
1481      if (!Ind.isConstant())
1482        return nullptr;
1483
1484      const auto IndVal = Ind.getAsInteger()->getLimitedValue();
1485      if (IndVal >= NumInits)
1486        return nullptr;
1487
1488      Init = ILE->getInit(IndVal);
1489    }
1490  }
1491
1492  return Init;
1493}
1494
1495PathDiagnosticPieceRef StoreSiteFinder::VisitNode(const ExplodedNode *Succ,
1496                                                  BugReporterContext &BRC,
1497                                                  PathSensitiveBugReport &BR) {
1498  if (Satisfied)
1499    return nullptr;
1500
1501  const ExplodedNode *StoreSite = nullptr;
1502  const ExplodedNode *Pred = Succ->getFirstPred();
1503  const Expr *InitE = nullptr;
1504  bool IsParam = false;
1505
1506  // First see if we reached the declaration of the region.
1507  if (const auto *VR = dyn_cast<VarRegion>(R)) {
1508    if (isInitializationOfVar(Pred, VR)) {
1509      StoreSite = Pred;
1510      InitE = VR->getDecl()->getInit();
1511    }
1512  }
1513
1514  // If this is a post initializer expression, initializing the region, we
1515  // should track the initializer expression.
1516  if (std::optional<PostInitializer> PIP =
1517          Pred->getLocationAs<PostInitializer>()) {
1518    const MemRegion *FieldReg = (const MemRegion *)PIP->getLocationValue();
1519    if (FieldReg == R) {
1520      StoreSite = Pred;
1521      InitE = PIP->getInitializer()->getInit();
1522    }
1523  }
1524
1525  // Otherwise, see if this is the store site:
1526  // (1) Succ has this binding and Pred does not, i.e. this is
1527  //     where the binding first occurred.
1528  // (2) Succ has this binding and is a PostStore node for this region, i.e.
1529  //     the same binding was re-assigned here.
1530  if (!StoreSite) {
1531    if (Succ->getState()->getSVal(R) != V)
1532      return nullptr;
1533
1534    if (hasVisibleUpdate(Pred, Pred->getState()->getSVal(R), Succ, V)) {
1535      std::optional<PostStore> PS = Succ->getLocationAs<PostStore>();
1536      if (!PS || PS->getLocationValue() != R)
1537        return nullptr;
1538    }
1539
1540    StoreSite = Succ;
1541
1542    if (std::optional<PostStmt> P = Succ->getLocationAs<PostStmt>()) {
1543      // If this is an assignment expression, we can track the value
1544      // being assigned.
1545      if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>()) {
1546        if (BO->isAssignmentOp())
1547          InitE = BO->getRHS();
1548      }
1549      // If we have a declaration like 'S s{1,2}' that needs special
1550      // handling, we handle it here.
1551      else if (const auto *DS = P->getStmtAs<DeclStmt>()) {
1552        const auto *Decl = DS->getSingleDecl();
1553        if (isa<VarDecl>(Decl)) {
1554          const auto *VD = cast<VarDecl>(Decl);
1555
1556          // FIXME: Here we only track the inner most region, so we lose
1557          // information, but it's still better than a crash or no information
1558          // at all.
1559          //
1560          // E.g.: The region we have is 's.s2.s3.s4.y' and we only track 'y',
1561          // and throw away the rest.
1562          if (const auto *ILE = dyn_cast<InitListExpr>(VD->getInit()))
1563            InitE = tryExtractInitializerFromList(ILE, R);
1564        }
1565      } else if (const auto *CE = P->getStmtAs<CXXConstructExpr>()) {
1566
1567        const auto State = Succ->getState();
1568
1569        if (isTrivialCopyOrMoveCtor(CE) && isa<SubRegion>(R)) {
1570          // Migrate the field regions from the current object to
1571          // the parent object. If we track 'a.y.e' and encounter
1572          // 'S a = b' then we need to track 'b.y.e'.
1573
1574          // Push the regions to a stack, from last to first, so
1575          // considering the example above the stack will look like
1576          // (bottom) 'e' -> 'y' (top).
1577
1578          std::stack<const SubRegion *> SRStack;
1579          const SubRegion *SR = cast<SubRegion>(R);
1580          while (isa<FieldRegion>(SR) || isa<ElementRegion>(SR)) {
1581            SRStack.push(SR);
1582            SR = cast<SubRegion>(SR->getSuperRegion());
1583          }
1584
1585          // Get the region for the object we copied/moved from.
1586          const auto *OriginEx = CE->getArg(0);
1587          const auto OriginVal =
1588              State->getSVal(OriginEx, Succ->getLocationContext());
1589
1590          // Pop the stored field regions and apply them to the origin
1591          // object in the same order we had them on the copy.
1592          // OriginField will evolve like 'b' -> 'b.y' -> 'b.y.e'.
1593          SVal OriginField = OriginVal;
1594          while (!SRStack.empty()) {
1595            const auto *TopR = SRStack.top();
1596            SRStack.pop();
1597
1598            if (const auto *FR = dyn_cast<FieldRegion>(TopR)) {
1599              OriginField = State->getLValue(FR->getDecl(), OriginField);
1600            } else if (const auto *ER = dyn_cast<ElementRegion>(TopR)) {
1601              OriginField = State->getLValue(ER->getElementType(),
1602                                             ER->getIndex(), OriginField);
1603            } else {
1604              // FIXME: handle other region type
1605            }
1606          }
1607
1608          // Track 'b.y.e'.
1609          getParentTracker().track(V, OriginField.getAsRegion(), Options);
1610          InitE = OriginEx;
1611        }
1612      }
1613      // This branch can occur in cases like `Ctor() : field{ x, y } {}'.
1614      else if (const auto *ILE = P->getStmtAs<InitListExpr>()) {
1615        // FIXME: Here we only track the top level region, so we lose
1616        // information, but it's still better than a crash or no information
1617        // at all.
1618        //
1619        // E.g.: The region we have is 's.s2.s3.s4.y' and we only track 'y', and
1620        // throw away the rest.
1621        InitE = tryExtractInitializerFromList(ILE, R);
1622      }
1623    }
1624
1625    // If this is a call entry, the variable should be a parameter.
1626    // FIXME: Handle CXXThisRegion as well. (This is not a priority because
1627    // 'this' should never be NULL, but this visitor isn't just for NULL and
1628    // UndefinedVal.)
1629    if (std::optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
1630      if (const auto *VR = dyn_cast<VarRegion>(R)) {
1631
1632        if (const auto *Param = dyn_cast<ParmVarDecl>(VR->getDecl())) {
1633          ProgramStateManager &StateMgr = BRC.getStateManager();
1634          CallEventManager &CallMgr = StateMgr.getCallEventManager();
1635
1636          CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
1637                                                  Succ->getState());
1638          InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
1639        } else {
1640          // Handle Objective-C 'self'.
1641          assert(isa<ImplicitParamDecl>(VR->getDecl()));
1642          InitE = cast<ObjCMessageExpr>(CE->getCalleeContext()->getCallSite())
1643                      ->getInstanceReceiver()->IgnoreParenCasts();
1644        }
1645        IsParam = true;
1646      }
1647    }
1648
1649    // If this is a CXXTempObjectRegion, the Expr responsible for its creation
1650    // is wrapped inside of it.
1651    if (const auto *TmpR = dyn_cast<CXXTempObjectRegion>(R))
1652      InitE = TmpR->getExpr();
1653  }
1654
1655  if (!StoreSite)
1656    return nullptr;
1657
1658  Satisfied = true;
1659
1660  // If we have an expression that provided the value, try to track where it
1661  // came from.
1662  if (InitE) {
1663    if (!IsParam)
1664      InitE = InitE->IgnoreParenCasts();
1665
1666    getParentTracker().track(InitE, StoreSite, Options);
1667  }
1668
1669  // Let's try to find the region where the value came from.
1670  const MemRegion *OldRegion = nullptr;
1671
1672  // If we have init expression, it might be simply a reference
1673  // to a variable, so we can use it.
1674  if (InitE) {
1675    // That region might still be not exactly what we are looking for.
1676    // In situations like `int &ref = val;`, we can't say that
1677    // `ref` is initialized with `val`, rather refers to `val`.
1678    //
1679    // In order, to mitigate situations like this, we check if the last
1680    // stored value in that region is the value that we track.
1681    //
1682    // TODO: support other situations better.
1683    if (const MemRegion *Candidate =
1684            getLocationRegionIfReference(InitE, Succ, false)) {
1685      const StoreManager &SM = BRC.getStateManager().getStoreManager();
1686
1687      // Here we traverse the graph up to find the last node where the
1688      // candidate region is still in the store.
1689      for (const ExplodedNode *N = StoreSite; N; N = N->getFirstPred()) {
1690        if (SM.includedInBindings(N->getState()->getStore(), Candidate)) {
1691          // And if it was bound to the target value, we can use it.
1692          if (N->getState()->getSVal(Candidate) == V) {
1693            OldRegion = Candidate;
1694          }
1695          break;
1696        }
1697      }
1698    }
1699  }
1700
1701  // Otherwise, if the current region does indeed contain the value
1702  // we are looking for, we can look for a region where this value
1703  // was before.
1704  //
1705  // It can be useful for situations like:
1706  //     new = identity(old)
1707  // where the analyzer knows that 'identity' returns the value of its
1708  // first argument.
1709  //
1710  // NOTE: If the region R is not a simple var region, it can contain
1711  //       V in one of its subregions.
1712  if (!OldRegion && StoreSite->getState()->getSVal(R) == V) {
1713    // Let's go up the graph to find the node where the region is
1714    // bound to V.
1715    const ExplodedNode *NodeWithoutBinding = StoreSite->getFirstPred();
1716    for (;
1717         NodeWithoutBinding && NodeWithoutBinding->getState()->getSVal(R) == V;
1718         NodeWithoutBinding = NodeWithoutBinding->getFirstPred()) {
1719    }
1720
1721    if (NodeWithoutBinding) {
1722      // Let's try to find a unique binding for the value in that node.
1723      // We want to use this to find unique bindings because of the following
1724      // situations:
1725      //     b = a;
1726      //     c = identity(b);
1727      //
1728      // Telling the user that the value of 'a' is assigned to 'c', while
1729      // correct, can be confusing.
1730      StoreManager::FindUniqueBinding FB(V.getAsLocSymbol());
1731      BRC.getStateManager().iterBindings(NodeWithoutBinding->getState(), FB);
1732      if (FB)
1733        OldRegion = FB.getRegion();
1734    }
1735  }
1736
1737  if (Options.Kind == TrackingKind::Condition && OriginSFC &&
1738      !OriginSFC->isParentOf(StoreSite->getStackFrame()))
1739    return nullptr;
1740
1741  // Okay, we've found the binding. Emit an appropriate message.
1742  SmallString<256> sbuf;
1743  llvm::raw_svector_ostream os(sbuf);
1744
1745  StoreInfo SI = {StoreInfo::Assignment, // default kind
1746                  StoreSite,
1747                  InitE,
1748                  V,
1749                  R,
1750                  OldRegion};
1751
1752  if (std::optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
1753    const Stmt *S = PS->getStmt();
1754    const auto *DS = dyn_cast<DeclStmt>(S);
1755    const auto *VR = dyn_cast<VarRegion>(R);
1756
1757    if (DS) {
1758      SI.StoreKind = StoreInfo::Initialization;
1759    } else if (isa<BlockExpr>(S)) {
1760      SI.StoreKind = StoreInfo::BlockCapture;
1761      if (VR) {
1762        // See if we can get the BlockVarRegion.
1763        ProgramStateRef State = StoreSite->getState();
1764        SVal V = StoreSite->getSVal(S);
1765        if (const auto *BDR =
1766                dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
1767          if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
1768            getParentTracker().track(State->getSVal(OriginalR), OriginalR,
1769                                     Options, OriginSFC);
1770          }
1771        }
1772      }
1773    }
1774  } else if (SI.StoreSite->getLocation().getAs<CallEnter>() &&
1775             isa<VarRegion>(SI.Dest)) {
1776    SI.StoreKind = StoreInfo::CallArgument;
1777  }
1778
1779  return getParentTracker().handle(SI, BRC, Options);
1780}
1781
1782//===----------------------------------------------------------------------===//
1783// Implementation of TrackConstraintBRVisitor.
1784//===----------------------------------------------------------------------===//
1785
1786void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
1787  static int tag = 0;
1788  ID.AddPointer(&tag);
1789  ID.AddBoolean(Assumption);
1790  ID.Add(Constraint);
1791}
1792
1793/// Return the tag associated with this visitor.  This tag will be used
1794/// to make all PathDiagnosticPieces created by this visitor.
1795const char *TrackConstraintBRVisitor::getTag() {
1796  return "TrackConstraintBRVisitor";
1797}
1798
1799bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
1800  if (IsZeroCheck)
1801    return N->getState()->isNull(Constraint).isUnderconstrained();
1802  return (bool)N->getState()->assume(Constraint, !Assumption);
1803}
1804
1805PathDiagnosticPieceRef TrackConstraintBRVisitor::VisitNode(
1806    const ExplodedNode *N, BugReporterContext &BRC, PathSensitiveBugReport &) {
1807  const ExplodedNode *PrevN = N->getFirstPred();
1808  if (IsSatisfied)
1809    return nullptr;
1810
1811  // Start tracking after we see the first state in which the value is
1812  // constrained.
1813  if (!IsTrackingTurnedOn)
1814    if (!isUnderconstrained(N))
1815      IsTrackingTurnedOn = true;
1816  if (!IsTrackingTurnedOn)
1817    return nullptr;
1818
1819  // Check if in the previous state it was feasible for this constraint
1820  // to *not* be true.
1821  if (isUnderconstrained(PrevN)) {
1822    IsSatisfied = true;
1823
1824    // At this point, the negation of the constraint should be infeasible. If it
1825    // is feasible, make sure that the negation of the constrainti was
1826    // infeasible in the current state.  If it is feasible, we somehow missed
1827    // the transition point.
1828    assert(!isUnderconstrained(N));
1829
1830    // We found the transition point for the constraint.  We now need to
1831    // pretty-print the constraint. (work-in-progress)
1832    SmallString<64> sbuf;
1833    llvm::raw_svector_ostream os(sbuf);
1834
1835    if (isa<Loc>(Constraint)) {
1836      os << "Assuming pointer value is ";
1837      os << (Assumption ? "non-null" : "null");
1838    }
1839
1840    if (os.str().empty())
1841      return nullptr;
1842
1843    // Construct a new PathDiagnosticPiece.
1844    ProgramPoint P = N->getLocation();
1845
1846    // If this node already have a specialized note, it's probably better
1847    // than our generic note.
1848    // FIXME: This only looks for note tags, not for other ways to add a note.
1849    if (isa_and_nonnull<NoteTag>(P.getTag()))
1850      return nullptr;
1851
1852    PathDiagnosticLocation L =
1853      PathDiagnosticLocation::create(P, BRC.getSourceManager());
1854    if (!L.isValid())
1855      return nullptr;
1856
1857    auto X = std::make_shared<PathDiagnosticEventPiece>(L, os.str());
1858    X->setTag(getTag());
1859    return std::move(X);
1860  }
1861
1862  return nullptr;
1863}
1864
1865//===----------------------------------------------------------------------===//
1866// Implementation of SuppressInlineDefensiveChecksVisitor.
1867//===----------------------------------------------------------------------===//
1868
1869SuppressInlineDefensiveChecksVisitor::
1870SuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N)
1871    : V(Value) {
1872  // Check if the visitor is disabled.
1873  AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
1874  if (!Options.ShouldSuppressInlinedDefensiveChecks)
1875    IsSatisfied = true;
1876}
1877
1878void SuppressInlineDefensiveChecksVisitor::Profile(
1879    llvm::FoldingSetNodeID &ID) const {
1880  static int id = 0;
1881  ID.AddPointer(&id);
1882  ID.Add(V);
1883}
1884
1885const char *SuppressInlineDefensiveChecksVisitor::getTag() {
1886  return "IDCVisitor";
1887}
1888
1889PathDiagnosticPieceRef
1890SuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
1891                                                BugReporterContext &BRC,
1892                                                PathSensitiveBugReport &BR) {
1893  const ExplodedNode *Pred = Succ->getFirstPred();
1894  if (IsSatisfied)
1895    return nullptr;
1896
1897  // Start tracking after we see the first state in which the value is null.
1898  if (!IsTrackingTurnedOn)
1899    if (Succ->getState()->isNull(V).isConstrainedTrue())
1900      IsTrackingTurnedOn = true;
1901  if (!IsTrackingTurnedOn)
1902    return nullptr;
1903
1904  // Check if in the previous state it was feasible for this value
1905  // to *not* be null.
1906  if (!Pred->getState()->isNull(V).isConstrainedTrue() &&
1907      Succ->getState()->isNull(V).isConstrainedTrue()) {
1908    IsSatisfied = true;
1909
1910    // Check if this is inlined defensive checks.
1911    const LocationContext *CurLC = Succ->getLocationContext();
1912    const LocationContext *ReportLC = BR.getErrorNode()->getLocationContext();
1913    if (CurLC != ReportLC && !CurLC->isParentOf(ReportLC)) {
1914      BR.markInvalid("Suppress IDC", CurLC);
1915      return nullptr;
1916    }
1917
1918    // Treat defensive checks in function-like macros as if they were an inlined
1919    // defensive check. If the bug location is not in a macro and the
1920    // terminator for the current location is in a macro then suppress the
1921    // warning.
1922    auto BugPoint = BR.getErrorNode()->getLocation().getAs<StmtPoint>();
1923
1924    if (!BugPoint)
1925      return nullptr;
1926
1927    ProgramPoint CurPoint = Succ->getLocation();
1928    const Stmt *CurTerminatorStmt = nullptr;
1929    if (auto BE = CurPoint.getAs<BlockEdge>()) {
1930      CurTerminatorStmt = BE->getSrc()->getTerminator().getStmt();
1931    } else if (auto SP = CurPoint.getAs<StmtPoint>()) {
1932      const Stmt *CurStmt = SP->getStmt();
1933      if (!CurStmt->getBeginLoc().isMacroID())
1934        return nullptr;
1935
1936      CFGStmtMap *Map = CurLC->getAnalysisDeclContext()->getCFGStmtMap();
1937      CurTerminatorStmt = Map->getBlock(CurStmt)->getTerminatorStmt();
1938    } else {
1939      return nullptr;
1940    }
1941
1942    if (!CurTerminatorStmt)
1943      return nullptr;
1944
1945    SourceLocation TerminatorLoc = CurTerminatorStmt->getBeginLoc();
1946    if (TerminatorLoc.isMacroID()) {
1947      SourceLocation BugLoc = BugPoint->getStmt()->getBeginLoc();
1948
1949      // Suppress reports unless we are in that same macro.
1950      if (!BugLoc.isMacroID() ||
1951          getMacroName(BugLoc, BRC) != getMacroName(TerminatorLoc, BRC)) {
1952        BR.markInvalid("Suppress Macro IDC", CurLC);
1953      }
1954      return nullptr;
1955    }
1956  }
1957  return nullptr;
1958}
1959
1960//===----------------------------------------------------------------------===//
1961// TrackControlDependencyCondBRVisitor.
1962//===----------------------------------------------------------------------===//
1963
1964namespace {
1965/// Tracks the expressions that are a control dependency of the node that was
1966/// supplied to the constructor.
1967/// For example:
1968///
1969///   cond = 1;
1970///   if (cond)
1971///     10 / 0;
1972///
1973/// An error is emitted at line 3. This visitor realizes that the branch
1974/// on line 2 is a control dependency of line 3, and tracks it's condition via
1975/// trackExpressionValue().
1976class TrackControlDependencyCondBRVisitor final
1977    : public TrackingBugReporterVisitor {
1978  const ExplodedNode *Origin;
1979  ControlDependencyCalculator ControlDeps;
1980  llvm::SmallSet<const CFGBlock *, 32> VisitedBlocks;
1981
1982public:
1983  TrackControlDependencyCondBRVisitor(TrackerRef ParentTracker,
1984                                      const ExplodedNode *O)
1985      : TrackingBugReporterVisitor(ParentTracker), Origin(O),
1986        ControlDeps(&O->getCFG()) {}
1987
1988  void Profile(llvm::FoldingSetNodeID &ID) const override {
1989    static int x = 0;
1990    ID.AddPointer(&x);
1991  }
1992
1993  PathDiagnosticPieceRef VisitNode(const ExplodedNode *N,
1994                                   BugReporterContext &BRC,
1995                                   PathSensitiveBugReport &BR) override;
1996};
1997} // end of anonymous namespace
1998
1999static std::shared_ptr<PathDiagnosticEventPiece>
2000constructDebugPieceForTrackedCondition(const Expr *Cond,
2001                                       const ExplodedNode *N,
2002                                       BugReporterContext &BRC) {
2003
2004  if (BRC.getAnalyzerOptions().AnalysisDiagOpt == PD_NONE ||
2005      !BRC.getAnalyzerOptions().ShouldTrackConditionsDebug)
2006    return nullptr;
2007
2008  std::string ConditionText = std::string(Lexer::getSourceText(
2009      CharSourceRange::getTokenRange(Cond->getSourceRange()),
2010      BRC.getSourceManager(), BRC.getASTContext().getLangOpts()));
2011
2012  return std::make_shared<PathDiagnosticEventPiece>(
2013      PathDiagnosticLocation::createBegin(
2014          Cond, BRC.getSourceManager(), N->getLocationContext()),
2015          (Twine() + "Tracking condition '" + ConditionText + "'").str());
2016}
2017
2018static bool isAssertlikeBlock(const CFGBlock *B, ASTContext &Context) {
2019  if (B->succ_size() != 2)
2020    return false;
2021
2022  const CFGBlock *Then = B->succ_begin()->getReachableBlock();
2023  const CFGBlock *Else = (B->succ_begin() + 1)->getReachableBlock();
2024
2025  if (!Then || !Else)
2026    return false;
2027
2028  if (Then->isInevitablySinking() != Else->isInevitablySinking())
2029    return true;
2030
2031  // For the following condition the following CFG would be built:
2032  //
2033  //                          ------------->
2034  //                         /              \
2035  //                       [B1] -> [B2] -> [B3] -> [sink]
2036  // assert(A && B || C);            \       \
2037  //                                  -----------> [go on with the execution]
2038  //
2039  // It so happens that CFGBlock::getTerminatorCondition returns 'A' for block
2040  // B1, 'A && B' for B2, and 'A && B || C' for B3. Let's check whether we
2041  // reached the end of the condition!
2042  if (const Stmt *ElseCond = Else->getTerminatorCondition())
2043    if (const auto *BinOp = dyn_cast<BinaryOperator>(ElseCond))
2044      if (BinOp->isLogicalOp())
2045        return isAssertlikeBlock(Else, Context);
2046
2047  return false;
2048}
2049
2050PathDiagnosticPieceRef
2051TrackControlDependencyCondBRVisitor::VisitNode(const ExplodedNode *N,
2052                                               BugReporterContext &BRC,
2053                                               PathSensitiveBugReport &BR) {
2054  // We can only reason about control dependencies within the same stack frame.
2055  if (Origin->getStackFrame() != N->getStackFrame())
2056    return nullptr;
2057
2058  CFGBlock *NB = const_cast<CFGBlock *>(N->getCFGBlock());
2059
2060  // Skip if we already inspected this block.
2061  if (!VisitedBlocks.insert(NB).second)
2062    return nullptr;
2063
2064  CFGBlock *OriginB = const_cast<CFGBlock *>(Origin->getCFGBlock());
2065
2066  // TODO: Cache CFGBlocks for each ExplodedNode.
2067  if (!OriginB || !NB)
2068    return nullptr;
2069
2070  if (isAssertlikeBlock(NB, BRC.getASTContext()))
2071    return nullptr;
2072
2073  if (ControlDeps.isControlDependent(OriginB, NB)) {
2074    // We don't really want to explain for range loops. Evidence suggests that
2075    // the only thing that leads to is the addition of calls to operator!=.
2076    if (llvm::isa_and_nonnull<CXXForRangeStmt>(NB->getTerminatorStmt()))
2077      return nullptr;
2078
2079    if (const Expr *Condition = NB->getLastCondition()) {
2080
2081      // If we can't retrieve a sensible condition, just bail out.
2082      const Expr *InnerExpr = peelOffOuterExpr(Condition, N);
2083      if (!InnerExpr)
2084        return nullptr;
2085
2086      // If the condition was a function call, we likely won't gain much from
2087      // tracking it either. Evidence suggests that it will mostly trigger in
2088      // scenarios like this:
2089      //
2090      //   void f(int *x) {
2091      //     x = nullptr;
2092      //     if (alwaysTrue()) // We don't need a whole lot of explanation
2093      //                       // here, the function name is good enough.
2094      //       *x = 5;
2095      //   }
2096      //
2097      // Its easy to create a counterexample where this heuristic would make us
2098      // lose valuable information, but we've never really seen one in practice.
2099      if (isa<CallExpr>(InnerExpr))
2100        return nullptr;
2101
2102      // Keeping track of the already tracked conditions on a visitor level
2103      // isn't sufficient, because a new visitor is created for each tracked
2104      // expression, hence the BugReport level set.
2105      if (BR.addTrackedCondition(N)) {
2106        getParentTracker().track(InnerExpr, N,
2107                                 {bugreporter::TrackingKind::Condition,
2108                                  /*EnableNullFPSuppression=*/false});
2109        return constructDebugPieceForTrackedCondition(Condition, N, BRC);
2110      }
2111    }
2112  }
2113
2114  return nullptr;
2115}
2116
2117//===----------------------------------------------------------------------===//
2118// Implementation of trackExpressionValue.
2119//===----------------------------------------------------------------------===//
2120
2121static const Expr *peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N) {
2122
2123  Ex = Ex->IgnoreParenCasts();
2124  if (const auto *FE = dyn_cast<FullExpr>(Ex))
2125    return peelOffOuterExpr(FE->getSubExpr(), N);
2126  if (const auto *OVE = dyn_cast<OpaqueValueExpr>(Ex))
2127    return peelOffOuterExpr(OVE->getSourceExpr(), N);
2128  if (const auto *POE = dyn_cast<PseudoObjectExpr>(Ex)) {
2129    const auto *PropRef = dyn_cast<ObjCPropertyRefExpr>(POE->getSyntacticForm());
2130    if (PropRef && PropRef->isMessagingGetter()) {
2131      const Expr *GetterMessageSend =
2132          POE->getSemanticExpr(POE->getNumSemanticExprs() - 1);
2133      assert(isa<ObjCMessageExpr>(GetterMessageSend->IgnoreParenCasts()));
2134      return peelOffOuterExpr(GetterMessageSend, N);
2135    }
2136  }
2137
2138  // Peel off the ternary operator.
2139  if (const auto *CO = dyn_cast<ConditionalOperator>(Ex)) {
2140    // Find a node where the branching occurred and find out which branch
2141    // we took (true/false) by looking at the ExplodedGraph.
2142    const ExplodedNode *NI = N;
2143    do {
2144      ProgramPoint ProgPoint = NI->getLocation();
2145      if (std::optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) {
2146        const CFGBlock *srcBlk = BE->getSrc();
2147        if (const Stmt *term = srcBlk->getTerminatorStmt()) {
2148          if (term == CO) {
2149            bool TookTrueBranch = (*(srcBlk->succ_begin()) == BE->getDst());
2150            if (TookTrueBranch)
2151              return peelOffOuterExpr(CO->getTrueExpr(), N);
2152            else
2153              return peelOffOuterExpr(CO->getFalseExpr(), N);
2154          }
2155        }
2156      }
2157      NI = NI->getFirstPred();
2158    } while (NI);
2159  }
2160
2161  if (auto *BO = dyn_cast<BinaryOperator>(Ex))
2162    if (const Expr *SubEx = peelOffPointerArithmetic(BO))
2163      return peelOffOuterExpr(SubEx, N);
2164
2165  if (auto *UO = dyn_cast<UnaryOperator>(Ex)) {
2166    if (UO->getOpcode() == UO_LNot)
2167      return peelOffOuterExpr(UO->getSubExpr(), N);
2168
2169    // FIXME: There's a hack in our Store implementation that always computes
2170    // field offsets around null pointers as if they are always equal to 0.
2171    // The idea here is to report accesses to fields as null dereferences
2172    // even though the pointer value that's being dereferenced is actually
2173    // the offset of the field rather than exactly 0.
2174    // See the FIXME in StoreManager's getLValueFieldOrIvar() method.
2175    // This code interacts heavily with this hack; otherwise the value
2176    // would not be null at all for most fields, so we'd be unable to track it.
2177    if (UO->getOpcode() == UO_AddrOf && UO->getSubExpr()->isLValue())
2178      if (const Expr *DerefEx = bugreporter::getDerefExpr(UO->getSubExpr()))
2179        return peelOffOuterExpr(DerefEx, N);
2180  }
2181
2182  return Ex;
2183}
2184
2185/// Find the ExplodedNode where the lvalue (the value of 'Ex')
2186/// was computed.
2187static const ExplodedNode* findNodeForExpression(const ExplodedNode *N,
2188                                                 const Expr *Inner) {
2189  while (N) {
2190    if (N->getStmtForDiagnostics() == Inner)
2191      return N;
2192    N = N->getFirstPred();
2193  }
2194  return N;
2195}
2196
2197//===----------------------------------------------------------------------===//
2198//                            Tracker implementation
2199//===----------------------------------------------------------------------===//
2200
2201PathDiagnosticPieceRef StoreHandler::constructNote(StoreInfo SI,
2202                                                   BugReporterContext &BRC,
2203                                                   StringRef NodeText) {
2204  // Construct a new PathDiagnosticPiece.
2205  ProgramPoint P = SI.StoreSite->getLocation();
2206  PathDiagnosticLocation L;
2207  if (P.getAs<CallEnter>() && SI.SourceOfTheValue)
2208    L = PathDiagnosticLocation(SI.SourceOfTheValue, BRC.getSourceManager(),
2209                               P.getLocationContext());
2210
2211  if (!L.isValid() || !L.asLocation().isValid())
2212    L = PathDiagnosticLocation::create(P, BRC.getSourceManager());
2213
2214  if (!L.isValid() || !L.asLocation().isValid())
2215    return nullptr;
2216
2217  return std::make_shared<PathDiagnosticEventPiece>(L, NodeText);
2218}
2219
2220namespace {
2221class DefaultStoreHandler final : public StoreHandler {
2222public:
2223  using StoreHandler::StoreHandler;
2224
2225  PathDiagnosticPieceRef handle(StoreInfo SI, BugReporterContext &BRC,
2226                                TrackingOptions Opts) override {
2227    // Okay, we've found the binding. Emit an appropriate message.
2228    SmallString<256> Buffer;
2229    llvm::raw_svector_ostream OS(Buffer);
2230
2231    switch (SI.StoreKind) {
2232    case StoreInfo::Initialization:
2233    case StoreInfo::BlockCapture:
2234      showBRDiagnostics(OS, SI);
2235      break;
2236    case StoreInfo::CallArgument:
2237      showBRParamDiagnostics(OS, SI);
2238      break;
2239    case StoreInfo::Assignment:
2240      showBRDefaultDiagnostics(OS, SI);
2241      break;
2242    }
2243
2244    if (Opts.Kind == bugreporter::TrackingKind::Condition)
2245      OS << WillBeUsedForACondition;
2246
2247    return constructNote(SI, BRC, OS.str());
2248  }
2249};
2250
2251class ControlDependencyHandler final : public ExpressionHandler {
2252public:
2253  using ExpressionHandler::ExpressionHandler;
2254
2255  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2256                         const ExplodedNode *LVNode,
2257                         TrackingOptions Opts) override {
2258    PathSensitiveBugReport &Report = getParentTracker().getReport();
2259
2260    // We only track expressions if we believe that they are important. Chances
2261    // are good that control dependencies to the tracking point are also
2262    // important because of this, let's explain why we believe control reached
2263    // this point.
2264    // TODO: Shouldn't we track control dependencies of every bug location,
2265    // rather than only tracked expressions?
2266    if (LVNode->getState()
2267            ->getAnalysisManager()
2268            .getAnalyzerOptions()
2269            .ShouldTrackConditions) {
2270      Report.addVisitor<TrackControlDependencyCondBRVisitor>(
2271          &getParentTracker(), InputNode);
2272      return {/*FoundSomethingToTrack=*/true};
2273    }
2274
2275    return {};
2276  }
2277};
2278
2279class NilReceiverHandler final : public ExpressionHandler {
2280public:
2281  using ExpressionHandler::ExpressionHandler;
2282
2283  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2284                         const ExplodedNode *LVNode,
2285                         TrackingOptions Opts) override {
2286    // The message send could be nil due to the receiver being nil.
2287    // At this point in the path, the receiver should be live since we are at
2288    // the message send expr. If it is nil, start tracking it.
2289    if (const Expr *Receiver =
2290            NilReceiverBRVisitor::getNilReceiver(Inner, LVNode))
2291      return getParentTracker().track(Receiver, LVNode, Opts);
2292
2293    return {};
2294  }
2295};
2296
2297class ArrayIndexHandler final : public ExpressionHandler {
2298public:
2299  using ExpressionHandler::ExpressionHandler;
2300
2301  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2302                         const ExplodedNode *LVNode,
2303                         TrackingOptions Opts) override {
2304    // Track the index if this is an array subscript.
2305    if (const auto *Arr = dyn_cast<ArraySubscriptExpr>(Inner))
2306      return getParentTracker().track(
2307          Arr->getIdx(), LVNode,
2308          {Opts.Kind, /*EnableNullFPSuppression*/ false});
2309
2310    return {};
2311  }
2312};
2313
2314// TODO: extract it into more handlers
2315class InterestingLValueHandler final : public ExpressionHandler {
2316public:
2317  using ExpressionHandler::ExpressionHandler;
2318
2319  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2320                         const ExplodedNode *LVNode,
2321                         TrackingOptions Opts) override {
2322    ProgramStateRef LVState = LVNode->getState();
2323    const StackFrameContext *SFC = LVNode->getStackFrame();
2324    PathSensitiveBugReport &Report = getParentTracker().getReport();
2325    Tracker::Result Result;
2326
2327    // See if the expression we're interested refers to a variable.
2328    // If so, we can track both its contents and constraints on its value.
2329    if (ExplodedGraph::isInterestingLValueExpr(Inner)) {
2330      SVal LVal = LVNode->getSVal(Inner);
2331
2332      const MemRegion *RR = getLocationRegionIfReference(Inner, LVNode);
2333      bool LVIsNull = LVState->isNull(LVal).isConstrainedTrue();
2334
2335      // If this is a C++ reference to a null pointer, we are tracking the
2336      // pointer. In addition, we should find the store at which the reference
2337      // got initialized.
2338      if (RR && !LVIsNull)
2339        Result.combineWith(getParentTracker().track(LVal, RR, Opts, SFC));
2340
2341      // In case of C++ references, we want to differentiate between a null
2342      // reference and reference to null pointer.
2343      // If the LVal is null, check if we are dealing with null reference.
2344      // For those, we want to track the location of the reference.
2345      const MemRegion *R =
2346          (RR && LVIsNull) ? RR : LVNode->getSVal(Inner).getAsRegion();
2347
2348      if (R) {
2349
2350        // Mark both the variable region and its contents as interesting.
2351        SVal V = LVState->getRawSVal(loc::MemRegionVal(R));
2352        Report.addVisitor<NoStoreFuncVisitor>(cast<SubRegion>(R), Opts.Kind);
2353
2354        // When we got here, we do have something to track, and we will
2355        // interrupt.
2356        Result.FoundSomethingToTrack = true;
2357        Result.WasInterrupted = true;
2358
2359        MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary(
2360            LVNode, R, Opts.EnableNullFPSuppression, Report, V);
2361
2362        Report.markInteresting(V, Opts.Kind);
2363        Report.addVisitor<UndefOrNullArgVisitor>(R);
2364
2365        // If the contents are symbolic and null, find out when they became
2366        // null.
2367        if (V.getAsLocSymbol(/*IncludeBaseRegions=*/true))
2368          if (LVState->isNull(V).isConstrainedTrue())
2369            Report.addVisitor<TrackConstraintBRVisitor>(V.castAs<DefinedSVal>(),
2370                                                        false);
2371
2372        // Add visitor, which will suppress inline defensive checks.
2373        if (auto DV = V.getAs<DefinedSVal>())
2374          if (!DV->isZeroConstant() && Opts.EnableNullFPSuppression)
2375            // Note that LVNode may be too late (i.e., too far from the
2376            // InputNode) because the lvalue may have been computed before the
2377            // inlined call was evaluated. InputNode may as well be too early
2378            // here, because the symbol is already dead; this, however, is fine
2379            // because we can still find the node in which it collapsed to null
2380            // previously.
2381            Report.addVisitor<SuppressInlineDefensiveChecksVisitor>(*DV,
2382                                                                    InputNode);
2383        getParentTracker().track(V, R, Opts, SFC);
2384      }
2385    }
2386
2387    return Result;
2388  }
2389};
2390
2391/// Adds a ReturnVisitor if the given statement represents a call that was
2392/// inlined.
2393///
2394/// This will search back through the ExplodedGraph, starting from the given
2395/// node, looking for when the given statement was processed. If it turns out
2396/// the statement is a call that was inlined, we add the visitor to the
2397/// bug report, so it can print a note later.
2398class InlinedFunctionCallHandler final : public ExpressionHandler {
2399  using ExpressionHandler::ExpressionHandler;
2400
2401  Tracker::Result handle(const Expr *E, const ExplodedNode *InputNode,
2402                         const ExplodedNode *ExprNode,
2403                         TrackingOptions Opts) override {
2404    if (!CallEvent::isCallStmt(E))
2405      return {};
2406
2407    // First, find when we processed the statement.
2408    // If we work with a 'CXXNewExpr' that is going to be purged away before
2409    // its call take place. We would catch that purge in the last condition
2410    // as a 'StmtPoint' so we have to bypass it.
2411    const bool BypassCXXNewExprEval = isa<CXXNewExpr>(E);
2412
2413    // This is moving forward when we enter into another context.
2414    const StackFrameContext *CurrentSFC = ExprNode->getStackFrame();
2415
2416    do {
2417      // If that is satisfied we found our statement as an inlined call.
2418      if (std::optional<CallExitEnd> CEE =
2419              ExprNode->getLocationAs<CallExitEnd>())
2420        if (CEE->getCalleeContext()->getCallSite() == E)
2421          break;
2422
2423      // Try to move forward to the end of the call-chain.
2424      ExprNode = ExprNode->getFirstPred();
2425      if (!ExprNode)
2426        break;
2427
2428      const StackFrameContext *PredSFC = ExprNode->getStackFrame();
2429
2430      // If that is satisfied we found our statement.
2431      // FIXME: This code currently bypasses the call site for the
2432      //        conservatively evaluated allocator.
2433      if (!BypassCXXNewExprEval)
2434        if (std::optional<StmtPoint> SP = ExprNode->getLocationAs<StmtPoint>())
2435          // See if we do not enter into another context.
2436          if (SP->getStmt() == E && CurrentSFC == PredSFC)
2437            break;
2438
2439      CurrentSFC = PredSFC;
2440    } while (ExprNode->getStackFrame() == CurrentSFC);
2441
2442    // Next, step over any post-statement checks.
2443    while (ExprNode && ExprNode->getLocation().getAs<PostStmt>())
2444      ExprNode = ExprNode->getFirstPred();
2445    if (!ExprNode)
2446      return {};
2447
2448    // Finally, see if we inlined the call.
2449    std::optional<CallExitEnd> CEE = ExprNode->getLocationAs<CallExitEnd>();
2450    if (!CEE)
2451      return {};
2452
2453    const StackFrameContext *CalleeContext = CEE->getCalleeContext();
2454    if (CalleeContext->getCallSite() != E)
2455      return {};
2456
2457    // Check the return value.
2458    ProgramStateRef State = ExprNode->getState();
2459    SVal RetVal = ExprNode->getSVal(E);
2460
2461    // Handle cases where a reference is returned and then immediately used.
2462    if (cast<Expr>(E)->isGLValue())
2463      if (std::optional<Loc> LValue = RetVal.getAs<Loc>())
2464        RetVal = State->getSVal(*LValue);
2465
2466    // See if the return value is NULL. If so, suppress the report.
2467    AnalyzerOptions &Options = State->getAnalysisManager().options;
2468
2469    bool EnableNullFPSuppression = false;
2470    if (Opts.EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths)
2471      if (std::optional<Loc> RetLoc = RetVal.getAs<Loc>())
2472        EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
2473
2474    PathSensitiveBugReport &Report = getParentTracker().getReport();
2475    Report.addVisitor<ReturnVisitor>(&getParentTracker(), CalleeContext,
2476                                     EnableNullFPSuppression, Options,
2477                                     Opts.Kind);
2478    return {true};
2479  }
2480};
2481
2482class DefaultExpressionHandler final : public ExpressionHandler {
2483public:
2484  using ExpressionHandler::ExpressionHandler;
2485
2486  Tracker::Result handle(const Expr *Inner, const ExplodedNode *InputNode,
2487                         const ExplodedNode *LVNode,
2488                         TrackingOptions Opts) override {
2489    ProgramStateRef LVState = LVNode->getState();
2490    const StackFrameContext *SFC = LVNode->getStackFrame();
2491    PathSensitiveBugReport &Report = getParentTracker().getReport();
2492    Tracker::Result Result;
2493
2494    // If the expression is not an "lvalue expression", we can still
2495    // track the constraints on its contents.
2496    SVal V = LVState->getSValAsScalarOrLoc(Inner, LVNode->getLocationContext());
2497
2498    // Is it a symbolic value?
2499    if (auto L = V.getAs<loc::MemRegionVal>()) {
2500      // FIXME: this is a hack for fixing a later crash when attempting to
2501      // dereference a void* pointer.
2502      // We should not try to dereference pointers at all when we don't care
2503      // what is written inside the pointer.
2504      bool CanDereference = true;
2505      if (const auto *SR = L->getRegionAs<SymbolicRegion>()) {
2506        if (SR->getPointeeStaticType()->isVoidType())
2507          CanDereference = false;
2508      } else if (L->getRegionAs<AllocaRegion>())
2509        CanDereference = false;
2510
2511      // At this point we are dealing with the region's LValue.
2512      // However, if the rvalue is a symbolic region, we should track it as
2513      // well. Try to use the correct type when looking up the value.
2514      SVal RVal;
2515      if (ExplodedGraph::isInterestingLValueExpr(Inner))
2516        RVal = LVState->getRawSVal(*L, Inner->getType());
2517      else if (CanDereference)
2518        RVal = LVState->getSVal(L->getRegion());
2519
2520      if (CanDereference) {
2521        Report.addVisitor<UndefOrNullArgVisitor>(L->getRegion());
2522        Result.FoundSomethingToTrack = true;
2523
2524        if (auto KV = RVal.getAs<KnownSVal>())
2525          Result.combineWith(
2526              getParentTracker().track(*KV, L->getRegion(), Opts, SFC));
2527      }
2528
2529      const MemRegion *RegionRVal = RVal.getAsRegion();
2530      if (isa_and_nonnull<SymbolicRegion>(RegionRVal)) {
2531        Report.markInteresting(RegionRVal, Opts.Kind);
2532        Report.addVisitor<TrackConstraintBRVisitor>(
2533            loc::MemRegionVal(RegionRVal),
2534            /*assumption=*/false);
2535        Result.FoundSomethingToTrack = true;
2536      }
2537    }
2538
2539    return Result;
2540  }
2541};
2542
2543/// Attempts to add visitors to track an RValue expression back to its point of
2544/// origin.
2545class PRValueHandler final : public ExpressionHandler {
2546public:
2547  using ExpressionHandler::ExpressionHandler;
2548
2549  Tracker::Result handle(const Expr *E, const ExplodedNode *InputNode,
2550                         const ExplodedNode *ExprNode,
2551                         TrackingOptions Opts) override {
2552    if (!E->isPRValue())
2553      return {};
2554
2555    const ExplodedNode *RVNode = findNodeForExpression(ExprNode, E);
2556    if (!RVNode)
2557      return {};
2558
2559    Tracker::Result CombinedResult;
2560    Tracker &Parent = getParentTracker();
2561
2562    const auto track = [&CombinedResult, &Parent, ExprNode,
2563                        Opts](const Expr *Inner) {
2564      CombinedResult.combineWith(Parent.track(Inner, ExprNode, Opts));
2565    };
2566
2567    // FIXME: Initializer lists can appear in many different contexts
2568    // and most of them needs a special handling. For now let's handle
2569    // what we can. If the initializer list only has 1 element, we track
2570    // that.
2571    // This snippet even handles nesting, e.g.: int *x{{{{{y}}}}};
2572    if (const auto *ILE = dyn_cast<InitListExpr>(E)) {
2573      if (ILE->getNumInits() == 1) {
2574        track(ILE->getInit(0));
2575
2576        return CombinedResult;
2577      }
2578
2579      return {};
2580    }
2581
2582    ProgramStateRef RVState = RVNode->getState();
2583    SVal V = RVState->getSValAsScalarOrLoc(E, RVNode->getLocationContext());
2584    const auto *BO = dyn_cast<BinaryOperator>(E);
2585
2586    if (!BO || !BO->isMultiplicativeOp() || !V.isZeroConstant())
2587      return {};
2588
2589    SVal RHSV = RVState->getSVal(BO->getRHS(), RVNode->getLocationContext());
2590    SVal LHSV = RVState->getSVal(BO->getLHS(), RVNode->getLocationContext());
2591
2592    // Track both LHS and RHS of a multiplication.
2593    if (BO->getOpcode() == BO_Mul) {
2594      if (LHSV.isZeroConstant())
2595        track(BO->getLHS());
2596      if (RHSV.isZeroConstant())
2597        track(BO->getRHS());
2598    } else { // Track only the LHS of a division or a modulo.
2599      if (LHSV.isZeroConstant())
2600        track(BO->getLHS());
2601    }
2602
2603    return CombinedResult;
2604  }
2605};
2606} // namespace
2607
2608Tracker::Tracker(PathSensitiveBugReport &Report) : Report(Report) {
2609  // Default expression handlers.
2610  addLowPriorityHandler<ControlDependencyHandler>();
2611  addLowPriorityHandler<NilReceiverHandler>();
2612  addLowPriorityHandler<ArrayIndexHandler>();
2613  addLowPriorityHandler<InterestingLValueHandler>();
2614  addLowPriorityHandler<InlinedFunctionCallHandler>();
2615  addLowPriorityHandler<DefaultExpressionHandler>();
2616  addLowPriorityHandler<PRValueHandler>();
2617  // Default store handlers.
2618  addHighPriorityHandler<DefaultStoreHandler>();
2619}
2620
2621Tracker::Result Tracker::track(const Expr *E, const ExplodedNode *N,
2622                               TrackingOptions Opts) {
2623  if (!E || !N)
2624    return {};
2625
2626  const Expr *Inner = peelOffOuterExpr(E, N);
2627  const ExplodedNode *LVNode = findNodeForExpression(N, Inner);
2628  if (!LVNode)
2629    return {};
2630
2631  Result CombinedResult;
2632  // Iterate through the handlers in the order according to their priorities.
2633  for (ExpressionHandlerPtr &Handler : ExpressionHandlers) {
2634    CombinedResult.combineWith(Handler->handle(Inner, N, LVNode, Opts));
2635    if (CombinedResult.WasInterrupted) {
2636      // There is no need to confuse our users here.
2637      // We got interrupted, but our users don't need to know about it.
2638      CombinedResult.WasInterrupted = false;
2639      break;
2640    }
2641  }
2642
2643  return CombinedResult;
2644}
2645
2646Tracker::Result Tracker::track(SVal V, const MemRegion *R, TrackingOptions Opts,
2647                               const StackFrameContext *Origin) {
2648  if (auto KV = V.getAs<KnownSVal>()) {
2649    Report.addVisitor<StoreSiteFinder>(this, *KV, R, Opts, Origin);
2650    return {true};
2651  }
2652  return {};
2653}
2654
2655PathDiagnosticPieceRef Tracker::handle(StoreInfo SI, BugReporterContext &BRC,
2656                                       TrackingOptions Opts) {
2657  // Iterate through the handlers in the order according to their priorities.
2658  for (StoreHandlerPtr &Handler : StoreHandlers) {
2659    if (PathDiagnosticPieceRef Result = Handler->handle(SI, BRC, Opts))
2660      // If the handler produced a non-null piece, return it.
2661      // There is no need in asking other handlers.
2662      return Result;
2663  }
2664  return {};
2665}
2666
2667bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
2668                                       const Expr *E,
2669
2670                                       PathSensitiveBugReport &Report,
2671                                       TrackingOptions Opts) {
2672  return Tracker::create(Report)
2673      ->track(E, InputNode, Opts)
2674      .FoundSomethingToTrack;
2675}
2676
2677void bugreporter::trackStoredValue(KnownSVal V, const MemRegion *R,
2678                                   PathSensitiveBugReport &Report,
2679                                   TrackingOptions Opts,
2680                                   const StackFrameContext *Origin) {
2681  Tracker::create(Report)->track(V, R, Opts, Origin);
2682}
2683
2684//===----------------------------------------------------------------------===//
2685// Implementation of NulReceiverBRVisitor.
2686//===----------------------------------------------------------------------===//
2687
2688const Expr *NilReceiverBRVisitor::getNilReceiver(const Stmt *S,
2689                                                 const ExplodedNode *N) {
2690  const auto *ME = dyn_cast<ObjCMessageExpr>(S);
2691  if (!ME)
2692    return nullptr;
2693  if (const Expr *Receiver = ME->getInstanceReceiver()) {
2694    ProgramStateRef state = N->getState();
2695    SVal V = N->getSVal(Receiver);
2696    if (state->isNull(V).isConstrainedTrue())
2697      return Receiver;
2698  }
2699  return nullptr;
2700}
2701
2702PathDiagnosticPieceRef
2703NilReceiverBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
2704                                PathSensitiveBugReport &BR) {
2705  std::optional<PreStmt> P = N->getLocationAs<PreStmt>();
2706  if (!P)
2707    return nullptr;
2708
2709  const Stmt *S = P->getStmt();
2710  const Expr *Receiver = getNilReceiver(S, N);
2711  if (!Receiver)
2712    return nullptr;
2713
2714  llvm::SmallString<256> Buf;
2715  llvm::raw_svector_ostream OS(Buf);
2716
2717  if (const auto *ME = dyn_cast<ObjCMessageExpr>(S)) {
2718    OS << "'";
2719    ME->getSelector().print(OS);
2720    OS << "' not called";
2721  }
2722  else {
2723    OS << "No method is called";
2724  }
2725  OS << " because the receiver is nil";
2726
2727  // The receiver was nil, and hence the method was skipped.
2728  // Register a BugReporterVisitor to issue a message telling us how
2729  // the receiver was null.
2730  bugreporter::trackExpressionValue(N, Receiver, BR,
2731                                    {bugreporter::TrackingKind::Thorough,
2732                                     /*EnableNullFPSuppression*/ false});
2733  // Issue a message saying that the method was skipped.
2734  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
2735                                     N->getLocationContext());
2736  return std::make_shared<PathDiagnosticEventPiece>(L, OS.str());
2737}
2738
2739//===----------------------------------------------------------------------===//
2740// Visitor that tries to report interesting diagnostics from conditions.
2741//===----------------------------------------------------------------------===//
2742
2743/// Return the tag associated with this visitor.  This tag will be used
2744/// to make all PathDiagnosticPieces created by this visitor.
2745const char *ConditionBRVisitor::getTag() { return "ConditionBRVisitor"; }
2746
2747PathDiagnosticPieceRef
2748ConditionBRVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
2749                              PathSensitiveBugReport &BR) {
2750  auto piece = VisitNodeImpl(N, BRC, BR);
2751  if (piece) {
2752    piece->setTag(getTag());
2753    if (auto *ev = dyn_cast<PathDiagnosticEventPiece>(piece.get()))
2754      ev->setPrunable(true, /* override */ false);
2755  }
2756  return piece;
2757}
2758
2759PathDiagnosticPieceRef
2760ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
2761                                  BugReporterContext &BRC,
2762                                  PathSensitiveBugReport &BR) {
2763  ProgramPoint ProgPoint = N->getLocation();
2764  const std::pair<const ProgramPointTag *, const ProgramPointTag *> &Tags =
2765      ExprEngine::geteagerlyAssumeBinOpBifurcationTags();
2766
2767  // If an assumption was made on a branch, it should be caught
2768  // here by looking at the state transition.
2769  if (std::optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) {
2770    const CFGBlock *SrcBlock = BE->getSrc();
2771    if (const Stmt *Term = SrcBlock->getTerminatorStmt()) {
2772      // If the tag of the previous node is 'Eagerly Assume...' the current
2773      // 'BlockEdge' has the same constraint information. We do not want to
2774      // report the value as it is just an assumption on the predecessor node
2775      // which will be caught in the next VisitNode() iteration as a 'PostStmt'.
2776      const ProgramPointTag *PreviousNodeTag =
2777          N->getFirstPred()->getLocation().getTag();
2778      if (PreviousNodeTag == Tags.first || PreviousNodeTag == Tags.second)
2779        return nullptr;
2780
2781      return VisitTerminator(Term, N, SrcBlock, BE->getDst(), BR, BRC);
2782    }
2783    return nullptr;
2784  }
2785
2786  if (std::optional<PostStmt> PS = ProgPoint.getAs<PostStmt>()) {
2787    const ProgramPointTag *CurrentNodeTag = PS->getTag();
2788    if (CurrentNodeTag != Tags.first && CurrentNodeTag != Tags.second)
2789      return nullptr;
2790
2791    bool TookTrue = CurrentNodeTag == Tags.first;
2792    return VisitTrueTest(cast<Expr>(PS->getStmt()), BRC, BR, N, TookTrue);
2793  }
2794
2795  return nullptr;
2796}
2797
2798PathDiagnosticPieceRef ConditionBRVisitor::VisitTerminator(
2799    const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk,
2800    const CFGBlock *dstBlk, PathSensitiveBugReport &R,
2801    BugReporterContext &BRC) {
2802  const Expr *Cond = nullptr;
2803
2804  // In the code below, Term is a CFG terminator and Cond is a branch condition
2805  // expression upon which the decision is made on this terminator.
2806  //
2807  // For example, in "if (x == 0)", the "if (x == 0)" statement is a terminator,
2808  // and "x == 0" is the respective condition.
2809  //
2810  // Another example: in "if (x && y)", we've got two terminators and two
2811  // conditions due to short-circuit nature of operator "&&":
2812  // 1. The "if (x && y)" statement is a terminator,
2813  //    and "y" is the respective condition.
2814  // 2. Also "x && ..." is another terminator,
2815  //    and "x" is its condition.
2816
2817  switch (Term->getStmtClass()) {
2818  // FIXME: Stmt::SwitchStmtClass is worth handling, however it is a bit
2819  // more tricky because there are more than two branches to account for.
2820  default:
2821    return nullptr;
2822  case Stmt::IfStmtClass:
2823    Cond = cast<IfStmt>(Term)->getCond();
2824    break;
2825  case Stmt::ConditionalOperatorClass:
2826    Cond = cast<ConditionalOperator>(Term)->getCond();
2827    break;
2828  case Stmt::BinaryOperatorClass:
2829    // When we encounter a logical operator (&& or ||) as a CFG terminator,
2830    // then the condition is actually its LHS; otherwise, we'd encounter
2831    // the parent, such as if-statement, as a terminator.
2832    const auto *BO = cast<BinaryOperator>(Term);
2833    assert(BO->isLogicalOp() &&
2834           "CFG terminator is not a short-circuit operator!");
2835    Cond = BO->getLHS();
2836    break;
2837  }
2838
2839  Cond = Cond->IgnoreParens();
2840
2841  // However, when we encounter a logical operator as a branch condition,
2842  // then the condition is actually its RHS, because LHS would be
2843  // the condition for the logical operator terminator.
2844  while (const auto *InnerBO = dyn_cast<BinaryOperator>(Cond)) {
2845    if (!InnerBO->isLogicalOp())
2846      break;
2847    Cond = InnerBO->getRHS()->IgnoreParens();
2848  }
2849
2850  assert(Cond);
2851  assert(srcBlk->succ_size() == 2);
2852  const bool TookTrue = *(srcBlk->succ_begin()) == dstBlk;
2853  return VisitTrueTest(Cond, BRC, R, N, TookTrue);
2854}
2855
2856PathDiagnosticPieceRef
2857ConditionBRVisitor::VisitTrueTest(const Expr *Cond, BugReporterContext &BRC,
2858                                  PathSensitiveBugReport &R,
2859                                  const ExplodedNode *N, bool TookTrue) {
2860  ProgramStateRef CurrentState = N->getState();
2861  ProgramStateRef PrevState = N->getFirstPred()->getState();
2862  const LocationContext *LCtx = N->getLocationContext();
2863
2864  // If the constraint information is changed between the current and the
2865  // previous program state we assuming the newly seen constraint information.
2866  // If we cannot evaluate the condition (and the constraints are the same)
2867  // the analyzer has no information about the value and just assuming it.
2868  bool IsAssuming =
2869      !BRC.getStateManager().haveEqualConstraints(CurrentState, PrevState) ||
2870      CurrentState->getSVal(Cond, LCtx).isUnknownOrUndef();
2871
2872  // These will be modified in code below, but we need to preserve the original
2873  //  values in case we want to throw the generic message.
2874  const Expr *CondTmp = Cond;
2875  bool TookTrueTmp = TookTrue;
2876
2877  while (true) {
2878    CondTmp = CondTmp->IgnoreParenCasts();
2879    switch (CondTmp->getStmtClass()) {
2880      default:
2881        break;
2882      case Stmt::BinaryOperatorClass:
2883        if (auto P = VisitTrueTest(Cond, cast<BinaryOperator>(CondTmp),
2884                                   BRC, R, N, TookTrueTmp, IsAssuming))
2885          return P;
2886        break;
2887      case Stmt::DeclRefExprClass:
2888        if (auto P = VisitTrueTest(Cond, cast<DeclRefExpr>(CondTmp),
2889                                   BRC, R, N, TookTrueTmp, IsAssuming))
2890          return P;
2891        break;
2892      case Stmt::MemberExprClass:
2893        if (auto P = VisitTrueTest(Cond, cast<MemberExpr>(CondTmp),
2894                                   BRC, R, N, TookTrueTmp, IsAssuming))
2895          return P;
2896        break;
2897      case Stmt::UnaryOperatorClass: {
2898        const auto *UO = cast<UnaryOperator>(CondTmp);
2899        if (UO->getOpcode() == UO_LNot) {
2900          TookTrueTmp = !TookTrueTmp;
2901          CondTmp = UO->getSubExpr();
2902          continue;
2903        }
2904        break;
2905      }
2906    }
2907    break;
2908  }
2909
2910  // Condition too complex to explain? Just say something so that the user
2911  // knew we've made some path decision at this point.
2912  // If it is too complex and we know the evaluation of the condition do not
2913  // repeat the note from 'BugReporter.cpp'
2914  if (!IsAssuming)
2915    return nullptr;
2916
2917  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
2918  if (!Loc.isValid() || !Loc.asLocation().isValid())
2919    return nullptr;
2920
2921  return std::make_shared<PathDiagnosticEventPiece>(
2922      Loc, TookTrue ? GenericTrueMessage : GenericFalseMessage);
2923}
2924
2925bool ConditionBRVisitor::patternMatch(const Expr *Ex, const Expr *ParentEx,
2926                                      raw_ostream &Out, BugReporterContext &BRC,
2927                                      PathSensitiveBugReport &report,
2928                                      const ExplodedNode *N,
2929                                      std::optional<bool> &prunable,
2930                                      bool IsSameFieldName) {
2931  const Expr *OriginalExpr = Ex;
2932  Ex = Ex->IgnoreParenCasts();
2933
2934  if (isa<GNUNullExpr, ObjCBoolLiteralExpr, CXXBoolLiteralExpr, IntegerLiteral,
2935          FloatingLiteral>(Ex)) {
2936    // Use heuristics to determine if the expression is a macro
2937    // expanding to a literal and if so, use the macro's name.
2938    SourceLocation BeginLoc = OriginalExpr->getBeginLoc();
2939    SourceLocation EndLoc = OriginalExpr->getEndLoc();
2940    if (BeginLoc.isMacroID() && EndLoc.isMacroID()) {
2941      const SourceManager &SM = BRC.getSourceManager();
2942      const LangOptions &LO = BRC.getASTContext().getLangOpts();
2943      if (Lexer::isAtStartOfMacroExpansion(BeginLoc, SM, LO) &&
2944          Lexer::isAtEndOfMacroExpansion(EndLoc, SM, LO)) {
2945        CharSourceRange R = Lexer::getAsCharRange({BeginLoc, EndLoc}, SM, LO);
2946        Out << Lexer::getSourceText(R, SM, LO);
2947        return false;
2948      }
2949    }
2950  }
2951
2952  if (const auto *DR = dyn_cast<DeclRefExpr>(Ex)) {
2953    const bool quotes = isa<VarDecl>(DR->getDecl());
2954    if (quotes) {
2955      Out << '\'';
2956      const LocationContext *LCtx = N->getLocationContext();
2957      const ProgramState *state = N->getState().get();
2958      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
2959                                                LCtx).getAsRegion()) {
2960        if (report.isInteresting(R))
2961          prunable = false;
2962        else {
2963          const ProgramState *state = N->getState().get();
2964          SVal V = state->getSVal(R);
2965          if (report.isInteresting(V))
2966            prunable = false;
2967        }
2968      }
2969    }
2970    Out << DR->getDecl()->getDeclName().getAsString();
2971    if (quotes)
2972      Out << '\'';
2973    return quotes;
2974  }
2975
2976  if (const auto *IL = dyn_cast<IntegerLiteral>(Ex)) {
2977    QualType OriginalTy = OriginalExpr->getType();
2978    if (OriginalTy->isPointerType()) {
2979      if (IL->getValue() == 0) {
2980        Out << "null";
2981        return false;
2982      }
2983    }
2984    else if (OriginalTy->isObjCObjectPointerType()) {
2985      if (IL->getValue() == 0) {
2986        Out << "nil";
2987        return false;
2988      }
2989    }
2990
2991    Out << IL->getValue();
2992    return false;
2993  }
2994
2995  if (const auto *ME = dyn_cast<MemberExpr>(Ex)) {
2996    if (!IsSameFieldName)
2997      Out << "field '" << ME->getMemberDecl()->getName() << '\'';
2998    else
2999      Out << '\''
3000          << Lexer::getSourceText(
3001                 CharSourceRange::getTokenRange(Ex->getSourceRange()),
3002                 BRC.getSourceManager(), BRC.getASTContext().getLangOpts(),
3003                 nullptr)
3004          << '\'';
3005  }
3006
3007  return false;
3008}
3009
3010PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest(
3011    const Expr *Cond, const BinaryOperator *BExpr, BugReporterContext &BRC,
3012    PathSensitiveBugReport &R, const ExplodedNode *N, bool TookTrue,
3013    bool IsAssuming) {
3014  bool shouldInvert = false;
3015  std::optional<bool> shouldPrune;
3016
3017  // Check if the field name of the MemberExprs is ambiguous. Example:
3018  // " 'a.d' is equal to 'h.d' " in 'test/Analysis/null-deref-path-notes.cpp'.
3019  bool IsSameFieldName = false;
3020  const auto *LhsME = dyn_cast<MemberExpr>(BExpr->getLHS()->IgnoreParenCasts());
3021  const auto *RhsME = dyn_cast<MemberExpr>(BExpr->getRHS()->IgnoreParenCasts());
3022
3023  if (LhsME && RhsME)
3024    IsSameFieldName =
3025        LhsME->getMemberDecl()->getName() == RhsME->getMemberDecl()->getName();
3026
3027  SmallString<128> LhsString, RhsString;
3028  {
3029    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
3030    const bool isVarLHS = patternMatch(BExpr->getLHS(), BExpr, OutLHS, BRC, R,
3031                                       N, shouldPrune, IsSameFieldName);
3032    const bool isVarRHS = patternMatch(BExpr->getRHS(), BExpr, OutRHS, BRC, R,
3033                                       N, shouldPrune, IsSameFieldName);
3034
3035    shouldInvert = !isVarLHS && isVarRHS;
3036  }
3037
3038  BinaryOperator::Opcode Op = BExpr->getOpcode();
3039
3040  if (BinaryOperator::isAssignmentOp(Op)) {
3041    // For assignment operators, all that we care about is that the LHS
3042    // evaluates to "true" or "false".
3043    return VisitConditionVariable(LhsString, BExpr->getLHS(), BRC, R, N,
3044                                  TookTrue);
3045  }
3046
3047  // For non-assignment operations, we require that we can understand
3048  // both the LHS and RHS.
3049  if (LhsString.empty() || RhsString.empty() ||
3050      !BinaryOperator::isComparisonOp(Op) || Op == BO_Cmp)
3051    return nullptr;
3052
3053  // Should we invert the strings if the LHS is not a variable name?
3054  SmallString<256> buf;
3055  llvm::raw_svector_ostream Out(buf);
3056  Out << (IsAssuming ? "Assuming " : "")
3057      << (shouldInvert ? RhsString : LhsString) << " is ";
3058
3059  // Do we need to invert the opcode?
3060  if (shouldInvert)
3061    switch (Op) {
3062      default: break;
3063      case BO_LT: Op = BO_GT; break;
3064      case BO_GT: Op = BO_LT; break;
3065      case BO_LE: Op = BO_GE; break;
3066      case BO_GE: Op = BO_LE; break;
3067    }
3068
3069  if (!TookTrue)
3070    switch (Op) {
3071      case BO_EQ: Op = BO_NE; break;
3072      case BO_NE: Op = BO_EQ; break;
3073      case BO_LT: Op = BO_GE; break;
3074      case BO_GT: Op = BO_LE; break;
3075      case BO_LE: Op = BO_GT; break;
3076      case BO_GE: Op = BO_LT; break;
3077      default:
3078        return nullptr;
3079    }
3080
3081  switch (Op) {
3082    case BO_EQ:
3083      Out << "equal to ";
3084      break;
3085    case BO_NE:
3086      Out << "not equal to ";
3087      break;
3088    default:
3089      Out << BinaryOperator::getOpcodeStr(Op) << ' ';
3090      break;
3091  }
3092
3093  Out << (shouldInvert ? LhsString : RhsString);
3094  const LocationContext *LCtx = N->getLocationContext();
3095  const SourceManager &SM = BRC.getSourceManager();
3096
3097  if (isVarAnInterestingCondition(BExpr->getLHS(), N, &R) ||
3098      isVarAnInterestingCondition(BExpr->getRHS(), N, &R))
3099    Out << WillBeUsedForACondition;
3100
3101  // Convert 'field ...' to 'Field ...' if it is a MemberExpr.
3102  std::string Message = std::string(Out.str());
3103  Message[0] = toupper(Message[0]);
3104
3105  // If we know the value create a pop-up note to the value part of 'BExpr'.
3106  if (!IsAssuming) {
3107    PathDiagnosticLocation Loc;
3108    if (!shouldInvert) {
3109      if (LhsME && LhsME->getMemberLoc().isValid())
3110        Loc = PathDiagnosticLocation(LhsME->getMemberLoc(), SM);
3111      else
3112        Loc = PathDiagnosticLocation(BExpr->getLHS(), SM, LCtx);
3113    } else {
3114      if (RhsME && RhsME->getMemberLoc().isValid())
3115        Loc = PathDiagnosticLocation(RhsME->getMemberLoc(), SM);
3116      else
3117        Loc = PathDiagnosticLocation(BExpr->getRHS(), SM, LCtx);
3118    }
3119
3120    return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Message);
3121  }
3122
3123  PathDiagnosticLocation Loc(Cond, SM, LCtx);
3124  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Message);
3125  if (shouldPrune)
3126    event->setPrunable(*shouldPrune);
3127  return event;
3128}
3129
3130PathDiagnosticPieceRef ConditionBRVisitor::VisitConditionVariable(
3131    StringRef LhsString, const Expr *CondVarExpr, BugReporterContext &BRC,
3132    PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue) {
3133  // FIXME: If there's already a constraint tracker for this variable,
3134  // we shouldn't emit anything here (c.f. the double note in
3135  // test/Analysis/inlining/path-notes.c)
3136  SmallString<256> buf;
3137  llvm::raw_svector_ostream Out(buf);
3138  Out << "Assuming " << LhsString << " is ";
3139
3140  if (!printValue(CondVarExpr, Out, N, TookTrue, /*IsAssuming=*/true))
3141    return nullptr;
3142
3143  const LocationContext *LCtx = N->getLocationContext();
3144  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
3145
3146  if (isVarAnInterestingCondition(CondVarExpr, N, &report))
3147    Out << WillBeUsedForACondition;
3148
3149  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3150
3151  if (isInterestingExpr(CondVarExpr, N, &report))
3152    event->setPrunable(false);
3153
3154  return event;
3155}
3156
3157PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest(
3158    const Expr *Cond, const DeclRefExpr *DRE, BugReporterContext &BRC,
3159    PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue,
3160    bool IsAssuming) {
3161  const auto *VD = dyn_cast<VarDecl>(DRE->getDecl());
3162  if (!VD)
3163    return nullptr;
3164
3165  SmallString<256> Buf;
3166  llvm::raw_svector_ostream Out(Buf);
3167
3168  Out << (IsAssuming ? "Assuming '" : "'") << VD->getDeclName() << "' is ";
3169
3170  if (!printValue(DRE, Out, N, TookTrue, IsAssuming))
3171    return nullptr;
3172
3173  const LocationContext *LCtx = N->getLocationContext();
3174
3175  if (isVarAnInterestingCondition(DRE, N, &report))
3176    Out << WillBeUsedForACondition;
3177
3178  // If we know the value create a pop-up note to the 'DRE'.
3179  if (!IsAssuming) {
3180    PathDiagnosticLocation Loc(DRE, BRC.getSourceManager(), LCtx);
3181    return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
3182  }
3183
3184  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
3185  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3186
3187  if (isInterestingExpr(DRE, N, &report))
3188    event->setPrunable(false);
3189
3190  return std::move(event);
3191}
3192
3193PathDiagnosticPieceRef ConditionBRVisitor::VisitTrueTest(
3194    const Expr *Cond, const MemberExpr *ME, BugReporterContext &BRC,
3195    PathSensitiveBugReport &report, const ExplodedNode *N, bool TookTrue,
3196    bool IsAssuming) {
3197  SmallString<256> Buf;
3198  llvm::raw_svector_ostream Out(Buf);
3199
3200  Out << (IsAssuming ? "Assuming field '" : "Field '")
3201      << ME->getMemberDecl()->getName() << "' is ";
3202
3203  if (!printValue(ME, Out, N, TookTrue, IsAssuming))
3204    return nullptr;
3205
3206  const LocationContext *LCtx = N->getLocationContext();
3207  PathDiagnosticLocation Loc;
3208
3209  // If we know the value create a pop-up note to the member of the MemberExpr.
3210  if (!IsAssuming && ME->getMemberLoc().isValid())
3211    Loc = PathDiagnosticLocation(ME->getMemberLoc(), BRC.getSourceManager());
3212  else
3213    Loc = PathDiagnosticLocation(Cond, BRC.getSourceManager(), LCtx);
3214
3215  if (!Loc.isValid() || !Loc.asLocation().isValid())
3216    return nullptr;
3217
3218  if (isVarAnInterestingCondition(ME, N, &report))
3219    Out << WillBeUsedForACondition;
3220
3221  // If we know the value create a pop-up note.
3222  if (!IsAssuming)
3223    return std::make_shared<PathDiagnosticPopUpPiece>(Loc, Out.str());
3224
3225  auto event = std::make_shared<PathDiagnosticEventPiece>(Loc, Out.str());
3226  if (isInterestingExpr(ME, N, &report))
3227    event->setPrunable(false);
3228  return event;
3229}
3230
3231bool ConditionBRVisitor::printValue(const Expr *CondVarExpr, raw_ostream &Out,
3232                                    const ExplodedNode *N, bool TookTrue,
3233                                    bool IsAssuming) {
3234  QualType Ty = CondVarExpr->getType();
3235
3236  if (Ty->isPointerType()) {
3237    Out << (TookTrue ? "non-null" : "null");
3238    return true;
3239  }
3240
3241  if (Ty->isObjCObjectPointerType()) {
3242    Out << (TookTrue ? "non-nil" : "nil");
3243    return true;
3244  }
3245
3246  if (!Ty->isIntegralOrEnumerationType())
3247    return false;
3248
3249  std::optional<const llvm::APSInt *> IntValue;
3250  if (!IsAssuming)
3251    IntValue = getConcreteIntegerValue(CondVarExpr, N);
3252
3253  if (IsAssuming || !IntValue) {
3254    if (Ty->isBooleanType())
3255      Out << (TookTrue ? "true" : "false");
3256    else
3257      Out << (TookTrue ? "not equal to 0" : "0");
3258  } else {
3259    if (Ty->isBooleanType())
3260      Out << ((*IntValue)->getBoolValue() ? "true" : "false");
3261    else
3262      Out << **IntValue;
3263  }
3264
3265  return true;
3266}
3267
3268constexpr llvm::StringLiteral ConditionBRVisitor::GenericTrueMessage;
3269constexpr llvm::StringLiteral ConditionBRVisitor::GenericFalseMessage;
3270
3271bool ConditionBRVisitor::isPieceMessageGeneric(
3272    const PathDiagnosticPiece *Piece) {
3273  return Piece->getString() == GenericTrueMessage ||
3274         Piece->getString() == GenericFalseMessage;
3275}
3276
3277//===----------------------------------------------------------------------===//
3278// Implementation of LikelyFalsePositiveSuppressionBRVisitor.
3279//===----------------------------------------------------------------------===//
3280
3281void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor(
3282    BugReporterContext &BRC, const ExplodedNode *N,
3283    PathSensitiveBugReport &BR) {
3284  // Here we suppress false positives coming from system headers. This list is
3285  // based on known issues.
3286  const AnalyzerOptions &Options = BRC.getAnalyzerOptions();
3287  const Decl *D = N->getLocationContext()->getDecl();
3288
3289  if (AnalysisDeclContext::isInStdNamespace(D)) {
3290    // Skip reports within the 'std' namespace. Although these can sometimes be
3291    // the user's fault, we currently don't report them very well, and
3292    // Note that this will not help for any other data structure libraries, like
3293    // TR1, Boost, or llvm/ADT.
3294    if (Options.ShouldSuppressFromCXXStandardLibrary) {
3295      BR.markInvalid(getTag(), nullptr);
3296      return;
3297    } else {
3298      // If the complete 'std' suppression is not enabled, suppress reports
3299      // from the 'std' namespace that are known to produce false positives.
3300
3301      // The analyzer issues a false use-after-free when std::list::pop_front
3302      // or std::list::pop_back are called multiple times because we cannot
3303      // reason about the internal invariants of the data structure.
3304      if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
3305        const CXXRecordDecl *CD = MD->getParent();
3306        if (CD->getName() == "list") {
3307          BR.markInvalid(getTag(), nullptr);
3308          return;
3309        }
3310      }
3311
3312      // The analyzer issues a false positive when the constructor of
3313      // std::__independent_bits_engine from algorithms is used.
3314      if (const auto *MD = dyn_cast<CXXConstructorDecl>(D)) {
3315        const CXXRecordDecl *CD = MD->getParent();
3316        if (CD->getName() == "__independent_bits_engine") {
3317          BR.markInvalid(getTag(), nullptr);
3318          return;
3319        }
3320      }
3321
3322      for (const LocationContext *LCtx = N->getLocationContext(); LCtx;
3323           LCtx = LCtx->getParent()) {
3324        const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());
3325        if (!MD)
3326          continue;
3327
3328        const CXXRecordDecl *CD = MD->getParent();
3329        // The analyzer issues a false positive on
3330        //   std::basic_string<uint8_t> v; v.push_back(1);
3331        // and
3332        //   std::u16string s; s += u'a';
3333        // because we cannot reason about the internal invariants of the
3334        // data structure.
3335        if (CD->getName() == "basic_string") {
3336          BR.markInvalid(getTag(), nullptr);
3337          return;
3338        }
3339
3340        // The analyzer issues a false positive on
3341        //    std::shared_ptr<int> p(new int(1)); p = nullptr;
3342        // because it does not reason properly about temporary destructors.
3343        if (CD->getName() == "shared_ptr") {
3344          BR.markInvalid(getTag(), nullptr);
3345          return;
3346        }
3347      }
3348    }
3349  }
3350
3351  // Skip reports within the sys/queue.h macros as we do not have the ability to
3352  // reason about data structure shapes.
3353  const SourceManager &SM = BRC.getSourceManager();
3354  FullSourceLoc Loc = BR.getLocation().asLocation();
3355  while (Loc.isMacroID()) {
3356    Loc = Loc.getSpellingLoc();
3357    if (SM.getFilename(Loc).endswith("sys/queue.h")) {
3358      BR.markInvalid(getTag(), nullptr);
3359      return;
3360    }
3361  }
3362}
3363
3364//===----------------------------------------------------------------------===//
3365// Implementation of UndefOrNullArgVisitor.
3366//===----------------------------------------------------------------------===//
3367
3368PathDiagnosticPieceRef
3369UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N, BugReporterContext &BRC,
3370                                 PathSensitiveBugReport &BR) {
3371  ProgramStateRef State = N->getState();
3372  ProgramPoint ProgLoc = N->getLocation();
3373
3374  // We are only interested in visiting CallEnter nodes.
3375  std::optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
3376  if (!CEnter)
3377    return nullptr;
3378
3379  // Check if one of the arguments is the region the visitor is tracking.
3380  CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
3381  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
3382  unsigned Idx = 0;
3383  ArrayRef<ParmVarDecl *> parms = Call->parameters();
3384
3385  for (const auto ParamDecl : parms) {
3386    const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
3387    ++Idx;
3388
3389    // Are we tracking the argument or its subregion?
3390    if ( !ArgReg || !R->isSubRegionOf(ArgReg->StripCasts()))
3391      continue;
3392
3393    // Check the function parameter type.
3394    assert(ParamDecl && "Formal parameter has no decl?");
3395    QualType T = ParamDecl->getType();
3396
3397    if (!(T->isAnyPointerType() || T->isReferenceType())) {
3398      // Function can only change the value passed in by address.
3399      continue;
3400    }
3401
3402    // If it is a const pointer value, the function does not intend to
3403    // change the value.
3404    if (T->getPointeeType().isConstQualified())
3405      continue;
3406
3407    // Mark the call site (LocationContext) as interesting if the value of the
3408    // argument is undefined or '0'/'NULL'.
3409    SVal BoundVal = State->getSVal(R);
3410    if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
3411      BR.markInteresting(CEnter->getCalleeContext());
3412      return nullptr;
3413    }
3414  }
3415  return nullptr;
3416}
3417
3418//===----------------------------------------------------------------------===//
3419// Implementation of FalsePositiveRefutationBRVisitor.
3420//===----------------------------------------------------------------------===//
3421
3422FalsePositiveRefutationBRVisitor::FalsePositiveRefutationBRVisitor()
3423    : Constraints(ConstraintMap::Factory().getEmptyMap()) {}
3424
3425void FalsePositiveRefutationBRVisitor::finalizeVisitor(
3426    BugReporterContext &BRC, const ExplodedNode *EndPathNode,
3427    PathSensitiveBugReport &BR) {
3428  // Collect new constraints
3429  addConstraints(EndPathNode, /*OverwriteConstraintsOnExistingSyms=*/true);
3430
3431  // Create a refutation manager
3432  llvm::SMTSolverRef RefutationSolver = llvm::CreateZ3Solver();
3433  ASTContext &Ctx = BRC.getASTContext();
3434
3435  // Add constraints to the solver
3436  for (const auto &I : Constraints) {
3437    const SymbolRef Sym = I.first;
3438    auto RangeIt = I.second.begin();
3439
3440    llvm::SMTExprRef SMTConstraints = SMTConv::getRangeExpr(
3441        RefutationSolver, Ctx, Sym, RangeIt->From(), RangeIt->To(),
3442        /*InRange=*/true);
3443    while ((++RangeIt) != I.second.end()) {
3444      SMTConstraints = RefutationSolver->mkOr(
3445          SMTConstraints, SMTConv::getRangeExpr(RefutationSolver, Ctx, Sym,
3446                                                RangeIt->From(), RangeIt->To(),
3447                                                /*InRange=*/true));
3448    }
3449
3450    RefutationSolver->addConstraint(SMTConstraints);
3451  }
3452
3453  // And check for satisfiability
3454  std::optional<bool> IsSAT = RefutationSolver->check();
3455  if (!IsSAT)
3456    return;
3457
3458  if (!*IsSAT)
3459    BR.markInvalid("Infeasible constraints", EndPathNode->getLocationContext());
3460}
3461
3462void FalsePositiveRefutationBRVisitor::addConstraints(
3463    const ExplodedNode *N, bool OverwriteConstraintsOnExistingSyms) {
3464  // Collect new constraints
3465  ConstraintMap NewCs = getConstraintMap(N->getState());
3466  ConstraintMap::Factory &CF = N->getState()->get_context<ConstraintMap>();
3467
3468  // Add constraints if we don't have them yet
3469  for (auto const &C : NewCs) {
3470    const SymbolRef &Sym = C.first;
3471    if (!Constraints.contains(Sym)) {
3472      // This symbol is new, just add the constraint.
3473      Constraints = CF.add(Constraints, Sym, C.second);
3474    } else if (OverwriteConstraintsOnExistingSyms) {
3475      // Overwrite the associated constraint of the Symbol.
3476      Constraints = CF.remove(Constraints, Sym);
3477      Constraints = CF.add(Constraints, Sym, C.second);
3478    }
3479  }
3480}
3481
3482PathDiagnosticPieceRef FalsePositiveRefutationBRVisitor::VisitNode(
3483    const ExplodedNode *N, BugReporterContext &, PathSensitiveBugReport &) {
3484  addConstraints(N, /*OverwriteConstraintsOnExistingSyms=*/false);
3485  return nullptr;
3486}
3487
3488void FalsePositiveRefutationBRVisitor::Profile(
3489    llvm::FoldingSetNodeID &ID) const {
3490  static int Tag = 0;
3491  ID.AddPointer(&Tag);
3492}
3493
3494//===----------------------------------------------------------------------===//
3495// Implementation of TagVisitor.
3496//===----------------------------------------------------------------------===//
3497
3498int NoteTag::Kind = 0;
3499
3500void TagVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
3501  static int Tag = 0;
3502  ID.AddPointer(&Tag);
3503}
3504
3505PathDiagnosticPieceRef TagVisitor::VisitNode(const ExplodedNode *N,
3506                                             BugReporterContext &BRC,
3507                                             PathSensitiveBugReport &R) {
3508  ProgramPoint PP = N->getLocation();
3509  const NoteTag *T = dyn_cast_or_null<NoteTag>(PP.getTag());
3510  if (!T)
3511    return nullptr;
3512
3513  if (std::optional<std::string> Msg = T->generateMessage(BRC, R)) {
3514    PathDiagnosticLocation Loc =
3515        PathDiagnosticLocation::create(PP, BRC.getSourceManager());
3516    auto Piece = std::make_shared<PathDiagnosticEventPiece>(Loc, *Msg);
3517    Piece->setPrunable(T->isPrunable());
3518    return Piece;
3519  }
3520
3521  return nullptr;
3522}
3523