BugReporterVisitors.cpp revision 702077f14100f2d7acdb12ad49b53e64efc37d72
15350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek// BugReporterVisitors.cpp - Helpers for reporting bugs -----------*- C++ -*--//
25350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//
35350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//                     The LLVM Compiler Infrastructure
45350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//
55350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek// This file is distributed under the University of Illinois Open Source
65350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek// License. See LICENSE.TXT for details.
75350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//
85350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===//
95350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//
105350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//  This file defines a set of BugReporter "visitors" which can be used to
115350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//  enhance the diagnostics reported for a bug.
125350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//
135350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===//
1450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitor.h"
155350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek#include "clang/AST/Expr.h"
165350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek#include "clang/AST/ExprObjC.h"
179b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
189b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
1980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
209b663716449b618ba0390b1dbebc54fa8e971124Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
21681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
238fe83e1df954d72c0f4ffc15d20a5222ec151c21Benjamin Kramer#include "llvm/ADT/SmallString.h"
2485e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose#include "llvm/ADT/StringExtras.h"
25a93d0f280693b8418bc88cf7a8c93325f7fcf4c6Benjamin Kramer#include "llvm/Support/raw_ostream.h"
265350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
275350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenekusing namespace clang;
289ef6537a894c33003359b1f9b9676e9178e028b7Ted Kremenekusing namespace ento;
295350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
30cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaksusing llvm::FoldingSetNodeID;
31cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
325350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===//
335350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek// Utility functions.
345350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===//
355350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
369b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaksbool bugreporter::isDeclRefExprToReference(const Expr *E) {
379b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E)) {
389b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks    return DRE->getDecl()->getType()->isReferenceType();
399b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks  }
409b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks  return false;
419b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks}
429b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks
43dede2fd56d053a114a65ba72583981ce7aab27daJordan Roseconst Expr *bugreporter::getDerefExpr(const Stmt *S) {
445350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  // Pattern match for a few useful cases (do something smarter later):
455350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  //   a[0], p->f, *p
46dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose  const Expr *E = dyn_cast<Expr>(S);
47dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose  if (!E)
483682f1ea9c7fddc7dcbc590891158ba40f7fca16Jordan Rose    return 0;
49dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose  E = E->IgnoreParenCasts();
501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek  while (true) {
52dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose    if (const BinaryOperator *B = dyn_cast<BinaryOperator>(E)) {
5311abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      assert(B->isAssignmentOp());
54dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose      E = B->getLHS()->IgnoreParenCasts();
5511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      continue;
5611abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    }
57dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose    else if (const UnaryOperator *U = dyn_cast<UnaryOperator>(E)) {
5811abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      if (U->getOpcode() == UO_Deref)
5911abcecc8c919673237cf37384290a1ef1943976Ted Kremenek        return U->getSubExpr()->IgnoreParenCasts();
6011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    }
61dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose    else if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
629b925ac059089dfe74e3b8fa5effe519fb9ee885Anna Zaks      if (ME->isArrow() || isDeclRefExprToReference(ME->getBase())) {
63d91696e8680bbe89df1076fded1bc54104526060Anna Zaks        return ME->getBase()->IgnoreParenCasts();
64d91696e8680bbe89df1076fded1bc54104526060Anna Zaks      }
6511abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    }
66dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose    else if (const ObjCIvarRefExpr *IvarRef = dyn_cast<ObjCIvarRefExpr>(E)) {
67991bcb4370fe849603346ebbddc8dd47bc29d235Jordan Rose      return IvarRef->getBase()->IgnoreParenCasts();
68991bcb4370fe849603346ebbddc8dd47bc29d235Jordan Rose    }
69dede2fd56d053a114a65ba72583981ce7aab27daJordan Rose    else if (const ArraySubscriptExpr *AE = dyn_cast<ArraySubscriptExpr>(E)) {
7011abcecc8c919673237cf37384290a1ef1943976Ted Kremenek      return AE->getBase();
7111abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    }
7211abcecc8c919673237cf37384290a1ef1943976Ted Kremenek    break;
735350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  }
741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  return NULL;
765350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek}
775350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
785a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisconst Stmt *bugreporter::GetDenomExpr(const ExplodedNode *N) {
796403b57eda05a22273d920ad0bd2991d11eaa7b8Zhongxing Xu  const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
805350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
815350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    return BE->getRHS();
825350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  return NULL;
835350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek}
845350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
855a4f98ff943e6a501b0fe47ade007c9bbf96cb88Argyrios Kyrtzidisconst Stmt *bugreporter::GetRetValExpr(const ExplodedNode *N) {
865350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
875350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  if (const ReturnStmt *RS = dyn_cast<ReturnStmt>(S))
885350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    return RS->getRetValue();
895350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  return NULL;
905350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek}
915350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
925350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===//
935350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek// Definitions for bug reporter visitors.
945350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek//===----------------------------------------------------------------------===//
9523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
9623f395ee1bf4e4aa76b310d896a951799eaca94aAnna ZaksPathDiagnosticPiece*
9723f395ee1bf4e4aa76b310d896a951799eaca94aAnna ZaksBugReporterVisitor::getEndPath(BugReporterContext &BRC,
9823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                               const ExplodedNode *EndPathNode,
9923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                               BugReport &BR) {
10023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  return 0;
10123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks}
10223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
10323f395ee1bf4e4aa76b310d896a951799eaca94aAnna ZaksPathDiagnosticPiece*
10423f395ee1bf4e4aa76b310d896a951799eaca94aAnna ZaksBugReporterVisitor::getDefaultEndPath(BugReporterContext &BRC,
10523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                      const ExplodedNode *EndPathNode,
10623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks                                      BugReport &BR) {
1075a0917d1367115d5fddfe7551f8634759217b54bAnna Zaks  PathDiagnosticLocation L =
1085a0917d1367115d5fddfe7551f8634759217b54bAnna Zaks    PathDiagnosticLocation::createEndOfPath(EndPathNode,BRC.getSourceManager());
10923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
11023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  BugReport::ranges_iterator Beg, End;
11123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  llvm::tie(Beg, End) = BR.getRanges();
11223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
11323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  // Only add the statement itself as a range if we didn't specify any
11423f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  // special ranges for this report.
11523f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  PathDiagnosticPiece *P = new PathDiagnosticEventPiece(L,
11623f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks      BR.getDescription(),
11723f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks      Beg == End);
11823f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  for (; Beg != End; ++Beg)
11923f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks    P->addRange(*Beg);
12023f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
12123f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks  return P;
12223f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks}
12323f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
12423f395ee1bf4e4aa76b310d896a951799eaca94aAnna Zaks
1257aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rosenamespace {
1267aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose/// Emits an extra note at the return statement of an interesting stack frame.
1277aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose///
1287aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose/// The returned value is marked as an interesting value, and if it's null,
1297aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose/// adds a visitor to track where it became null.
1307aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose///
1317aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose/// This visitor is intended to be used when another visitor discovers that an
1327aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose/// interesting value comes from an inlined function call.
1337aba1171b32265b2206f3fa8f8886953051b58f5Jordan Roseclass ReturnVisitor : public BugReporterVisitorImpl<ReturnVisitor> {
1347aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  const StackFrameContext *StackFrame;
1356a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  enum {
1366a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    Initial,
1378c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    MaybeUnsuppress,
1386a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    Satisfied
1396a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  } Mode;
140aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks
141aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks  bool EnableNullFPSuppression;
1426a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
1437aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rosepublic:
1448c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose  ReturnVisitor(const StackFrameContext *Frame, bool Suppressed)
145aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    : StackFrame(Frame), Mode(Initial), EnableNullFPSuppression(Suppressed) {}
1467aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
147b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  static void *getTag() {
1487aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    static int Tag = 0;
149b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    return static_cast<void *>(&Tag);
150b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  }
151b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
152b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose  virtual void Profile(llvm::FoldingSetNodeID &ID) const {
153b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    ID.AddPointer(ReturnVisitor::getTag());
1547aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    ID.AddPointer(StackFrame);
155aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    ID.AddBoolean(EnableNullFPSuppression);
1567aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  }
1577aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
1587aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  /// Adds a ReturnVisitor if the given statement represents a call that was
1597aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  /// inlined.
1607aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  ///
1617aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  /// This will search back through the ExplodedGraph, starting from the given
1627aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  /// node, looking for when the given statement was processed. If it turns out
1637aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  /// the statement is a call that was inlined, we add the visitor to the
1647aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  /// bug report, so it can print a note later.
1657aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  static void addVisitorIfNecessary(const ExplodedNode *Node, const Stmt *S,
166aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                    BugReport &BR,
167aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                    bool InEnableNullFPSuppression) {
1687aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    if (!CallEvent::isCallStmt(S))
1697aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      return;
1707aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
1717aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // First, find when we processed the statement.
1727aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    do {
1737a95de68c093991047ed8d339479ccad51b88663David Blaikie      if (Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>())
1747aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose        if (CEE->getCalleeContext()->getCallSite() == S)
1757aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose          break;
1767a95de68c093991047ed8d339479ccad51b88663David Blaikie      if (Optional<StmtPoint> SP = Node->getLocationAs<StmtPoint>())
1777aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose        if (SP->getStmt() == S)
1787aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose          break;
1797aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
1807aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      Node = Node->getFirstPred();
1817aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    } while (Node);
1827aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
1837aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // Next, step over any post-statement checks.
1847a95de68c093991047ed8d339479ccad51b88663David Blaikie    while (Node && Node->getLocation().getAs<PostStmt>())
1857aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      Node = Node->getFirstPred();
1868c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    if (!Node)
1878c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      return;
1887aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
1897aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // Finally, see if we inlined the call.
1908c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    Optional<CallExitEnd> CEE = Node->getLocationAs<CallExitEnd>();
1918c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    if (!CEE)
1928c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      return;
1938c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
1948c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    const StackFrameContext *CalleeContext = CEE->getCalleeContext();
1958c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    if (CalleeContext->getCallSite() != S)
1968c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      return;
1978c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
1988c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    // Check the return value.
1998c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    ProgramStateRef State = Node->getState();
2008c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    SVal RetVal = State->getSVal(S, Node->getLocationContext());
2018c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
2028c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    // Handle cases where a reference is returned and then immediately used.
2038c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    if (cast<Expr>(S)->isGLValue())
2048c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      if (Optional<Loc> LValue = RetVal.getAs<Loc>())
2058c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose        RetVal = State->getSVal(*LValue);
2068c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
2078c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    // See if the return value is NULL. If so, suppress the report.
2088c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    SubEngine *Eng = State->getStateManager().getOwningEngine();
2098c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    assert(Eng && "Cannot file a bug report without an owning engine");
2108c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    AnalyzerOptions &Options = Eng->getAnalysisManager().options;
2118c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
212aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    bool EnableNullFPSuppression = false;
213aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    if (InEnableNullFPSuppression && Options.shouldSuppressNullReturnPaths())
2148c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      if (Optional<Loc> RetLoc = RetVal.getAs<Loc>())
215aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks        EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
2168c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
2178c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    BR.markInteresting(CalleeContext);
218aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    BR.addVisitor(new ReturnVisitor(CalleeContext, EnableNullFPSuppression));
2197aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  }
2207aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2216a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  /// Returns true if any counter-suppression heuristics are enabled for
2226a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  /// ReturnVisitor.
2236a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  static bool hasCounterSuppression(AnalyzerOptions &Options) {
2246a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return Options.shouldAvoidSuppressingNullArgumentPaths();
2256a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  }
2267aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2276a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  PathDiagnosticPiece *visitNodeInitial(const ExplodedNode *N,
2286a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                                        const ExplodedNode *PrevN,
2296a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                                        BugReporterContext &BRC,
2306a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                                        BugReport &BR) {
2317aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // Only print a message at the interesting return statement.
2327aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    if (N->getLocationContext() != StackFrame)
2337aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      return 0;
2347aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2357a95de68c093991047ed8d339479ccad51b88663David Blaikie    Optional<StmtPoint> SP = N->getLocationAs<StmtPoint>();
2367aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    if (!SP)
2377aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      return 0;
2387aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2397aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    const ReturnStmt *Ret = dyn_cast<ReturnStmt>(SP->getStmt());
2407aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    if (!Ret)
2417aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      return 0;
2427aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2437aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // Okay, we're at the right return statement, but do we have the return
2447aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // value available?
2457aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    ProgramStateRef State = N->getState();
2467aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    SVal V = State->getSVal(Ret, StackFrame);
2477aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    if (V.isUnknownOrUndef())
2487aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      return 0;
2497aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2507aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    // Don't print any more notes after this one.
2516a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    Mode = Satisfied;
2527aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
2539abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    const Expr *RetE = Ret->getRetValue();
2549abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    assert(RetE && "Tracking a return value for a void function");
2559abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose
2569abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    // Handle cases where a reference is returned and then immediately used.
2579abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    Optional<Loc> LValue;
2589abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    if (RetE->isGLValue()) {
2599abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose      if ((LValue = V.getAs<Loc>())) {
2609abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose        SVal RValue = State->getRawSVal(*LValue, RetE->getType());
2619abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose        if (RValue.getAs<DefinedSVal>())
2629abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose          V = RValue;
2639abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose      }
2649abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    }
2659abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose
266deb8f5d533b7bcd962976ecdbc1464fe754b6de0Jordan Rose    // Ignore aggregate rvalues.
267deb8f5d533b7bcd962976ecdbc1464fe754b6de0Jordan Rose    if (V.getAs<nonloc::LazyCompoundVal>() ||
268deb8f5d533b7bcd962976ecdbc1464fe754b6de0Jordan Rose        V.getAs<nonloc::CompoundVal>())
269deb8f5d533b7bcd962976ecdbc1464fe754b6de0Jordan Rose      return 0;
270deb8f5d533b7bcd962976ecdbc1464fe754b6de0Jordan Rose
2717aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    RetE = RetE->IgnoreParenCasts();
2727aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
27353221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose    // If we can't prove the return value is 0, just mark it interesting, and
27453221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose    // make sure to track it into any further inner functions.
27585a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose    if (!State->isNull(V).isConstrainedTrue()) {
2767aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      BR.markInteresting(V);
277aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks      ReturnVisitor::addVisitorIfNecessary(N, RetE, BR,
278aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                           EnableNullFPSuppression);
27953221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose      return 0;
28053221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose    }
28153221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose
28253221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose    // If we're returning 0, we should track where that 0 came from.
283aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    bugreporter::trackNullOrUndefValue(N, RetE, BR, /*IsArg*/ false,
284aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                       EnableNullFPSuppression);
28553221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose
286b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    // Build an appropriate message based on the return value.
287b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    SmallString<64> Msg;
288b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose    llvm::raw_svector_ostream Out(Msg);
289b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
2905251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie    if (V.getAs<Loc>()) {
2918c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      // If we have counter-suppression enabled, make sure we keep visiting
2928c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      // future nodes. We want to emit a path note as well, in case
293b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose      // the report is resurrected as valid later on.
294b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose      ExprEngine &Eng = BRC.getBugReporter().getEngine();
2956a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose      AnalyzerOptions &Options = Eng.getAnalysisManager().options;
296aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks      if (EnableNullFPSuppression && hasCounterSuppression(Options))
2978c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose        Mode = MaybeUnsuppress;
298b9d4e5e3bb235f1149e99d3c833ff7cb3474c9f1Jordan Rose
29953221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose      if (RetE->getType()->isObjCObjectPointerType())
30053221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose        Out << "Returning nil";
30153221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose      else
30253221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose        Out << "Returning null pointer";
30353221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose    } else {
30453221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose      Out << "Returning zero";
3057aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    }
3067aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
3079abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    if (LValue) {
3089abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose      if (const MemRegion *MR = LValue->getAsRegion()) {
3099abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose        if (MR->canPrintPretty()) {
3109abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose          Out << " (reference to '";
3119abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose          MR->printPretty(Out);
3129abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose          Out << "')";
3139abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose        }
3149abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose      }
3159abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    } else {
3169abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose      // FIXME: We should have a more generalized location printing mechanism.
3179abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose      if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(RetE))
3189abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose        if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(DR->getDecl()))
3199abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose          Out << " (loaded from '" << *DD << "')";
3209abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    }
3217aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
3227aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    PathDiagnosticLocation L(Ret, BRC.getSourceManager(), StackFrame);
3237aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose    return new PathDiagnosticEventPiece(L, Out.str());
3247aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose  }
3256a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3268c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose  PathDiagnosticPiece *visitNodeMaybeUnsuppress(const ExplodedNode *N,
3278c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose                                                const ExplodedNode *PrevN,
3288c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose                                                BugReporterContext &BRC,
3298c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose                                                BugReport &BR) {
3308c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose#ifndef NDEBUG
3318c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    ExprEngine &Eng = BRC.getBugReporter().getEngine();
3328c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    AnalyzerOptions &Options = Eng.getAnalysisManager().options;
3338c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    assert(hasCounterSuppression(Options));
3348c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose#endif
3358c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
3366a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    // Are we at the entry node for this call?
3377a95de68c093991047ed8d339479ccad51b88663David Blaikie    Optional<CallEnter> CE = N->getLocationAs<CallEnter>();
3386a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    if (!CE)
3396a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose      return 0;
3406a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3416a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    if (CE->getCalleeContext() != StackFrame)
3426a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose      return 0;
3436a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3446a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    Mode = Satisfied;
3456a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3468c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    // Don't automatically suppress a report if one of the arguments is
3478c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    // known to be a null pointer. Instead, start tracking /that/ null
3488c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    // value back to its origin.
3498c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    ProgramStateManager &StateMgr = BRC.getStateManager();
3508c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    CallEventManager &CallMgr = StateMgr.getCallEventManager();
3518c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
3528c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    ProgramStateRef State = N->getState();
3538c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    CallEventRef<> Call = CallMgr.getCaller(StackFrame, State);
3548c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    for (unsigned I = 0, E = Call->getNumArgs(); I != E; ++I) {
3558c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      Optional<Loc> ArgV = Call->getArgSVal(I).getAs<Loc>();
3568c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      if (!ArgV)
3578c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose        continue;
3588c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
3598c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      const Expr *ArgE = Call->getArgExpr(I);
3608c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      if (!ArgE)
3618c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose        continue;
3628c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
3638c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      // Is it possible for this argument to be non-null?
36485a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose      if (!State->isNull(*ArgV).isConstrainedTrue())
3658c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose        continue;
3668c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
367aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks      if (bugreporter::trackNullOrUndefValue(N, ArgE, BR, /*IsArg=*/true,
368aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                             EnableNullFPSuppression))
3698c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose        BR.removeInvalidation(ReturnVisitor::getTag(), StackFrame);
3708c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
3718c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      // If we /can't/ track the null pointer, we should err on the side of
3728c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      // false negatives, and continue towards marking this report invalid.
3738c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      // (We will still look at the other arguments, though.)
3746a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    }
3756a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3766a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    return 0;
3776a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  }
3786a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3796a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
3806a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                                 const ExplodedNode *PrevN,
3816a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                                 BugReporterContext &BRC,
3826a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose                                 BugReport &BR) {
3836a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    switch (Mode) {
3846a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    case Initial:
3856a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose      return visitNodeInitial(N, PrevN, BRC, BR);
3868c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    case MaybeUnsuppress:
3878c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      return visitNodeMaybeUnsuppress(N, PrevN, BRC, BR);
3886a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    case Satisfied:
3896a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose      return 0;
3906a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    }
3916a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
3926a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose    llvm_unreachable("Invalid visit mode!");
3936a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  }
3948c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose
3958c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose  PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
3968c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose                                  const ExplodedNode *N,
3978c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose                                  BugReport &BR) {
398aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    if (EnableNullFPSuppression)
3998c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose      BR.markInvalid(ReturnVisitor::getTag(), StackFrame);
4008c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose    return 0;
4018c84707fd0fbe9f6f7d17fadd5a9fe162dff8445Jordan Rose  }
4027aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose};
4037aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose} // end anonymous namespace
4047aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
4057aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
40650bbc165b063155cc23c360deb7b865502e068e2Anna Zaksvoid FindLastStoreBRVisitor ::Profile(llvm::FoldingSetNodeID &ID) const {
40750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  static int tag = 0;
40850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ID.AddPointer(&tag);
40950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ID.AddPointer(R);
41050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ID.Add(V);
411aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks  ID.AddBoolean(EnableNullFPSuppression);
41250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}
4135350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
414166b7bd43551964d65bcf4918f51a167b8374e2aJordan RosePathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
415166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose                                                       const ExplodedNode *Pred,
416166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose                                                       BugReporterContext &BRC,
417166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose                                                       BugReport &BR) {
4181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4190dd15d78fb0c99faa5df724139ba4c16a9a345c6Ted Kremenek  if (Satisfied)
42050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    return NULL;
4210f2c907b2b5ee8896f5f0c51e35f80447b49b2c0Daniel Dunbar
422166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  const ExplodedNode *StoreSite = 0;
423166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  const Expr *InitE = 0;
42409f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose  bool IsParam = false;
4251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
426166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  // First see if we reached the declaration of the region.
427166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
4287a95de68c093991047ed8d339479ccad51b88663David Blaikie    if (Optional<PostStmt> P = Pred->getLocationAs<PostStmt>()) {
429166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose      if (const DeclStmt *DS = P->getStmtAs<DeclStmt>()) {
430166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose        if (DS->getSingleDecl() == VR->getDecl()) {
431166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose          StoreSite = Pred;
432166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose          InitE = VR->getDecl()->getInit();
4337aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose        }
4347aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose      }
4355350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    }
436166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  }
4371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
4386f4160828db75f36b22a204da202723c592644f3Jordan Rose  // Otherwise, see if this is the store site:
4396f4160828db75f36b22a204da202723c592644f3Jordan Rose  // (1) Succ has this binding and Pred does not, i.e. this is
4406f4160828db75f36b22a204da202723c592644f3Jordan Rose  //     where the binding first occurred.
4416f4160828db75f36b22a204da202723c592644f3Jordan Rose  // (2) Succ has this binding and is a PostStore node for this region, i.e.
4426f4160828db75f36b22a204da202723c592644f3Jordan Rose  //     the same binding was re-assigned here.
443166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  if (!StoreSite) {
444166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose    if (Succ->getState()->getSVal(R) != V)
445166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose      return NULL;
4466f4160828db75f36b22a204da202723c592644f3Jordan Rose
4476f4160828db75f36b22a204da202723c592644f3Jordan Rose    if (Pred->getState()->getSVal(R) == V) {
4486f4160828db75f36b22a204da202723c592644f3Jordan Rose      Optional<PostStore> PS = Succ->getLocationAs<PostStore>();
4496f4160828db75f36b22a204da202723c592644f3Jordan Rose      if (!PS || PS->getLocationValue() != R)
4506f4160828db75f36b22a204da202723c592644f3Jordan Rose        return NULL;
4516f4160828db75f36b22a204da202723c592644f3Jordan Rose    }
4521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
453166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose    StoreSite = Succ;
4547aba1171b32265b2206f3fa8f8886953051b58f5Jordan Rose
455166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose    // If this is an assignment expression, we can track the value
456166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose    // being assigned.
4577a95de68c093991047ed8d339479ccad51b88663David Blaikie    if (Optional<PostStmt> P = Succ->getLocationAs<PostStmt>())
458166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose      if (const BinaryOperator *BO = P->getStmtAs<BinaryOperator>())
459166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose        if (BO->isAssignmentOp())
460166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose          InitE = BO->getRHS();
46185e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose
46285e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    // If this is a call entry, the variable should be a parameter.
46385e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    // FIXME: Handle CXXThisRegion as well. (This is not a priority because
46485e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    // 'this' should never be NULL, but this visitor isn't just for NULL and
46585e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    // UndefinedVal.)
4667a95de68c093991047ed8d339479ccad51b88663David Blaikie    if (Optional<CallEnter> CE = Succ->getLocationAs<CallEnter>()) {
4676c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
4686c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
4696c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek
4706c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        ProgramStateManager &StateMgr = BRC.getStateManager();
4716c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        CallEventManager &CallMgr = StateMgr.getCallEventManager();
4726c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek
4736c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        CallEventRef<> Call = CallMgr.getCaller(CE->getCalleeContext(),
4746c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek                                                Succ->getState());
4756c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        InitE = Call->getArgExpr(Param->getFunctionScopeIndex());
4766c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        IsParam = true;
4776c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      }
47885e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    }
4796022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks
4806022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    // If this is a CXXTempObjectRegion, the Expr responsible for its creation
4816022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    // is wrapped inside of it.
4826022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    if (const CXXTempObjectRegion *TmpR = dyn_cast<CXXTempObjectRegion>(R))
4836022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      InitE = TmpR->getExpr();
48450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  }
4851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
486166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  if (!StoreSite)
48750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    return NULL;
4880dd15d78fb0c99faa5df724139ba4c16a9a345c6Ted Kremenek  Satisfied = true;
489166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose
49053221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose  // If we have an expression that provided the value, try to track where it
49153221da865144db0ba6bd89ab30bcf81de0fe5d2Jordan Rose  // came from.
492166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  if (InitE) {
4935251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie    if (V.isUndef() || V.getAs<loc::ConcreteInt>()) {
49409f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose      if (!IsParam)
49509f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose        InitE = InitE->IgnoreParenCasts();
496aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks      bugreporter::trackNullOrUndefValue(StoreSite, InitE, BR, IsParam,
497aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                         EnableNullFPSuppression);
49809f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose    } else {
49909f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose      ReturnVisitor::addVisitorIfNecessary(StoreSite, InitE->IgnoreParenCasts(),
500aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                           BR, EnableNullFPSuppression);
50109f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose    }
502166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  }
503166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose
50485e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose  if (!R->canPrintPretty())
50585e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    return 0;
50685e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose
507166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  // Okay, we've found the binding. Emit an appropriate message.
508f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> sbuf;
50950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  llvm::raw_svector_ostream os(sbuf);
5101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5117a95de68c093991047ed8d339479ccad51b88663David Blaikie  if (Optional<PostStmt> PS = StoreSite->getLocationAs<PostStmt>()) {
5125846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    const Stmt *S = PS->getStmt();
5135846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    const char *action = 0;
5145846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    const DeclStmt *DS = dyn_cast<DeclStmt>(S);
5155846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    const VarRegion *VR = dyn_cast<VarRegion>(R);
5165846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek
5175846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    if (DS) {
5185846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek      action = "initialized to ";
5195846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    } else if (isa<BlockExpr>(S)) {
5205846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek      action = "captured by block as ";
5215846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek      if (VR) {
5225846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        // See if we can get the BlockVarRegion.
5235846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        ProgramStateRef State = StoreSite->getState();
5245846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        SVal V = State->getSVal(S, PS->getLocationContext());
5255846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        if (const BlockDataRegion *BDR =
5265846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek              dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
5275846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek          if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
5280dd15d78fb0c99faa5df724139ba4c16a9a345c6Ted Kremenek            if (Optional<KnownSVal> KV =
5290dd15d78fb0c99faa5df724139ba4c16a9a345c6Ted Kremenek                State->getSVal(OriginalR).getAs<KnownSVal>())
530aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks              BR.addVisitor(new FindLastStoreBRVisitor(*KV, OriginalR,
531aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                                      EnableNullFPSuppression));
5325846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek          }
5335846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        }
5345350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek      }
5355846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    }
5365846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek
5375846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek    if (action) {
5385846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek      if (!R)
5395846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        return 0;
5405846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek
5414238f41d484729aca260140fbbc53a68769bf60aTed Kremenek      os << '\'';
5424238f41d484729aca260140fbbc53a68769bf60aTed Kremenek      R->printPretty(os);
5434238f41d484729aca260140fbbc53a68769bf60aTed Kremenek      os << "' ";
5441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5455251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie      if (V.getAs<loc::ConcreteInt>()) {
5465350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        bool b = false;
5475350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        if (R->isBoundable()) {
5489697934650354bed2e509d8e7e44f21a1fb00f76Ted Kremenek          if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
549018220c343c103b7dfaa117a7a474c7a7fd6d068Zhongxing Xu            if (TR->getValueType()->isObjCObjectPointerType()) {
5505846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek              os << action << "nil";
5515350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek              b = true;
5525350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek            }
5535350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek          }
5545350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        }
5551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
5565350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek        if (!b)
5575846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek          os << action << "a null pointer value";
558dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie      } else if (Optional<nonloc::ConcreteInt> CVal =
5595251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie                     V.getAs<nonloc::ConcreteInt>()) {
5605251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie        os << action << CVal->getValue();
561592362b46ad69db0db0988e7f9d8cbe647510bddTed Kremenek      }
5625846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek      else if (DS) {
5635846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        if (V.isUndef()) {
5645846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek          if (isa<VarRegion>(R)) {
5655846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek            const VarDecl *VD = cast<VarDecl>(DS->getSingleDecl());
5665846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek            if (VD->getInit())
5675846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek              os << "initialized to a garbage value";
5685846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek            else
5695846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek              os << "declared without an initial value";
5705846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek          }
5715846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        }
5725846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek        else {
5735846720f08a6b225484bfe663599c2b057a99bc8Ted Kremenek          os << "initialized here";
57450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks        }
575685379965c1b105ce89cf4f6c60810932b7f4d0dJordan Rose      }
5765350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    }
5777a95de68c093991047ed8d339479ccad51b88663David Blaikie  } else if (StoreSite->getLocation().getAs<CallEnter>()) {
5786c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek    if (const VarRegion *VR = dyn_cast<VarRegion>(R)) {
5796c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      const ParmVarDecl *Param = cast<ParmVarDecl>(VR->getDecl());
58085e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose
5816c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      os << "Passing ";
58285e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose
5836c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      if (V.getAs<loc::ConcreteInt>()) {
5846c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        if (Param->getType()->isObjCObjectPointerType())
5856c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek          os << "nil object reference";
5866c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        else
5876c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek          os << "null pointer value";
5886c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      } else if (V.isUndef()) {
5896c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        os << "uninitialized value";
5906c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      } else if (Optional<nonloc::ConcreteInt> CI =
5916c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek                     V.getAs<nonloc::ConcreteInt>()) {
5926c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        os << "the value " << CI->getValue();
5936c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      } else {
5946c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek        os << "value";
5956c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      }
59685e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose
5976c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      // Printed parameter indexes are 1-based, not 0-based.
5986c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      unsigned Idx = Param->getFunctionScopeIndex() + 1;
5996c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      os << " via " << Idx << llvm::getOrdinalSuffix(Idx) << " parameter '";
60085e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose
6016c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      R->printPretty(os);
6026c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek      os << '\'';
6036c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek    }
60450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  }
6051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
60650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  if (os.str().empty()) {
6075251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie    if (V.getAs<loc::ConcreteInt>()) {
60850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      bool b = false;
60950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      if (R->isBoundable()) {
61050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks        if (const TypedValueRegion *TR = dyn_cast<TypedValueRegion>(R)) {
61150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks          if (TR->getValueType()->isObjCObjectPointerType()) {
61250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks            os << "nil object reference stored to ";
61350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks            b = true;
61450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks          }
61550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks        }
61650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      }
6171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      if (!b)
61950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks        os << "Null pointer value stored to ";
6205350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    }
62150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    else if (V.isUndef()) {
62250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      os << "Uninitialized value stored to ";
623dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie    } else if (Optional<nonloc::ConcreteInt> CV =
6245251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie                   V.getAs<nonloc::ConcreteInt>()) {
6255251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie      os << "The value " << CV->getValue() << " is assigned to ";
62650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    }
62750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    else
628685379965c1b105ce89cf4f6c60810932b7f4d0dJordan Rose      os << "Value assigned to ";
6291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
63085e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    os << '\'';
63185e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    R->printPretty(os);
63285e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    os << '\'';
6335350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  }
6345350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
6354fdf97bf51d2a156cec3232efd6dae110aa02aa0Anna Zaks  // Construct a new PathDiagnosticPiece.
636166b7bd43551964d65bcf4918f51a167b8374e2aJordan Rose  ProgramPoint P = StoreSite->getLocation();
63785e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose  PathDiagnosticLocation L;
6386c5038cf8486d92ae53bf4513141bd40a5ae0734Ted Kremenek  if (P.getAs<CallEnter>() && InitE)
63985e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    L = PathDiagnosticLocation(InitE, BRC.getSourceManager(),
64085e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose                               P.getLocationContext());
64185e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose  else
64285e99373835fe1b4cec624bc48dc8dfe14c2a783Jordan Rose    L = PathDiagnosticLocation::create(P, BRC.getSourceManager());
6434fdf97bf51d2a156cec3232efd6dae110aa02aa0Anna Zaks  if (!L.isValid())
64450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    return NULL;
64550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  return new PathDiagnosticEventPiece(L, os.str());
64650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}
6470f2c907b2b5ee8896f5f0c51e35f80447b49b2c0Daniel Dunbar
64850bbc165b063155cc23c360deb7b865502e068e2Anna Zaksvoid TrackConstraintBRVisitor::Profile(llvm::FoldingSetNodeID &ID) const {
64950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  static int tag = 0;
65050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ID.AddPointer(&tag);
65150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ID.AddBoolean(Assumption);
65250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  ID.Add(Constraint);
65350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}
6541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
655b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek/// Return the tag associated with this visitor.  This tag will be used
656b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek/// to make all PathDiagnosticPieces created by this visitor.
657b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenekconst char *TrackConstraintBRVisitor::getTag() {
658b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  return "TrackConstraintBRVisitor";
659b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek}
660b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
66185a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rosebool TrackConstraintBRVisitor::isUnderconstrained(const ExplodedNode *N) const {
66285a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose  if (IsZeroCheck)
66385a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose    return N->getState()->isNull(Constraint).isUnderconstrained();
66485a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose  return N->getState()->assume(Constraint, !Assumption);
66585a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose}
66685a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose
66750bbc165b063155cc23c360deb7b865502e068e2Anna ZaksPathDiagnosticPiece *
66850bbc165b063155cc23c360deb7b865502e068e2Anna ZaksTrackConstraintBRVisitor::VisitNode(const ExplodedNode *N,
66950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                    const ExplodedNode *PrevN,
67050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                    BugReporterContext &BRC,
67150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                    BugReport &BR) {
67285a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose  if (IsSatisfied)
67350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    return NULL;
6741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  // Check if in the previous state it was feasible for this constraint
67650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  // to *not* be true.
67785a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose  if (isUnderconstrained(PrevN)) {
6781eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
67985a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose    IsSatisfied = true;
6801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // As a sanity check, make sure that the negation of the constraint
68250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // was infeasible in the current state.  If it is feasible, we somehow
68350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // missed the transition point.
68485a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose    if (isUnderconstrained(N))
68550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      return NULL;
6861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
68750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // We found the transition point for the constraint.  We now need to
68850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    // pretty-print the constraint. (work-in-progress)
68985a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose    SmallString<64> sbuf;
69085a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose    llvm::raw_svector_ostream os(sbuf);
6911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
6925251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie    if (Constraint.getAs<Loc>()) {
69350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      os << "Assuming pointer value is ";
69450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      os << (Assumption ? "non-null" : "null");
69550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    }
6961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
69750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    if (os.str().empty())
69850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      return NULL;
69950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks
7004fdf97bf51d2a156cec3232efd6dae110aa02aa0Anna Zaks    // Construct a new PathDiagnosticPiece.
70150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    ProgramPoint P = N->getLocation();
7021531bb0c69d9afff6a6434e4cadf345eb628b287Anna Zaks    PathDiagnosticLocation L =
7031531bb0c69d9afff6a6434e4cadf345eb628b287Anna Zaks      PathDiagnosticLocation::create(P, BRC.getSourceManager());
7044fdf97bf51d2a156cec3232efd6dae110aa02aa0Anna Zaks    if (!L.isValid())
70550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      return NULL;
706b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
707b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    PathDiagnosticEventPiece *X = new PathDiagnosticEventPiece(L, os.str());
708b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    X->setTag(getTag());
709b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    return X;
7101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  }
7115350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
71250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  return NULL;
7135350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek}
7145350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek
715cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna ZaksSuppressInlineDefensiveChecksVisitor::
716cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna ZaksSuppressInlineDefensiveChecksVisitor(DefinedSVal Value, const ExplodedNode *N)
717a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks  : V(Value), IsSatisfied(false), IsTrackingTurnedOn(false) {
718f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks
719f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks    // Check if the visitor is disabled.
720f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks    SubEngine *Eng = N->getState()->getStateManager().getOwningEngine();
721f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks    assert(Eng && "Cannot file a bug report without an owning engine");
722f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks    AnalyzerOptions &Options = Eng->getAnalysisManager().options;
723f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks    if (!Options.shouldSuppressInlinedDefensiveChecks())
724f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks      IsSatisfied = true;
725f8ba81e8bbc4d0d424c3b4c3581a9467e972c4deAnna Zaks
726a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks    assert(N->getState()->isNull(V).isConstrainedTrue() &&
727a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks           "The visitor only tracks the cases where V is constrained to 0");
728cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks}
729cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
730cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaksvoid SuppressInlineDefensiveChecksVisitor::Profile(FoldingSetNodeID &ID) const {
731cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  static int id = 0;
732cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  ID.AddPointer(&id);
733cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  ID.Add(V);
734cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks}
735cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
736cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaksconst char *SuppressInlineDefensiveChecksVisitor::getTag() {
737cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  return "IDCVisitor";
738cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks}
739cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
740cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna ZaksPathDiagnosticPiece *
7410415998dd77986630efe8f1aed633519cc41e1f3Anna ZaksSuppressInlineDefensiveChecksVisitor::VisitNode(const ExplodedNode *Succ,
7420415998dd77986630efe8f1aed633519cc41e1f3Anna Zaks                                                const ExplodedNode *Pred,
743cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks                                                BugReporterContext &BRC,
744cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks                                                BugReport &BR) {
745cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  if (IsSatisfied)
746cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks    return 0;
747713e07591995d761f65c7132289dce003a29870fAnna Zaks
748a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks  // Start tracking after we see the first state in which the value is null.
749a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks  if (!IsTrackingTurnedOn)
750a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks    if (Succ->getState()->isNull(V).isConstrainedTrue())
751a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks      IsTrackingTurnedOn = true;
752a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks  if (!IsTrackingTurnedOn)
753a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks    return 0;
754a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks
755cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  // Check if in the previous state it was feasible for this value
756cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  // to *not* be null.
757810169e7a1f858a787d2db050deebaee7e10c97fAnna Zaks  if (!Pred->getState()->isNull(V).isConstrainedTrue()) {
758cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks    IsSatisfied = true;
759cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
760810169e7a1f858a787d2db050deebaee7e10c97fAnna Zaks    assert(Succ->getState()->isNull(V).isConstrainedTrue());
761cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
7620415998dd77986630efe8f1aed633519cc41e1f3Anna Zaks    // Check if this is inlined defensive checks.
7630415998dd77986630efe8f1aed633519cc41e1f3Anna Zaks    const LocationContext *CurLC =Succ->getLocationContext();
764cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks    const LocationContext *ReportLC = BR.getErrorNode()->getLocationContext();
765cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks    if (CurLC != ReportLC && !CurLC->isParentOf(ReportLC))
766cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks      BR.markInvalid("Suppress IDC", CurLC);
767cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  }
768cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks  return 0;
769cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks}
770cc5dbdae70c6eb2423921f52a35ba4686d2969cfAnna Zaks
7716022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaksstatic const MemRegion *getLocationRegionIfReference(const Expr *E,
7726022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks                                                     const ExplodedNode *N) {
7736022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(E)) {
7746022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
7756022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      if (!VD->getType()->isReferenceType())
7766022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks        return 0;
7776022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      ProgramStateManager &StateMgr = N->getState()->getStateManager();
7786022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      MemRegionManager &MRMgr = StateMgr.getRegionManager();
7796022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      return MRMgr.getVarRegion(VD, N->getLocationContext());
7806022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    }
7816022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  }
7826022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks
7836022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  // FIXME: This does not handle other kinds of null references,
7846022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  // for example, references from FieldRegions:
7856022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  //   struct Wrapper { int &ref; };
7866022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  //   Wrapper w = { *(int *)0 };
7876022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  //   w.ref = 1;
7886022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks
7896022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks  return 0;
7906022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks}
7916022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks
792cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaksstatic const Expr *peelOffOuterExpr(const Expr *Ex,
7931533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks                                    const ExplodedNode *N) {
794cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  Ex = Ex->IgnoreParenCasts();
795cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  if (const ExprWithCleanups *EWC = dyn_cast<ExprWithCleanups>(Ex))
796cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks    return peelOffOuterExpr(EWC->getSubExpr(), N);
797cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(Ex))
798cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks    return peelOffOuterExpr(OVE->getSourceExpr(), N);
799cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks
800cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  // Peel off the ternary operator.
801cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  if (const ConditionalOperator *CO = dyn_cast<ConditionalOperator>(Ex)) {
802702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks    // Find a node where the branching occured and find out which branch
803702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks    // we took (true/false) by looking at the ExplodedGraph.
804702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks    const ExplodedNode *NI = N;
805cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks    do {
806702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks      ProgramPoint ProgPoint = NI->getLocation();
807702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks      if (Optional<BlockEdge> BE = ProgPoint.getAs<BlockEdge>()) {
808702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks        const CFGBlock *srcBlk = BE->getSrc();
809702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks        if (const Stmt *term = srcBlk->getTerminator()) {
810702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks          if (term == CO) {
811702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks            bool TookTrueBranch = (*(srcBlk->succ_begin()) == BE->getDst());
812702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks            if (TookTrueBranch)
813702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks              return peelOffOuterExpr(CO->getTrueExpr(), N);
814702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks            else
815702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks              return peelOffOuterExpr(CO->getFalseExpr(), N);
816702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks          }
817702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks        }
818cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks      }
819702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks      NI = NI->getFirstPred();
820702077f14100f2d7acdb12ad49b53e64efc37d72Anna Zaks    } while (NI);
821dc9c160dede7e2f5cc11755db6aaa57e7fccbcecAnna Zaks  }
822cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  return Ex;
8231533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks}
8241533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks
8251533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaksbool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
8261533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks                                        const Stmt *S,
827aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                        BugReport &report, bool IsArg,
828aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                        bool EnableNullFPSuppression) {
8291533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks  if (!S || !N)
8301533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks    return false;
8311533833e21ae5b3f5f39b168b3fbac109ee77008Anna Zaks
832cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  if (const Expr *Ex = dyn_cast<Expr>(S)) {
833cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks    Ex = Ex->IgnoreParenCasts();
834cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks    const Expr *PeeledEx = peelOffOuterExpr(Ex, N);
835cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks    if (Ex != PeeledEx)
836cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks      S = PeeledEx;
837cabc3fddae63f5eb3bd44bdecce7a3fbd69421a9Anna Zaks  }
8380415998dd77986630efe8f1aed633519cc41e1f3Anna Zaks
83977b72231a0316509cc939b052be35fafce606567Jordan Rose  const Expr *Inner = 0;
8400183768813658d419e3124b576744b03ec8e9b55Jordan Rose  if (const Expr *Ex = dyn_cast<Expr>(S)) {
8410183768813658d419e3124b576744b03ec8e9b55Jordan Rose    Ex = Ex->IgnoreParenCasts();
84277b72231a0316509cc939b052be35fafce606567Jordan Rose    if (ExplodedGraph::isInterestingLValueExpr(Ex) || CallEvent::isCallStmt(Ex))
84377b72231a0316509cc939b052be35fafce606567Jordan Rose      Inner = Ex;
8440183768813658d419e3124b576744b03ec8e9b55Jordan Rose  }
8450183768813658d419e3124b576744b03ec8e9b55Jordan Rose
84609f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose  if (IsArg) {
8477a95de68c093991047ed8d339479ccad51b88663David Blaikie    assert(N->getLocation().getAs<CallEnter>() && "Tracking arg but not at call");
84809f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose  } else {
84909f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose    // Walk through nodes until we get one that matches the statement exactly.
8500183768813658d419e3124b576744b03ec8e9b55Jordan Rose    // Alternately, if we hit a known lvalue for the statement, we know we've
8510183768813658d419e3124b576744b03ec8e9b55Jordan Rose    // gone too far (though we can likely track the lvalue better anyway).
85209f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose    do {
85309f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose      const ProgramPoint &pp = N->getLocation();
8544de4715ad02aa8c9437a9e0e2854a0ccc71a3188Anna Zaks      if (Optional<StmtPoint> ps = pp.getAs<StmtPoint>()) {
85577b72231a0316509cc939b052be35fafce606567Jordan Rose        if (ps->getStmt() == S || ps->getStmt() == Inner)
85609f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose          break;
8577a95de68c093991047ed8d339479ccad51b88663David Blaikie      } else if (Optional<CallExitEnd> CEE = pp.getAs<CallExitEnd>()) {
85877b72231a0316509cc939b052be35fafce606567Jordan Rose        if (CEE->getCalleeContext()->getCallSite() == S ||
85977b72231a0316509cc939b052be35fafce606567Jordan Rose            CEE->getCalleeContext()->getCallSite() == Inner)
86009f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose          break;
86109f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose      }
86209f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose      N = N->getFirstPred();
86309f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose    } while (N);
864882998923889a2fcce9b49696506c499e22cf38fTed Kremenek
86509f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose    if (!N)
8666a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose      return false;
86709f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose  }
868882998923889a2fcce9b49696506c499e22cf38fTed Kremenek
8698bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef state = N->getState();
8701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
87184e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  // The message send could be nil due to the receiver being nil.
87284e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  // At this point in the path, the receiver should be live since we are at the
87384e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  // message send expr. If it is nil, start tracking it.
87484e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  if (const Expr *Receiver = NilReceiverBRVisitor::getNilReceiver(S, N))
87584e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks    trackNullOrUndefValue(N, Receiver, report, IsArg, EnableNullFPSuppression);
87684e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks
87784e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks
87884e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  // See if the expression we're interested refers to a variable.
879364b9f95fa47b0ca7f1cc694195f7a9953652f81Jordan Rose  // If so, we can track both its contents and constraints on its value.
88077b72231a0316509cc939b052be35fafce606567Jordan Rose  if (Inner && ExplodedGraph::isInterestingLValueExpr(Inner)) {
8810183768813658d419e3124b576744b03ec8e9b55Jordan Rose    const MemRegion *R = 0;
8820183768813658d419e3124b576744b03ec8e9b55Jordan Rose
8836022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    // Find the ExplodedNode where the lvalue (the value of 'Ex')
8846022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    // was computed.  We need this for getting the location value.
8856022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    const ExplodedNode *LVNode = N;
8866022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    while (LVNode) {
8876022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      if (Optional<PostStmt> P = LVNode->getLocation().getAs<PostStmt>()) {
8886022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks        if (P->getStmt() == Inner)
8896022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks          break;
89043b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek      }
8916022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      LVNode = LVNode->getFirstPred();
8920183768813658d419e3124b576744b03ec8e9b55Jordan Rose    }
8936022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    assert(LVNode && "Unable to find the lvalue node.");
8946022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    ProgramStateRef LVState = LVNode->getState();
8956022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    SVal LVal = LVState->getSVal(Inner, LVNode->getLocationContext());
8966022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks
8976022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    if (LVState->isNull(LVal).isConstrainedTrue()) {
8986022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // In case of C++ references, we want to differentiate between a null
8996022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // reference and reference to null pointer.
9006022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // If the LVal is null, check if we are dealing with null reference.
9016022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // For those, we want to track the location of the reference.
9026022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      if (const MemRegion *RR = getLocationRegionIfReference(Inner, N))
9036022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks        R = RR;
9046022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks    } else {
9056022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      R = LVState->getSVal(Inner, LVNode->getLocationContext()).getAsRegion();
90643b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek
9076022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // If this is a C++ reference to a null pointer, we are tracking the
9086022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // pointer. In additon, we should find the store at which the reference
9096022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      // got initialized.
9106022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks      if (const MemRegion *RR = getLocationRegionIfReference(Inner, N)) {
9116022c4e17c0d2ad9c43ef6bc830d394b670a4705Anna Zaks        if (Optional<KnownSVal> KV = LVal.getAs<KnownSVal>())
912aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks          report.addVisitor(new FindLastStoreBRVisitor(*KV, RR,
913aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                                      EnableNullFPSuppression));
91443b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek      }
9150183768813658d419e3124b576744b03ec8e9b55Jordan Rose    }
91643b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek
9170183768813658d419e3124b576744b03ec8e9b55Jordan Rose    if (R) {
9180183768813658d419e3124b576744b03ec8e9b55Jordan Rose      // Mark both the variable region and its contents as interesting.
9190183768813658d419e3124b576744b03ec8e9b55Jordan Rose      SVal V = state->getRawSVal(loc::MemRegionVal(R));
9200183768813658d419e3124b576744b03ec8e9b55Jordan Rose
9210183768813658d419e3124b576744b03ec8e9b55Jordan Rose      // If the value matches the default for the variable region, that
9220183768813658d419e3124b576744b03ec8e9b55Jordan Rose      // might mean that it's been cleared out of the state. Fall back to
9230183768813658d419e3124b576744b03ec8e9b55Jordan Rose      // the full argument expression (with casts and such intact).
9240183768813658d419e3124b576744b03ec8e9b55Jordan Rose      if (IsArg) {
9250183768813658d419e3124b576744b03ec8e9b55Jordan Rose        bool UseArgValue = V.isUnknownOrUndef() || V.isZeroConstant();
9260183768813658d419e3124b576744b03ec8e9b55Jordan Rose        if (!UseArgValue) {
9270183768813658d419e3124b576744b03ec8e9b55Jordan Rose          const SymbolRegionValue *SRV =
9280183768813658d419e3124b576744b03ec8e9b55Jordan Rose            dyn_cast_or_null<SymbolRegionValue>(V.getAsLocSymbol());
9290183768813658d419e3124b576744b03ec8e9b55Jordan Rose          if (SRV)
9300183768813658d419e3124b576744b03ec8e9b55Jordan Rose            UseArgValue = (SRV->getRegion() == R);
93109f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose        }
9320183768813658d419e3124b576744b03ec8e9b55Jordan Rose        if (UseArgValue)
9330183768813658d419e3124b576744b03ec8e9b55Jordan Rose          V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
9340183768813658d419e3124b576744b03ec8e9b55Jordan Rose      }
93509f7bf14d25bdc55cb715bc8d40600906848a409Jordan Rose
9360183768813658d419e3124b576744b03ec8e9b55Jordan Rose      report.markInteresting(R);
9370183768813658d419e3124b576744b03ec8e9b55Jordan Rose      report.markInteresting(V);
9380183768813658d419e3124b576744b03ec8e9b55Jordan Rose      report.addVisitor(new UndefOrNullArgVisitor(R));
939685379965c1b105ce89cf4f6c60810932b7f4d0dJordan Rose
9400183768813658d419e3124b576744b03ec8e9b55Jordan Rose      if (isa<SymbolicRegion>(R)) {
9410183768813658d419e3124b576744b03ec8e9b55Jordan Rose        TrackConstraintBRVisitor *VI =
9420183768813658d419e3124b576744b03ec8e9b55Jordan Rose          new TrackConstraintBRVisitor(loc::MemRegionVal(R), false);
9430183768813658d419e3124b576744b03ec8e9b55Jordan Rose        report.addVisitor(VI);
9440183768813658d419e3124b576744b03ec8e9b55Jordan Rose      }
94543b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek
9460183768813658d419e3124b576744b03ec8e9b55Jordan Rose      // If the contents are symbolic, find out when they became null.
9470183768813658d419e3124b576744b03ec8e9b55Jordan Rose      if (V.getAsLocSymbol()) {
9480183768813658d419e3124b576744b03ec8e9b55Jordan Rose        BugReporterVisitor *ConstraintTracker =
9490183768813658d419e3124b576744b03ec8e9b55Jordan Rose          new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
9500183768813658d419e3124b576744b03ec8e9b55Jordan Rose        report.addVisitor(ConstraintTracker);
9510183768813658d419e3124b576744b03ec8e9b55Jordan Rose
9520183768813658d419e3124b576744b03ec8e9b55Jordan Rose        // Add visitor, which will suppress inline defensive checks.
953aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks        if (N->getState()->isNull(V).isConstrainedTrue() &&
954aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks            EnableNullFPSuppression) {
9550183768813658d419e3124b576744b03ec8e9b55Jordan Rose          BugReporterVisitor *IDCSuppressor =
9560183768813658d419e3124b576744b03ec8e9b55Jordan Rose            new SuppressInlineDefensiveChecksVisitor(V.castAs<DefinedSVal>(),
957a4bb4f6ca8dd31ad96cb9526a5abe1273f18ff40Anna Zaks                                                     N);
9580183768813658d419e3124b576744b03ec8e9b55Jordan Rose          report.addVisitor(IDCSuppressor);
959685379965c1b105ce89cf4f6c60810932b7f4d0dJordan Rose        }
9605350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek      }
9610183768813658d419e3124b576744b03ec8e9b55Jordan Rose
9620183768813658d419e3124b576744b03ec8e9b55Jordan Rose      if (Optional<KnownSVal> KV = V.getAs<KnownSVal>())
963aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks        report.addVisitor(new FindLastStoreBRVisitor(*KV, R,
964aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                                     EnableNullFPSuppression));
9650183768813658d419e3124b576744b03ec8e9b55Jordan Rose      return true;
9665350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    }
9675350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  }
9681eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
96943b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek  // If the expression is not an "lvalue expression", we can still
97043b82b823a6113fdbee54243b280db9c55ef72cbTed Kremenek  // track the constraints on its contents.
9715eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek  SVal V = state->getSValAsScalarOrLoc(S, N->getLocationContext());
9721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
9739abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose  // If the value came from an inlined function call, we should at least make
9749abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose  // sure that function isn't pruned in our output.
9759abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose  if (const Expr *E = dyn_cast<Expr>(S))
9769abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose    S = E->IgnoreParenCasts();
977aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks
978aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks  ReturnVisitor::addVisitorIfNecessary(N, S, report, EnableNullFPSuppression);
9799abf1b4577b75ffcc46afbdfb55de334f68f05c0Jordan Rose
9805350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  // Uncomment this to find cases where we aren't properly getting the
9815350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  // base value that was dereferenced.
9825350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  // assert(!V.isUnknownOrUndef());
9835350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  // Is it a symbolic value?
984dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie  if (Optional<loc::MemRegionVal> L = V.getAs<loc::MemRegionVal>()) {
985d91696e8680bbe89df1076fded1bc54104526060Anna Zaks    // At this point we are dealing with the region's LValue.
986d91696e8680bbe89df1076fded1bc54104526060Anna Zaks    // However, if the rvalue is a symbolic region, we should track it as well.
987d91696e8680bbe89df1076fded1bc54104526060Anna Zaks    SVal RVal = state->getSVal(L->getRegion());
988d91696e8680bbe89df1076fded1bc54104526060Anna Zaks    const MemRegion *RegionRVal = RVal.getAsRegion();
989522fc21f3adc647817edc8017e6928a64c96899bAnna Zaks    report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
990522fc21f3adc647817edc8017e6928a64c96899bAnna Zaks
991d91696e8680bbe89df1076fded1bc54104526060Anna Zaks    if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
992d91696e8680bbe89df1076fded1bc54104526060Anna Zaks      report.markInteresting(RegionRVal);
993d91696e8680bbe89df1076fded1bc54104526060Anna Zaks      report.addVisitor(new TrackConstraintBRVisitor(
994d91696e8680bbe89df1076fded1bc54104526060Anna Zaks        loc::MemRegionVal(RegionRVal), false));
9955350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek    }
9965350066e7b19d17a5b137caa6c039ab9626dbfa5Ted Kremenek  }
9976a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose
9986a329ee7567cf3267ffab2bc755ea8c773d967e7Jordan Rose  return true;
99950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks}
100094fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek
100184e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaksconst Expr *NilReceiverBRVisitor::getNilReceiver(const Stmt *S,
100284e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks                                                 const ExplodedNode *N) {
1003aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks  const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S);
1004aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks  if (!ME)
1005aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks    return 0;
100684e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  if (const Expr *Receiver = ME->getInstanceReceiver()) {
100784e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks    ProgramStateRef state = N->getState();
100884e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks    SVal V = state->getSVal(Receiver, N->getLocationContext());
100984e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks    if (state->isNull(V).isConstrainedTrue())
101084e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks      return Receiver;
101184e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  }
101284e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  return 0;
101394fd0b8c88db9b1cd99457d3cd8cd333341dd39cTed Kremenek}
1014ff7f736211070be873df0a345295fd1453ee7c50Ted Kremenek
101550bbc165b063155cc23c360deb7b865502e068e2Anna ZaksPathDiagnosticPiece *NilReceiverBRVisitor::VisitNode(const ExplodedNode *N,
101650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                     const ExplodedNode *PrevN,
101750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                     BugReporterContext &BRC,
101850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                     BugReport &BR) {
10194a49df3be929d442535d6721ab8a2bbc8a7cd528Anna Zaks  Optional<PreStmt> P = N->getLocationAs<PreStmt>();
102050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  if (!P)
102150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    return 0;
1022aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks
102384e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks  const Expr *Receiver = getNilReceiver(P->getStmt(), N);
102450bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  if (!Receiver)
102550bbc165b063155cc23c360deb7b865502e068e2Anna Zaks    return 0;
102685a92cfa52ddf4c45fe2baca4d7fea0bdc5ed103Jordan Rose
102750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  // The receiver was nil, and hence the method was skipped.
102850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  // Register a BugReporterVisitor to issue a message telling us how
102950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  // the receiver was null.
1030aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks  bugreporter::trackNullOrUndefValue(N, Receiver, BR, /*IsArg*/ false,
103184e8a960ad76b3c7ca550b4cc92a1b90ed16d5c1Anna Zaks                                     /*EnableNullFPSuppression*/ false);
103250bbc165b063155cc23c360deb7b865502e068e2Anna Zaks  // Issue a message saying that the method was skipped.
1033220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks  PathDiagnosticLocation L(Receiver, BRC.getSourceManager(),
1034220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                     N->getLocationContext());
1035907344e4977ac704f248d82ef235b88be08584d5Anna Zaks  return new PathDiagnosticEventPiece(L, "No method is called "
103650bbc165b063155cc23c360deb7b865502e068e2Anna Zaks      "because the receiver is nil");
1037ff7f736211070be873df0a345295fd1453ee7c50Ted Kremenek}
10382bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10398e6431adab313e283a992698f6fc7afe62420999Anna Zaks// Registers every VarDecl inside a Stmt with a last store visitor.
104050bbc165b063155cc23c360deb7b865502e068e2Anna Zaksvoid FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
1041aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                                const Stmt *S,
1042aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                                bool EnableNullFPSuppression) {
10438e6431adab313e283a992698f6fc7afe62420999Anna Zaks  const ExplodedNode *N = BR.getErrorNode();
10442bbbe50dbaa0bf231c16333b335304655deeb26bTom Care  std::deque<const Stmt *> WorkList;
10452bbbe50dbaa0bf231c16333b335304655deeb26bTom Care  WorkList.push_back(S);
10462bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10472bbbe50dbaa0bf231c16333b335304655deeb26bTom Care  while (!WorkList.empty()) {
10482bbbe50dbaa0bf231c16333b335304655deeb26bTom Care    const Stmt *Head = WorkList.front();
10492bbbe50dbaa0bf231c16333b335304655deeb26bTom Care    WorkList.pop_front();
10502bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10518bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek    ProgramStateRef state = N->getState();
10528e6431adab313e283a992698f6fc7afe62420999Anna Zaks    ProgramStateManager &StateMgr = state->getStateManager();
10532bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10542bbbe50dbaa0bf231c16333b335304655deeb26bTom Care    if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Head)) {
10552bbbe50dbaa0bf231c16333b335304655deeb26bTom Care      if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
10562bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        const VarRegion *R =
10572bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        StateMgr.getRegionManager().getVarRegion(VD, N->getLocationContext());
10582bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10592bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        // What did we load?
10605eca482fe895ea57bc82410222e6426c09e63284Ted Kremenek        SVal V = state->getSVal(S, N->getLocationContext());
10612bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10625251abea41b446c26e3239c8dd6c7edea6fc335dDavid Blaikie        if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
106350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks          // Register a new visitor with the BugReport.
1064aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks          BR.addVisitor(new FindLastStoreBRVisitor(V.castAs<KnownSVal>(), R,
1065aabb4c5eacca6d78ef778f33ec5cd4c755d71a39Anna Zaks                                                   EnableNullFPSuppression));
10662bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        }
10672bbbe50dbaa0bf231c16333b335304655deeb26bTom Care      }
10682bbbe50dbaa0bf231c16333b335304655deeb26bTom Care    }
10692bbbe50dbaa0bf231c16333b335304655deeb26bTom Care
10702bbbe50dbaa0bf231c16333b335304655deeb26bTom Care    for (Stmt::const_child_iterator I = Head->child_begin();
10712bbbe50dbaa0bf231c16333b335304655deeb26bTom Care        I != Head->child_end(); ++I)
10722bbbe50dbaa0bf231c16333b335304655deeb26bTom Care      WorkList.push_back(*I);
10732bbbe50dbaa0bf231c16333b335304655deeb26bTom Care  }
10742bbbe50dbaa0bf231c16333b335304655deeb26bTom Care}
1075993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1076993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek//===----------------------------------------------------------------------===//
1077993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek// Visitor that tries to report interesting diagnostics from conditions.
1078993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek//===----------------------------------------------------------------------===//
1079b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
1080b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek/// Return the tag associated with this visitor.  This tag will be used
1081b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek/// to make all PathDiagnosticPieces created by this visitor.
1082b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenekconst char *ConditionBRVisitor::getTag() {
1083b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  return "ConditionBRVisitor";
1084b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek}
1085b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek
108650bbc165b063155cc23c360deb7b865502e068e2Anna ZaksPathDiagnosticPiece *ConditionBRVisitor::VisitNode(const ExplodedNode *N,
108750bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                   const ExplodedNode *Prev,
108850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                   BugReporterContext &BRC,
108950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                                   BugReport &BR) {
1090c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  PathDiagnosticPiece *piece = VisitNodeImpl(N, Prev, BRC, BR);
1091b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  if (piece) {
1092b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    piece->setTag(getTag());
1093b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek    if (PathDiagnosticEventPiece *ev=dyn_cast<PathDiagnosticEventPiece>(piece))
1094b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek      ev->setPrunable(true, /* override */ false);
1095b85cce094887ab5cf1c47acfe306e2fb1d3cfbb1Ted Kremenek  }
1096c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek  return piece;
1097c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek}
1098c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek
1099c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted KremenekPathDiagnosticPiece *ConditionBRVisitor::VisitNodeImpl(const ExplodedNode *N,
1100c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek                                                       const ExplodedNode *Prev,
1101c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek                                                       BugReporterContext &BRC,
1102c89f4b05721f53cfbaf32fc0c4919a4616e68440Ted Kremenek                                                       BugReport &BR) {
1103993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
110422505ef15e32db31a4f834a387cf73a913bc8f66Ted Kremenek  ProgramPoint progPoint = N->getLocation();
11058bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef CurrentState = N->getState();
11068bef8238181a30e52dea380789a7e2d760eac532Ted Kremenek  ProgramStateRef PrevState = Prev->getState();
1107681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1108681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  // Compare the GDMs of the state, because that is where constraints
1109681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  // are managed.  Note that ensure that we only look at nodes that
1110681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  // were generated by the analyzer engine proper, not checkers.
1111681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  if (CurrentState->getGDM().getRoot() ==
1112681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      PrevState->getGDM().getRoot())
1113681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    return 0;
1114993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1115993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  // If an assumption was made on a branch, it should be caught
1116993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  // here by looking at the state transition.
11177a95de68c093991047ed8d339479ccad51b88663David Blaikie  if (Optional<BlockEdge> BE = progPoint.getAs<BlockEdge>()) {
1118681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    const CFGBlock *srcBlk = BE->getSrc();
1119681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    if (const Stmt *term = srcBlk->getTerminator())
112076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      return VisitTerminator(term, N, srcBlk, BE->getDst(), BR, BRC);
1121681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    return 0;
1122681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  }
1123681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
11247a95de68c093991047ed8d339479ccad51b88663David Blaikie  if (Optional<PostStmt> PS = progPoint.getAs<PostStmt>()) {
1125681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    // FIXME: Assuming that BugReporter is a GRBugReporter is a layering
1126681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    // violation.
1127681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    const std::pair<const ProgramPointTag *, const ProgramPointTag *> &tags =
1128681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      cast<GRBugReporter>(BRC.getBugReporter()).
11290caa2d47b84337e942b3f6652adfafe4ae506cfeTed Kremenek        getEngine().geteagerlyAssumeBinOpBifurcationTags();
1130681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1131681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    const ProgramPointTag *tag = PS->getTag();
1132681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    if (tag == tags.first)
1133220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks      return VisitTrueTest(cast<Expr>(PS->getStmt()), true,
113476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                           BRC, BR, N);
1135681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    if (tag == tags.second)
1136220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks      return VisitTrueTest(cast<Expr>(PS->getStmt()), false,
113776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                           BRC, BR, N);
1138681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1139993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    return 0;
1140993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  }
1141993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1142993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  return 0;
1143993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek}
1144993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1145993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted KremenekPathDiagnosticPiece *
114650bbc165b063155cc23c360deb7b865502e068e2Anna ZaksConditionBRVisitor::VisitTerminator(const Stmt *Term,
1147220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                    const ExplodedNode *N,
114850bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                    const CFGBlock *srcBlk,
114950bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                    const CFGBlock *dstBlk,
115076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                    BugReport &R,
115150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                    BugReporterContext &BRC) {
1152993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  const Expr *Cond = 0;
1153993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1154993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  switch (Term->getStmtClass()) {
1155993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  default:
1156993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    return 0;
1157993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  case Stmt::IfStmtClass:
1158993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    Cond = cast<IfStmt>(Term)->getCond();
1159993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    break;
1160993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  case Stmt::ConditionalOperatorClass:
1161993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    Cond = cast<ConditionalOperator>(Term)->getCond();
1162993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    break;
1163993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  }
1164993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1165993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  assert(Cond);
1166993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  assert(srcBlk->succ_size() == 2);
1167993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  const bool tookTrue = *(srcBlk->succ_begin()) == dstBlk;
1168c47dc1b9734ea9bebb281499d58d22c2647713a9Ted Kremenek  return VisitTrueTest(Cond, tookTrue, BRC, R, N);
1169993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek}
1170993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1171993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted KremenekPathDiagnosticPiece *
117250bbc165b063155cc23c360deb7b865502e068e2Anna ZaksConditionBRVisitor::VisitTrueTest(const Expr *Cond,
117350bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                  bool tookTrue,
1174220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                  BugReporterContext &BRC,
117576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  BugReport &R,
117676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  const ExplodedNode *N) {
1177993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1178993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  const Expr *Ex = Cond;
1179993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1180681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  while (true) {
1181c47dc1b9734ea9bebb281499d58d22c2647713a9Ted Kremenek    Ex = Ex->IgnoreParenCasts();
1182993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    switch (Ex->getStmtClass()) {
1183993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek      default:
1184993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek        return 0;
1185681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      case Stmt::BinaryOperatorClass:
118676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        return VisitTrueTest(Cond, cast<BinaryOperator>(Ex), tookTrue, BRC,
118776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                             R, N);
1188993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek      case Stmt::DeclRefExprClass:
118976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        return VisitTrueTest(Cond, cast<DeclRefExpr>(Ex), tookTrue, BRC,
119076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                             R, N);
1191993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek      case Stmt::UnaryOperatorClass: {
1192993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek        const UnaryOperator *UO = cast<UnaryOperator>(Ex);
1193993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek        if (UO->getOpcode() == UO_LNot) {
1194993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek          tookTrue = !tookTrue;
1195c47dc1b9734ea9bebb281499d58d22c2647713a9Ted Kremenek          Ex = UO->getSubExpr();
1196993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek          continue;
1197993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek        }
1198993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek        return 0;
1199993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek      }
1200993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    }
1201681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  }
1202681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek}
1203681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1204cfa88f893915ceb8ae4ce2f17c46c24a4d67502fDmitri Gribenkobool ConditionBRVisitor::patternMatch(const Expr *Ex, raw_ostream &Out,
120576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                      BugReporterContext &BRC,
120676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                      BugReport &report,
120776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                      const ExplodedNode *N,
1208dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie                                      Optional<bool> &prunable) {
1209681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  const Expr *OriginalExpr = Ex;
1210681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  Ex = Ex->IgnoreParenCasts();
1211681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1212681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Ex)) {
12133b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    const bool quotes = isa<VarDecl>(DR->getDecl());
121476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    if (quotes) {
12153b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      Out << '\'';
121676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      const LocationContext *LCtx = N->getLocationContext();
121776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      const ProgramState *state = N->getState().getPtr();
121876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      if (const MemRegion *R = state->getLValue(cast<VarDecl>(DR->getDecl()),
121976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                                LCtx).getAsRegion()) {
122076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        if (report.isInteresting(R))
122176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek          prunable = false;
122276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        else {
122376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek          const ProgramState *state = N->getState().getPtr();
122476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek          SVal V = state->getSVal(R);
122576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek          if (report.isInteresting(V))
122676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek            prunable = false;
122776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        }
122876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      }
122976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    }
12303b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    Out << DR->getDecl()->getDeclName().getAsString();
12313b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    if (quotes)
12323b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      Out << '\'';
12333b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    return quotes;
1234681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  }
1235681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1236681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  if (const IntegerLiteral *IL = dyn_cast<IntegerLiteral>(Ex)) {
1237681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    QualType OriginalTy = OriginalExpr->getType();
1238681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    if (OriginalTy->isPointerType()) {
1239681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      if (IL->getValue() == 0) {
1240681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek        Out << "null";
12413b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek        return false;
1242681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      }
1243681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    }
1244681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    else if (OriginalTy->isObjCObjectPointerType()) {
1245681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      if (IL->getValue() == 0) {
1246681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek        Out << "nil";
12473b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek        return false;
1248681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      }
1249681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    }
1250681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1251681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    Out << IL->getValue();
12523b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    return false;
1253681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  }
12543b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek
12553b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek  return false;
1256681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek}
1257681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1258681bc114b51c1198cdec9a165c7d3230abb8f427Ted KremenekPathDiagnosticPiece *
125950bbc165b063155cc23c360deb7b865502e068e2Anna ZaksConditionBRVisitor::VisitTrueTest(const Expr *Cond,
126050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                  const BinaryOperator *BExpr,
126150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                  const bool tookTrue,
1262220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                  BugReporterContext &BRC,
126376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  BugReport &R,
126476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  const ExplodedNode *N) {
1265681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
12663b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek  bool shouldInvert = false;
1267dc84cd5efdd3430efb22546b4ac656aa0540b210David Blaikie  Optional<bool> shouldPrune;
12683b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek
1269f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<128> LhsString, RhsString;
1270681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  {
127176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    llvm::raw_svector_ostream OutLHS(LhsString), OutRHS(RhsString);
127276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    const bool isVarLHS = patternMatch(BExpr->getLHS(), OutLHS, BRC, R, N,
127376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                       shouldPrune);
127476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    const bool isVarRHS = patternMatch(BExpr->getRHS(), OutRHS, BRC, R, N,
127576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                       shouldPrune);
12763b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek
12773b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    shouldInvert = !isVarLHS && isVarRHS;
1278681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  }
1279681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1280d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  BinaryOperator::Opcode Op = BExpr->getOpcode();
1281d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek
1282d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  if (BinaryOperator::isAssignmentOp(Op)) {
1283d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    // For assignment operators, all that we care about is that the LHS
1284d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    // evaluates to "true" or "false".
1285d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    return VisitConditionVariable(LhsString, BExpr->getLHS(), tookTrue,
128676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  BRC, R, N);
1287d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  }
1288d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek
1289d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  // For non-assignment operations, we require that we can understand
1290d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  // both the LHS and RHS.
1291681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  if (LhsString.empty() || RhsString.empty())
1292681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    return 0;
12933b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek
1294d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  // Should we invert the strings if the LHS is not a variable name?
1295f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> buf;
1296681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  llvm::raw_svector_ostream Out(buf);
12973b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek  Out << "Assuming " << (shouldInvert ? RhsString : LhsString) << " is ";
1298681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
1299681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  // Do we need to invert the opcode?
13003b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek  if (shouldInvert)
13013b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    switch (Op) {
13023b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      default: break;
13033b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      case BO_LT: Op = BO_GT; break;
13043b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      case BO_GT: Op = BO_LT; break;
13053b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      case BO_LE: Op = BO_GE; break;
13063b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek      case BO_GE: Op = BO_LE; break;
13073b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek    }
13083b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek
1309681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  if (!tookTrue)
1310681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    switch (Op) {
1311681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      case BO_EQ: Op = BO_NE; break;
1312681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      case BO_NE: Op = BO_EQ; break;
1313681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      case BO_LT: Op = BO_GE; break;
1314681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      case BO_GT: Op = BO_LE; break;
1315681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      case BO_LE: Op = BO_GT; break;
13164ee7c9cedc015bc161fa290aa558356b9bcf1bfaTed Kremenek      case BO_GE: Op = BO_LT; break;
1317681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      default:
1318681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek        return 0;
1319681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    }
1320681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
13216ae325737c2ef7ce60ac6650a96bd489ef6e7ebeTed Kremenek  switch (Op) {
1322681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    case BO_EQ:
1323681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      Out << "equal to ";
1324681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      break;
1325681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    case BO_NE:
1326681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      Out << "not equal to ";
1327681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      break;
1328681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek    default:
1329681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      Out << BinaryOperator::getOpcodeStr(Op) << ' ';
1330681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek      break;
1331681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek  }
1332681bc114b51c1198cdec9a165c7d3230abb8f427Ted Kremenek
13333b9e8e40dab1295de4f14d9cf8d24c22422a42d2Ted Kremenek  Out << (shouldInvert ? LhsString : RhsString);
133476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  const LocationContext *LCtx = N->getLocationContext();
133576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
133676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  PathDiagnosticEventPiece *event =
133776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    new PathDiagnosticEventPiece(Loc, Out.str());
133876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (shouldPrune.hasValue())
133976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    event->setPrunable(shouldPrune.getValue());
134076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return event;
1341d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek}
1342d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek
1343d1247c5002ee511e6f6c3c26214221c391d437cdTed KremenekPathDiagnosticPiece *
1344d1247c5002ee511e6f6c3c26214221c391d437cdTed KremenekConditionBRVisitor::VisitConditionVariable(StringRef LhsString,
1345d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek                                           const Expr *CondVarExpr,
1346d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek                                           const bool tookTrue,
1347d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek                                           BugReporterContext &BRC,
134876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                           BugReport &report,
134976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                           const ExplodedNode *N) {
1350b0e1badc2a9b8275b48dfb15c6907a282b949b02Jordan Rose  // FIXME: If there's already a constraint tracker for this variable,
1351b0e1badc2a9b8275b48dfb15c6907a282b949b02Jordan Rose  // we shouldn't emit anything here (c.f. the double note in
1352b0e1badc2a9b8275b48dfb15c6907a282b949b02Jordan Rose  // test/Analysis/inlining/path-notes.c)
1353f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> buf;
1354d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  llvm::raw_svector_ostream Out(buf);
1355d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  Out << "Assuming " << LhsString << " is ";
1356d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek
1357d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  QualType Ty = CondVarExpr->getType();
1358d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek
1359d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  if (Ty->isPointerType())
1360d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    Out << (tookTrue ? "not null" : "null");
1361d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  else if (Ty->isObjCObjectPointerType())
1362d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    Out << (tookTrue ? "not nil" : "nil");
1363d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  else if (Ty->isBooleanType())
1364d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    Out << (tookTrue ? "true" : "false");
1365d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  else if (Ty->isIntegerType())
1366d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    Out << (tookTrue ? "non-zero" : "zero");
1367d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek  else
1368d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek    return 0;
1369d1247c5002ee511e6f6c3c26214221c391d437cdTed Kremenek
137076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  const LocationContext *LCtx = N->getLocationContext();
137176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  PathDiagnosticLocation Loc(CondVarExpr, BRC.getSourceManager(), LCtx);
137276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  PathDiagnosticEventPiece *event =
137376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    new PathDiagnosticEventPiece(Loc, Out.str());
137476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
137576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(CondVarExpr)) {
137676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    if (const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl())) {
137776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      const ProgramState *state = N->getState().getPtr();
137876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
137976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        if (report.isInteresting(R))
138076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek          event->setPrunable(false);
138176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      }
138276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    }
138376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  }
138476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
138576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return event;
1386993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek}
1387993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1388993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted KremenekPathDiagnosticPiece *
138950bbc165b063155cc23c360deb7b865502e068e2Anna ZaksConditionBRVisitor::VisitTrueTest(const Expr *Cond,
139050bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                  const DeclRefExpr *DR,
139150bbc165b063155cc23c360deb7b865502e068e2Anna Zaks                                  const bool tookTrue,
1392220ac8c175cb1bf9b18d82eefe036995d7a2164dAnna Zaks                                  BugReporterContext &BRC,
139376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  BugReport &report,
139476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek                                  const ExplodedNode *N) {
1395993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1396993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  const VarDecl *VD = dyn_cast<VarDecl>(DR->getDecl());
1397993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  if (!VD)
1398993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    return 0;
1399993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1400f7ccbad5d9949e7ddd1cbef43d482553b811e026Dylan Noblesmith  SmallString<256> Buf;
1401993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  llvm::raw_svector_ostream Out(Buf);
1402993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1403993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  Out << "Assuming '";
1404993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  VD->getDeclName().printName(Out);
1405993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  Out << "' is ";
1406993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1407993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  QualType VDTy = VD->getType();
1408993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
1409993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  if (VDTy->isPointerType())
1410993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    Out << (tookTrue ? "non-null" : "null");
1411993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  else if (VDTy->isObjCObjectPointerType())
1412993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    Out << (tookTrue ? "non-nil" : "nil");
1413993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  else if (VDTy->isScalarType())
1414993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    Out << (tookTrue ? "not equal to 0" : "0");
1415993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek  else
1416993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek    return 0;
1417993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek
141876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  const LocationContext *LCtx = N->getLocationContext();
141976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  PathDiagnosticLocation Loc(Cond, BRC.getSourceManager(), LCtx);
142076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  PathDiagnosticEventPiece *event =
142176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    new PathDiagnosticEventPiece(Loc, Out.str());
142276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek
142376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  const ProgramState *state = N->getState().getPtr();
142476aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  if (const MemRegion *R = state->getLValue(VD, LCtx).getAsRegion()) {
142576aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    if (report.isInteresting(R))
142676aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      event->setPrunable(false);
142776aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    else {
142876aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      SVal V = state->getSVal(R);
142976aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek      if (report.isInteresting(V))
143076aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek        event->setPrunable(false);
143176aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek    }
143276aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  }
143376aadc346c3a4c363238a1e1232f324c3355d9e0Ted Kremenek  return event;
1434993124ecdd44ec1430a3b7f01b22f65bbaadb586Ted Kremenek}
14350cf3d471546251b12bdceff360f66c079c40526cTed Kremenek
1436a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
1437a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose// FIXME: Copied from ExprEngineCallAndReturn.cpp.
1438a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rosestatic bool isInStdNamespace(const Decl *D) {
1439a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  const DeclContext *DC = D->getDeclContext()->getEnclosingNamespaceContext();
1440a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  const NamespaceDecl *ND = dyn_cast<NamespaceDecl>(DC);
1441a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  if (!ND)
1442a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    return false;
1443a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
1444a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  while (const NamespaceDecl *Parent = dyn_cast<NamespaceDecl>(ND->getParent()))
1445a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    ND = Parent;
1446a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
1447a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  return ND->getName() == "std";
1448a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose}
1449a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
1450a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
145180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna ZaksPathDiagnosticPiece *
145286ff12c8a8a356ca284ca7687749216fbfd74519Anna ZaksLikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
145386ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks                                                    const ExplodedNode *N,
145486ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks                                                    BugReport &BR) {
1455a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  // Here we suppress false positives coming from system headers. This list is
145686ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  // based on known issues.
145786ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks
1458a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  // Skip reports within the 'std' namespace. Although these can sometimes be
1459a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  // the user's fault, we currently don't report them very well, and
1460a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  // Note that this will not help for any other data structure libraries, like
1461a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  // TR1, Boost, or llvm/ADT.
1462a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  ExprEngine &Eng = BRC.getBugReporter().getEngine();
1463a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  AnalyzerOptions &Options = Eng.getAnalysisManager().options;
1464a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  if (Options.shouldSuppressFromCXXStandardLibrary()) {
1465a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    const LocationContext *LCtx = N->getLocationContext();
1466a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    if (isInStdNamespace(LCtx->getDecl())) {
1467a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose      BR.markInvalid(getTag(), 0);
1468a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose      return 0;
1469a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    }
1470a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  }
1471a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose
147286ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  // Skip reports within the sys/queue.h macros as we do not have the ability to
147386ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  // reason about data structure shapes.
147486ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  SourceManager &SM = BRC.getSourceManager();
1475a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose  FullSourceLoc Loc = BR.getLocation(SM).asLocation();
147686ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  while (Loc.isMacroID()) {
147786ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks    if (SM.isInSystemMacro(Loc) &&
147886ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks       (SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) {
147986ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks      BR.markInvalid(getTag(), 0);
148086ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks      return 0;
148186ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks    }
1482a12643622ad3b85972dfdd80fe9006a3e8d8fb80Jordan Rose    Loc = Loc.getSpellingLoc();
148386ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  }
148486ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks
148586ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks  return 0;
148686ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks}
148786ff12c8a8a356ca284ca7687749216fbfd74519Anna Zaks
148886ff12c8a8a356ca284ca7687749216fbfd74519Anna ZaksPathDiagnosticPiece *
148980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna ZaksUndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
149080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                                  const ExplodedNode *PrevN,
149180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                                  BugReporterContext &BRC,
149280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                                  BugReport &BR) {
149380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
149480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  ProgramStateRef State = N->getState();
149580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  ProgramPoint ProgLoc = N->getLocation();
149680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
149780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  // We are only interested in visiting CallEnter nodes.
14987a95de68c093991047ed8d339479ccad51b88663David Blaikie  Optional<CallEnter> CEnter = ProgLoc.getAs<CallEnter>();
149980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  if (!CEnter)
150080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    return 0;
150180de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
150280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  // Check if one of the arguments is the region the visitor is tracking.
150380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  CallEventManager &CEMgr = BRC.getStateManager().getCallEventManager();
150480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  CallEventRef<> Call = CEMgr.getCaller(CEnter->getCalleeContext(), State);
150580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  unsigned Idx = 0;
150680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  for (CallEvent::param_iterator I = Call->param_begin(),
150780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks                                 E = Call->param_end(); I != E; ++I, ++Idx) {
150880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    const MemRegion *ArgReg = Call->getArgSVal(Idx).getAsRegion();
150980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
1510522fc21f3adc647817edc8017e6928a64c96899bAnna Zaks    // Are we tracking the argument or its subregion?
1511522fc21f3adc647817edc8017e6928a64c96899bAnna Zaks    if ( !ArgReg || (ArgReg != R && !R->isSubRegionOf(ArgReg->StripCasts())))
151228694c1fe44082970cd53ca7ffef25f668e4c545Anna Zaks      continue;
151380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
151480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    // Check the function parameter type.
151580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    const ParmVarDecl *ParamDecl = *I;
151680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    assert(ParamDecl && "Formal parameter has no decl?");
151780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    QualType T = ParamDecl->getType();
151880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
151980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    if (!(T->isAnyPointerType() || T->isReferenceType())) {
152080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks      // Function can only change the value passed in by address.
152128694c1fe44082970cd53ca7ffef25f668e4c545Anna Zaks      continue;
152280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    }
152380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
152480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    // If it is a const pointer value, the function does not intend to
152580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    // change the value.
152680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    if (T->getPointeeType().isConstQualified())
152728694c1fe44082970cd53ca7ffef25f668e4c545Anna Zaks      continue;
152880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks
152980de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    // Mark the call site (LocationContext) as interesting if the value of the
153080de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    // argument is undefined or '0'/'NULL'.
1531522fc21f3adc647817edc8017e6928a64c96899bAnna Zaks    SVal BoundVal = State->getSVal(R);
153280de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    if (BoundVal.isUndef() || BoundVal.isZeroConstant()) {
153380de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks      BR.markInteresting(CEnter->getCalleeContext());
153480de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks      return 0;
153580de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks    }
153680de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  }
153780de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks  return 0;
153880de487e03dd0f44e4572e2122ebc1aa6a3961f5Anna Zaks}
1539