BugReporterVisitors.cpp revision 20165e796c16311a83911db74c04d797e93471b2
17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// BugReporterVisitors.cpp - Helpers for reporting bugs -----------*- C++ -*--//
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//                     The LLVM Compiler Infrastructure
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// License. See LICENSE.TXT for details.
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//  This file defines a set of BugReporter "visitors" which can be used to
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//  enhance the diagnostics reported for a bug.
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//
13a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===//
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/AST/Expr.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/AST/ExprObjC.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
22a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
23a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "llvm/ADT/SmallString.h"
24a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
25a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using namespace clang;
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)using namespace ento;
27a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
28a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)//===----------------------------------------------------------------------===//
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Utility functions.
30eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//===----------------------------------------------------------------------===//
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)const Stmt *bugreporter::GetDerefExpr(const ExplodedNode *N) {
33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  // Pattern match for a few useful cases (do something smarter later):
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   a[0], p->f, *p
35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
37a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (true) {
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(S)) {
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      assert(B->isAssignmentOp());
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      S = B->getLHS()->IgnoreParenCasts();
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      continue;
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(S)) {
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (U->getOpcode() == UO_Deref)
45a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        return U->getSubExpr()->IgnoreParenCasts();
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else if (const MemberExpr *ME = dyn_cast<MemberExpr>(S)) {
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return ME->getBase()->IgnoreParenCasts();
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(S)) {
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return AE->getBase();
527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    }
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    break;
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const Stmt *bugreporter::GetDenomExpr(const ExplodedNode *N) {
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return BE->getRHS();
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)const Stmt *bugreporter::GetRetValExpr(const ExplodedNode *N) {
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
687d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return RS->getRetValue();
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return NULL;
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Definitions for bug reporter visitors.
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)//===----------------------------------------------------------------------===//
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)PathDiagnosticPiece*
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)BugReporterVisitor::getEndPath(BugReporterContext &BRC,
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               const ExplodedNode *EndPathNode,
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                               BugReport &BR) {
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return 0;
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
84a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)PathDiagnosticPiece*
85a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)BugReporterVisitor::getDefaultEndPath(BugReporterContext &BRC,
86a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                      const ExplodedNode *EndPathNode,
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                      BugReport &BR) {
88a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  PathDiagnosticLocation L =
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  BugReport::ranges_iterator Beg, End;
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  llvm::tie(Beg, End) = BR.getRanges();
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Only add the statement itself as a range if we didn't specify any
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // special ranges for this report.
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  PathDiagnosticPiece *P = new PathDiagnosticEventPiece(L,
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      BR.getDescription(),
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      Beg == End);
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  for (; Beg != End; ++Beg)
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    P->addRange(*Beg);
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return P;
1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid FindLastStoreBRVisitor ::Profile(llvm::FoldingSetNodeID &ID) const {
1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  static int tag = 0;
1087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  ID.AddPointer(&tag);
1097d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ID.AddPointer(R);
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ID.Add(V);
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *N,
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                     const ExplodedNode *PrevN,
115a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                     BugReporterContext &BRC,
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                                                     BugReport &BR) {
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (satisfied)
119a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return NULL;
1207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  if (!StoreSite) {
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Make sure the region is actually bound to value V here.
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // This is necessary because the region may not actually be live at the
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // report's error node.
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    if (N->getState()->getSVal(R) != V)
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      return NULL;
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const ExplodedNode *Node = N, *Last = N;
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    // Now look for the store of V.
1317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    for ( ; Node ; Node = Node->getFirstPred()) {
1327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
1337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        if (const PostStmt *P = Node->getLocationAs<PostStmt>())
1347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)          if (const DeclStmt *DS = P->getStmtAs<DeclStmt>())
1357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)            if (DS->getSingleDecl() == VR->getDecl()) {
1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              // Record the last seen initialization point.
1377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)              Last = Node;
138ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch              break;
139ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch            }
140ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      }
141c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch
142c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      // Does the region still bind to value V?  If not, we are done
143c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch      // looking for store sites.
144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)      if (Node->getState()->getSVal(R) != V)
145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)        break;
146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
1477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      Last = Node;
1487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
1497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
150    if (!Node) {
151      satisfied = true;
152      return NULL;
153    }
154
155    StoreSite = Last;
156  }
157
158  if (StoreSite != N)
159    return NULL;
160
161  satisfied = true;
162  SmallString<256> sbuf;
163  llvm::raw_svector_ostream os(sbuf);
164
165  if (const PostStmt *PS = N->getLocationAs<PostStmt>()) {
166    if (const DeclStmt *DS = PS->getStmtAs<DeclStmt>()) {
167
168      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
169        os << "Variable '" << *VR->getDecl() << "' ";
170      }
171      else
172        return NULL;
173
174      if (isa<loc::ConcreteInt>(V)) {
175        bool b = false;
176        if (R->isBoundable()) {
177          if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
178            if (TR->getValueType()->isObjCObjectPointerType()) {
179              os << "initialized to nil";
180              b = true;
181            }
182          }
183        }
184
185        if (!b)
186          os << "initialized to a null pointer value";
187      }
188      else if (isa<nonloc::ConcreteInt>(V)) {
189        os << "initialized to " << cast<nonloc::ConcreteInt>(V).getValue();
190      }
191      else if (V.isUndef()) {
192        if (isa<VarRegion>(R)) {
193          const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
194          if (VD->getInit())
195            os << "initialized to a garbage value";
196          else
197            os << "declared without an initial value";
198        }
199      }
200    }
201  }
202
203  if (os.str().empty()) {
204    if (isa<loc::ConcreteInt>(V)) {
205      bool b = false;
206      if (R->isBoundable()) {
207        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
208          if (TR->getValueType()->isObjCObjectPointerType()) {
209            os << "nil object reference stored to ";
210            b = true;
211          }
212        }
213      }
214
215      if (!b)
216        os << "Null pointer value stored to ";
217    }
218    else if (V.isUndef()) {
219      os << "Uninitialized value stored to ";
220    }
221    else if (isa<nonloc::ConcreteInt>(V)) {
222      os << "The value " << cast<nonloc::ConcreteInt>(V).getValue()
223               << " is assigned to ";
224    }
225    else
226      return NULL;
227
228    if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
229      os << '\'' << *VR->getDecl() << '\'';
230    }
231    else
232      return NULL;
233  }
234
235  // Construct a new PathDiagnosticPiece.
236  ProgramPoint P = N->getLocation();
237  PathDiagnosticLocation L =
238    PathDiagnosticLocation::create(P, BRC.getSourceManager());
239  if (!L.isValid())
240    return NULL;
241  return new PathDiagnosticEventPiece(L, os.str());
242}
243
244void TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
245  static int tag = 0;
246  ID.AddPointer(&tag);
247  ID.AddBoolean(Assumption);
248  ID.Add(Constraint);
249}
250
251PathDiagnosticPiece *
252TrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
253                                    const ExplodedNode *PrevN,
254                                    BugReporterContext &BRC,
255                                    BugReport &BR) {
256  if (isSatisfied)
257    return NULL;
258
259  // Check if in the previous state it was feasible for this constraint
260  // to *not* be true.
261  if (PrevN->getState()->assume(Constraint, !Assumption)) {
262
263    isSatisfied = true;
264
265    // As a sanity check, make sure that the negation of the constraint
266    // was infeasible in the current state.  If it is feasible, we somehow
267    // missed the transition point.
268    if (N->getState()->assume(Constraint, !Assumption))
269      return NULL;
270
271    // We found the transition point for the constraint.  We now need to
272    // pretty-print the constraint. (work-in-progress)
273    std::string sbuf;
274    llvm::raw_string_ostream os(sbuf);
275
276    if (isa<Loc>(Constraint)) {
277      os << "Assuming pointer value is ";
278      os << (Assumption ? "non-null" : "null");
279    }
280
281    if (os.str().empty())
282      return NULL;
283
284    // Construct a new PathDiagnosticPiece.
285    ProgramPoint P = N->getLocation();
286    PathDiagnosticLocation L =
287      PathDiagnosticLocation::create(P, BRC.getSourceManager());
288    if (!L.isValid())
289      return NULL;
290    return new PathDiagnosticEventPiece(L, os.str());
291  }
292
293  return NULL;
294}
295
296BugReporterVisitor *
297bugreporter::getTrackNullOrUndefValueVisitor(const ExplodedNode *N,
298                                             const Stmt *S,
299                                             BugReport *report) {
300  if (!S || !N)
301    return 0;
302
303  ProgramStateManager &StateMgr = N->getState()->getStateManager();
304
305  // Walk through nodes until we get one that matches the statement
306  // exactly.
307  while (N) {
308    const ProgramPoint &pp = N->getLocation();
309    if (const PostStmt *ps = dyn_cast<PostStmt>(&pp)) {
310      if (ps->getStmt() == S)
311        break;
312    }
313    N = N->getFirstPred();
314  }
315
316  if (!N)
317    return 0;
318
319  ProgramStateRef state = N->getState();
320
321  // Walk through lvalue-to-rvalue conversions.
322  const Expr *Ex = dyn_cast<Expr>(S);
323  if (Ex) {
324    Ex = Ex->IgnoreParenLValueCasts();
325    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
326      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
327        const VarRegion *R =
328          StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
329
330        // What did we load?
331        SVal V = state->getRawSVal(loc::MemRegionVal(R));
332        report->markInteresting(R);
333        report->markInteresting(V);
334        return new FindLastStoreBRVisitor(V, R);
335      }
336    }
337  }
338
339  SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
340
341  // Uncomment this to find cases where we aren't properly getting the
342  // base value that was dereferenced.
343  // assert(!V.isUnknownOrUndef());
344
345  // Is it a symbolic value?
346  if (loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&V)) {
347    const SubRegion *R = cast<SubRegion>(L->getRegion());
348    while (R && !isa<SymbolicRegion>(R)) {
349      R = dyn_cast<SubRegion>(R->getSuperRegion());
350    }
351
352    if (R) {
353      report->markInteresting(R);
354      return new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
355    }
356  }
357
358  return 0;
359}
360
361BugReporterVisitor *
362FindLastStoreBRVisitor::createVisitorObject(const ExplodedNode *N,
363                                            const MemRegion *R) {
364  assert(R && "The memory region is null.");
365
366  ProgramStateRef state = N->getState();
367  SVal V = state->getSVal(R);
368  if (V.isUnknown())
369    return 0;
370
371  return new FindLastStoreBRVisitor(V, R);
372}
373
374
375PathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
376                                                     const ExplodedNode *PrevN,
377                                                     BugReporterContext &BRC,
378                                                     BugReport &BR) {
379  const PostStmt *P = N->getLocationAs<PostStmt>();
380  if (!P)
381    return 0;
382  const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
383  if (!ME)
384    return 0;
385  const Expr *Receiver = ME->getInstanceReceiver();
386  if (!Receiver)
387    return 0;
388  ProgramStateRef state = N->getState();
389  const SVal &V = state->getSVal(Receiver, N->getLocationContext());
390  const DefinedOrUnknownSVal *DV = dyn_cast<DefinedOrUnknownSVal>(&V);
391  if (!DV)
392    return 0;
393  state = state->assume(*DV, true);
394  if (state)
395    return 0;
396
397  // The receiver was nil, and hence the method was skipped.
398  // Register a BugReporterVisitor to issue a message telling us how
399  // the receiver was null.
400  BR.addVisitor(bugreporter::getTrackNullOrUndefValueVisitor(N, Receiver, &BR));
401  // Issue a message saying that the method was skipped.
402  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
403                                     N->getLocationContext());
404  return new PathDiagnosticEventPiece(L, "No method is called "
405      "because the receiver is nil");
406}
407
408// Registers every VarDecl inside a Stmt with a last store visitor.
409void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
410                                                       const Stmt *S) {
411  const ExplodedNode *N = BR.getErrorNode();
412  std::deque<const Stmt *> WorkList;
413  WorkList.push_back(S);
414
415  while (!WorkList.empty()) {
416    const Stmt *Head = WorkList.front();
417    WorkList.pop_front();
418
419    ProgramStateRef state = N->getState();
420    ProgramStateManager &StateMgr = state->getStateManager();
421
422    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
423      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
424        const VarRegion *R =
425        StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
426
427        // What did we load?
428        SVal V = state->getSVal(S, N->getLocationContext());
429
430        if (isa<loc::ConcreteInt>(V) || isa<nonloc::ConcreteInt>(V)) {
431          // Register a new visitor with the BugReport.
432          BR.addVisitor(new FindLastStoreBRVisitor(V, R));
433        }
434      }
435    }
436
437    for (Stmt::const_child_iterator I = Head->child_begin();
438        I != Head->child_end(); ++I)
439      WorkList.push_back(*I);
440  }
441}
442
443//===----------------------------------------------------------------------===//
444// Visitor that tries to report interesting diagnostics from conditions.
445//===----------------------------------------------------------------------===//
446PathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
447                                                   const ExplodedNode *Prev,
448                                                   BugReporterContext &BRC,
449                                                   BugReport &BR) {
450  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
451  if (PathDiagnosticEventPiece *ev =
452      dyn_cast_or_null<PathDiagnosticEventPiece>(piece))
453    ev->setPrunable(true, /* override */ false);
454  return piece;
455}
456
457PathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
458                                                       const ExplodedNode *Prev,
459                                                       BugReporterContext &BRC,
460                                                       BugReport &BR) {
461
462  const ProgramPoint &progPoint = N->getLocation();
463
464  ProgramStateRef CurrentState = N->getState();
465  ProgramStateRef PrevState = Prev->getState();
466
467  // Compare the GDMs of the state, because that is where constraints
468  // are managed.  Note that ensure that we only look at nodes that
469  // were generated by the analyzer engine proper, not checkers.
470  if (CurrentState->getGDM().getRoot() ==
471      PrevState->getGDM().getRoot())
472    return 0;
473
474  // If an assumption was made on a branch, it should be caught
475  // here by looking at the state transition.
476  if (const BlockEdge *BE = dyn_cast<BlockEdge>(&progPoint)) {
477    const CFGBlock *srcBlk = BE->getSrc();
478    if (const Stmt *term = srcBlk->getTerminator())
479      return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
480    return 0;
481  }
482
483  if (const PostStmt *PS = dyn_cast<PostStmt>(&progPoint)) {
484    // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
485    // violation.
486    const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
487      cast<GRBugReporter>(BRC.getBugReporter()).
488        getEngine().getEagerlyAssumeTags();
489
490    const ProgramPointTag *tag = PS->getTag();
491    if (tag == tags.first)
492      return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
493                           BRC, BR, N);
494    if (tag == tags.second)
495      return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
496                           BRC, BR, N);
497
498    return 0;
499  }
500
501  return 0;
502}
503
504PathDiagnosticPiece *
505ConditionBRVisitor::VisitTerminator(const Stmt *Term,
506                                    const ExplodedNode *N,
507                                    const CFGBlock *srcBlk,
508                                    const CFGBlock *dstBlk,
509                                    BugReport &R,
510                                    BugReporterContext &BRC) {
511  const Expr *Cond = 0;
512
513  switch (Term->getStmtClass()) {
514  default:
515    return 0;
516  case Stmt::IfStmtClass:
517    Cond = cast<IfStmt>(Term)->getCond();
518    break;
519  case Stmt::ConditionalOperatorClass:
520    Cond = cast<ConditionalOperator>(Term)->getCond();
521    break;
522  }
523
524  assert(Cond);
525  assert(srcBlk->succ_size() == 2);
526  const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
527  return VisitTrueTest(Cond->IgnoreParenNoopCasts(BRC.getASTContext()),
528                       tookTrue, BRC, R, N);
529}
530
531PathDiagnosticPiece *
532ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
533                                  bool tookTrue,
534                                  BugReporterContext &BRC,
535                                  BugReport &R,
536                                  const ExplodedNode *N) {
537
538  const Expr *Ex = Cond;
539
540  while (true) {
541    Ex = Ex->IgnoreParens();
542    switch (Ex->getStmtClass()) {
543      default:
544        return 0;
545      case Stmt::BinaryOperatorClass:
546        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
547                             R, N);
548      case Stmt::DeclRefExprClass:
549        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
550                             R, N);
551      case Stmt::UnaryOperatorClass: {
552        const UnaryOperator *UO = cast<UnaryOperator>(Ex);
553        if (UO->getOpcode() == UO_LNot) {
554          tookTrue = !tookTrue;
555          Ex = UO->getSubExpr()->IgnoreParenNoopCasts(BRC.getASTContext());
556          continue;
557        }
558        return 0;
559      }
560    }
561  }
562}
563
564bool ConditionBRVisitor::patternMatch(const Expr *Ex, llvm::raw_ostream &Out,
565                                      BugReporterContext &BRC,
566                                      BugReport &report,
567                                      const ExplodedNode *N,
568                                      llvm::Optional<bool> &prunable) {
569  const Expr *OriginalExpr = Ex;
570  Ex = Ex->IgnoreParenCasts();
571
572  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
573    const bool quotes = isa<VarDecl>(DR->getDecl());
574    if (quotes) {
575      Out << '\'';
576      const LocationContext *LCtx = N->getLocationContext();
577      const ProgramState *state = N->getState().getPtr();
578      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
579                                                LCtx).getAsRegion()) {
580        if (report.isInteresting(R))
581          prunable = false;
582        else {
583          const ProgramState *state = N->getState().getPtr();
584          SVal V = state->getSVal(R);
585          if (report.isInteresting(V))
586            prunable = false;
587        }
588      }
589    }
590    Out << DR->getDecl()->getDeclName().getAsString();
591    if (quotes)
592      Out << '\'';
593    return quotes;
594  }
595
596  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
597    QualType OriginalTy = OriginalExpr->getType();
598    if (OriginalTy->isPointerType()) {
599      if (IL->getValue() == 0) {
600        Out << "null";
601        return false;
602      }
603    }
604    else if (OriginalTy->isObjCObjectPointerType()) {
605      if (IL->getValue() == 0) {
606        Out << "nil";
607        return false;
608      }
609    }
610
611    Out << IL->getValue();
612    return false;
613  }
614
615  return false;
616}
617
618PathDiagnosticPiece *
619ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
620                                  const BinaryOperator *BExpr,
621                                  const bool tookTrue,
622                                  BugReporterContext &BRC,
623                                  BugReport &R,
624                                  const ExplodedNode *N) {
625
626  bool shouldInvert = false;
627  llvm::Optional<bool> shouldPrune;
628
629  SmallString<128> LhsString, RhsString;
630  {
631    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
632    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
633                                       shouldPrune);
634    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
635                                       shouldPrune);
636
637    shouldInvert = !isVarLHS && isVarRHS;
638  }
639
640  BinaryOperator::Opcode Op = BExpr->getOpcode();
641
642  if (BinaryOperator::isAssignmentOp(Op)) {
643    // For assignment operators, all that we care about is that the LHS
644    // evaluates to "true" or "false".
645    return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
646                                  BRC, R, N);
647  }
648
649  // For non-assignment operations, we require that we can understand
650  // both the LHS and RHS.
651  if (LhsString.empty() || RhsString.empty())
652    return 0;
653
654  // Should we invert the strings if the LHS is not a variable name?
655  SmallString<256> buf;
656  llvm::raw_svector_ostream Out(buf);
657  Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is ";
658
659  // Do we need to invert the opcode?
660  if (shouldInvert)
661    switch (Op) {
662      default: break;
663      case BO_LT: Op = BO_GT; break;
664      case BO_GT: Op = BO_LT; break;
665      case BO_LE: Op = BO_GE; break;
666      case BO_GE: Op = BO_LE; break;
667    }
668
669  if (!tookTrue)
670    switch (Op) {
671      case BO_EQ: Op = BO_NE; break;
672      case BO_NE: Op = BO_EQ; break;
673      case BO_LT: Op = BO_GE; break;
674      case BO_GT: Op = BO_LE; break;
675      case BO_LE: Op = BO_GT; break;
676      case BO_GE: Op = BO_LT; break;
677      default:
678        return 0;
679    }
680
681  switch (Op) {
682    case BO_EQ:
683      Out << "equal to ";
684      break;
685    case BO_NE:
686      Out << "not equal to ";
687      break;
688    default:
689      Out << BinaryOperator::getOpcodeStr(Op) << ' ';
690      break;
691  }
692
693  Out << (shouldInvert ? LhsString : RhsString);
694  const LocationContext *LCtx = N->getLocationContext();
695  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
696  PathDiagnosticEventPiece *event =
697    new PathDiagnosticEventPiece(Loc, Out.str());
698  if (shouldPrune.hasValue())
699    event->setPrunable(shouldPrune.getValue());
700  return event;
701}
702
703PathDiagnosticPiece *
704ConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
705                                           const Expr *CondVarExpr,
706                                           const bool tookTrue,
707                                           BugReporterContext &BRC,
708                                           BugReport &report,
709                                           const ExplodedNode *N) {
710  SmallString<256> buf;
711  llvm::raw_svector_ostream Out(buf);
712  Out << "Assuming " << LhsString << " is ";
713
714  QualType Ty = CondVarExpr->getType();
715
716  if (Ty->isPointerType())
717    Out << (tookTrue ? "not null" : "null");
718  else if (Ty->isObjCObjectPointerType())
719    Out << (tookTrue ? "not nil" : "nil");
720  else if (Ty->isBooleanType())
721    Out << (tookTrue ? "true" : "false");
722  else if (Ty->isIntegerType())
723    Out << (tookTrue ? "non-zero" : "zero");
724  else
725    return 0;
726
727  const LocationContext *LCtx = N->getLocationContext();
728  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
729  PathDiagnosticEventPiece *event =
730    new PathDiagnosticEventPiece(Loc, Out.str());
731
732  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
733    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
734      const ProgramState *state = N->getState().getPtr();
735      if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
736        if (report.isInteresting(R))
737          event->setPrunable(false);
738      }
739    }
740  }
741
742  return event;
743}
744
745PathDiagnosticPiece *
746ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
747                                  const DeclRefExpr *DR,
748                                  const bool tookTrue,
749                                  BugReporterContext &BRC,
750                                  BugReport &report,
751                                  const ExplodedNode *N) {
752
753  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
754  if (!VD)
755    return 0;
756
757  SmallString<256> Buf;
758  llvm::raw_svector_ostream Out(Buf);
759
760  Out << "Assuming '";
761  VD->getDeclName().printName(Out);
762  Out << "' is ";
763
764  QualType VDTy = VD->getType();
765
766  if (VDTy->isPointerType())
767    Out << (tookTrue ? "non-null" : "null");
768  else if (VDTy->isObjCObjectPointerType())
769    Out << (tookTrue ? "non-nil" : "nil");
770  else if (VDTy->isScalarType())
771    Out << (tookTrue ? "not equal to 0" : "0");
772  else
773    return 0;
774
775  const LocationContext *LCtx = N->getLocationContext();
776  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
777  PathDiagnosticEventPiece *event =
778    new PathDiagnosticEventPiece(Loc, Out.str());
779
780  const ProgramState *state = N->getState().getPtr();
781  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
782    if (report.isInteresting(R))
783      event->setPrunable(false);
784    else {
785      SVal V = state->getSVal(R);
786      if (report.isInteresting(V))
787        event->setPrunable(false);
788    }
789  }
790  return event;
791}
792
793