BugReporterVisitors.cpp revision 4238f41d484729aca260140fbbc53a68769bf60a
1// BugReporterVisitors.cpp - Helpers for reporting bugs -----------*- C++ -*--//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10//  This file defines a set of BugReporter "visitors" which can be used to
11//  enhance the diagnostics reported for a bug.
12//
13//===----------------------------------------------------------------------===//
14#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
15#include "clang/AST/Expr.h"
16#include "clang/AST/ExprObjC.h"
17#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
18#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
19#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
20#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
21#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
22#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
23#include "llvm/ADT/SmallString.h"
24#include "llvm/ADT/StringExtras.h"
25#include "llvm/Support/raw_ostream.h"
26
27using namespace clang;
28using namespace ento;
29
30//===----------------------------------------------------------------------===//
31// Utility functions.
32//===----------------------------------------------------------------------===//
33
34bool bugreporter::isDeclRefExprToReference(const Expr *E) {
35  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
36    return DRE->getDecl()->getType()->isReferenceType();
37  }
38  return false;
39}
40
41const Expr *bugreporter::getDerefExpr(const Stmt *S) {
42  // Pattern match for a few useful cases (do something smarter later):
43  //   a[0], p->f, *p
44  const Expr *E = dyn_cast<Expr>(S);
45  if (!E)
46    return 0;
47  E = E->IgnoreParenCasts();
48
49  while (true) {
50    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) {
51      assert(B->isAssignmentOp());
52      E = B->getLHS()->IgnoreParenCasts();
53      continue;
54    }
55    else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
56      if (U->getOpcode() == UO_Deref)
57        return U->getSubExpr()->IgnoreParenCasts();
58    }
59    else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
60      if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) {
61        return ME->getBase()->IgnoreParenCasts();
62      }
63    }
64    else if (const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
65      return IvarRef->getBase()->IgnoreParenCasts();
66    }
67    else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(E)) {
68      return AE->getBase();
69    }
70    break;
71  }
72
73  return NULL;
74}
75
76const Stmt *bugreporter::GetDenomExpr(const ExplodedNode *N) {
77  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
78  if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
79    return BE->getRHS();
80  return NULL;
81}
82
83const Stmt *bugreporter::GetRetValExpr(const ExplodedNode *N) {
84  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
85  if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
86    return RS->getRetValue();
87  return NULL;
88}
89
90//===----------------------------------------------------------------------===//
91// Definitions for bug reporter visitors.
92//===----------------------------------------------------------------------===//
93
94PathDiagnosticPiece*
95BugReporterVisitor::getEndPath(BugReporterContext &BRC,
96                               const ExplodedNode *EndPathNode,
97                               BugReport &BR) {
98  return 0;
99}
100
101PathDiagnosticPiece*
102BugReporterVisitor::getDefaultEndPath(BugReporterContext &BRC,
103                                      const ExplodedNode *EndPathNode,
104                                      BugReport &BR) {
105  PathDiagnosticLocation L =
106    PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
107
108  BugReport::ranges_iterator Beg, End;
109  llvm::tie(Beg, End) = BR.getRanges();
110
111  // Only add the statement itself as a range if we didn't specify any
112  // special ranges for this report.
113  PathDiagnosticPiece *P = new PathDiagnosticEventPiece(L,
114      BR.getDescription(),
115      Beg == End);
116  for (; Beg != End; ++Beg)
117    P->addRange(*Beg);
118
119  return P;
120}
121
122
123namespace {
124/// Emits an extra note at the return statement of an interesting stack frame.
125///
126/// The returned value is marked as an interesting value, and if it's null,
127/// adds a visitor to track where it became null.
128///
129/// This visitor is intended to be used when another visitor discovers that an
130/// interesting value comes from an inlined function call.
131class ReturnVisitor : public BugReporterVisitorImpl<ReturnVisitor> {
132  const StackFrameContext *StackFrame;
133  enum {
134    Initial,
135    MaybeSuppress,
136    Satisfied
137  } Mode;
138
139public:
140  ReturnVisitor(const StackFrameContext *Frame)
141    : StackFrame(Frame), Mode(Initial) {}
142
143  static void *getTag() {
144    static int Tag = 0;
145    return static_cast<void *>(&Tag);
146  }
147
148  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
149    ID.AddPointer(ReturnVisitor::getTag());
150    ID.AddPointer(StackFrame);
151  }
152
153  /// Adds a ReturnVisitor if the given statement represents a call that was
154  /// inlined.
155  ///
156  /// This will search back through the ExplodedGraph, starting from the given
157  /// node, looking for when the given statement was processed. If it turns out
158  /// the statement is a call that was inlined, we add the visitor to the
159  /// bug report, so it can print a note later.
160  static void addVisitorIfNecessary(const ExplodedNode *Node, const Stmt *S,
161                                    BugReport &BR) {
162    if (!CallEvent::isCallStmt(S))
163      return;
164
165    // First, find when we processed the statement.
166    do {
167      if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>())
168        if (CEE->getCalleeContext()->getCallSite() == S)
169          break;
170      if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>())
171        if (SP->getStmt() == S)
172          break;
173
174      Node = Node->getFirstPred();
175    } while (Node);
176
177    // Next, step over any post-statement checks.
178    while (Node && Node->getLocation().getAs<PostStmt>())
179      Node = Node->getFirstPred();
180
181    // Finally, see if we inlined the call.
182    if (Node) {
183      if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>()) {
184        const StackFrameContext *CalleeContext = CEE->getCalleeContext();
185        if (CalleeContext->getCallSite() == S) {
186          BR.markInteresting(CalleeContext);
187          BR.addVisitor(new ReturnVisitor(CalleeContext));
188        }
189      }
190    }
191  }
192
193  /// Returns true if any counter-suppression heuristics are enabled for
194  /// ReturnVisitor.
195  static bool hasCounterSuppression(AnalyzerOptions &Options) {
196    return Options.shouldAvoidSuppressingNullArgumentPaths();
197  }
198
199  PathDiagnosticPiece *visitNodeInitial(const ExplodedNode *N,
200                                        const ExplodedNode *PrevN,
201                                        BugReporterContext &BRC,
202                                        BugReport &BR) {
203    // Only print a message at the interesting return statement.
204    if (N->getLocationContext() != StackFrame)
205      return 0;
206
207    Optional<StmtPoint> SP = N->getLocationAs<StmtPoint>();
208    if (!SP)
209      return 0;
210
211    const ReturnStmt *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
212    if (!Ret)
213      return 0;
214
215    // Okay, we're at the right return statement, but do we have the return
216    // value available?
217    ProgramStateRef State = N->getState();
218    SVal V = State->getSVal(Ret, StackFrame);
219    if (V.isUnknownOrUndef())
220      return 0;
221
222    // Don't print any more notes after this one.
223    Mode = Satisfied;
224
225    const Expr *RetE = Ret->getRetValue();
226    assert(RetE && "Tracking a return value for a void function");
227    RetE = RetE->IgnoreParenCasts();
228
229    // If we can't prove the return value is 0, just mark it interesting, and
230    // make sure to track it into any further inner functions.
231    if (State->assume(V.castAs<DefinedSVal>(), true)) {
232      BR.markInteresting(V);
233      ReturnVisitor::addVisitorIfNecessary(N, RetE, BR);
234      return 0;
235    }
236
237    // If we're returning 0, we should track where that 0 came from.
238    bugreporter::trackNullOrUndefValue(N, RetE, BR);
239
240    // Build an appropriate message based on the return value.
241    SmallString<64> Msg;
242    llvm::raw_svector_ostream Out(Msg);
243
244    if (V.getAs<Loc>()) {
245      // If we are pruning null-return paths as unlikely error paths, mark the
246      // report invalid. We still want to emit a path note, however, in case
247      // the report is resurrected as valid later on.
248      ExprEngine &Eng = BRC.getBugReporter().getEngine();
249      AnalyzerOptions &Options = Eng.getAnalysisManager().options;
250      if (Options.shouldSuppressNullReturnPaths()) {
251        if (hasCounterSuppression(Options))
252          Mode = MaybeSuppress;
253        else
254          BR.markInvalid(ReturnVisitor::getTag(), StackFrame);
255      }
256
257      if (RetE->getType()->isObjCObjectPointerType())
258        Out << "Returning nil";
259      else
260        Out << "Returning null pointer";
261    } else {
262      Out << "Returning zero";
263    }
264
265    // FIXME: We should have a more generalized location printing mechanism.
266    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
267      if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
268        Out << " (loaded from '" << *DD << "')";
269
270    PathDiagnosticLocation L(Ret, BRC.getSourceManager(), StackFrame);
271    return new PathDiagnosticEventPiece(L, Out.str());
272  }
273
274  PathDiagnosticPiece *visitNodeMaybeSuppress(const ExplodedNode *N,
275                                              const ExplodedNode *PrevN,
276                                              BugReporterContext &BRC,
277                                              BugReport &BR) {
278    // Are we at the entry node for this call?
279    Optional<CallEnter> CE = N->getLocationAs<CallEnter>();
280    if (!CE)
281      return 0;
282
283    if (CE->getCalleeContext() != StackFrame)
284      return 0;
285
286    Mode = Satisfied;
287
288    ExprEngine &Eng = BRC.getBugReporter().getEngine();
289    AnalyzerOptions &Options = Eng.getAnalysisManager().options;
290    if (Options.shouldAvoidSuppressingNullArgumentPaths()) {
291      // Don't automatically suppress a report if one of the arguments is
292      // known to be a null pointer. Instead, start tracking /that/ null
293      // value back to its origin.
294      ProgramStateManager &StateMgr = BRC.getStateManager();
295      CallEventManager &CallMgr = StateMgr.getCallEventManager();
296
297      ProgramStateRef State = N->getState();
298      CallEventRef<> Call = CallMgr.getCaller(StackFrame, State);
299      for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
300        SVal ArgV = Call->getArgSVal(I);
301        if (!ArgV.getAs<Loc>())
302          continue;
303
304        const Expr *ArgE = Call->getArgExpr(I);
305        if (!ArgE)
306          continue;
307
308        // Is it possible for this argument to be non-null?
309        if (State->assume(ArgV.castAs<Loc>(), true))
310          continue;
311
312        if (bugreporter::trackNullOrUndefValue(N, ArgE, BR, /*IsArg=*/true))
313          return 0;
314
315        // If we /can't/ track the null pointer, we should err on the side of
316        // false negatives, and continue towards marking this report invalid.
317        // (We will still look at the other arguments, though.)
318      }
319    }
320
321    // There is no reason not to suppress this report; go ahead and do it.
322    BR.markInvalid(ReturnVisitor::getTag(), StackFrame);
323    return 0;
324  }
325
326  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
327                                 const ExplodedNode *PrevN,
328                                 BugReporterContext &BRC,
329                                 BugReport &BR) {
330    switch (Mode) {
331    case Initial:
332      return visitNodeInitial(N, PrevN, BRC, BR);
333    case MaybeSuppress:
334      return visitNodeMaybeSuppress(N, PrevN, BRC, BR);
335    case Satisfied:
336      return 0;
337    }
338
339    llvm_unreachable("Invalid visit mode!");
340  }
341};
342} // end anonymous namespace
343
344
345void FindLastStoreBRVisitor ::Profile(llvm::FoldingSetNodeID &ID) const {
346  static int tag = 0;
347  ID.AddPointer(&tag);
348  ID.AddPointer(R);
349  ID.Add(V);
350}
351
352PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
353                                                       const ExplodedNode *Pred,
354                                                       BugReporterContext &BRC,
355                                                       BugReport &BR) {
356
357  if (Satisfied)
358    return NULL;
359
360  const ExplodedNode *StoreSite = 0;
361  const Expr *InitE = 0;
362  bool IsParam = false;
363
364  // First see if we reached the declaration of the region.
365  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
366    if (Optional<PostStmt> P = Pred->getLocationAs<PostStmt>()) {
367      if (const DeclStmt *DS = P->getStmtAs<DeclStmt>()) {
368        if (DS->getSingleDecl() == VR->getDecl()) {
369          StoreSite = Pred;
370          InitE = VR->getDecl()->getInit();
371        }
372      }
373    }
374  }
375
376  // Otherwise, check that Succ has this binding and Pred does not, i.e. this is
377  // where the binding first occurred.
378  if (!StoreSite) {
379    if (Succ->getState()->getSVal(R) != V)
380      return NULL;
381    if (Pred->getState()->getSVal(R) == V)
382      return NULL;
383
384    StoreSite = Succ;
385
386    // If this is an assignment expression, we can track the value
387    // being assigned.
388    if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>())
389      if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>())
390        if (BO->isAssignmentOp())
391          InitE = BO->getRHS();
392
393    // If this is a call entry, the variable should be a parameter.
394    // FIXME: Handle CXXThisRegion as well. (This is not a priority because
395    // 'this' should never be NULL, but this visitor isn't just for NULL and
396    // UndefinedVal.)
397    if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
398      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
399        const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
400
401        ProgramStateManager &StateMgr = BRC.getStateManager();
402        CallEventManager &CallMgr = StateMgr.getCallEventManager();
403
404        CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
405                                                Succ->getState());
406        InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
407        IsParam = true;
408      }
409    }
410  }
411
412  if (!StoreSite)
413    return NULL;
414  Satisfied = true;
415
416  // If we have an expression that provided the value, try to track where it
417  // came from.
418  if (InitE) {
419    if (V.isUndef() || V.getAs<loc::ConcreteInt>()) {
420      if (!IsParam)
421        InitE = InitE->IgnoreParenCasts();
422      bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam);
423    } else {
424      ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(),
425                                           BR);
426    }
427  }
428
429  if (!R->canPrintPretty())
430    return 0;
431
432  // Okay, we've found the binding. Emit an appropriate message.
433  SmallString<256> sbuf;
434  llvm::raw_svector_ostream os(sbuf);
435
436  if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
437    const Stmt *S = PS->getStmt();
438    const char *action = 0;
439    const DeclStmt *DS = dyn_cast<DeclStmt>(S);
440    const VarRegion *VR = dyn_cast<VarRegion>(R);
441
442    if (DS) {
443      action = "initialized to ";
444    } else if (isa<BlockExpr>(S)) {
445      action = "captured by block as ";
446      if (VR) {
447        // See if we can get the BlockVarRegion.
448        ProgramStateRef State = StoreSite->getState();
449        SVal V = State->getSVal(S, PS->getLocationContext());
450        if (const BlockDataRegion *BDR =
451              dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
452          if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
453            if (Optional<KnownSVal> KV =
454                State->getSVal(OriginalR).getAs<KnownSVal>())
455              BR.addVisitor(new FindLastStoreBRVisitor(*KV, OriginalR));
456          }
457        }
458      }
459    }
460
461    if (action) {
462      if (!R)
463        return 0;
464
465      os << '\'';
466      R->printPretty(os);
467      os << "' ";
468
469      if (V.getAs<loc::ConcreteInt>()) {
470        bool b = false;
471        if (R->isBoundable()) {
472          if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
473            if (TR->getValueType()->isObjCObjectPointerType()) {
474              os << action << "nil";
475              b = true;
476            }
477          }
478        }
479
480        if (!b)
481          os << action << "a null pointer value";
482      } else if (Optional<nonloc::ConcreteInt> CVal =
483                     V.getAs<nonloc::ConcreteInt>()) {
484        os << action << CVal->getValue();
485      }
486      else if (DS) {
487        if (V.isUndef()) {
488          if (isa<VarRegion>(R)) {
489            const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
490            if (VD->getInit())
491              os << "initialized to a garbage value";
492            else
493              os << "declared without an initial value";
494          }
495        }
496        else {
497          os << "initialized here";
498        }
499      }
500    }
501  } else if (StoreSite->getLocation().getAs<CallEnter>()) {
502    if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
503      const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
504
505      os << "Passing ";
506
507      if (V.getAs<loc::ConcreteInt>()) {
508        if (Param->getType()->isObjCObjectPointerType())
509          os << "nil object reference";
510        else
511          os << "null pointer value";
512      } else if (V.isUndef()) {
513        os << "uninitialized value";
514      } else if (Optional<nonloc::ConcreteInt> CI =
515                     V.getAs<nonloc::ConcreteInt>()) {
516        os << "the value " << CI->getValue();
517      } else {
518        os << "value";
519      }
520
521      // Printed parameter indexes are 1-based, not 0-based.
522      unsigned Idx = Param->getFunctionScopeIndex() + 1;
523      os << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter '";
524
525      R->printPretty(os);
526      os << '\'';
527    }
528  }
529
530  if (os.str().empty()) {
531    if (V.getAs<loc::ConcreteInt>()) {
532      bool b = false;
533      if (R->isBoundable()) {
534        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
535          if (TR->getValueType()->isObjCObjectPointerType()) {
536            os << "nil object reference stored to ";
537            b = true;
538          }
539        }
540      }
541
542      if (!b)
543        os << "Null pointer value stored to ";
544    }
545    else if (V.isUndef()) {
546      os << "Uninitialized value stored to ";
547    } else if (Optional<nonloc::ConcreteInt> CV =
548                   V.getAs<nonloc::ConcreteInt>()) {
549      os << "The value " << CV->getValue() << " is assigned to ";
550    }
551    else
552      os << "Value assigned to ";
553
554    os << '\'';
555    R->printPretty(os);
556    os << '\'';
557  }
558
559  // Construct a new PathDiagnosticPiece.
560  ProgramPoint P = StoreSite->getLocation();
561  PathDiagnosticLocation L;
562  if (P.getAs<CallEnter>() && InitE)
563    L = PathDiagnosticLocation(InitE, BRC.getSourceManager(),
564                               P.getLocationContext());
565  else
566    L = PathDiagnosticLocation::create(P, BRC.getSourceManager());
567  if (!L.isValid())
568    return NULL;
569  return new PathDiagnosticEventPiece(L, os.str());
570}
571
572void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
573  static int tag = 0;
574  ID.AddPointer(&tag);
575  ID.AddBoolean(Assumption);
576  ID.Add(Constraint);
577}
578
579/// Return the tag associated with this visitor.  This tag will be used
580/// to make all PathDiagnosticPieces created by this visitor.
581const char *TrackConstraintBRVisitor::getTag() {
582  return "TrackConstraintBRVisitor";
583}
584
585PathDiagnosticPiece *
586TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
587                                    const ExplodedNode *PrevN,
588                                    BugReporterContext &BRC,
589                                    BugReport &BR) {
590  if (isSatisfied)
591    return NULL;
592
593  // Check if in the previous state it was feasible for this constraint
594  // to *not* be true.
595  if (PrevN->getState()->assume(Constraint, !Assumption)) {
596
597    isSatisfied = true;
598
599    // As a sanity check, make sure that the negation of the constraint
600    // was infeasible in the current state.  If it is feasible, we somehow
601    // missed the transition point.
602    if (N->getState()->assume(Constraint, !Assumption))
603      return NULL;
604
605    // We found the transition point for the constraint.  We now need to
606    // pretty-print the constraint. (work-in-progress)
607    std::string sbuf;
608    llvm::raw_string_ostream os(sbuf);
609
610    if (Constraint.getAs<Loc>()) {
611      os << "Assuming pointer value is ";
612      os << (Assumption ? "non-null" : "null");
613    }
614
615    if (os.str().empty())
616      return NULL;
617
618    // Construct a new PathDiagnosticPiece.
619    ProgramPoint P = N->getLocation();
620    PathDiagnosticLocation L =
621      PathDiagnosticLocation::create(P, BRC.getSourceManager());
622    if (!L.isValid())
623      return NULL;
624
625    PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
626    X->setTag(getTag());
627    return X;
628  }
629
630  return NULL;
631}
632
633bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
634                                        BugReport &report, bool IsArg) {
635  if (!S || !N)
636    return false;
637
638  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
639    S = OVE->getSourceExpr();
640
641  if (IsArg) {
642    assert(N->getLocation().getAs<CallEnter>() && "Tracking arg but not at call");
643  } else {
644    // Walk through nodes until we get one that matches the statement exactly.
645    do {
646      const ProgramPoint &pp = N->getLocation();
647      if (Optional<PostStmt> ps = pp.getAs<PostStmt>()) {
648        if (ps->getStmt() == S)
649          break;
650      } else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
651        if (CEE->getCalleeContext()->getCallSite() == S)
652          break;
653      }
654      N = N->getFirstPred();
655    } while (N);
656
657    if (!N)
658      return false;
659  }
660
661  ProgramStateRef state = N->getState();
662
663  // See if the expression we're interested refers to a variable.
664  // If so, we can track both its contents and constraints on its value.
665  if (const Expr *Ex = dyn_cast<Expr>(S)) {
666    // Strip off parens and casts. Note that this will never have issues with
667    // C++ user-defined implicit conversions, because those have a constructor
668    // or function call inside.
669    Ex = Ex->IgnoreParenCasts();
670
671    if (ExplodedGraph::isInterestingLValueExpr(Ex)) {
672      const MemRegion *R = 0;
673
674      // First check if this is a DeclRefExpr for a C++ reference type.
675      // For those, we want the location of the reference.
676      if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
677        if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
678          if (VD->getType()->isReferenceType()) {
679            ProgramStateManager &StateMgr = state->getStateManager();
680            MemRegionManager &MRMgr = StateMgr.getRegionManager();
681            R = MRMgr.getVarRegion(VD, N->getLocationContext());
682          }
683        }
684      }
685
686      // For all other cases, find the location by scouring the ExplodedGraph.
687      if (!R) {
688        // Find the ExplodedNode where the lvalue (the value of 'Ex')
689        // was computed.  We need this for getting the location value.
690        const ExplodedNode *LVNode = N;
691        const Expr *SearchEx = Ex;
692        if (const OpaqueValueExpr *OPE = dyn_cast<OpaqueValueExpr>(Ex)) {
693          SearchEx = OPE->getSourceExpr();
694        }
695        while (LVNode) {
696          if (Optional<PostStmt> P = LVNode->getLocation().getAs<PostStmt>()) {
697            if (P->getStmt() == SearchEx)
698              break;
699          }
700          LVNode = LVNode->getFirstPred();
701        }
702        assert(LVNode && "Unable to find the lvalue node.");
703        ProgramStateRef LVState = LVNode->getState();
704        if (Optional<Loc> L =
705              LVState->getSVal(Ex, LVNode->getLocationContext()).getAs<Loc>()) {
706          R = L->getAsRegion();
707        }
708      }
709
710      if (R) {
711        // Mark both the variable region and its contents as interesting.
712        SVal V = state->getRawSVal(loc::MemRegionVal(R));
713
714        // If the value matches the default for the variable region, that
715        // might mean that it's been cleared out of the state. Fall back to
716        // the full argument expression (with casts and such intact).
717        if (IsArg) {
718          bool UseArgValue = V.isUnknownOrUndef() || V.isZeroConstant();
719          if (!UseArgValue) {
720            const SymbolRegionValue *SRV =
721              dyn_cast_or_null<SymbolRegionValue>(V.getAsLocSymbol());
722            if (SRV)
723              UseArgValue = (SRV->getRegion() == R);
724          }
725          if (UseArgValue)
726            V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
727        }
728
729        report.markInteresting(R);
730        report.markInteresting(V);
731        report.addVisitor(new UndefOrNullArgVisitor(R));
732
733        if (isa<SymbolicRegion>(R)) {
734          TrackConstraintBRVisitor *VI =
735            new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
736          report.addVisitor(VI);
737        }
738
739        // If the contents are symbolic, find out when they became null.
740        if (V.getAsLocSymbol()) {
741          BugReporterVisitor *ConstraintTracker =
742              new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
743          report.addVisitor(ConstraintTracker);
744        }
745
746        if (Optional<KnownSVal> KV = V.getAs<KnownSVal>())
747          report.addVisitor(new FindLastStoreBRVisitor(*KV, R));
748        return true;
749      }
750    }
751  }
752
753  // If the expression is not an "lvalue expression", we can still
754  // track the constraints on its contents.
755  SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
756
757  // Uncomment this to find cases where we aren't properly getting the
758  // base value that was dereferenced.
759  // assert(!V.isUnknownOrUndef());
760  // Is it a symbolic value?
761  if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
762    // At this point we are dealing with the region's LValue.
763    // However, if the rvalue is a symbolic region, we should track it as well.
764    SVal RVal = state->getSVal(L->getRegion());
765    const MemRegion *RegionRVal = RVal.getAsRegion();
766    report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
767
768
769    if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
770      report.markInteresting(RegionRVal);
771      report.addVisitor(new TrackConstraintBRVisitor(
772        loc::MemRegionVal(RegionRVal), false));
773    }
774  } else {
775    // Otherwise, if the value came from an inlined function call,
776    // we should at least make sure that function isn't pruned in our output.
777    if (const Expr *E = dyn_cast<Expr>(S))
778      S = E->IgnoreParenCasts();
779    ReturnVisitor::addVisitorIfNecessary(N, S, report);
780  }
781
782  return true;
783}
784
785BugReporterVisitor *
786FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
787                                            const MemRegion *R) {
788  assert(R && "The memory region is null.");
789
790  ProgramStateRef state = N->getState();
791  if (Optional<KnownSVal> KV = state->getSVal(R).getAs<KnownSVal>())
792    return new FindLastStoreBRVisitor(*KV, R);
793  return 0;
794}
795
796PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
797                                                     const ExplodedNode *PrevN,
798                                                     BugReporterContext &BRC,
799                                                     BugReport &BR) {
800  Optional<PostStmt> P = N->getLocationAs<PostStmt>();
801  if (!P)
802    return 0;
803  const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
804  if (!ME)
805    return 0;
806  const Expr *Receiver = ME->getInstanceReceiver();
807  if (!Receiver)
808    return 0;
809  ProgramStateRef state = N->getState();
810  const SVal &V = state->getSVal(Receiver, N->getLocationContext());
811  Optional<DefinedOrUnknownSVal> DV = V.getAs<DefinedOrUnknownSVal>();
812  if (!DV)
813    return 0;
814  state = state->assume(*DV, true);
815  if (state)
816    return 0;
817
818  // The receiver was nil, and hence the method was skipped.
819  // Register a BugReporterVisitor to issue a message telling us how
820  // the receiver was null.
821  bugreporter::trackNullOrUndefValue(N, Receiver, BR);
822  // Issue a message saying that the method was skipped.
823  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
824                                     N->getLocationContext());
825  return new PathDiagnosticEventPiece(L, "No method is called "
826      "because the receiver is nil");
827}
828
829// Registers every VarDecl inside a Stmt with a last store visitor.
830void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
831                                                       const Stmt *S) {
832  const ExplodedNode *N = BR.getErrorNode();
833  std::deque<const Stmt *> WorkList;
834  WorkList.push_back(S);
835
836  while (!WorkList.empty()) {
837    const Stmt *Head = WorkList.front();
838    WorkList.pop_front();
839
840    ProgramStateRef state = N->getState();
841    ProgramStateManager &StateMgr = state->getStateManager();
842
843    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
844      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
845        const VarRegion *R =
846        StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
847
848        // What did we load?
849        SVal V = state->getSVal(S, N->getLocationContext());
850
851        if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
852          // Register a new visitor with the BugReport.
853          BR.addVisitor(new FindLastStoreBRVisitor(V.castAs<KnownSVal>(), R));
854        }
855      }
856    }
857
858    for (Stmt::const_child_iterator I = Head->child_begin();
859        I != Head->child_end(); ++I)
860      WorkList.push_back(*I);
861  }
862}
863
864//===----------------------------------------------------------------------===//
865// Visitor that tries to report interesting diagnostics from conditions.
866//===----------------------------------------------------------------------===//
867
868/// Return the tag associated with this visitor.  This tag will be used
869/// to make all PathDiagnosticPieces created by this visitor.
870const char *ConditionBRVisitor::getTag() {
871  return "ConditionBRVisitor";
872}
873
874PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
875                                                   const ExplodedNode *Prev,
876                                                   BugReporterContext &BRC,
877                                                   BugReport &BR) {
878  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
879  if (piece) {
880    piece->setTag(getTag());
881    if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
882      ev->setPrunable(true, /* override */ false);
883  }
884  return piece;
885}
886
887PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
888                                                       const ExplodedNode *Prev,
889                                                       BugReporterContext &BRC,
890                                                       BugReport &BR) {
891
892  ProgramPoint progPoint = N->getLocation();
893  ProgramStateRef CurrentState = N->getState();
894  ProgramStateRef PrevState = Prev->getState();
895
896  // Compare the GDMs of the state, because that is where constraints
897  // are managed.  Note that ensure that we only look at nodes that
898  // were generated by the analyzer engine proper, not checkers.
899  if (CurrentState->getGDM().getRoot() ==
900      PrevState->getGDM().getRoot())
901    return 0;
902
903  // If an assumption was made on a branch, it should be caught
904  // here by looking at the state transition.
905  if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
906    const CFGBlock *srcBlk = BE->getSrc();
907    if (const Stmt *term = srcBlk->getTerminator())
908      return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
909    return 0;
910  }
911
912  if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
913    // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
914    // violation.
915    const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
916      cast<GRBugReporter>(BRC.getBugReporter()).
917        getEngine().geteagerlyAssumeBinOpBifurcationTags();
918
919    const ProgramPointTag *tag = PS->getTag();
920    if (tag == tags.first)
921      return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
922                           BRC, BR, N);
923    if (tag == tags.second)
924      return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
925                           BRC, BR, N);
926
927    return 0;
928  }
929
930  return 0;
931}
932
933PathDiagnosticPiece *
934ConditionBRVisitor::VisitTerminator(const Stmt *Term,
935                                    const ExplodedNode *N,
936                                    const CFGBlock *srcBlk,
937                                    const CFGBlock *dstBlk,
938                                    BugReport &R,
939                                    BugReporterContext &BRC) {
940  const Expr *Cond = 0;
941
942  switch (Term->getStmtClass()) {
943  default:
944    return 0;
945  case Stmt::IfStmtClass:
946    Cond = cast<IfStmt>(Term)->getCond();
947    break;
948  case Stmt::ConditionalOperatorClass:
949    Cond = cast<ConditionalOperator>(Term)->getCond();
950    break;
951  }
952
953  assert(Cond);
954  assert(srcBlk->succ_size() == 2);
955  const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
956  return VisitTrueTest(Cond, tookTrue, BRC, R, N);
957}
958
959PathDiagnosticPiece *
960ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
961                                  bool tookTrue,
962                                  BugReporterContext &BRC,
963                                  BugReport &R,
964                                  const ExplodedNode *N) {
965
966  const Expr *Ex = Cond;
967
968  while (true) {
969    Ex = Ex->IgnoreParenCasts();
970    switch (Ex->getStmtClass()) {
971      default:
972        return 0;
973      case Stmt::BinaryOperatorClass:
974        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
975                             R, N);
976      case Stmt::DeclRefExprClass:
977        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
978                             R, N);
979      case Stmt::UnaryOperatorClass: {
980        const UnaryOperator *UO = cast<UnaryOperator>(Ex);
981        if (UO->getOpcode() == UO_LNot) {
982          tookTrue = !tookTrue;
983          Ex = UO->getSubExpr();
984          continue;
985        }
986        return 0;
987      }
988    }
989  }
990}
991
992bool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
993                                      BugReporterContext &BRC,
994                                      BugReport &report,
995                                      const ExplodedNode *N,
996                                      Optional<bool> &prunable) {
997  const Expr *OriginalExpr = Ex;
998  Ex = Ex->IgnoreParenCasts();
999
1000  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
1001    const bool quotes = isa<VarDecl>(DR->getDecl());
1002    if (quotes) {
1003      Out << '\'';
1004      const LocationContext *LCtx = N->getLocationContext();
1005      const ProgramState *state = N->getState().getPtr();
1006      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
1007                                                LCtx).getAsRegion()) {
1008        if (report.isInteresting(R))
1009          prunable = false;
1010        else {
1011          const ProgramState *state = N->getState().getPtr();
1012          SVal V = state->getSVal(R);
1013          if (report.isInteresting(V))
1014            prunable = false;
1015        }
1016      }
1017    }
1018    Out << DR->getDecl()->getDeclName().getAsString();
1019    if (quotes)
1020      Out << '\'';
1021    return quotes;
1022  }
1023
1024  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
1025    QualType OriginalTy = OriginalExpr->getType();
1026    if (OriginalTy->isPointerType()) {
1027      if (IL->getValue() == 0) {
1028        Out << "null";
1029        return false;
1030      }
1031    }
1032    else if (OriginalTy->isObjCObjectPointerType()) {
1033      if (IL->getValue() == 0) {
1034        Out << "nil";
1035        return false;
1036      }
1037    }
1038
1039    Out << IL->getValue();
1040    return false;
1041  }
1042
1043  return false;
1044}
1045
1046PathDiagnosticPiece *
1047ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
1048                                  const BinaryOperator *BExpr,
1049                                  const bool tookTrue,
1050                                  BugReporterContext &BRC,
1051                                  BugReport &R,
1052                                  const ExplodedNode *N) {
1053
1054  bool shouldInvert = false;
1055  Optional<bool> shouldPrune;
1056
1057  SmallString<128> LhsString, RhsString;
1058  {
1059    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
1060    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
1061                                       shouldPrune);
1062    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
1063                                       shouldPrune);
1064
1065    shouldInvert = !isVarLHS && isVarRHS;
1066  }
1067
1068  BinaryOperator::Opcode Op = BExpr->getOpcode();
1069
1070  if (BinaryOperator::isAssignmentOp(Op)) {
1071    // For assignment operators, all that we care about is that the LHS
1072    // evaluates to "true" or "false".
1073    return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
1074                                  BRC, R, N);
1075  }
1076
1077  // For non-assignment operations, we require that we can understand
1078  // both the LHS and RHS.
1079  if (LhsString.empty() || RhsString.empty())
1080    return 0;
1081
1082  // Should we invert the strings if the LHS is not a variable name?
1083  SmallString<256> buf;
1084  llvm::raw_svector_ostream Out(buf);
1085  Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is ";
1086
1087  // Do we need to invert the opcode?
1088  if (shouldInvert)
1089    switch (Op) {
1090      default: break;
1091      case BO_LT: Op = BO_GT; break;
1092      case BO_GT: Op = BO_LT; break;
1093      case BO_LE: Op = BO_GE; break;
1094      case BO_GE: Op = BO_LE; break;
1095    }
1096
1097  if (!tookTrue)
1098    switch (Op) {
1099      case BO_EQ: Op = BO_NE; break;
1100      case BO_NE: Op = BO_EQ; break;
1101      case BO_LT: Op = BO_GE; break;
1102      case BO_GT: Op = BO_LE; break;
1103      case BO_LE: Op = BO_GT; break;
1104      case BO_GE: Op = BO_LT; break;
1105      default:
1106        return 0;
1107    }
1108
1109  switch (Op) {
1110    case BO_EQ:
1111      Out << "equal to ";
1112      break;
1113    case BO_NE:
1114      Out << "not equal to ";
1115      break;
1116    default:
1117      Out << BinaryOperator::getOpcodeStr(Op) << ' ';
1118      break;
1119  }
1120
1121  Out << (shouldInvert ? LhsString : RhsString);
1122  const LocationContext *LCtx = N->getLocationContext();
1123  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1124  PathDiagnosticEventPiece *event =
1125    new PathDiagnosticEventPiece(Loc, Out.str());
1126  if (shouldPrune.hasValue())
1127    event->setPrunable(shouldPrune.getValue());
1128  return event;
1129}
1130
1131PathDiagnosticPiece *
1132ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
1133                                           const Expr *CondVarExpr,
1134                                           const bool tookTrue,
1135                                           BugReporterContext &BRC,
1136                                           BugReport &report,
1137                                           const ExplodedNode *N) {
1138  // FIXME: If there's already a constraint tracker for this variable,
1139  // we shouldn't emit anything here (c.f. the double note in
1140  // test/Analysis/inlining/path-notes.c)
1141  SmallString<256> buf;
1142  llvm::raw_svector_ostream Out(buf);
1143  Out << "Assuming " << LhsString << " is ";
1144
1145  QualType Ty = CondVarExpr->getType();
1146
1147  if (Ty->isPointerType())
1148    Out << (tookTrue ? "not null" : "null");
1149  else if (Ty->isObjCObjectPointerType())
1150    Out << (tookTrue ? "not nil" : "nil");
1151  else if (Ty->isBooleanType())
1152    Out << (tookTrue ? "true" : "false");
1153  else if (Ty->isIntegerType())
1154    Out << (tookTrue ? "non-zero" : "zero");
1155  else
1156    return 0;
1157
1158  const LocationContext *LCtx = N->getLocationContext();
1159  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
1160  PathDiagnosticEventPiece *event =
1161    new PathDiagnosticEventPiece(Loc, Out.str());
1162
1163  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
1164    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1165      const ProgramState *state = N->getState().getPtr();
1166      if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1167        if (report.isInteresting(R))
1168          event->setPrunable(false);
1169      }
1170    }
1171  }
1172
1173  return event;
1174}
1175
1176PathDiagnosticPiece *
1177ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
1178                                  const DeclRefExpr *DR,
1179                                  const bool tookTrue,
1180                                  BugReporterContext &BRC,
1181                                  BugReport &report,
1182                                  const ExplodedNode *N) {
1183
1184  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
1185  if (!VD)
1186    return 0;
1187
1188  SmallString<256> Buf;
1189  llvm::raw_svector_ostream Out(Buf);
1190
1191  Out << "Assuming '";
1192  VD->getDeclName().printName(Out);
1193  Out << "' is ";
1194
1195  QualType VDTy = VD->getType();
1196
1197  if (VDTy->isPointerType())
1198    Out << (tookTrue ? "non-null" : "null");
1199  else if (VDTy->isObjCObjectPointerType())
1200    Out << (tookTrue ? "non-nil" : "nil");
1201  else if (VDTy->isScalarType())
1202    Out << (tookTrue ? "not equal to 0" : "0");
1203  else
1204    return 0;
1205
1206  const LocationContext *LCtx = N->getLocationContext();
1207  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1208  PathDiagnosticEventPiece *event =
1209    new PathDiagnosticEventPiece(Loc, Out.str());
1210
1211  const ProgramState *state = N->getState().getPtr();
1212  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1213    if (report.isInteresting(R))
1214      event->setPrunable(false);
1215    else {
1216      SVal V = state->getSVal(R);
1217      if (report.isInteresting(V))
1218        event->setPrunable(false);
1219    }
1220  }
1221  return event;
1222}
1223
1224PathDiagnosticPiece *
1225LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
1226                                                    const ExplodedNode *N,
1227                                                    BugReport &BR) {
1228  const Stmt *S = BR.getStmt();
1229  if (!S)
1230    return 0;
1231
1232  // Here we suppress false positives coming from system macros. This list is
1233  // based on known issues.
1234
1235  // Skip reports within the sys/queue.h macros as we do not have the ability to
1236  // reason about data structure shapes.
1237  SourceManager &SM = BRC.getSourceManager();
1238  SourceLocation Loc = S->getLocStart();
1239  while (Loc.isMacroID()) {
1240    if (SM.isInSystemMacro(Loc) &&
1241       (SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) {
1242      BR.markInvalid(getTag(), 0);
1243      return 0;
1244    }
1245    Loc = SM.getSpellingLoc(Loc);
1246  }
1247
1248  return 0;
1249}
1250
1251PathDiagnosticPiece *
1252UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
1253                                  const ExplodedNode *PrevN,
1254                                  BugReporterContext &BRC,
1255                                  BugReport &BR) {
1256
1257  ProgramStateRef State = N->getState();
1258  ProgramPoint ProgLoc = N->getLocation();
1259
1260  // We are only interested in visiting CallEnter nodes.
1261  Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
1262  if (!CEnter)
1263    return 0;
1264
1265  // Check if one of the arguments is the region the visitor is tracking.
1266  CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
1267  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
1268  unsigned Idx = 0;
1269  for (CallEvent::param_iterator I = Call->param_begin(),
1270                                 E = Call->param_end(); I != E; ++I, ++Idx) {
1271    const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
1272
1273    // Are we tracking the argument or its subregion?
1274    if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
1275      continue;
1276
1277    // Check the function parameter type.
1278    const ParmVarDecl *ParamDecl = *I;
1279    assert(ParamDecl && "Formal parameter has no decl?");
1280    QualType T = ParamDecl->getType();
1281
1282    if (!(T->isAnyPointerType() || T->isReferenceType())) {
1283      // Function can only change the value passed in by address.
1284      continue;
1285    }
1286
1287    // If it is a const pointer value, the function does not intend to
1288    // change the value.
1289    if (T->getPointeeType().isConstQualified())
1290      continue;
1291
1292    // Mark the call site (LocationContext) as interesting if the value of the
1293    // argument is undefined or '0'/'NULL'.
1294    SVal BoundVal = State->getSVal(R);
1295    if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
1296      BR.markInteresting(CEnter->getCalleeContext());
1297      return 0;
1298    }
1299  }
1300  return 0;
1301}
1302