BugReporterVisitors.cpp revision 09f7bf14d25bdc55cb715bc8d40600906848a409
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  bool IsParam = false;
287
288  // First see if we reached the declaration of the region.
289  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
290    if (const PostStmt *P = Pred->getLocationAs<PostStmt>()) {
291      if (const DeclStmt *DS = P->getStmtAs<DeclStmt>()) {
292        if (DS->getSingleDecl() == VR->getDecl()) {
293          StoreSite = Pred;
294          InitE = VR->getDecl()->getInit();
295        }
296      }
297    }
298  }
299
300  // Otherwise, check that Succ has this binding and Pred does not, i.e. this is
301  // where the binding first occurred.
302  if (!StoreSite) {
303    if (Succ->getState()->getSVal(R) != V)
304      return NULL;
305    if (Pred->getState()->getSVal(R) == V)
306      return NULL;
307
308    StoreSite = Succ;
309
310    // If this is an assignment expression, we can track the value
311    // being assigned.
312    if (const PostStmt *P = Succ->getLocationAs<PostStmt>())
313      if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>())
314        if (BO->isAssignmentOp())
315          InitE = BO->getRHS();
316
317    // If this is a call entry, the variable should be a parameter.
318    // FIXME: Handle CXXThisRegion as well. (This is not a priority because
319    // 'this' should never be NULL, but this visitor isn't just for NULL and
320    // UndefinedVal.)
321    if (const CallEnter *CE = Succ->getLocationAs<CallEnter>()) {
322      const VarRegion *VR = cast<VarRegion>(R);
323      const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
324
325      ProgramStateManager &StateMgr = BRC.getStateManager();
326      CallEventManager &CallMgr = StateMgr.getCallEventManager();
327
328      CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
329                                              Succ->getState());
330      InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
331      IsParam = true;
332    }
333  }
334
335  if (!StoreSite)
336    return NULL;
337  satisfied = true;
338
339  // If we have an expression that provided the value, try to track where it
340  // came from.
341  if (InitE) {
342    if (V.isUndef() || isa<loc::ConcreteInt>(V)) {
343      if (!IsParam)
344        InitE = InitE->IgnoreParenCasts();
345      bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam);
346    } else {
347      ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(),
348                                           BR);
349    }
350  }
351
352  if (!R->canPrintPretty())
353    return 0;
354
355  // Okay, we've found the binding. Emit an appropriate message.
356  SmallString<256> sbuf;
357  llvm::raw_svector_ostream os(sbuf);
358
359  if (const PostStmt *PS = StoreSite->getLocationAs<PostStmt>()) {
360    if (const DeclStmt *DS = PS->getStmtAs<DeclStmt>()) {
361
362      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
363        os << "Variable '" << *VR->getDecl() << "' ";
364      }
365      else
366        return NULL;
367
368      if (isa<loc::ConcreteInt>(V)) {
369        bool b = false;
370        if (R->isBoundable()) {
371          if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
372            if (TR->getValueType()->isObjCObjectPointerType()) {
373              os << "initialized to nil";
374              b = true;
375            }
376          }
377        }
378
379        if (!b)
380          os << "initialized to a null pointer value";
381      }
382      else if (isa<nonloc::ConcreteInt>(V)) {
383        os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
384      }
385      else if (V.isUndef()) {
386        if (isa<VarRegion>(R)) {
387          const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
388          if (VD->getInit())
389            os << "initialized to a garbage value";
390          else
391            os << "declared without an initial value";
392        }
393      }
394      else {
395        os << "initialized here";
396      }
397    }
398  } else if (isa<CallEnter>(StoreSite->getLocation())) {
399    const ParmVarDecl *Param = cast<ParmVarDecl>(cast<VarRegion>(R)->getDecl());
400
401    os << "Passing ";
402
403    if (isa<loc::ConcreteInt>(V)) {
404      if (Param->getType()->isObjCObjectPointerType())
405        os << "nil object reference";
406      else
407        os << "null pointer value";
408    } else if (V.isUndef()) {
409      os << "uninitialized value";
410    } else if (isa<nonloc::ConcreteInt>(V)) {
411      os << "the value " << cast<nonloc::ConcreteInt>(V).getValue();
412    } else {
413      os << "value";
414    }
415
416    // Printed parameter indexes are 1-based, not 0-based.
417    unsigned Idx = Param->getFunctionScopeIndex() + 1;
418    os << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter '";
419
420    R->printPretty(os);
421    os << '\'';
422  }
423
424  if (os.str().empty()) {
425    if (isa<loc::ConcreteInt>(V)) {
426      bool b = false;
427      if (R->isBoundable()) {
428        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
429          if (TR->getValueType()->isObjCObjectPointerType()) {
430            os << "nil object reference stored to ";
431            b = true;
432          }
433        }
434      }
435
436      if (!b)
437        os << "Null pointer value stored to ";
438    }
439    else if (V.isUndef()) {
440      os << "Uninitialized value stored to ";
441    }
442    else if (isa<nonloc::ConcreteInt>(V)) {
443      os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
444               << " is assigned to ";
445    }
446    else
447      os << "Value assigned to ";
448
449    os << '\'';
450    R->printPretty(os);
451    os << '\'';
452  }
453
454  // Construct a new PathDiagnosticPiece.
455  ProgramPoint P = StoreSite->getLocation();
456  PathDiagnosticLocation L;
457  if (isa<CallEnter>(P))
458    L = PathDiagnosticLocation(InitE, BRC.getSourceManager(),
459                               P.getLocationContext());
460  else
461    L = PathDiagnosticLocation::create(P, BRC.getSourceManager());
462  if (!L.isValid())
463    return NULL;
464  return new PathDiagnosticEventPiece(L, os.str());
465}
466
467void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
468  static int tag = 0;
469  ID.AddPointer(&tag);
470  ID.AddBoolean(Assumption);
471  ID.Add(Constraint);
472}
473
474/// Return the tag associated with this visitor.  This tag will be used
475/// to make all PathDiagnosticPieces created by this visitor.
476const char *TrackConstraintBRVisitor::getTag() {
477  return "TrackConstraintBRVisitor";
478}
479
480PathDiagnosticPiece *
481TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
482                                    const ExplodedNode *PrevN,
483                                    BugReporterContext &BRC,
484                                    BugReport &BR) {
485  if (isSatisfied)
486    return NULL;
487
488  // Check if in the previous state it was feasible for this constraint
489  // to *not* be true.
490  if (PrevN->getState()->assume(Constraint, !Assumption)) {
491
492    isSatisfied = true;
493
494    // As a sanity check, make sure that the negation of the constraint
495    // was infeasible in the current state.  If it is feasible, we somehow
496    // missed the transition point.
497    if (N->getState()->assume(Constraint, !Assumption))
498      return NULL;
499
500    // We found the transition point for the constraint.  We now need to
501    // pretty-print the constraint. (work-in-progress)
502    std::string sbuf;
503    llvm::raw_string_ostream os(sbuf);
504
505    if (isa<Loc>(Constraint)) {
506      os << "Assuming pointer value is ";
507      os << (Assumption ? "non-null" : "null");
508    }
509
510    if (os.str().empty())
511      return NULL;
512
513    // Construct a new PathDiagnosticPiece.
514    ProgramPoint P = N->getLocation();
515    PathDiagnosticLocation L =
516      PathDiagnosticLocation::create(P, BRC.getSourceManager());
517    if (!L.isValid())
518      return NULL;
519
520    PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
521    X->setTag(getTag());
522    return X;
523  }
524
525  return NULL;
526}
527
528void bugreporter::trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S,
529                                        BugReport &report, bool IsArg) {
530  if (!S || !N)
531    return;
532
533  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(S))
534    S = OVE->getSourceExpr();
535
536  if (IsArg) {
537    assert(isa<CallEnter>(N->getLocation()) && "Tracking arg but not at call");
538  } else {
539    // Walk through nodes until we get one that matches the statement exactly.
540    do {
541      const ProgramPoint &pp = N->getLocation();
542      if (const PostStmt *ps = dyn_cast<PostStmt>(&pp)) {
543        if (ps->getStmt() == S)
544          break;
545      } else if (const CallExitEnd *CEE = dyn_cast<CallExitEnd>(&pp)) {
546        if (CEE->getCalleeContext()->getCallSite() == S)
547          break;
548      }
549      N = N->getFirstPred();
550    } while (N);
551
552    if (!N)
553      return;
554  }
555
556  ProgramStateRef state = N->getState();
557
558  // See if the expression we're interested refers to a variable.
559  // If so, we can track both its contents and constraints on its value.
560  if (const Expr *Ex = dyn_cast<Expr>(S)) {
561    // Strip off parens and casts. Note that this will never have issues with
562    // C++ user-defined implicit conversions, because those have a constructor
563    // or function call inside.
564    Ex = Ex->IgnoreParenCasts();
565    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
566      // FIXME: Right now we only track VarDecls because it's non-trivial to
567      // get a MemRegion for any other DeclRefExprs. <rdar://problem/12114812>
568      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
569        ProgramStateManager &StateMgr = state->getStateManager();
570        MemRegionManager &MRMgr = StateMgr.getRegionManager();
571        const VarRegion *R = MRMgr.getVarRegion(VD, N->getLocationContext());
572
573        // Mark both the variable region and its contents as interesting.
574        SVal V = state->getRawSVal(loc::MemRegionVal(R));
575
576        // If the value matches the default for the variable region, that
577        // might mean that it's been cleared out of the state. Fall back to
578        // the full argument expression (with casts and such intact).
579        if (IsArg) {
580          bool UseArgValue = V.isUnknownOrUndef() || V.isZeroConstant();
581          if (!UseArgValue) {
582            const SymbolRegionValue *SRV =
583              dyn_cast_or_null<SymbolRegionValue>(V.getAsLocSymbol());
584            if (SRV)
585              UseArgValue = (SRV->getRegion() == R);
586          }
587          if (UseArgValue)
588            V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
589        }
590
591        report.markInteresting(R);
592        report.markInteresting(V);
593        report.addVisitor(new UndefOrNullArgVisitor(R));
594
595        // If the contents are symbolic, find out when they became null.
596        if (V.getAsLocSymbol()) {
597          BugReporterVisitor *ConstraintTracker
598            = new TrackConstraintBRVisitor(cast<DefinedSVal>(V), false);
599          report.addVisitor(ConstraintTracker);
600        }
601
602        report.addVisitor(new FindLastStoreBRVisitor(V, R));
603        return;
604      }
605    }
606  }
607
608  // If the expression does NOT refer to a variable, we can still track
609  // constraints on its contents.
610  SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
611
612  // Uncomment this to find cases where we aren't properly getting the
613  // base value that was dereferenced.
614  // assert(!V.isUnknownOrUndef());
615
616  // Is it a symbolic value?
617  if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
618    // At this point we are dealing with the region's LValue.
619    // However, if the rvalue is a symbolic region, we should track it as well.
620    SVal RVal = state->getSVal(L->getRegion());
621    const MemRegion *RegionRVal = RVal.getAsRegion();
622    report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
623
624
625    if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
626      report.markInteresting(RegionRVal);
627      report.addVisitor(new TrackConstraintBRVisitor(
628        loc::MemRegionVal(RegionRVal), false));
629    }
630  } else {
631    // Otherwise, if the value came from an inlined function call,
632    // we should at least make sure that function isn't pruned in our output.
633    if (const Expr *E = dyn_cast<Expr>(S))
634      S = E->IgnoreParenCasts();
635    ReturnVisitor::addVisitorIfNecessary(N, S, report);
636  }
637}
638
639BugReporterVisitor *
640FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
641                                            const MemRegion *R) {
642  assert(R && "The memory region is null.");
643
644  ProgramStateRef state = N->getState();
645  SVal V = state->getSVal(R);
646  if (V.isUnknown())
647    return 0;
648
649  return new FindLastStoreBRVisitor(V, R);
650}
651
652
653PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
654                                                     const ExplodedNode *PrevN,
655                                                     BugReporterContext &BRC,
656                                                     BugReport &BR) {
657  const PostStmt *P = N->getLocationAs<PostStmt>();
658  if (!P)
659    return 0;
660  const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
661  if (!ME)
662    return 0;
663  const Expr *Receiver = ME->getInstanceReceiver();
664  if (!Receiver)
665    return 0;
666  ProgramStateRef state = N->getState();
667  const SVal &V = state->getSVal(Receiver, N->getLocationContext());
668  const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
669  if (!DV)
670    return 0;
671  state = state->assume(*DV, true);
672  if (state)
673    return 0;
674
675  // The receiver was nil, and hence the method was skipped.
676  // Register a BugReporterVisitor to issue a message telling us how
677  // the receiver was null.
678  bugreporter::trackNullOrUndefValue(N, Receiver, BR);
679  // Issue a message saying that the method was skipped.
680  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
681                                     N->getLocationContext());
682  return new PathDiagnosticEventPiece(L, "No method is called "
683      "because the receiver is nil");
684}
685
686// Registers every VarDecl inside a Stmt with a last store visitor.
687void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
688                                                       const Stmt *S) {
689  const ExplodedNode *N = BR.getErrorNode();
690  std::deque<const Stmt *> WorkList;
691  WorkList.push_back(S);
692
693  while (!WorkList.empty()) {
694    const Stmt *Head = WorkList.front();
695    WorkList.pop_front();
696
697    ProgramStateRef state = N->getState();
698    ProgramStateManager &StateMgr = state->getStateManager();
699
700    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
701      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
702        const VarRegion *R =
703        StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
704
705        // What did we load?
706        SVal V = state->getSVal(S, N->getLocationContext());
707
708        if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) {
709          // Register a new visitor with the BugReport.
710          BR.addVisitor(new FindLastStoreBRVisitor(V, R));
711        }
712      }
713    }
714
715    for (Stmt::const_child_iterator I = Head->child_begin();
716        I != Head->child_end(); ++I)
717      WorkList.push_back(*I);
718  }
719}
720
721//===----------------------------------------------------------------------===//
722// Visitor that tries to report interesting diagnostics from conditions.
723//===----------------------------------------------------------------------===//
724
725/// Return the tag associated with this visitor.  This tag will be used
726/// to make all PathDiagnosticPieces created by this visitor.
727const char *ConditionBRVisitor::getTag() {
728  return "ConditionBRVisitor";
729}
730
731PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
732                                                   const ExplodedNode *Prev,
733                                                   BugReporterContext &BRC,
734                                                   BugReport &BR) {
735  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
736  if (piece) {
737    piece->setTag(getTag());
738    if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
739      ev->setPrunable(true, /* override */ false);
740  }
741  return piece;
742}
743
744PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
745                                                       const ExplodedNode *Prev,
746                                                       BugReporterContext &BRC,
747                                                       BugReport &BR) {
748
749  ProgramPoint progPoint = N->getLocation();
750  ProgramStateRef CurrentState = N->getState();
751  ProgramStateRef PrevState = Prev->getState();
752
753  // Compare the GDMs of the state, because that is where constraints
754  // are managed.  Note that ensure that we only look at nodes that
755  // were generated by the analyzer engine proper, not checkers.
756  if (CurrentState->getGDM().getRoot() ==
757      PrevState->getGDM().getRoot())
758    return 0;
759
760  // If an assumption was made on a branch, it should be caught
761  // here by looking at the state transition.
762  if (const BlockEdge *BE = dyn_cast<BlockEdge>(&progPoint)) {
763    const CFGBlock *srcBlk = BE->getSrc();
764    if (const Stmt *term = srcBlk->getTerminator())
765      return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
766    return 0;
767  }
768
769  if (const PostStmt *PS = dyn_cast<PostStmt>(&progPoint)) {
770    // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
771    // violation.
772    const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
773      cast<GRBugReporter>(BRC.getBugReporter()).
774        getEngine().geteagerlyAssumeBinOpBifurcationTags();
775
776    const ProgramPointTag *tag = PS->getTag();
777    if (tag == tags.first)
778      return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
779                           BRC, BR, N);
780    if (tag == tags.second)
781      return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
782                           BRC, BR, N);
783
784    return 0;
785  }
786
787  return 0;
788}
789
790PathDiagnosticPiece *
791ConditionBRVisitor::VisitTerminator(const Stmt *Term,
792                                    const ExplodedNode *N,
793                                    const CFGBlock *srcBlk,
794                                    const CFGBlock *dstBlk,
795                                    BugReport &R,
796                                    BugReporterContext &BRC) {
797  const Expr *Cond = 0;
798
799  switch (Term->getStmtClass()) {
800  default:
801    return 0;
802  case Stmt::IfStmtClass:
803    Cond = cast<IfStmt>(Term)->getCond();
804    break;
805  case Stmt::ConditionalOperatorClass:
806    Cond = cast<ConditionalOperator>(Term)->getCond();
807    break;
808  }
809
810  assert(Cond);
811  assert(srcBlk->succ_size() == 2);
812  const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
813  return VisitTrueTest(Cond, tookTrue, BRC, R, N);
814}
815
816PathDiagnosticPiece *
817ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
818                                  bool tookTrue,
819                                  BugReporterContext &BRC,
820                                  BugReport &R,
821                                  const ExplodedNode *N) {
822
823  const Expr *Ex = Cond;
824
825  while (true) {
826    Ex = Ex->IgnoreParenCasts();
827    switch (Ex->getStmtClass()) {
828      default:
829        return 0;
830      case Stmt::BinaryOperatorClass:
831        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
832                             R, N);
833      case Stmt::DeclRefExprClass:
834        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
835                             R, N);
836      case Stmt::UnaryOperatorClass: {
837        const UnaryOperator *UO = cast<UnaryOperator>(Ex);
838        if (UO->getOpcode() == UO_LNot) {
839          tookTrue = !tookTrue;
840          Ex = UO->getSubExpr();
841          continue;
842        }
843        return 0;
844      }
845    }
846  }
847}
848
849bool ConditionBRVisitor::patternMatch(const Expr *Ex, llvm::raw_ostream &Out,
850                                      BugReporterContext &BRC,
851                                      BugReport &report,
852                                      const ExplodedNode *N,
853                                      llvm::Optional<bool> &prunable) {
854  const Expr *OriginalExpr = Ex;
855  Ex = Ex->IgnoreParenCasts();
856
857  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
858    const bool quotes = isa<VarDecl>(DR->getDecl());
859    if (quotes) {
860      Out << '\'';
861      const LocationContext *LCtx = N->getLocationContext();
862      const ProgramState *state = N->getState().getPtr();
863      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
864                                                LCtx).getAsRegion()) {
865        if (report.isInteresting(R))
866          prunable = false;
867        else {
868          const ProgramState *state = N->getState().getPtr();
869          SVal V = state->getSVal(R);
870          if (report.isInteresting(V))
871            prunable = false;
872        }
873      }
874    }
875    Out << DR->getDecl()->getDeclName().getAsString();
876    if (quotes)
877      Out << '\'';
878    return quotes;
879  }
880
881  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
882    QualType OriginalTy = OriginalExpr->getType();
883    if (OriginalTy->isPointerType()) {
884      if (IL->getValue() == 0) {
885        Out << "null";
886        return false;
887      }
888    }
889    else if (OriginalTy->isObjCObjectPointerType()) {
890      if (IL->getValue() == 0) {
891        Out << "nil";
892        return false;
893      }
894    }
895
896    Out << IL->getValue();
897    return false;
898  }
899
900  return false;
901}
902
903PathDiagnosticPiece *
904ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
905                                  const BinaryOperator *BExpr,
906                                  const bool tookTrue,
907                                  BugReporterContext &BRC,
908                                  BugReport &R,
909                                  const ExplodedNode *N) {
910
911  bool shouldInvert = false;
912  llvm::Optional<bool> shouldPrune;
913
914  SmallString<128> LhsString, RhsString;
915  {
916    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
917    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
918                                       shouldPrune);
919    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
920                                       shouldPrune);
921
922    shouldInvert = !isVarLHS && isVarRHS;
923  }
924
925  BinaryOperator::Opcode Op = BExpr->getOpcode();
926
927  if (BinaryOperator::isAssignmentOp(Op)) {
928    // For assignment operators, all that we care about is that the LHS
929    // evaluates to "true" or "false".
930    return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
931                                  BRC, R, N);
932  }
933
934  // For non-assignment operations, we require that we can understand
935  // both the LHS and RHS.
936  if (LhsString.empty() || RhsString.empty())
937    return 0;
938
939  // Should we invert the strings if the LHS is not a variable name?
940  SmallString<256> buf;
941  llvm::raw_svector_ostream Out(buf);
942  Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is ";
943
944  // Do we need to invert the opcode?
945  if (shouldInvert)
946    switch (Op) {
947      default: break;
948      case BO_LT: Op = BO_GT; break;
949      case BO_GT: Op = BO_LT; break;
950      case BO_LE: Op = BO_GE; break;
951      case BO_GE: Op = BO_LE; break;
952    }
953
954  if (!tookTrue)
955    switch (Op) {
956      case BO_EQ: Op = BO_NE; break;
957      case BO_NE: Op = BO_EQ; break;
958      case BO_LT: Op = BO_GE; break;
959      case BO_GT: Op = BO_LE; break;
960      case BO_LE: Op = BO_GT; break;
961      case BO_GE: Op = BO_LT; break;
962      default:
963        return 0;
964    }
965
966  switch (Op) {
967    case BO_EQ:
968      Out << "equal to ";
969      break;
970    case BO_NE:
971      Out << "not equal to ";
972      break;
973    default:
974      Out << BinaryOperator::getOpcodeStr(Op) << ' ';
975      break;
976  }
977
978  Out << (shouldInvert ? LhsString : RhsString);
979  const LocationContext *LCtx = N->getLocationContext();
980  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
981  PathDiagnosticEventPiece *event =
982    new PathDiagnosticEventPiece(Loc, Out.str());
983  if (shouldPrune.hasValue())
984    event->setPrunable(shouldPrune.getValue());
985  return event;
986}
987
988PathDiagnosticPiece *
989ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
990                                           const Expr *CondVarExpr,
991                                           const bool tookTrue,
992                                           BugReporterContext &BRC,
993                                           BugReport &report,
994                                           const ExplodedNode *N) {
995  // FIXME: If there's already a constraint tracker for this variable,
996  // we shouldn't emit anything here (c.f. the double note in
997  // test/Analysis/inlining/path-notes.c)
998  SmallString<256> buf;
999  llvm::raw_svector_ostream Out(buf);
1000  Out << "Assuming " << LhsString << " is ";
1001
1002  QualType Ty = CondVarExpr->getType();
1003
1004  if (Ty->isPointerType())
1005    Out << (tookTrue ? "not null" : "null");
1006  else if (Ty->isObjCObjectPointerType())
1007    Out << (tookTrue ? "not nil" : "nil");
1008  else if (Ty->isBooleanType())
1009    Out << (tookTrue ? "true" : "false");
1010  else if (Ty->isIntegerType())
1011    Out << (tookTrue ? "non-zero" : "zero");
1012  else
1013    return 0;
1014
1015  const LocationContext *LCtx = N->getLocationContext();
1016  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
1017  PathDiagnosticEventPiece *event =
1018    new PathDiagnosticEventPiece(Loc, Out.str());
1019
1020  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
1021    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1022      const ProgramState *state = N->getState().getPtr();
1023      if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1024        if (report.isInteresting(R))
1025          event->setPrunable(false);
1026      }
1027    }
1028  }
1029
1030  return event;
1031}
1032
1033PathDiagnosticPiece *
1034ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
1035                                  const DeclRefExpr *DR,
1036                                  const bool tookTrue,
1037                                  BugReporterContext &BRC,
1038                                  BugReport &report,
1039                                  const ExplodedNode *N) {
1040
1041  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
1042  if (!VD)
1043    return 0;
1044
1045  SmallString<256> Buf;
1046  llvm::raw_svector_ostream Out(Buf);
1047
1048  Out << "Assuming '";
1049  VD->getDeclName().printName(Out);
1050  Out << "' is ";
1051
1052  QualType VDTy = VD->getType();
1053
1054  if (VDTy->isPointerType())
1055    Out << (tookTrue ? "non-null" : "null");
1056  else if (VDTy->isObjCObjectPointerType())
1057    Out << (tookTrue ? "non-nil" : "nil");
1058  else if (VDTy->isScalarType())
1059    Out << (tookTrue ? "not equal to 0" : "0");
1060  else
1061    return 0;
1062
1063  const LocationContext *LCtx = N->getLocationContext();
1064  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1065  PathDiagnosticEventPiece *event =
1066    new PathDiagnosticEventPiece(Loc, Out.str());
1067
1068  const ProgramState *state = N->getState().getPtr();
1069  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1070    if (report.isInteresting(R))
1071      event->setPrunable(false);
1072    else {
1073      SVal V = state->getSVal(R);
1074      if (report.isInteresting(V))
1075        event->setPrunable(false);
1076    }
1077  }
1078  return event;
1079}
1080
1081PathDiagnosticPiece *
1082UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
1083                                  const ExplodedNode *PrevN,
1084                                  BugReporterContext &BRC,
1085                                  BugReport &BR) {
1086
1087  ProgramStateRef State = N->getState();
1088  ProgramPoint ProgLoc = N->getLocation();
1089
1090  // We are only interested in visiting CallEnter nodes.
1091  CallEnter *CEnter = dyn_cast<CallEnter>(&ProgLoc);
1092  if (!CEnter)
1093    return 0;
1094
1095  // Check if one of the arguments is the region the visitor is tracking.
1096  CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
1097  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
1098  unsigned Idx = 0;
1099  for (CallEvent::param_iterator I = Call->param_begin(),
1100                                 E = Call->param_end(); I != E; ++I, ++Idx) {
1101    const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
1102
1103    // Are we tracking the argument or its subregion?
1104    if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
1105      continue;
1106
1107    // Check the function parameter type.
1108    const ParmVarDecl *ParamDecl = *I;
1109    assert(ParamDecl && "Formal parameter has no decl?");
1110    QualType T = ParamDecl->getType();
1111
1112    if (!(T->isAnyPointerType() || T->isReferenceType())) {
1113      // Function can only change the value passed in by address.
1114      continue;
1115    }
1116
1117    // If it is a const pointer value, the function does not intend to
1118    // change the value.
1119    if (T->getPointeeType().isConstQualified())
1120      continue;
1121
1122    // Mark the call site (LocationContext) as interesting if the value of the
1123    // argument is undefined or '0'/'NULL'.
1124    SVal BoundVal = State->getSVal(R);
1125    if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
1126      BR.markInteresting(CEnter->getCalleeContext());
1127      return 0;
1128    }
1129  }
1130  return 0;
1131}
1132