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 
28 using namespace clang;
29 using namespace ento;
30 
31 //===----------------------------------------------------------------------===//
32 // Utility functions.
33 //===----------------------------------------------------------------------===//
34 
35 bool 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 
42 const 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 
81 const 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 
88 const 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 
99 PathDiagnosticPiece*
100 BugReporterVisitor::getEndPath(BugReporterContext &BRC,
101                                const ExplodedNode *EndPathNode,
102                                BugReport &BR) {
103   return 0;
104 }
105 
106 PathDiagnosticPiece*
107 BugReporterVisitor::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 
128 namespace {
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.
136 class ReturnVisitor : public BugReporterVisitorImpl<ReturnVisitor> {
137   const StackFrameContext *StackFrame;
138   bool Satisfied;
139 public:
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 
269 void 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 
276 PathDiagnosticPiece *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 
463 void 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 
470 PathDiagnosticPiece *
471 TrackConstraintBRVisitor::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 
515 void 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 
607 BugReporterVisitor *
608 FindLastStoreBRVisitor::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 
621 PathDiagnosticPiece *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.
655 void 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 //===----------------------------------------------------------------------===//
692 PathDiagnosticPiece *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 
703 PathDiagnosticPiece *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 
749 PathDiagnosticPiece *
750 ConditionBRVisitor::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 
775 PathDiagnosticPiece *
776 ConditionBRVisitor::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 
808 bool 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 
862 PathDiagnosticPiece *
863 ConditionBRVisitor::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 
947 PathDiagnosticPiece *
948 ConditionBRVisitor::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 
992 PathDiagnosticPiece *
993 ConditionBRVisitor::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 
1040 PathDiagnosticPiece *
1041 UndefOrNullArgVisitor::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