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