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