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