BugReporterVisitors.cpp revision 6c5038cf8486d92ae53bf4513141bd40a5ae0734
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 << "Variable '" << *VR->getDecl() << "' ";
466
467      if (V.getAs<loc::ConcreteInt>()) {
468        bool b = false;
469        if (R->isBoundable()) {
470          if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
471            if (TR->getValueType()->isObjCObjectPointerType()) {
472              os << action << "nil";
473              b = true;
474            }
475          }
476        }
477
478        if (!b)
479          os << action << "a null pointer value";
480      } else if (Optional<nonloc::ConcreteInt> CVal =
481                     V.getAs<nonloc::ConcreteInt>()) {
482        os << action << CVal->getValue();
483      }
484      else if (DS) {
485        if (V.isUndef()) {
486          if (isa<VarRegion>(R)) {
487            const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
488            if (VD->getInit())
489              os << "initialized to a garbage value";
490            else
491              os << "declared without an initial value";
492          }
493        }
494        else {
495          os << "initialized here";
496        }
497      }
498    }
499  } else if (StoreSite->getLocation().getAs<CallEnter>()) {
500    if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
501      const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
502
503      os << "Passing ";
504
505      if (V.getAs<loc::ConcreteInt>()) {
506        if (Param->getType()->isObjCObjectPointerType())
507          os << "nil object reference";
508        else
509          os << "null pointer value";
510      } else if (V.isUndef()) {
511        os << "uninitialized value";
512      } else if (Optional<nonloc::ConcreteInt> CI =
513                     V.getAs<nonloc::ConcreteInt>()) {
514        os << "the value " << CI->getValue();
515      } else {
516        os << "value";
517      }
518
519      // Printed parameter indexes are 1-based, not 0-based.
520      unsigned Idx = Param->getFunctionScopeIndex() + 1;
521      os << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter '";
522
523      R->printPretty(os);
524      os << '\'';
525    }
526  }
527
528  if (os.str().empty()) {
529    if (V.getAs<loc::ConcreteInt>()) {
530      bool b = false;
531      if (R->isBoundable()) {
532        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
533          if (TR->getValueType()->isObjCObjectPointerType()) {
534            os << "nil object reference stored to ";
535            b = true;
536          }
537        }
538      }
539
540      if (!b)
541        os << "Null pointer value stored to ";
542    }
543    else if (V.isUndef()) {
544      os << "Uninitialized value stored to ";
545    } else if (Optional<nonloc::ConcreteInt> CV =
546                   V.getAs<nonloc::ConcreteInt>()) {
547      os << "The value " << CV->getValue() << " is assigned to ";
548    }
549    else
550      os << "Value assigned to ";
551
552    os << '\'';
553    R->printPretty(os);
554    os << '\'';
555  }
556
557  // Construct a new PathDiagnosticPiece.
558  ProgramPoint P = StoreSite->getLocation();
559  PathDiagnosticLocation L;
560  if (P.getAs<CallEnter>() && InitE)
561    L = PathDiagnosticLocation(InitE, BRC.getSourceManager(),
562                               P.getLocationContext());
563  else
564    L = PathDiagnosticLocation::create(P, BRC.getSourceManager());
565  if (!L.isValid())
566    return NULL;
567  return new PathDiagnosticEventPiece(L, os.str());
568}
569
570void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
571  static int tag = 0;
572  ID.AddPointer(&tag);
573  ID.AddBoolean(Assumption);
574  ID.Add(Constraint);
575}
576
577/// Return the tag associated with this visitor.  This tag will be used
578/// to make all PathDiagnosticPieces created by this visitor.
579const char *TrackConstraintBRVisitor::getTag() {
580  return "TrackConstraintBRVisitor";
581}
582
583PathDiagnosticPiece *
584TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
585                                    const ExplodedNode *PrevN,
586                                    BugReporterContext &BRC,
587                                    BugReport &BR) {
588  if (isSatisfied)
589    return NULL;
590
591  // Check if in the previous state it was feasible for this constraint
592  // to *not* be true.
593  if (PrevN->getState()->assume(Constraint, !Assumption)) {
594
595    isSatisfied = true;
596
597    // As a sanity check, make sure that the negation of the constraint
598    // was infeasible in the current state.  If it is feasible, we somehow
599    // missed the transition point.
600    if (N->getState()->assume(Constraint, !Assumption))
601      return NULL;
602
603    // We found the transition point for the constraint.  We now need to
604    // pretty-print the constraint. (work-in-progress)
605    std::string sbuf;
606    llvm::raw_string_ostream os(sbuf);
607
608    if (Constraint.getAs<Loc>()) {
609      os << "Assuming pointer value is ";
610      os << (Assumption ? "non-null" : "null");
611    }
612
613    if (os.str().empty())
614      return NULL;
615
616    // Construct a new PathDiagnosticPiece.
617    ProgramPoint P = N->getLocation();
618    PathDiagnosticLocation L =
619      PathDiagnosticLocation::create(P, BRC.getSourceManager());
620    if (!L.isValid())
621      return NULL;
622
623    PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
624    X->setTag(getTag());
625    return X;
626  }
627
628  return NULL;
629}
630
631bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
632                                        BugReport &report, bool IsArg) {
633  if (!S || !N)
634    return false;
635
636  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
637    S = OVE->getSourceExpr();
638
639  if (IsArg) {
640    assert(N->getLocation().getAs<CallEnter>() && "Tracking arg but not at call");
641  } else {
642    // Walk through nodes until we get one that matches the statement exactly.
643    do {
644      const ProgramPoint &pp = N->getLocation();
645      if (Optional<PostStmt> ps = pp.getAs<PostStmt>()) {
646        if (ps->getStmt() == S)
647          break;
648      } else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
649        if (CEE->getCalleeContext()->getCallSite() == S)
650          break;
651      }
652      N = N->getFirstPred();
653    } while (N);
654
655    if (!N)
656      return false;
657  }
658
659  ProgramStateRef state = N->getState();
660
661  // See if the expression we're interested refers to a variable.
662  // If so, we can track both its contents and constraints on its value.
663  if (const Expr *Ex = dyn_cast<Expr>(S)) {
664    // Strip off parens and casts. Note that this will never have issues with
665    // C++ user-defined implicit conversions, because those have a constructor
666    // or function call inside.
667    Ex = Ex->IgnoreParenCasts();
668
669    if (ExplodedGraph::isInterestingLValueExpr(Ex)) {
670      const MemRegion *R = 0;
671
672      // First check if this is a DeclRefExpr for a C++ reference type.
673      // For those, we want the location of the reference.
674      if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
675        if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
676          if (VD->getType()->isReferenceType()) {
677            ProgramStateManager &StateMgr = state->getStateManager();
678            MemRegionManager &MRMgr = StateMgr.getRegionManager();
679            R = MRMgr.getVarRegion(VD, N->getLocationContext());
680          }
681        }
682      }
683
684      // For all other cases, find the location by scouring the ExplodedGraph.
685      if (!R) {
686        // Find the ExplodedNode where the lvalue (the value of 'Ex')
687        // was computed.  We need this for getting the location value.
688        const ExplodedNode *LVNode = N;
689        const Expr *SearchEx = Ex;
690        if (const OpaqueValueExpr *OPE = dyn_cast<OpaqueValueExpr>(Ex)) {
691          SearchEx = OPE->getSourceExpr();
692        }
693        while (LVNode) {
694          if (Optional<PostStmt> P = LVNode->getLocation().getAs<PostStmt>()) {
695            if (P->getStmt() == SearchEx)
696              break;
697          }
698          LVNode = LVNode->getFirstPred();
699        }
700        assert(LVNode && "Unable to find the lvalue node.");
701        ProgramStateRef LVState = LVNode->getState();
702        if (Optional<Loc> L =
703              LVState->getSVal(Ex, LVNode->getLocationContext()).getAs<Loc>()) {
704          R = L->getAsRegion();
705        }
706      }
707
708      if (R) {
709        // Mark both the variable region and its contents as interesting.
710        SVal V = state->getRawSVal(loc::MemRegionVal(R));
711
712        // If the value matches the default for the variable region, that
713        // might mean that it's been cleared out of the state. Fall back to
714        // the full argument expression (with casts and such intact).
715        if (IsArg) {
716          bool UseArgValue = V.isUnknownOrUndef() || V.isZeroConstant();
717          if (!UseArgValue) {
718            const SymbolRegionValue *SRV =
719              dyn_cast_or_null<SymbolRegionValue>(V.getAsLocSymbol());
720            if (SRV)
721              UseArgValue = (SRV->getRegion() == R);
722          }
723          if (UseArgValue)
724            V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
725        }
726
727        report.markInteresting(R);
728        report.markInteresting(V);
729        report.addVisitor(new UndefOrNullArgVisitor(R));
730
731        if (isa<SymbolicRegion>(R)) {
732          TrackConstraintBRVisitor *VI =
733            new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
734          report.addVisitor(VI);
735        }
736
737        // If the contents are symbolic, find out when they became null.
738        if (V.getAsLocSymbol()) {
739          BugReporterVisitor *ConstraintTracker =
740              new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
741          report.addVisitor(ConstraintTracker);
742        }
743
744        if (Optional<KnownSVal> KV = V.getAs<KnownSVal>())
745          report.addVisitor(new FindLastStoreBRVisitor(*KV, R));
746        return true;
747      }
748    }
749  }
750
751  // If the expression is not an "lvalue expression", we can still
752  // track the constraints on its contents.
753  SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
754
755  // Uncomment this to find cases where we aren't properly getting the
756  // base value that was dereferenced.
757  // assert(!V.isUnknownOrUndef());
758  // Is it a symbolic value?
759  if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
760    // At this point we are dealing with the region's LValue.
761    // However, if the rvalue is a symbolic region, we should track it as well.
762    SVal RVal = state->getSVal(L->getRegion());
763    const MemRegion *RegionRVal = RVal.getAsRegion();
764    report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
765
766
767    if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
768      report.markInteresting(RegionRVal);
769      report.addVisitor(new TrackConstraintBRVisitor(
770        loc::MemRegionVal(RegionRVal), false));
771    }
772  } else {
773    // Otherwise, if the value came from an inlined function call,
774    // we should at least make sure that function isn't pruned in our output.
775    if (const Expr *E = dyn_cast<Expr>(S))
776      S = E->IgnoreParenCasts();
777    ReturnVisitor::addVisitorIfNecessary(N, S, report);
778  }
779
780  return true;
781}
782
783BugReporterVisitor *
784FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
785                                            const MemRegion *R) {
786  assert(R && "The memory region is null.");
787
788  ProgramStateRef state = N->getState();
789  if (Optional<KnownSVal> KV = state->getSVal(R).getAs<KnownSVal>())
790    return new FindLastStoreBRVisitor(*KV, R);
791  return 0;
792}
793
794PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
795                                                     const ExplodedNode *PrevN,
796                                                     BugReporterContext &BRC,
797                                                     BugReport &BR) {
798  Optional<PostStmt> P = N->getLocationAs<PostStmt>();
799  if (!P)
800    return 0;
801  const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
802  if (!ME)
803    return 0;
804  const Expr *Receiver = ME->getInstanceReceiver();
805  if (!Receiver)
806    return 0;
807  ProgramStateRef state = N->getState();
808  const SVal &V = state->getSVal(Receiver, N->getLocationContext());
809  Optional<DefinedOrUnknownSVal> DV = V.getAs<DefinedOrUnknownSVal>();
810  if (!DV)
811    return 0;
812  state = state->assume(*DV, true);
813  if (state)
814    return 0;
815
816  // The receiver was nil, and hence the method was skipped.
817  // Register a BugReporterVisitor to issue a message telling us how
818  // the receiver was null.
819  bugreporter::trackNullOrUndefValue(N, Receiver, BR);
820  // Issue a message saying that the method was skipped.
821  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
822                                     N->getLocationContext());
823  return new PathDiagnosticEventPiece(L, "No method is called "
824      "because the receiver is nil");
825}
826
827// Registers every VarDecl inside a Stmt with a last store visitor.
828void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
829                                                       const Stmt *S) {
830  const ExplodedNode *N = BR.getErrorNode();
831  std::deque<const Stmt *> WorkList;
832  WorkList.push_back(S);
833
834  while (!WorkList.empty()) {
835    const Stmt *Head = WorkList.front();
836    WorkList.pop_front();
837
838    ProgramStateRef state = N->getState();
839    ProgramStateManager &StateMgr = state->getStateManager();
840
841    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
842      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
843        const VarRegion *R =
844        StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
845
846        // What did we load?
847        SVal V = state->getSVal(S, N->getLocationContext());
848
849        if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
850          // Register a new visitor with the BugReport.
851          BR.addVisitor(new FindLastStoreBRVisitor(V.castAs<KnownSVal>(), R));
852        }
853      }
854    }
855
856    for (Stmt::const_child_iterator I = Head->child_begin();
857        I != Head->child_end(); ++I)
858      WorkList.push_back(*I);
859  }
860}
861
862//===----------------------------------------------------------------------===//
863// Visitor that tries to report interesting diagnostics from conditions.
864//===----------------------------------------------------------------------===//
865
866/// Return the tag associated with this visitor.  This tag will be used
867/// to make all PathDiagnosticPieces created by this visitor.
868const char *ConditionBRVisitor::getTag() {
869  return "ConditionBRVisitor";
870}
871
872PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
873                                                   const ExplodedNode *Prev,
874                                                   BugReporterContext &BRC,
875                                                   BugReport &BR) {
876  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
877  if (piece) {
878    piece->setTag(getTag());
879    if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
880      ev->setPrunable(true, /* override */ false);
881  }
882  return piece;
883}
884
885PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
886                                                       const ExplodedNode *Prev,
887                                                       BugReporterContext &BRC,
888                                                       BugReport &BR) {
889
890  ProgramPoint progPoint = N->getLocation();
891  ProgramStateRef CurrentState = N->getState();
892  ProgramStateRef PrevState = Prev->getState();
893
894  // Compare the GDMs of the state, because that is where constraints
895  // are managed.  Note that ensure that we only look at nodes that
896  // were generated by the analyzer engine proper, not checkers.
897  if (CurrentState->getGDM().getRoot() ==
898      PrevState->getGDM().getRoot())
899    return 0;
900
901  // If an assumption was made on a branch, it should be caught
902  // here by looking at the state transition.
903  if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
904    const CFGBlock *srcBlk = BE->getSrc();
905    if (const Stmt *term = srcBlk->getTerminator())
906      return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
907    return 0;
908  }
909
910  if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
911    // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
912    // violation.
913    const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
914      cast<GRBugReporter>(BRC.getBugReporter()).
915        getEngine().geteagerlyAssumeBinOpBifurcationTags();
916
917    const ProgramPointTag *tag = PS->getTag();
918    if (tag == tags.first)
919      return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
920                           BRC, BR, N);
921    if (tag == tags.second)
922      return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
923                           BRC, BR, N);
924
925    return 0;
926  }
927
928  return 0;
929}
930
931PathDiagnosticPiece *
932ConditionBRVisitor::VisitTerminator(const Stmt *Term,
933                                    const ExplodedNode *N,
934                                    const CFGBlock *srcBlk,
935                                    const CFGBlock *dstBlk,
936                                    BugReport &R,
937                                    BugReporterContext &BRC) {
938  const Expr *Cond = 0;
939
940  switch (Term->getStmtClass()) {
941  default:
942    return 0;
943  case Stmt::IfStmtClass:
944    Cond = cast<IfStmt>(Term)->getCond();
945    break;
946  case Stmt::ConditionalOperatorClass:
947    Cond = cast<ConditionalOperator>(Term)->getCond();
948    break;
949  }
950
951  assert(Cond);
952  assert(srcBlk->succ_size() == 2);
953  const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
954  return VisitTrueTest(Cond, tookTrue, BRC, R, N);
955}
956
957PathDiagnosticPiece *
958ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
959                                  bool tookTrue,
960                                  BugReporterContext &BRC,
961                                  BugReport &R,
962                                  const ExplodedNode *N) {
963
964  const Expr *Ex = Cond;
965
966  while (true) {
967    Ex = Ex->IgnoreParenCasts();
968    switch (Ex->getStmtClass()) {
969      default:
970        return 0;
971      case Stmt::BinaryOperatorClass:
972        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
973                             R, N);
974      case Stmt::DeclRefExprClass:
975        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
976                             R, N);
977      case Stmt::UnaryOperatorClass: {
978        const UnaryOperator *UO = cast<UnaryOperator>(Ex);
979        if (UO->getOpcode() == UO_LNot) {
980          tookTrue = !tookTrue;
981          Ex = UO->getSubExpr();
982          continue;
983        }
984        return 0;
985      }
986    }
987  }
988}
989
990bool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
991                                      BugReporterContext &BRC,
992                                      BugReport &report,
993                                      const ExplodedNode *N,
994                                      Optional<bool> &prunable) {
995  const Expr *OriginalExpr = Ex;
996  Ex = Ex->IgnoreParenCasts();
997
998  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
999    const bool quotes = isa<VarDecl>(DR->getDecl());
1000    if (quotes) {
1001      Out << '\'';
1002      const LocationContext *LCtx = N->getLocationContext();
1003      const ProgramState *state = N->getState().getPtr();
1004      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
1005                                                LCtx).getAsRegion()) {
1006        if (report.isInteresting(R))
1007          prunable = false;
1008        else {
1009          const ProgramState *state = N->getState().getPtr();
1010          SVal V = state->getSVal(R);
1011          if (report.isInteresting(V))
1012            prunable = false;
1013        }
1014      }
1015    }
1016    Out << DR->getDecl()->getDeclName().getAsString();
1017    if (quotes)
1018      Out << '\'';
1019    return quotes;
1020  }
1021
1022  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
1023    QualType OriginalTy = OriginalExpr->getType();
1024    if (OriginalTy->isPointerType()) {
1025      if (IL->getValue() == 0) {
1026        Out << "null";
1027        return false;
1028      }
1029    }
1030    else if (OriginalTy->isObjCObjectPointerType()) {
1031      if (IL->getValue() == 0) {
1032        Out << "nil";
1033        return false;
1034      }
1035    }
1036
1037    Out << IL->getValue();
1038    return false;
1039  }
1040
1041  return false;
1042}
1043
1044PathDiagnosticPiece *
1045ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
1046                                  const BinaryOperator *BExpr,
1047                                  const bool tookTrue,
1048                                  BugReporterContext &BRC,
1049                                  BugReport &R,
1050                                  const ExplodedNode *N) {
1051
1052  bool shouldInvert = false;
1053  Optional<bool> shouldPrune;
1054
1055  SmallString<128> LhsString, RhsString;
1056  {
1057    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
1058    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
1059                                       shouldPrune);
1060    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
1061                                       shouldPrune);
1062
1063    shouldInvert = !isVarLHS && isVarRHS;
1064  }
1065
1066  BinaryOperator::Opcode Op = BExpr->getOpcode();
1067
1068  if (BinaryOperator::isAssignmentOp(Op)) {
1069    // For assignment operators, all that we care about is that the LHS
1070    // evaluates to "true" or "false".
1071    return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
1072                                  BRC, R, N);
1073  }
1074
1075  // For non-assignment operations, we require that we can understand
1076  // both the LHS and RHS.
1077  if (LhsString.empty() || RhsString.empty())
1078    return 0;
1079
1080  // Should we invert the strings if the LHS is not a variable name?
1081  SmallString<256> buf;
1082  llvm::raw_svector_ostream Out(buf);
1083  Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is ";
1084
1085  // Do we need to invert the opcode?
1086  if (shouldInvert)
1087    switch (Op) {
1088      default: break;
1089      case BO_LT: Op = BO_GT; break;
1090      case BO_GT: Op = BO_LT; break;
1091      case BO_LE: Op = BO_GE; break;
1092      case BO_GE: Op = BO_LE; break;
1093    }
1094
1095  if (!tookTrue)
1096    switch (Op) {
1097      case BO_EQ: Op = BO_NE; break;
1098      case BO_NE: Op = BO_EQ; break;
1099      case BO_LT: Op = BO_GE; break;
1100      case BO_GT: Op = BO_LE; break;
1101      case BO_LE: Op = BO_GT; break;
1102      case BO_GE: Op = BO_LT; break;
1103      default:
1104        return 0;
1105    }
1106
1107  switch (Op) {
1108    case BO_EQ:
1109      Out << "equal to ";
1110      break;
1111    case BO_NE:
1112      Out << "not equal to ";
1113      break;
1114    default:
1115      Out << BinaryOperator::getOpcodeStr(Op) << ' ';
1116      break;
1117  }
1118
1119  Out << (shouldInvert ? LhsString : RhsString);
1120  const LocationContext *LCtx = N->getLocationContext();
1121  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1122  PathDiagnosticEventPiece *event =
1123    new PathDiagnosticEventPiece(Loc, Out.str());
1124  if (shouldPrune.hasValue())
1125    event->setPrunable(shouldPrune.getValue());
1126  return event;
1127}
1128
1129PathDiagnosticPiece *
1130ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
1131                                           const Expr *CondVarExpr,
1132                                           const bool tookTrue,
1133                                           BugReporterContext &BRC,
1134                                           BugReport &report,
1135                                           const ExplodedNode *N) {
1136  // FIXME: If there's already a constraint tracker for this variable,
1137  // we shouldn't emit anything here (c.f. the double note in
1138  // test/Analysis/inlining/path-notes.c)
1139  SmallString<256> buf;
1140  llvm::raw_svector_ostream Out(buf);
1141  Out << "Assuming " << LhsString << " is ";
1142
1143  QualType Ty = CondVarExpr->getType();
1144
1145  if (Ty->isPointerType())
1146    Out << (tookTrue ? "not null" : "null");
1147  else if (Ty->isObjCObjectPointerType())
1148    Out << (tookTrue ? "not nil" : "nil");
1149  else if (Ty->isBooleanType())
1150    Out << (tookTrue ? "true" : "false");
1151  else if (Ty->isIntegerType())
1152    Out << (tookTrue ? "non-zero" : "zero");
1153  else
1154    return 0;
1155
1156  const LocationContext *LCtx = N->getLocationContext();
1157  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
1158  PathDiagnosticEventPiece *event =
1159    new PathDiagnosticEventPiece(Loc, Out.str());
1160
1161  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
1162    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1163      const ProgramState *state = N->getState().getPtr();
1164      if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1165        if (report.isInteresting(R))
1166          event->setPrunable(false);
1167      }
1168    }
1169  }
1170
1171  return event;
1172}
1173
1174PathDiagnosticPiece *
1175ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
1176                                  const DeclRefExpr *DR,
1177                                  const bool tookTrue,
1178                                  BugReporterContext &BRC,
1179                                  BugReport &report,
1180                                  const ExplodedNode *N) {
1181
1182  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
1183  if (!VD)
1184    return 0;
1185
1186  SmallString<256> Buf;
1187  llvm::raw_svector_ostream Out(Buf);
1188
1189  Out << "Assuming '";
1190  VD->getDeclName().printName(Out);
1191  Out << "' is ";
1192
1193  QualType VDTy = VD->getType();
1194
1195  if (VDTy->isPointerType())
1196    Out << (tookTrue ? "non-null" : "null");
1197  else if (VDTy->isObjCObjectPointerType())
1198    Out << (tookTrue ? "non-nil" : "nil");
1199  else if (VDTy->isScalarType())
1200    Out << (tookTrue ? "not equal to 0" : "0");
1201  else
1202    return 0;
1203
1204  const LocationContext *LCtx = N->getLocationContext();
1205  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1206  PathDiagnosticEventPiece *event =
1207    new PathDiagnosticEventPiece(Loc, Out.str());
1208
1209  const ProgramState *state = N->getState().getPtr();
1210  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1211    if (report.isInteresting(R))
1212      event->setPrunable(false);
1213    else {
1214      SVal V = state->getSVal(R);
1215      if (report.isInteresting(V))
1216        event->setPrunable(false);
1217    }
1218  }
1219  return event;
1220}
1221
1222PathDiagnosticPiece *
1223LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
1224                                                    const ExplodedNode *N,
1225                                                    BugReport &BR) {
1226  const Stmt *S = BR.getStmt();
1227  if (!S)
1228    return 0;
1229
1230  // Here we suppress false positives coming from system macros. This list is
1231  // based on known issues.
1232
1233  // Skip reports within the sys/queue.h macros as we do not have the ability to
1234  // reason about data structure shapes.
1235  SourceManager &SM = BRC.getSourceManager();
1236  SourceLocation Loc = S->getLocStart();
1237  while (Loc.isMacroID()) {
1238    if (SM.isInSystemMacro(Loc) &&
1239       (SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) {
1240      BR.markInvalid(getTag(), 0);
1241      return 0;
1242    }
1243    Loc = SM.getSpellingLoc(Loc);
1244  }
1245
1246  return 0;
1247}
1248
1249PathDiagnosticPiece *
1250UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
1251                                  const ExplodedNode *PrevN,
1252                                  BugReporterContext &BRC,
1253                                  BugReport &BR) {
1254
1255  ProgramStateRef State = N->getState();
1256  ProgramPoint ProgLoc = N->getLocation();
1257
1258  // We are only interested in visiting CallEnter nodes.
1259  Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
1260  if (!CEnter)
1261    return 0;
1262
1263  // Check if one of the arguments is the region the visitor is tracking.
1264  CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
1265  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
1266  unsigned Idx = 0;
1267  for (CallEvent::param_iterator I = Call->param_begin(),
1268                                 E = Call->param_end(); I != E; ++I, ++Idx) {
1269    const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
1270
1271    // Are we tracking the argument or its subregion?
1272    if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
1273      continue;
1274
1275    // Check the function parameter type.
1276    const ParmVarDecl *ParamDecl = *I;
1277    assert(ParamDecl && "Formal parameter has no decl?");
1278    QualType T = ParamDecl->getType();
1279
1280    if (!(T->isAnyPointerType() || T->isReferenceType())) {
1281      // Function can only change the value passed in by address.
1282      continue;
1283    }
1284
1285    // If it is a const pointer value, the function does not intend to
1286    // change the value.
1287    if (T->getPointeeType().isConstQualified())
1288      continue;
1289
1290    // Mark the call site (LocationContext) as interesting if the value of the
1291    // argument is undefined or '0'/'NULL'.
1292    SVal BoundVal = State->getSVal(R);
1293    if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
1294      BR.markInteresting(CEnter->getCalleeContext());
1295      return 0;
1296    }
1297  }
1298  return 0;
1299}
1300