clang  3.7.0
BugReporterVisitors.cpp
Go to the documentation of this file.
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 //===----------------------------------------------------------------------===//
15 #include "clang/AST/Expr.h"
16 #include "clang/AST/ExprObjC.h"
23 #include "llvm/ADT/SmallString.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/Support/raw_ostream.h"
26 
27 using namespace clang;
28 using namespace ento;
29 
30 using llvm::FoldingSetNodeID;
31 
32 //===----------------------------------------------------------------------===//
33 // Utility functions.
34 //===----------------------------------------------------------------------===//
35 
37  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
38  return DRE->getDecl()->getType()->isReferenceType();
39  }
40  return false;
41 }
42 
44  // Pattern match for a few useful cases:
45  // a[0], p->f, *p
46  const Expr *E = dyn_cast<Expr>(S);
47  if (!E)
48  return nullptr;
49  E = E->IgnoreParenCasts();
50 
51  while (true) {
52  if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) {
53  assert(B->isAssignmentOp());
54  E = B->getLHS()->IgnoreParenCasts();
55  continue;
56  }
57  else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
58  if (U->getOpcode() == UO_Deref)
59  return U->getSubExpr()->IgnoreParenCasts();
60  }
61  else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
62  if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) {
63  return ME->getBase()->IgnoreParenCasts();
64  } else {
65  // If we have a member expr with a dot, the base must have been
66  // dereferenced.
67  return getDerefExpr(ME->getBase());
68  }
69  }
70  else if (const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
71  return IvarRef->getBase()->IgnoreParenCasts();
72  }
73  else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(E)) {
74  return AE->getBase();
75  }
76  else if (isDeclRefExprToReference(E)) {
77  return E;
78  }
79  break;
80  }
81 
82  return nullptr;
83 }
84 
86  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
87  if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
88  return BE->getRHS();
89  return nullptr;
90 }
91 
93  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
94  if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
95  return RS->getRetValue();
96  return nullptr;
97 }
98 
99 //===----------------------------------------------------------------------===//
100 // Definitions for bug reporter visitors.
101 //===----------------------------------------------------------------------===//
102 
103 std::unique_ptr<PathDiagnosticPiece>
105  const ExplodedNode *EndPathNode, BugReport &BR) {
106  return nullptr;
107 }
108 
109 std::unique_ptr<PathDiagnosticPiece> BugReporterVisitor::getDefaultEndPath(
110  BugReporterContext &BRC, const ExplodedNode *EndPathNode, BugReport &BR) {
113 
114  const auto &Ranges = 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  auto P = llvm::make_unique<PathDiagnosticEventPiece>(
119  L, BR.getDescription(), Ranges.begin() == Ranges.end());
120  for (const SourceRange &Range : Ranges)
121  P->addRange(Range);
122 
123  return std::move(P);
124 }
125 
126 
127 namespace {
128 /// Emits an extra note at the return statement of an interesting stack frame.
129 ///
130 /// The returned value is marked as an interesting value, and if it's null,
131 /// adds a visitor to track where it became null.
132 ///
133 /// This visitor is intended to be used when another visitor discovers that an
134 /// interesting value comes from an inlined function call.
135 class ReturnVisitor : public BugReporterVisitorImpl<ReturnVisitor> {
136  const StackFrameContext *StackFrame;
137  enum {
138  Initial,
139  MaybeUnsuppress,
140  Satisfied
141  } Mode;
142 
143  bool EnableNullFPSuppression;
144 
145 public:
146  ReturnVisitor(const StackFrameContext *Frame, bool Suppressed)
147  : StackFrame(Frame), Mode(Initial), EnableNullFPSuppression(Suppressed) {}
148 
149  static void *getTag() {
150  static int Tag = 0;
151  return static_cast<void *>(&Tag);
152  }
153 
154  void Profile(llvm::FoldingSetNodeID &ID) const override {
155  ID.AddPointer(ReturnVisitor::getTag());
156  ID.AddPointer(StackFrame);
157  ID.AddBoolean(EnableNullFPSuppression);
158  }
159 
160  /// Adds a ReturnVisitor if the given statement represents a call that was
161  /// inlined.
162  ///
163  /// This will search back through the ExplodedGraph, starting from the given
164  /// node, looking for when the given statement was processed. If it turns out
165  /// the statement is a call that was inlined, we add the visitor to the
166  /// bug report, so it can print a note later.
167  static void addVisitorIfNecessary(const ExplodedNode *Node, const Stmt *S,
168  BugReport &BR,
169  bool InEnableNullFPSuppression) {
170  if (!CallEvent::isCallStmt(S))
171  return;
172 
173  // First, find when we processed the statement.
174  do {
176  if (CEE->getCalleeContext()->getCallSite() == S)
177  break;
178  if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>())
179  if (SP->getStmt() == S)
180  break;
181 
182  Node = Node->getFirstPred();
183  } while (Node);
184 
185  // Next, step over any post-statement checks.
186  while (Node && Node->getLocation().getAs<PostStmt>())
187  Node = Node->getFirstPred();
188  if (!Node)
189  return;
190 
191  // Finally, see if we inlined the call.
193  if (!CEE)
194  return;
195 
196  const StackFrameContext *CalleeContext = CEE->getCalleeContext();
197  if (CalleeContext->getCallSite() != S)
198  return;
199 
200  // Check the return value.
201  ProgramStateRef State = Node->getState();
202  SVal RetVal = State->getSVal(S, Node->getLocationContext());
203 
204  // Handle cases where a reference is returned and then immediately used.
205  if (cast<Expr>(S)->isGLValue())
206  if (Optional<Loc> LValue = RetVal.getAs<Loc>())
207  RetVal = State->getSVal(*LValue);
208 
209  // See if the return value is NULL. If so, suppress the report.
210  SubEngine *Eng = State->getStateManager().getOwningEngine();
211  assert(Eng && "Cannot file a bug report without an owning engine");
213 
214  bool EnableNullFPSuppression = false;
215  if (InEnableNullFPSuppression && Options.shouldSuppressNullReturnPaths())
216  if (Optional<Loc> RetLoc = RetVal.getAs<Loc>())
217  EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
218 
219  BR.markInteresting(CalleeContext);
220  BR.addVisitor(llvm::make_unique<ReturnVisitor>(CalleeContext,
221  EnableNullFPSuppression));
222  }
223 
224  /// Returns true if any counter-suppression heuristics are enabled for
225  /// ReturnVisitor.
226  static bool hasCounterSuppression(AnalyzerOptions &Options) {
228  }
229 
230  PathDiagnosticPiece *visitNodeInitial(const ExplodedNode *N,
231  const ExplodedNode *PrevN,
232  BugReporterContext &BRC,
233  BugReport &BR) {
234  // Only print a message at the interesting return statement.
235  if (N->getLocationContext() != StackFrame)
236  return nullptr;
237 
239  if (!SP)
240  return nullptr;
241 
242  const ReturnStmt *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
243  if (!Ret)
244  return nullptr;
245 
246  // Okay, we're at the right return statement, but do we have the return
247  // value available?
248  ProgramStateRef State = N->getState();
249  SVal V = State->getSVal(Ret, StackFrame);
250  if (V.isUnknownOrUndef())
251  return nullptr;
252 
253  // Don't print any more notes after this one.
254  Mode = Satisfied;
255 
256  const Expr *RetE = Ret->getRetValue();
257  assert(RetE && "Tracking a return value for a void function");
258 
259  // Handle cases where a reference is returned and then immediately used.
260  Optional<Loc> LValue;
261  if (RetE->isGLValue()) {
262  if ((LValue = V.getAs<Loc>())) {
263  SVal RValue = State->getRawSVal(*LValue, RetE->getType());
264  if (RValue.getAs<DefinedSVal>())
265  V = RValue;
266  }
267  }
268 
269  // Ignore aggregate rvalues.
270  if (V.getAs<nonloc::LazyCompoundVal>() ||
272  return nullptr;
273 
274  RetE = RetE->IgnoreParenCasts();
275 
276  // If we can't prove the return value is 0, just mark it interesting, and
277  // make sure to track it into any further inner functions.
278  if (!State->isNull(V).isConstrainedTrue()) {
279  BR.markInteresting(V);
280  ReturnVisitor::addVisitorIfNecessary(N, RetE, BR,
281  EnableNullFPSuppression);
282  return nullptr;
283  }
284 
285  // If we're returning 0, we should track where that 0 came from.
286  bugreporter::trackNullOrUndefValue(N, RetE, BR, /*IsArg*/ false,
287  EnableNullFPSuppression);
288 
289  // Build an appropriate message based on the return value.
290  SmallString<64> Msg;
291  llvm::raw_svector_ostream Out(Msg);
292 
293  if (V.getAs<Loc>()) {
294  // If we have counter-suppression enabled, make sure we keep visiting
295  // future nodes. We want to emit a path note as well, in case
296  // the report is resurrected as valid later on.
297  ExprEngine &Eng = BRC.getBugReporter().getEngine();
298  AnalyzerOptions &Options = Eng.getAnalysisManager().options;
299  if (EnableNullFPSuppression && hasCounterSuppression(Options))
300  Mode = MaybeUnsuppress;
301 
302  if (RetE->getType()->isObjCObjectPointerType())
303  Out << "Returning nil";
304  else
305  Out << "Returning null pointer";
306  } else {
307  Out << "Returning zero";
308  }
309 
310  if (LValue) {
311  if (const MemRegion *MR = LValue->getAsRegion()) {
312  if (MR->canPrintPretty()) {
313  Out << " (reference to ";
314  MR->printPretty(Out);
315  Out << ")";
316  }
317  }
318  } else {
319  // FIXME: We should have a more generalized location printing mechanism.
320  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
321  if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
322  Out << " (loaded from '" << *DD << "')";
323  }
324 
325  PathDiagnosticLocation L(Ret, BRC.getSourceManager(), StackFrame);
326  return new PathDiagnosticEventPiece(L, Out.str());
327  }
328 
329  PathDiagnosticPiece *visitNodeMaybeUnsuppress(const ExplodedNode *N,
330  const ExplodedNode *PrevN,
331  BugReporterContext &BRC,
332  BugReport &BR) {
333 #ifndef NDEBUG
334  ExprEngine &Eng = BRC.getBugReporter().getEngine();
335  AnalyzerOptions &Options = Eng.getAnalysisManager().options;
336  assert(hasCounterSuppression(Options));
337 #endif
338 
339  // Are we at the entry node for this call?
341  if (!CE)
342  return nullptr;
343 
344  if (CE->getCalleeContext() != StackFrame)
345  return nullptr;
346 
347  Mode = Satisfied;
348 
349  // Don't automatically suppress a report if one of the arguments is
350  // known to be a null pointer. Instead, start tracking /that/ null
351  // value back to its origin.
352  ProgramStateManager &StateMgr = BRC.getStateManager();
353  CallEventManager &CallMgr = StateMgr.getCallEventManager();
354 
355  ProgramStateRef State = N->getState();
356  CallEventRef<> Call = CallMgr.getCaller(StackFrame, State);
357  for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
358  Optional<Loc> ArgV = Call->getArgSVal(I).getAs<Loc>();
359  if (!ArgV)
360  continue;
361 
362  const Expr *ArgE = Call->getArgExpr(I);
363  if (!ArgE)
364  continue;
365 
366  // Is it possible for this argument to be non-null?
367  if (!State->isNull(*ArgV).isConstrainedTrue())
368  continue;
369 
370  if (bugreporter::trackNullOrUndefValue(N, ArgE, BR, /*IsArg=*/true,
371  EnableNullFPSuppression))
372  BR.removeInvalidation(ReturnVisitor::getTag(), StackFrame);
373 
374  // If we /can't/ track the null pointer, we should err on the side of
375  // false negatives, and continue towards marking this report invalid.
376  // (We will still look at the other arguments, though.)
377  }
378 
379  return nullptr;
380  }
381 
382  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
383  const ExplodedNode *PrevN,
384  BugReporterContext &BRC,
385  BugReport &BR) override {
386  switch (Mode) {
387  case Initial:
388  return visitNodeInitial(N, PrevN, BRC, BR);
389  case MaybeUnsuppress:
390  return visitNodeMaybeUnsuppress(N, PrevN, BRC, BR);
391  case Satisfied:
392  return nullptr;
393  }
394 
395  llvm_unreachable("Invalid visit mode!");
396  }
397 
398  std::unique_ptr<PathDiagnosticPiece> getEndPath(BugReporterContext &BRC,
399  const ExplodedNode *N,
400  BugReport &BR) override {
401  if (EnableNullFPSuppression)
402  BR.markInvalid(ReturnVisitor::getTag(), StackFrame);
403  return nullptr;
404  }
405 };
406 } // end anonymous namespace
407 
408 
409 void FindLastStoreBRVisitor ::Profile(llvm::FoldingSetNodeID &ID) const {
410  static int tag = 0;
411  ID.AddPointer(&tag);
412  ID.AddPointer(R);
413  ID.Add(V);
414  ID.AddBoolean(EnableNullFPSuppression);
415 }
416 
417 /// Returns true if \p N represents the DeclStmt declaring and initializing
418 /// \p VR.
419 static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR) {
421  if (!P)
422  return false;
423 
424  const DeclStmt *DS = P->getStmtAs<DeclStmt>();
425  if (!DS)
426  return false;
427 
428  if (DS->getSingleDecl() != VR->getDecl())
429  return false;
430 
431  const MemSpaceRegion *VarSpace = VR->getMemorySpace();
432  const StackSpaceRegion *FrameSpace = dyn_cast<StackSpaceRegion>(VarSpace);
433  if (!FrameSpace) {
434  // If we ever directly evaluate global DeclStmts, this assertion will be
435  // invalid, but this still seems preferable to silently accepting an
436  // initialization that may be for a path-sensitive variable.
437  assert(VR->getDecl()->isStaticLocal() && "non-static stackless VarRegion");
438  return true;
439  }
440 
441  assert(VR->getDecl()->hasLocalStorage());
442  const LocationContext *LCtx = N->getLocationContext();
443  return FrameSpace->getStackFrame() == LCtx->getCurrentStackFrame();
444 }
445 
447  const ExplodedNode *Pred,
448  BugReporterContext &BRC,
449  BugReport &BR) {
450 
451  if (Satisfied)
452  return nullptr;
453 
454  const ExplodedNode *StoreSite = nullptr;
455  const Expr *InitE = nullptr;
456  bool IsParam = false;
457 
458  // First see if we reached the declaration of the region.
459  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
460  if (isInitializationOfVar(Pred, VR)) {
461  StoreSite = Pred;
462  InitE = VR->getDecl()->getInit();
463  }
464  }
465 
466  // If this is a post initializer expression, initializing the region, we
467  // should track the initializer expression.
469  const MemRegion *FieldReg = (const MemRegion *)PIP->getLocationValue();
470  if (FieldReg && FieldReg == R) {
471  StoreSite = Pred;
472  InitE = PIP->getInitializer()->getInit();
473  }
474  }
475 
476  // Otherwise, see if this is the store site:
477  // (1) Succ has this binding and Pred does not, i.e. this is
478  // where the binding first occurred.
479  // (2) Succ has this binding and is a PostStore node for this region, i.e.
480  // the same binding was re-assigned here.
481  if (!StoreSite) {
482  if (Succ->getState()->getSVal(R) != V)
483  return nullptr;
484 
485  if (Pred->getState()->getSVal(R) == V) {
487  if (!PS || PS->getLocationValue() != R)
488  return nullptr;
489  }
490 
491  StoreSite = Succ;
492 
493  // If this is an assignment expression, we can track the value
494  // being assigned.
496  if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>())
497  if (BO->isAssignmentOp())
498  InitE = BO->getRHS();
499 
500  // If this is a call entry, the variable should be a parameter.
501  // FIXME: Handle CXXThisRegion as well. (This is not a priority because
502  // 'this' should never be NULL, but this visitor isn't just for NULL and
503  // UndefinedVal.)
504  if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
505  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
506  const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
507 
508  ProgramStateManager &StateMgr = BRC.getStateManager();
509  CallEventManager &CallMgr = StateMgr.getCallEventManager();
510 
511  CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
512  Succ->getState());
513  InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
514  IsParam = true;
515  }
516  }
517 
518  // If this is a CXXTempObjectRegion, the Expr responsible for its creation
519  // is wrapped inside of it.
520  if (const CXXTempObjectRegion *TmpR = dyn_cast<CXXTempObjectRegion>(R))
521  InitE = TmpR->getExpr();
522  }
523 
524  if (!StoreSite)
525  return nullptr;
526  Satisfied = true;
527 
528  // If we have an expression that provided the value, try to track where it
529  // came from.
530  if (InitE) {
531  if (V.isUndef() ||
533  if (!IsParam)
534  InitE = InitE->IgnoreParenCasts();
535  bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam,
536  EnableNullFPSuppression);
537  } else {
538  ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(),
539  BR, EnableNullFPSuppression);
540  }
541  }
542 
543  // Okay, we've found the binding. Emit an appropriate message.
544  SmallString<256> sbuf;
545  llvm::raw_svector_ostream os(sbuf);
546 
547  if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
548  const Stmt *S = PS->getStmt();
549  const char *action = nullptr;
550  const DeclStmt *DS = dyn_cast<DeclStmt>(S);
551  const VarRegion *VR = dyn_cast<VarRegion>(R);
552 
553  if (DS) {
554  action = R->canPrintPretty() ? "initialized to " :
555  "Initializing to ";
556  } else if (isa<BlockExpr>(S)) {
557  action = R->canPrintPretty() ? "captured by block as " :
558  "Captured by block as ";
559  if (VR) {
560  // See if we can get the BlockVarRegion.
561  ProgramStateRef State = StoreSite->getState();
562  SVal V = State->getSVal(S, PS->getLocationContext());
563  if (const BlockDataRegion *BDR =
564  dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
565  if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
566  if (Optional<KnownSVal> KV =
567  State->getSVal(OriginalR).getAs<KnownSVal>())
568  BR.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
569  *KV, OriginalR, EnableNullFPSuppression));
570  }
571  }
572  }
573  }
574 
575  if (action) {
576  if (R->canPrintPretty()) {
577  R->printPretty(os);
578  os << " ";
579  }
580 
581  if (V.getAs<loc::ConcreteInt>()) {
582  bool b = false;
583  if (R->isBoundable()) {
584  if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
585  if (TR->getValueType()->isObjCObjectPointerType()) {
586  os << action << "nil";
587  b = true;
588  }
589  }
590  }
591 
592  if (!b)
593  os << action << "a null pointer value";
594  } else if (Optional<nonloc::ConcreteInt> CVal =
595  V.getAs<nonloc::ConcreteInt>()) {
596  os << action << CVal->getValue();
597  }
598  else if (DS) {
599  if (V.isUndef()) {
600  if (isa<VarRegion>(R)) {
601  const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
602  if (VD->getInit()) {
603  os << (R->canPrintPretty() ? "initialized" : "Initializing")
604  << " to a garbage value";
605  } else {
606  os << (R->canPrintPretty() ? "declared" : "Declaring")
607  << " without an initial value";
608  }
609  }
610  }
611  else {
612  os << (R->canPrintPretty() ? "initialized" : "Initialized")
613  << " here";
614  }
615  }
616  }
617  } else if (StoreSite->getLocation().getAs<CallEnter>()) {
618  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
619  const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
620 
621  os << "Passing ";
622 
623  if (V.getAs<loc::ConcreteInt>()) {
624  if (Param->getType()->isObjCObjectPointerType())
625  os << "nil object reference";
626  else
627  os << "null pointer value";
628  } else if (V.isUndef()) {
629  os << "uninitialized value";
630  } else if (Optional<nonloc::ConcreteInt> CI =
631  V.getAs<nonloc::ConcreteInt>()) {
632  os << "the value " << CI->getValue();
633  } else {
634  os << "value";
635  }
636 
637  // Printed parameter indexes are 1-based, not 0-based.
638  unsigned Idx = Param->getFunctionScopeIndex() + 1;
639  os << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter";
640  if (R->canPrintPretty()) {
641  os << " ";
642  R->printPretty(os);
643  }
644  }
645  }
646 
647  if (os.str().empty()) {
648  if (V.getAs<loc::ConcreteInt>()) {
649  bool b = false;
650  if (R->isBoundable()) {
651  if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
652  if (TR->getValueType()->isObjCObjectPointerType()) {
653  os << "nil object reference stored";
654  b = true;
655  }
656  }
657  }
658  if (!b) {
659  if (R->canPrintPretty())
660  os << "Null pointer value stored";
661  else
662  os << "Storing null pointer value";
663  }
664 
665  } else if (V.isUndef()) {
666  if (R->canPrintPretty())
667  os << "Uninitialized value stored";
668  else
669  os << "Storing uninitialized value";
670 
671  } else if (Optional<nonloc::ConcreteInt> CV =
672  V.getAs<nonloc::ConcreteInt>()) {
673  if (R->canPrintPretty())
674  os << "The value " << CV->getValue() << " is assigned";
675  else
676  os << "Assigning " << CV->getValue();
677 
678  } else {
679  if (R->canPrintPretty())
680  os << "Value assigned";
681  else
682  os << "Assigning value";
683  }
684 
685  if (R->canPrintPretty()) {
686  os << " to ";
687  R->printPretty(os);
688  }
689  }
690 
691  // Construct a new PathDiagnosticPiece.
692  ProgramPoint P = StoreSite->getLocation();
694  if (P.getAs<CallEnter>() && InitE)
695  L = PathDiagnosticLocation(InitE, BRC.getSourceManager(),
696  P.getLocationContext());
697 
698  if (!L.isValid() || !L.asLocation().isValid())
700 
701  if (!L.isValid() || !L.asLocation().isValid())
702  return nullptr;
703 
704  return new PathDiagnosticEventPiece(L, os.str());
705 }
706 
707 void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
708  static int tag = 0;
709  ID.AddPointer(&tag);
710  ID.AddBoolean(Assumption);
711  ID.Add(Constraint);
712 }
713 
714 /// Return the tag associated with this visitor. This tag will be used
715 /// to make all PathDiagnosticPieces created by this visitor.
717  return "TrackConstraintBRVisitor";
718 }
719 
720 bool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
721  if (IsZeroCheck)
722  return N->getState()->isNull(Constraint).isUnderconstrained();
723  return (bool)N->getState()->assume(Constraint, !Assumption);
724 }
725 
728  const ExplodedNode *PrevN,
729  BugReporterContext &BRC,
730  BugReport &BR) {
731  if (IsSatisfied)
732  return nullptr;
733 
734  // Start tracking after we see the first state in which the value is
735  // constrained.
736  if (!IsTrackingTurnedOn)
737  if (!isUnderconstrained(N))
738  IsTrackingTurnedOn = true;
739  if (!IsTrackingTurnedOn)
740  return nullptr;
741 
742  // Check if in the previous state it was feasible for this constraint
743  // to *not* be true.
744  if (isUnderconstrained(PrevN)) {
745 
746  IsSatisfied = true;
747 
748  // As a sanity check, make sure that the negation of the constraint
749  // was infeasible in the current state. If it is feasible, we somehow
750  // missed the transition point.
751  assert(!isUnderconstrained(N));
752 
753  // We found the transition point for the constraint. We now need to
754  // pretty-print the constraint. (work-in-progress)
755  SmallString<64> sbuf;
756  llvm::raw_svector_ostream os(sbuf);
757 
758  if (Constraint.getAs<Loc>()) {
759  os << "Assuming pointer value is ";
760  os << (Assumption ? "non-null" : "null");
761  }
762 
763  if (os.str().empty())
764  return nullptr;
765 
766  // Construct a new PathDiagnosticPiece.
767  ProgramPoint P = N->getLocation();
770  if (!L.isValid())
771  return nullptr;
772 
774  X->setTag(getTag());
775  return X;
776  }
777 
778  return nullptr;
779 }
780 
783  : V(Value), IsSatisfied(false), IsTrackingTurnedOn(false) {
784 
785  // Check if the visitor is disabled.
786  SubEngine *Eng = N->getState()->getStateManager().getOwningEngine();
787  assert(Eng && "Cannot file a bug report without an owning engine");
788  AnalyzerOptions &Options = Eng->getAnalysisManager().options;
790  IsSatisfied = true;
791 
792  assert(N->getState()->isNull(V).isConstrainedTrue() &&
793  "The visitor only tracks the cases where V is constrained to 0");
794 }
795 
796 void SuppressInlineDefensiveChecksVisitor::Profile(FoldingSetNodeID &ID) const {
797  static int id = 0;
798  ID.AddPointer(&id);
799  ID.Add(V);
800 }
801 
803  return "IDCVisitor";
804 }
805 
808  const ExplodedNode *Pred,
809  BugReporterContext &BRC,
810  BugReport &BR) {
811  if (IsSatisfied)
812  return nullptr;
813 
814  // Start tracking after we see the first state in which the value is null.
815  if (!IsTrackingTurnedOn)
816  if (Succ->getState()->isNull(V).isConstrainedTrue())
817  IsTrackingTurnedOn = true;
818  if (!IsTrackingTurnedOn)
819  return nullptr;
820 
821  // Check if in the previous state it was feasible for this value
822  // to *not* be null.
823  if (!Pred->getState()->isNull(V).isConstrainedTrue()) {
824  IsSatisfied = true;
825 
826  assert(Succ->getState()->isNull(V).isConstrainedTrue());
827 
828  // Check if this is inlined defensive checks.
829  const LocationContext *CurLC =Succ->getLocationContext();
830  const LocationContext *ReportLC = BR.getErrorNode()->getLocationContext();
831  if (CurLC != ReportLC && !CurLC->isParentOf(ReportLC))
832  BR.markInvalid("Suppress IDC", CurLC);
833  }
834  return nullptr;
835 }
836 
838  const ExplodedNode *N) {
839  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
840  if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
841  if (!VD->getType()->isReferenceType())
842  return nullptr;
843  ProgramStateManager &StateMgr = N->getState()->getStateManager();
844  MemRegionManager &MRMgr = StateMgr.getRegionManager();
845  return MRMgr.getVarRegion(VD, N->getLocationContext());
846  }
847  }
848 
849  // FIXME: This does not handle other kinds of null references,
850  // for example, references from FieldRegions:
851  // struct Wrapper { int &ref; };
852  // Wrapper w = { *(int *)0 };
853  // w.ref = 1;
854 
855  return nullptr;
856 }
857 
858 static const Expr *peelOffOuterExpr(const Expr *Ex,
859  const ExplodedNode *N) {
860  Ex = Ex->IgnoreParenCasts();
861  if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Ex))
862  return peelOffOuterExpr(EWC->getSubExpr(), N);
863  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
864  return peelOffOuterExpr(OVE->getSourceExpr(), N);
865 
866  // Peel off the ternary operator.
867  if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
868  // Find a node where the branching occurred and find out which branch
869  // we took (true/false) by looking at the ExplodedGraph.
870  const ExplodedNode *NI = N;
871  do {
872  ProgramPoint ProgPoint = NI->getLocation();
873  if (Optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) {
874  const CFGBlock *srcBlk = BE->getSrc();
875  if (const Stmt *term = srcBlk->getTerminator()) {
876  if (term == CO) {
877  bool TookTrueBranch = (*(srcBlk->succ_begin()) == BE->getDst());
878  if (TookTrueBranch)
879  return peelOffOuterExpr(CO->getTrueExpr(), N);
880  else
881  return peelOffOuterExpr(CO->getFalseExpr(), N);
882  }
883  }
884  }
885  NI = NI->getFirstPred();
886  } while (NI);
887  }
888  return Ex;
889 }
890 
892  const Stmt *S,
893  BugReport &report, bool IsArg,
894  bool EnableNullFPSuppression) {
895  if (!S || !N)
896  return false;
897 
898  if (const Expr *Ex = dyn_cast<Expr>(S)) {
899  Ex = Ex->IgnoreParenCasts();
900  const Expr *PeeledEx = peelOffOuterExpr(Ex, N);
901  if (Ex != PeeledEx)
902  S = PeeledEx;
903  }
904 
905  const Expr *Inner = nullptr;
906  if (const Expr *Ex = dyn_cast<Expr>(S)) {
907  Ex = Ex->IgnoreParenCasts();
909  Inner = Ex;
910  }
911 
912  if (IsArg && !Inner) {
913  assert(N->getLocation().getAs<CallEnter>() && "Tracking arg but not at call");
914  } else {
915  // Walk through nodes until we get one that matches the statement exactly.
916  // Alternately, if we hit a known lvalue for the statement, we know we've
917  // gone too far (though we can likely track the lvalue better anyway).
918  do {
919  const ProgramPoint &pp = N->getLocation();
920  if (Optional<StmtPoint> ps = pp.getAs<StmtPoint>()) {
921  if (ps->getStmt() == S || ps->getStmt() == Inner)
922  break;
923  } else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
924  if (CEE->getCalleeContext()->getCallSite() == S ||
925  CEE->getCalleeContext()->getCallSite() == Inner)
926  break;
927  }
928  N = N->getFirstPred();
929  } while (N);
930 
931  if (!N)
932  return false;
933  }
934 
935  ProgramStateRef state = N->getState();
936 
937  // The message send could be nil due to the receiver being nil.
938  // At this point in the path, the receiver should be live since we are at the
939  // message send expr. If it is nil, start tracking it.
940  if (const Expr *Receiver = NilReceiverBRVisitor::getNilReceiver(S, N))
941  trackNullOrUndefValue(N, Receiver, report, false, EnableNullFPSuppression);
942 
943 
944  // See if the expression we're interested refers to a variable.
945  // If so, we can track both its contents and constraints on its value.
946  if (Inner && ExplodedGraph::isInterestingLValueExpr(Inner)) {
947  const MemRegion *R = nullptr;
948 
949  // Find the ExplodedNode where the lvalue (the value of 'Ex')
950  // was computed. We need this for getting the location value.
951  const ExplodedNode *LVNode = N;
952  while (LVNode) {
953  if (Optional<PostStmt> P = LVNode->getLocation().getAs<PostStmt>()) {
954  if (P->getStmt() == Inner)
955  break;
956  }
957  LVNode = LVNode->getFirstPred();
958  }
959  assert(LVNode && "Unable to find the lvalue node.");
960  ProgramStateRef LVState = LVNode->getState();
961  SVal LVal = LVState->getSVal(Inner, LVNode->getLocationContext());
962 
963  if (LVState->isNull(LVal).isConstrainedTrue()) {
964  // In case of C++ references, we want to differentiate between a null
965  // reference and reference to null pointer.
966  // If the LVal is null, check if we are dealing with null reference.
967  // For those, we want to track the location of the reference.
968  if (const MemRegion *RR = getLocationRegionIfReference(Inner, N))
969  R = RR;
970  } else {
971  R = LVState->getSVal(Inner, LVNode->getLocationContext()).getAsRegion();
972 
973  // If this is a C++ reference to a null pointer, we are tracking the
974  // pointer. In additon, we should find the store at which the reference
975  // got initialized.
976  if (const MemRegion *RR = getLocationRegionIfReference(Inner, N)) {
977  if (Optional<KnownSVal> KV = LVal.getAs<KnownSVal>())
978  report.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
979  *KV, RR, EnableNullFPSuppression));
980  }
981  }
982 
983  if (R) {
984  // Mark both the variable region and its contents as interesting.
985  SVal V = LVState->getRawSVal(loc::MemRegionVal(R));
986 
987  report.markInteresting(R);
988  report.markInteresting(V);
989  report.addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(R));
990 
991  // If the contents are symbolic, find out when they became null.
992  if (V.getAsLocSymbol(/*IncludeBaseRegions*/ true))
993  report.addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
994  V.castAs<DefinedSVal>(), false));
995 
996  // Add visitor, which will suppress inline defensive checks.
997  if (Optional<DefinedSVal> DV = V.getAs<DefinedSVal>()) {
998  if (!DV->isZeroConstant() && LVState->isNull(*DV).isConstrainedTrue() &&
999  EnableNullFPSuppression) {
1000  report.addVisitor(
1001  llvm::make_unique<SuppressInlineDefensiveChecksVisitor>(*DV,
1002  LVNode));
1003  }
1004  }
1005 
1006  if (Optional<KnownSVal> KV = V.getAs<KnownSVal>())
1007  report.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1008  *KV, R, EnableNullFPSuppression));
1009  return true;
1010  }
1011  }
1012 
1013  // If the expression is not an "lvalue expression", we can still
1014  // track the constraints on its contents.
1015  SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
1016 
1017  // If the value came from an inlined function call, we should at least make
1018  // sure that function isn't pruned in our output.
1019  if (const Expr *E = dyn_cast<Expr>(S))
1020  S = E->IgnoreParenCasts();
1021 
1022  ReturnVisitor::addVisitorIfNecessary(N, S, report, EnableNullFPSuppression);
1023 
1024  // Uncomment this to find cases where we aren't properly getting the
1025  // base value that was dereferenced.
1026  // assert(!V.isUnknownOrUndef());
1027  // Is it a symbolic value?
1029  // At this point we are dealing with the region's LValue.
1030  // However, if the rvalue is a symbolic region, we should track it as well.
1031  // Try to use the correct type when looking up the value.
1032  SVal RVal;
1033  if (const Expr *E = dyn_cast<Expr>(S))
1034  RVal = state->getRawSVal(L.getValue(), E->getType());
1035  else
1036  RVal = state->getSVal(L->getRegion());
1037 
1038  const MemRegion *RegionRVal = RVal.getAsRegion();
1039  report.addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(L->getRegion()));
1040 
1041  if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
1042  report.markInteresting(RegionRVal);
1043  report.addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
1044  loc::MemRegionVal(RegionRVal), false));
1045  }
1046  }
1047 
1048  return true;
1049 }
1050 
1052  const ExplodedNode *N) {
1053  const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S);
1054  if (!ME)
1055  return nullptr;
1056  if (const Expr *Receiver = ME->getInstanceReceiver()) {
1057  ProgramStateRef state = N->getState();
1058  SVal V = state->getSVal(Receiver, N->getLocationContext());
1059  if (state->isNull(V).isConstrainedTrue())
1060  return Receiver;
1061  }
1062  return nullptr;
1063 }
1064 
1066  const ExplodedNode *PrevN,
1067  BugReporterContext &BRC,
1068  BugReport &BR) {
1070  if (!P)
1071  return nullptr;
1072 
1073  const Stmt *S = P->getStmt();
1074  const Expr *Receiver = getNilReceiver(S, N);
1075  if (!Receiver)
1076  return nullptr;
1077 
1079  llvm::raw_svector_ostream OS(Buf);
1080 
1081  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
1082  OS << "'";
1083  ME->getSelector().print(OS);
1084  OS << "' not called";
1085  }
1086  else {
1087  OS << "No method is called";
1088  }
1089  OS << " because the receiver is nil";
1090 
1091  // The receiver was nil, and hence the method was skipped.
1092  // Register a BugReporterVisitor to issue a message telling us how
1093  // the receiver was null.
1094  bugreporter::trackNullOrUndefValue(N, Receiver, BR, /*IsArg*/ false,
1095  /*EnableNullFPSuppression*/ false);
1096  // Issue a message saying that the method was skipped.
1097  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
1098  N->getLocationContext());
1099  return new PathDiagnosticEventPiece(L, OS.str());
1100 }
1101 
1102 // Registers every VarDecl inside a Stmt with a last store visitor.
1104  const Stmt *S,
1105  bool EnableNullFPSuppression) {
1106  const ExplodedNode *N = BR.getErrorNode();
1107  std::deque<const Stmt *> WorkList;
1108  WorkList.push_back(S);
1109 
1110  while (!WorkList.empty()) {
1111  const Stmt *Head = WorkList.front();
1112  WorkList.pop_front();
1113 
1114  ProgramStateRef state = N->getState();
1115  ProgramStateManager &StateMgr = state->getStateManager();
1116 
1117  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
1118  if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1119  const VarRegion *R =
1120  StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
1121 
1122  // What did we load?
1123  SVal V = state->getSVal(S, N->getLocationContext());
1124 
1125  if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
1126  // Register a new visitor with the BugReport.
1127  BR.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
1128  V.castAs<KnownSVal>(), R, EnableNullFPSuppression));
1129  }
1130  }
1131  }
1132 
1133  for (const Stmt *SubStmt : Head->children())
1134  WorkList.push_back(SubStmt);
1135  }
1136 }
1137 
1138 //===----------------------------------------------------------------------===//
1139 // Visitor that tries to report interesting diagnostics from conditions.
1140 //===----------------------------------------------------------------------===//
1141 
1142 /// Return the tag associated with this visitor. This tag will be used
1143 /// to make all PathDiagnosticPieces created by this visitor.
1145  return "ConditionBRVisitor";
1146 }
1147 
1149  const ExplodedNode *Prev,
1150  BugReporterContext &BRC,
1151  BugReport &BR) {
1152  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
1153  if (piece) {
1154  piece->setTag(getTag());
1155  if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
1156  ev->setPrunable(true, /* override */ false);
1157  }
1158  return piece;
1159 }
1160 
1162  const ExplodedNode *Prev,
1163  BugReporterContext &BRC,
1164  BugReport &BR) {
1165 
1166  ProgramPoint progPoint = N->getLocation();
1167  ProgramStateRef CurrentState = N->getState();
1168  ProgramStateRef PrevState = Prev->getState();
1169 
1170  // Compare the GDMs of the state, because that is where constraints
1171  // are managed. Note that ensure that we only look at nodes that
1172  // were generated by the analyzer engine proper, not checkers.
1173  if (CurrentState->getGDM().getRoot() ==
1174  PrevState->getGDM().getRoot())
1175  return nullptr;
1176 
1177  // If an assumption was made on a branch, it should be caught
1178  // here by looking at the state transition.
1179  if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
1180  const CFGBlock *srcBlk = BE->getSrc();
1181  if (const Stmt *term = srcBlk->getTerminator())
1182  return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
1183  return nullptr;
1184  }
1185 
1186  if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
1187  // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
1188  // violation.
1189  const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
1190  cast<GRBugReporter>(BRC.getBugReporter()).
1191  getEngine().geteagerlyAssumeBinOpBifurcationTags();
1192 
1193  const ProgramPointTag *tag = PS->getTag();
1194  if (tag == tags.first)
1195  return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
1196  BRC, BR, N);
1197  if (tag == tags.second)
1198  return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
1199  BRC, BR, N);
1200 
1201  return nullptr;
1202  }
1203 
1204  return nullptr;
1205 }
1206 
1209  const ExplodedNode *N,
1210  const CFGBlock *srcBlk,
1211  const CFGBlock *dstBlk,
1212  BugReport &R,
1213  BugReporterContext &BRC) {
1214  const Expr *Cond = nullptr;
1215 
1216  switch (Term->getStmtClass()) {
1217  default:
1218  return nullptr;
1219  case Stmt::IfStmtClass:
1220  Cond = cast<IfStmt>(Term)->getCond();
1221  break;
1222  case Stmt::ConditionalOperatorClass:
1223  Cond = cast<ConditionalOperator>(Term)->getCond();
1224  break;
1225  }
1226 
1227  assert(Cond);
1228  assert(srcBlk->succ_size() == 2);
1229  const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
1230  return VisitTrueTest(Cond, tookTrue, BRC, R, N);
1231 }
1232 
1235  bool tookTrue,
1236  BugReporterContext &BRC,
1237  BugReport &R,
1238  const ExplodedNode *N) {
1239 
1240  const Expr *Ex = Cond;
1241 
1242  while (true) {
1243  Ex = Ex->IgnoreParenCasts();
1244  switch (Ex->getStmtClass()) {
1245  default:
1246  return nullptr;
1247  case Stmt::BinaryOperatorClass:
1248  return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
1249  R, N);
1250  case Stmt::DeclRefExprClass:
1251  return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
1252  R, N);
1253  case Stmt::UnaryOperatorClass: {
1254  const UnaryOperator *UO = cast<UnaryOperator>(Ex);
1255  if (UO->getOpcode() == UO_LNot) {
1256  tookTrue = !tookTrue;
1257  Ex = UO->getSubExpr();
1258  continue;
1259  }
1260  return nullptr;
1261  }
1262  }
1263  }
1264 }
1265 
1266 bool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
1267  BugReporterContext &BRC,
1268  BugReport &report,
1269  const ExplodedNode *N,
1270  Optional<bool> &prunable) {
1271  const Expr *OriginalExpr = Ex;
1272  Ex = Ex->IgnoreParenCasts();
1273 
1274  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
1275  const bool quotes = isa<VarDecl>(DR->getDecl());
1276  if (quotes) {
1277  Out << '\'';
1278  const LocationContext *LCtx = N->getLocationContext();
1279  const ProgramState *state = N->getState().get();
1280  if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
1281  LCtx).getAsRegion()) {
1282  if (report.isInteresting(R))
1283  prunable = false;
1284  else {
1285  const ProgramState *state = N->getState().get();
1286  SVal V = state->getSVal(R);
1287  if (report.isInteresting(V))
1288  prunable = false;
1289  }
1290  }
1291  }
1292  Out << DR->getDecl()->getDeclName().getAsString();
1293  if (quotes)
1294  Out << '\'';
1295  return quotes;
1296  }
1297 
1298  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
1299  QualType OriginalTy = OriginalExpr->getType();
1300  if (OriginalTy->isPointerType()) {
1301  if (IL->getValue() == 0) {
1302  Out << "null";
1303  return false;
1304  }
1305  }
1306  else if (OriginalTy->isObjCObjectPointerType()) {
1307  if (IL->getValue() == 0) {
1308  Out << "nil";
1309  return false;
1310  }
1311  }
1312 
1313  Out << IL->getValue();
1314  return false;
1315  }
1316 
1317  return false;
1318 }
1319 
1322  const BinaryOperator *BExpr,
1323  const bool tookTrue,
1324  BugReporterContext &BRC,
1325  BugReport &R,
1326  const ExplodedNode *N) {
1327 
1328  bool shouldInvert = false;
1329  Optional<bool> shouldPrune;
1330 
1331  SmallString<128> LhsString, RhsString;
1332  {
1333  llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
1334  const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
1335  shouldPrune);
1336  const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
1337  shouldPrune);
1338 
1339  shouldInvert = !isVarLHS && isVarRHS;
1340  }
1341 
1342  BinaryOperator::Opcode Op = BExpr->getOpcode();
1343 
1345  // For assignment operators, all that we care about is that the LHS
1346  // evaluates to "true" or "false".
1347  return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
1348  BRC, R, N);
1349  }
1350 
1351  // For non-assignment operations, we require that we can understand
1352  // both the LHS and RHS.
1353  if (LhsString.empty() || RhsString.empty() ||
1355  return nullptr;
1356 
1357  // Should we invert the strings if the LHS is not a variable name?
1358  SmallString<256> buf;
1359  llvm::raw_svector_ostream Out(buf);
1360  Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is ";
1361 
1362  // Do we need to invert the opcode?
1363  if (shouldInvert)
1364  switch (Op) {
1365  default: break;
1366  case BO_LT: Op = BO_GT; break;
1367  case BO_GT: Op = BO_LT; break;
1368  case BO_LE: Op = BO_GE; break;
1369  case BO_GE: Op = BO_LE; break;
1370  }
1371 
1372  if (!tookTrue)
1373  switch (Op) {
1374  case BO_EQ: Op = BO_NE; break;
1375  case BO_NE: Op = BO_EQ; break;
1376  case BO_LT: Op = BO_GE; break;
1377  case BO_GT: Op = BO_LE; break;
1378  case BO_LE: Op = BO_GT; break;
1379  case BO_GE: Op = BO_LT; break;
1380  default:
1381  return nullptr;
1382  }
1383 
1384  switch (Op) {
1385  case BO_EQ:
1386  Out << "equal to ";
1387  break;
1388  case BO_NE:
1389  Out << "not equal to ";
1390  break;
1391  default:
1392  Out << BinaryOperator::getOpcodeStr(Op) << ' ';
1393  break;
1394  }
1395 
1396  Out << (shouldInvert ? LhsString : RhsString);
1397  const LocationContext *LCtx = N->getLocationContext();
1398  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1399  PathDiagnosticEventPiece *event =
1400  new PathDiagnosticEventPiece(Loc, Out.str());
1401  if (shouldPrune.hasValue())
1402  event->setPrunable(shouldPrune.getValue());
1403  return event;
1404 }
1405 
1408  const Expr *CondVarExpr,
1409  const bool tookTrue,
1410  BugReporterContext &BRC,
1411  BugReport &report,
1412  const ExplodedNode *N) {
1413  // FIXME: If there's already a constraint tracker for this variable,
1414  // we shouldn't emit anything here (c.f. the double note in
1415  // test/Analysis/inlining/path-notes.c)
1416  SmallString<256> buf;
1417  llvm::raw_svector_ostream Out(buf);
1418  Out << "Assuming " << LhsString << " is ";
1419 
1420  QualType Ty = CondVarExpr->getType();
1421 
1422  if (Ty->isPointerType())
1423  Out << (tookTrue ? "not null" : "null");
1424  else if (Ty->isObjCObjectPointerType())
1425  Out << (tookTrue ? "not nil" : "nil");
1426  else if (Ty->isBooleanType())
1427  Out << (tookTrue ? "true" : "false");
1428  else if (Ty->isIntegralOrEnumerationType())
1429  Out << (tookTrue ? "non-zero" : "zero");
1430  else
1431  return nullptr;
1432 
1433  const LocationContext *LCtx = N->getLocationContext();
1434  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
1435  PathDiagnosticEventPiece *event =
1436  new PathDiagnosticEventPiece(Loc, Out.str());
1437 
1438  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
1439  if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
1440  const ProgramState *state = N->getState().get();
1441  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1442  if (report.isInteresting(R))
1443  event->setPrunable(false);
1444  }
1445  }
1446  }
1447 
1448  return event;
1449 }
1450 
1453  const DeclRefExpr *DR,
1454  const bool tookTrue,
1455  BugReporterContext &BRC,
1456  BugReport &report,
1457  const ExplodedNode *N) {
1458 
1459  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
1460  if (!VD)
1461  return nullptr;
1462 
1463  SmallString<256> Buf;
1464  llvm::raw_svector_ostream Out(Buf);
1465 
1466  Out << "Assuming '" << VD->getDeclName() << "' is ";
1467 
1468  QualType VDTy = VD->getType();
1469 
1470  if (VDTy->isPointerType())
1471  Out << (tookTrue ? "non-null" : "null");
1472  else if (VDTy->isObjCObjectPointerType())
1473  Out << (tookTrue ? "non-nil" : "nil");
1474  else if (VDTy->isScalarType())
1475  Out << (tookTrue ? "not equal to 0" : "0");
1476  else
1477  return nullptr;
1478 
1479  const LocationContext *LCtx = N->getLocationContext();
1480  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
1481  PathDiagnosticEventPiece *event =
1482  new PathDiagnosticEventPiece(Loc, Out.str());
1483 
1484  const ProgramState *state = N->getState().get();
1485  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
1486  if (report.isInteresting(R))
1487  event->setPrunable(false);
1488  else {
1489  SVal V = state->getSVal(R);
1490  if (report.isInteresting(V))
1491  event->setPrunable(false);
1492  }
1493  }
1494  return event;
1495 }
1496 
1497 
1498 // FIXME: Copied from ExprEngineCallAndReturn.cpp.
1499 static bool isInStdNamespace(const Decl *D) {
1501  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
1502  if (!ND)
1503  return false;
1504 
1505  while (const NamespaceDecl *Parent = dyn_cast<NamespaceDecl>(ND->getParent()))
1506  ND = Parent;
1507 
1508  return ND->isStdNamespace();
1509 }
1510 
1511 std::unique_ptr<PathDiagnosticPiece>
1513  const ExplodedNode *N,
1514  BugReport &BR) {
1515  // Here we suppress false positives coming from system headers. This list is
1516  // based on known issues.
1517  ExprEngine &Eng = BRC.getBugReporter().getEngine();
1518  AnalyzerOptions &Options = Eng.getAnalysisManager().options;
1519  const Decl *D = N->getLocationContext()->getDecl();
1520 
1521  if (isInStdNamespace(D)) {
1522  // Skip reports within the 'std' namespace. Although these can sometimes be
1523  // the user's fault, we currently don't report them very well, and
1524  // Note that this will not help for any other data structure libraries, like
1525  // TR1, Boost, or llvm/ADT.
1526  if (Options.shouldSuppressFromCXXStandardLibrary()) {
1527  BR.markInvalid(getTag(), nullptr);
1528  return nullptr;
1529 
1530  } else {
1531  // If the complete 'std' suppression is not enabled, suppress reports
1532  // from the 'std' namespace that are known to produce false positives.
1533 
1534  // The analyzer issues a false use-after-free when std::list::pop_front
1535  // or std::list::pop_back are called multiple times because we cannot
1536  // reason about the internal invariants of the datastructure.
1537  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
1538  const CXXRecordDecl *CD = MD->getParent();
1539  if (CD->getName() == "list") {
1540  BR.markInvalid(getTag(), nullptr);
1541  return nullptr;
1542  }
1543  }
1544 
1545  // The analyzer issues a false positive on
1546  // std::basic_string<uint8_t> v; v.push_back(1);
1547  // and
1548  // std::u16string s; s += u'a';
1549  // because we cannot reason about the internal invariants of the
1550  // datastructure.
1551  for (const LocationContext *LCtx = N->getLocationContext(); LCtx;
1552  LCtx = LCtx->getParent()) {
1553  const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl());
1554  if (!MD)
1555  continue;
1556 
1557  const CXXRecordDecl *CD = MD->getParent();
1558  if (CD->getName() == "basic_string") {
1559  BR.markInvalid(getTag(), nullptr);
1560  return nullptr;
1561  }
1562  }
1563  }
1564  }
1565 
1566  // Skip reports within the sys/queue.h macros as we do not have the ability to
1567  // reason about data structure shapes.
1570  while (Loc.isMacroID()) {
1571  Loc = Loc.getSpellingLoc();
1572  if (SM.getFilename(Loc).endswith("sys/queue.h")) {
1573  BR.markInvalid(getTag(), nullptr);
1574  return nullptr;
1575  }
1576  }
1577 
1578  return nullptr;
1579 }
1580 
1583  const ExplodedNode *PrevN,
1584  BugReporterContext &BRC,
1585  BugReport &BR) {
1586 
1587  ProgramStateRef State = N->getState();
1588  ProgramPoint ProgLoc = N->getLocation();
1589 
1590  // We are only interested in visiting CallEnter nodes.
1591  Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
1592  if (!CEnter)
1593  return nullptr;
1594 
1595  // Check if one of the arguments is the region the visitor is tracking.
1597  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
1598  unsigned Idx = 0;
1599  ArrayRef<ParmVarDecl*> parms = Call->parameters();
1600 
1601  for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();
1602  I != E; ++I, ++Idx) {
1603  const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
1604 
1605  // Are we tracking the argument or its subregion?
1606  if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
1607  continue;
1608 
1609  // Check the function parameter type.
1610  const ParmVarDecl *ParamDecl = *I;
1611  assert(ParamDecl && "Formal parameter has no decl?");
1612  QualType T = ParamDecl->getType();
1613 
1614  if (!(T->isAnyPointerType() || T->isReferenceType())) {
1615  // Function can only change the value passed in by address.
1616  continue;
1617  }
1618 
1619  // If it is a const pointer value, the function does not intend to
1620  // change the value.
1621  if (T->getPointeeType().isConstQualified())
1622  continue;
1623 
1624  // Mark the call site (LocationContext) as interesting if the value of the
1625  // argument is undefined or '0'/'NULL'.
1626  SVal BoundVal = State->getSVal(R);
1627  if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
1628  BR.markInteresting(CEnter->getCalleeContext());
1629  return nullptr;
1630  }
1631  }
1632  return nullptr;
1633 }
TypedValueRegion - An abstract class representing regions having a typed value.
Definition: MemRegion.h:498
const Expr * getDerefExpr(const Stmt *S)
StringRef getName() const
Definition: Decl.h:168
void setTag(const char *tag)
Tag this PathDiagnosticPiece with the given C-string.
MemRegion - The root abstract class for all memory regions.
Definition: MemRegion.h:77
bool isMacroID() const
bool isInteresting(SymbolRef sym)
succ_iterator succ_begin()
Definition: CFG.h:542
virtual bool canPrintPretty() const
Returns true if this region can be printed in a user-friendly way.
Definition: MemRegion.cpp:568
const ExplodedNode * getErrorNode() const
Definition: BugReporter.h:180
virtual PathDiagnosticLocation getLocation(const SourceManager &SM) const
Return the "definitive" location of the reported bug.
PathDiagnosticPiece * VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
unsigned getFunctionScopeIndex() const
Returns the index of this parameter in its prototype or method scope.
Definition: Decl.h:1386
ProgramPoint getLocation() const
getLocation - Returns the edge associated with the given node.
virtual bool isBoundable() const
Definition: MemRegion.h:188
Manages the lifetime of CallEvent objects.
Definition: CallEvent.h:897
PathDiagnosticPiece * VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
bool isStdNamespace() const
Definition: DeclBase.cpp:835
const Expr * getInit() const
Definition: Decl.h:1068
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:400
bool isBooleanType() const
Definition: Type.h:5489
void setPrunable(bool isPrunable, bool override=false)
PathDiagnosticPiece * VisitNode(const ExplodedNode *N, const ExplodedNode *Prev, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
bool shouldAvoidSuppressingNullArgumentPaths()
const Stmt * GetDenomExpr(const ExplodedNode *N)
Value representing integer constant.
Definition: SVals.h:339
unsigned succ_size() const
Definition: CFG.h:552
static const Expr * peelOffOuterExpr(const Expr *Ex, const ExplodedNode *N)
ParmVarDecl - Represents a parameter to a function.
Definition: Decl.h:1334
bool isZeroConstant() const
Definition: SVals.cpp:186
FullSourceLoc asLocation() const
bool isComparisonOp() const
Definition: Expr.h:3008
const MemSpaceRegion * getMemorySpace() const
Definition: MemRegion.cpp:1031
void Profile(llvm::FoldingSetNodeID &ID) const override
bool isScalarType() const
Definition: Type.h:5461
LineState State
bool isReferenceType() const
Definition: Type.h:5241
bool isAnyPointerType() const
Definition: Type.h:5235
Represents a program point after a store evaluation.
Definition: ProgramPoint.h:376
MemRegionManager & getRegionManager()
Definition: ProgramState.h:500
SymbolRef getAsLocSymbol(bool IncludeBaseRegions=false) const
If this SVal is a location and wraps a symbol, return that SymbolRef. Otherwise return 0...
Definition: SVals.cpp:69
Optional< T > getLocationAs() const LLVM_LVALUE_FUNCTION
bool patternMatch(const Expr *Ex, raw_ostream &Out, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N, Optional< bool > &prunable)
Expr * getLHS() const
Definition: Expr.h:2964
const VarDecl * getDecl() const
Definition: MemRegion.h:877
virtual llvm::iterator_range< ranges_iterator > getRanges()
Get the SourceRanges associated with the report.
std::unique_ptr< PathDiagnosticPiece > getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR) override
Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...
virtual std::unique_ptr< PathDiagnosticPiece > getEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR)
Provide custom definition for the final diagnostic piece on the path - the piece, which is displayed ...
BinaryOperatorKind
DeclContext * getEnclosingNamespaceContext()
Retrieve the nearest enclosing namespace context.
Definition: DeclBase.cpp:1474
SmallVector< CharSourceRange, 8 > Ranges
Definition: Format.cpp:1554
const CXXRecordDecl * getParent() const
Definition: DeclCXX.h:1817
bool isUnknownOrUndef() const
Definition: SVals.h:125
A builtin binary operation expression such as "x + y" or "x <= y".
Definition: Expr.h:2918
const Stmt * getCallSite() const
bool isParentOf(const LocationContext *LC) const
Expr * IgnoreParenCasts() LLVM_READONLY
Definition: Expr.cpp:2439
static void registerStatementVarDecls(BugReport &BR, const Stmt *S, bool EnableNullFPSuppression)
static PathDiagnosticLocation create(const Decl *D, const SourceManager &SM)
Create a location corresponding to the given declaration.
static const MemRegion * getLocationRegionIfReference(const Expr *E, const ExplodedNode *N)
StringRef getDescription() const
Definition: BugReporter.h:182
ExplodedNode * getFirstPred()
bool isStaticLocal() const
Definition: Decl.h:904
void addVisitor(std::unique_ptr< BugReporterVisitor > visitor)
Add custom or predefined bug report visitors to this report.
QualType getType() const
Definition: Decl.h:538
const LocationContext * getLocationContext() const
AnnotatingParser & P
const StackFrameContext * getStackFrame() const
Definition: MemRegion.h:371
bool isAssignmentOp() const
Definition: Expr.h:3043
Represents a ValueDecl that came out of a declarator. Contains type source information through TypeSo...
Definition: Decl.h:586
StringRef getFilename(SourceLocation SpellingLoc) const
Return the filename of the file containing a SourceLocation.
const MemRegion * StripCasts(bool StripBaseCasts=true) const
Definition: MemRegion.cpp:1089
ID
Defines the set of possible language-specific address spaces.
Definition: AddressSpaces.h:27
QualType getPointeeType() const
Definition: Type.cpp:414
SourceManager & SM
const ProgramStateRef & getState() const
CallEventRef getCaller(const StackFrameContext *CalleeCtx, ProgramStateRef State)
Definition: CallEvent.cpp:923
SVal getSVal(const Stmt *S, const LocationContext *LCtx) const
Returns the SVal bound to the statement 'S' in the state's environment.
Definition: ProgramState.h:693
Optional< T > getAs() const
Convert to the specified SVal type, returning None if this SVal is not of the desired type...
Definition: SVals.h:86
DeclContext * getDeclContext()
Definition: DeclBase.h:381
static const Expr * getNilReceiver(const Stmt *S, const ExplodedNode *N)
static bool isInStdNamespace(const Decl *D)
void Profile(llvm::FoldingSetNodeID &ID) const override
SuppressInlineDefensiveChecksVisitor(DefinedSVal Val, const ExplodedNode *N)
Expr * getSubExpr() const
Definition: Expr.h:1699
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1174
An expression that sends a message to the given Objective-C object or class.
Definition: ExprObjC.h:858
DeclarationName getDeclName() const
Definition: Decl.h:189
void markInteresting(SymbolRef sym)
ValueDecl * getDecl()
Definition: Expr.h:994
bool isGLValue() const
Definition: Expr.h:253
PathDiagnosticPiece * VisitTerminator(const Stmt *Term, const ExplodedNode *N, const CFGBlock *srcBlk, const CFGBlock *dstBlk, BugReport &R, BugReporterContext &BRC)
const MatchFinder::MatchFinderOptions & Options
CFGTerminator getTerminator()
Definition: CFG.h:623
static std::unique_ptr< PathDiagnosticPiece > getDefaultEndPath(BugReporterContext &BRC, const ExplodedNode *N, BugReport &BR)
Generates the default final diagnostic piece.
#define false
Definition: stdbool.h:33
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
Definition: Type.h:5476
const StackFrameContext * getCurrentStackFrame() const
static bool isCallStmt(const Stmt *S)
Returns true if this is a statement is a function or method call of some kind.
Definition: CallEvent.cpp:237
AnalysisManager & getAnalysisManager() override
Definition: ExprEngine.h:125
void Profile(llvm::FoldingSetNodeID &ID) const override
bool isValid() const
Return true if this is a valid SourceLocation object.
CallEventManager & getCallEventManager()
Definition: ProgramState.h:507
PathDiagnosticPiece * VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:1717
PathDiagnosticPiece * VisitNode(const ExplodedNode *N, const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
PathDiagnosticPiece * VisitTrueTest(const Expr *Cond, bool tookTrue, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N)
const Decl * getDecl() const
virtual void printPretty(raw_ostream &os) const
Print the region for use in diagnostics.
Definition: MemRegion.cpp:576
bool isUndef() const
Definition: SVals.h:121
PathDiagnosticPiece * VisitConditionVariable(StringRef LhsString, const Expr *CondVarExpr, const bool tookTrue, BugReporterContext &BRC, BugReport &R, const ExplodedNode *N)
Opcode getOpcode() const
Definition: Expr.h:1696
const Decl * getSingleDecl() const
Definition: Stmt.h:467
Expr * getInstanceReceiver()
Returns the object expression (receiver) for an instance message, or null for a message that is not a...
Definition: ExprObjC.h:1152
ast_type_traits::DynTypedNode Node
QualType getType() const
Definition: Expr.h:125
bool isDeclRefExprToReference(const Expr *E)
const LocationContext * getParent() const
StringRef getOpcodeStr() const
Definition: Expr.h:2980
const LocationContext * getLocationContext() const
Definition: ProgramPoint.h:155
const VarRegion * getVarRegion(const VarDecl *D, const LocationContext *LC)
Definition: MemRegion.cpp:765
GRBugReporter & getBugReporter()
Definition: BugReporter.h:534
const Stmt * GetRetValExpr(const ExplodedNode *N)
const MemRegion * getAsRegion() const
Definition: SVals.cpp:135
const Expr * getRetValue() const
Definition: Stmt.cpp:1013
Optional< T > getAs() const
Convert to the specified ProgramPoint type, returning None if this ProgramPoint is not of the desired...
Definition: ProgramPoint.h:127
Represents an SVal that is guaranteed to not be UnknownVal.
Definition: SVals.h:255
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition: Expr.h:2066
ProgramStateManager & getStateManager()
Definition: BugReporter.h:538
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition: ExprObjC.h:474
X
Definition: SemaDecl.cpp:11429
Represents a C++ struct/union/class.
Definition: DeclCXX.h:285
bool isObjCObjectPointerType() const
Definition: Type.h:5304
Opcode getOpcode() const
Definition: Expr.h:2961
PathDiagnosticPiece * VisitNode(const ExplodedNode *Succ, const ExplodedNode *Pred, BugReporterContext &BRC, BugReport &BR) override
Return a diagnostic piece which should be associated with the given node.
bool trackNullOrUndefValue(const ExplodedNode *N, const Stmt *S, BugReport &R, bool IsArg=false, bool EnableNullFPSuppression=true)
PathDiagnosticPiece * VisitNodeImpl(const ExplodedNode *N, const ExplodedNode *Prev, BugReporterContext &BRC, BugReport &BR)
static PathDiagnosticLocation createEndOfPath(const ExplodedNode *N, const SourceManager &SM)
void removeInvalidation(const void *Tag, const void *Data)
Definition: BugReporter.h:235
void markInvalid(const void *Tag, const void *Data)
Definition: BugReporter.h:228
static bool isInitializationOfVar(const ExplodedNode *N, const VarRegion *VR)
Loc getLValue(const VarDecl *D, const LocationContext *LC) const
Get the lvalue for a variable reference.
Definition: ProgramState.h:659
Expr * getRHS() const
Definition: Expr.h:2966
A SourceLocation and its associated SourceManager.
A reference to a declared variable, function, enum, etc. [C99 6.5.1p2].
Definition: Expr.h:899
virtual bool isSubRegionOf(const MemRegion *R) const
Check if the region is a subregion of the given region.
Definition: MemRegion.cpp:1081
A trivial tuple used to represent a source range.
bool isConstQualified() const
Determine whether this type is const-qualified.
Definition: Type.h:5075
T castAs() const
Convert to the specified SVal type, asserting that this SVal is of the desired type.
Definition: SVals.h:75
static bool isInterestingLValueExpr(const Expr *Ex)
Returns true if nodes for the given expression kind are always kept around.
This class handles loading and caching of source files into memory.
SourceManager & getSourceManager()
Definition: BugReporter.h:550
bool hasLocalStorage() const
Definition: Decl.h:887
FullSourceLoc getSpellingLoc() const
virtual AnalysisManager & getAnalysisManager()=0
ExprEngine & getEngine()
Definition: BugReporter.h:499
bool isPointerType() const
Definition: Type.h:5232