//=== FuchsiaHandleChecker.cpp - Find handle leaks/double closes -*- C++ -*--=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This checker checks if the handle of Fuchsia is properly used according to
// following rules.
//   - If a handle is acquired, it should be released before execution
//        ends.
//   - If a handle is released, it should not be released again.
//   - If a handle is released, it should not be used for other purposes
//        such as I/O.
//
// In this checker, each tracked handle is associated with a state. When the
// handle variable is passed to different function calls or syscalls, its state
// changes. The state changes can be generally represented by following ASCII
// Art:
//
//
//                                 +-------------+         +------------+
//          acquire_func succeeded |             | Escape  |            |
//               +----------------->  Allocated  +--------->  Escaped   <--+
//               |                 |             |         |            |  |
//               |                 +-----+------++         +------------+  |
//               |                       |      |                          |
// acquire_func  |         release_func  |      +--+                       |
//    failed     |                       |         | handle  +--------+    |
// +---------+   |                       |         | dies    |        |    |
// |         |   |                  +----v-----+   +---------> Leaked |    |
// |         |   |                  |          |             |(REPORT)|    |
// |  +----------+--+               | Released | Escape      +--------+    |
// |  |             |               |          +---------------------------+
// +--> Not tracked |               +----+---+-+
//    |             |                    |   |        As argument by value
//    +----------+--+       release_func |   +------+ in function call
//               |                       |          | or by reference in
//               |                       |          | use_func call
//    unowned    |                  +----v-----+    |     +-----------+
//  acquire_func |                  | Double   |    +-----> Use after |
//   succeeded   |                  | released |          | released  |
//               |                  | (REPORT) |          | (REPORT)  |
//        +---------------+         +----------+          +-----------+
//        | Allocated     |
//        | Unowned       |  release_func
//        |               +---------+
//        +---------------+         |
//                                  |
//                            +-----v----------+
//                            | Release of     |
//                            | unowned handle |
//                            | (REPORT)       |
//                            +----------------+
//
// acquire_func represents the functions or syscalls that may acquire a handle.
// release_func represents the functions or syscalls that may release a handle.
// use_func represents the functions or syscall that requires an open handle.
//
// If a tracked handle dies in "Released" or "Not Tracked" state, we assume it
// is properly used. Otherwise a bug and will be reported.
//
// Note that, the analyzer does not always know for sure if a function failed
// or succeeded. In those cases we use the state MaybeAllocated.
// Thus, the diagram above captures the intent, not implementation details.
//
// Due to the fact that the number of handle related syscalls in Fuchsia
// is large, we adopt the annotation attributes to descript syscalls'
// operations(acquire/release/use) on handles instead of hardcoding
// everything in the checker.
//
// We use following annotation attributes for handle related syscalls or
// functions:
//  1. __attribute__((acquire_handle("Fuchsia"))) |handle will be acquired
//  2. __attribute__((release_handle("Fuchsia"))) |handle will be released
//  3. __attribute__((use_handle("Fuchsia"))) |handle will not transit to
//     escaped state, it also needs to be open.
//
// For example, an annotated syscall:
//   zx_status_t zx_channel_create(
//   uint32_t options,
//   zx_handle_t* out0 __attribute__((acquire_handle("Fuchsia"))) ,
//   zx_handle_t* out1 __attribute__((acquire_handle("Fuchsia"))));
// denotes a syscall which will acquire two handles and save them to 'out0' and
// 'out1' when succeeded.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/Type.h"
#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/SymExpr.h"
#include "llvm/ADT/StringExtras.h"

using namespace clang;
using namespace ento;

namespace {

static const StringRef HandleTypeName = "zx_handle_t";
static const StringRef ErrorTypeName = "zx_status_t";

class HandleState {
private:
  enum class Kind { MaybeAllocated, Allocated, Released, Escaped, Unowned } K;
  SymbolRef ErrorSym;
  HandleState(Kind K, SymbolRef ErrorSym) : K(K), ErrorSym(ErrorSym) {}

public:
  bool operator==(const HandleState &Other) const {
    return K == Other.K && ErrorSym == Other.ErrorSym;
  }
  bool isAllocated() const { return K == Kind::Allocated; }
  bool maybeAllocated() const { return K == Kind::MaybeAllocated; }
  bool isReleased() const { return K == Kind::Released; }
  bool isEscaped() const { return K == Kind::Escaped; }
  bool isUnowned() const { return K == Kind::Unowned; }

  static HandleState getMaybeAllocated(SymbolRef ErrorSym) {
    return HandleState(Kind::MaybeAllocated, ErrorSym);
  }
  static HandleState getAllocated(ProgramStateRef State, HandleState S) {
    assert(S.maybeAllocated());
    assert(State->getConstraintManager()
               .isNull(State, S.getErrorSym())
               .isConstrained());
    return HandleState(Kind::Allocated, nullptr);
  }
  static HandleState getReleased() {
    return HandleState(Kind::Released, nullptr);
  }
  static HandleState getEscaped() {
    return HandleState(Kind::Escaped, nullptr);
  }
  static HandleState getUnowned() {
    return HandleState(Kind::Unowned, nullptr);
  }

  SymbolRef getErrorSym() const { return ErrorSym; }

  void Profile(llvm::FoldingSetNodeID &ID) const {
    ID.AddInteger(static_cast<int>(K));
    ID.AddPointer(ErrorSym);
  }

  LLVM_DUMP_METHOD void dump(raw_ostream &OS) const {
    switch (K) {
#define CASE(ID)                                                               \
  case ID:                                                                     \
    OS << #ID;                                                                 \
    break;
      CASE(Kind::MaybeAllocated)
      CASE(Kind::Allocated)
      CASE(Kind::Released)
      CASE(Kind::Escaped)
      CASE(Kind::Unowned)
    }
    if (ErrorSym) {
      OS << " ErrorSym: ";
      ErrorSym->dumpToStream(OS);
    }
  }

  LLVM_DUMP_METHOD void dump() const { dump(llvm::errs()); }
};

template <typename Attr> static bool hasFuchsiaAttr(const Decl *D) {
  return D->hasAttr<Attr>() && D->getAttr<Attr>()->getHandleType() == "Fuchsia";
}

template <typename Attr> static bool hasFuchsiaUnownedAttr(const Decl *D) {
  return D->hasAttr<Attr>() &&
         D->getAttr<Attr>()->getHandleType() == "FuchsiaUnowned";
}

class FuchsiaHandleChecker
    : public Checker<check::PostCall, check::PreCall, check::DeadSymbols,
                     check::PointerEscape, eval::Assume> {
  BugType LeakBugType{this, "Fuchsia handle leak", "Fuchsia Handle Error",
                      /*SuppressOnSink=*/true};
  BugType DoubleReleaseBugType{this, "Fuchsia handle double release",
                               "Fuchsia Handle Error"};
  BugType UseAfterReleaseBugType{this, "Fuchsia handle use after release",
                                 "Fuchsia Handle Error"};
  BugType ReleaseUnownedBugType{
      this, "Fuchsia handle release of unowned handle", "Fuchsia Handle Error"};

public:
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
  void checkDeadSymbols(SymbolReaper &SymReaper, CheckerContext &C) const;
  ProgramStateRef evalAssume(ProgramStateRef State, SVal Cond,
                             bool Assumption) const;
  ProgramStateRef checkPointerEscape(ProgramStateRef State,
                                     const InvalidatedSymbols &Escaped,
                                     const CallEvent *Call,
                                     PointerEscapeKind Kind) const;

  ExplodedNode *reportLeaks(ArrayRef<SymbolRef> LeakedHandles,
                            CheckerContext &C, ExplodedNode *Pred) const;

  void reportDoubleRelease(SymbolRef HandleSym, const SourceRange &Range,
                           CheckerContext &C) const;

  void reportUnownedRelease(SymbolRef HandleSym, const SourceRange &Range,
                            CheckerContext &C) const;

  void reportUseAfterFree(SymbolRef HandleSym, const SourceRange &Range,
                          CheckerContext &C) const;

  void reportBug(SymbolRef Sym, ExplodedNode *ErrorNode, CheckerContext &C,
                 const SourceRange *Range, const BugType &Type,
                 StringRef Msg) const;

  void printState(raw_ostream &Out, ProgramStateRef State, const char *NL,
                  const char *Sep) const override;
};
} // end anonymous namespace

REGISTER_MAP_WITH_PROGRAMSTATE(HStateMap, SymbolRef, HandleState)

static const ExplodedNode *getAcquireSite(const ExplodedNode *N, SymbolRef Sym,
                                          CheckerContext &Ctx) {
  ProgramStateRef State = N->getState();
  // When bug type is handle leak, exploded node N does not have state info for
  // leaking handle. Get the predecessor of N instead.
  if (!State->get<HStateMap>(Sym))
    N = N->getFirstPred();

  const ExplodedNode *Pred = N;
  while (N) {
    State = N->getState();
    if (!State->get<HStateMap>(Sym)) {
      const HandleState *HState = Pred->getState()->get<HStateMap>(Sym);
      if (HState && (HState->isAllocated() || HState->maybeAllocated()))
        return N;
    }
    Pred = N;
    N = N->getFirstPred();
  }
  return nullptr;
}

namespace {
class FuchsiaHandleSymbolVisitor final : public SymbolVisitor {
public:
  FuchsiaHandleSymbolVisitor(ProgramStateRef State) : State(std::move(State)) {}
  ProgramStateRef getState() const { return State; }

  bool VisitSymbol(SymbolRef S) override {
    if (const auto *HandleType = S->getType()->getAs<TypedefType>())
      if (HandleType->getDecl()->getName() == HandleTypeName)
        Symbols.push_back(S);
    return true;
  }

  SmallVector<SymbolRef, 1024> GetSymbols() { return Symbols; }

private:
  SmallVector<SymbolRef, 1024> Symbols;
  ProgramStateRef State;
};
} // end anonymous namespace

/// Returns the symbols extracted from the argument or empty vector if it cannot
/// be found. It is unlikely to have over 1024 symbols in one argument.
static SmallVector<SymbolRef, 1024>
getFuchsiaHandleSymbols(QualType QT, SVal Arg, ProgramStateRef State) {
  int PtrToHandleLevel = 0;
  while (QT->isAnyPointerType() || QT->isReferenceType()) {
    ++PtrToHandleLevel;
    QT = QT->getPointeeType();
  }
  if (QT->isStructureType()) {
    // If we see a structure, see if there is any handle referenced by the
    // structure.
    FuchsiaHandleSymbolVisitor Visitor(State);
    State->scanReachableSymbols(Arg, Visitor);
    return Visitor.GetSymbols();
  }
  if (const auto *HandleType = QT->getAs<TypedefType>()) {
    if (HandleType->getDecl()->getName() != HandleTypeName)
      return {};
    if (PtrToHandleLevel > 1)
      // Not supported yet.
      return {};

    if (PtrToHandleLevel == 0) {
      SymbolRef Sym = Arg.getAsSymbol();
      if (Sym) {
        return {Sym};
      } else {
        return {};
      }
    } else {
      assert(PtrToHandleLevel == 1);
      if (Optional<Loc> ArgLoc = Arg.getAs<Loc>()) {
        SymbolRef Sym = State->getSVal(*ArgLoc).getAsSymbol();
        if (Sym) {
          return {Sym};
        } else {
          return {};
        }
      }
    }
  }
  return {};
}

void FuchsiaHandleChecker::checkPreCall(const CallEvent &Call,
                                        CheckerContext &C) const {
  ProgramStateRef State = C.getState();
  const FunctionDecl *FuncDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
  if (!FuncDecl) {
    // Unknown call, escape by value handles. They are not covered by
    // PointerEscape callback.
    for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
      if (SymbolRef Handle = Call.getArgSVal(Arg).getAsSymbol())
        State = State->set<HStateMap>(Handle, HandleState::getEscaped());
    }
    C.addTransition(State);
    return;
  }

  for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
    if (Arg >= FuncDecl->getNumParams())
      break;
    const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
    SmallVector<SymbolRef, 1024> Handles =
        getFuchsiaHandleSymbols(PVD->getType(), Call.getArgSVal(Arg), State);

    // Handled in checkPostCall.
    if (hasFuchsiaAttr<ReleaseHandleAttr>(PVD) ||
        hasFuchsiaAttr<AcquireHandleAttr>(PVD))
      continue;

    for (SymbolRef Handle : Handles) {
      const HandleState *HState = State->get<HStateMap>(Handle);
      if (!HState || HState->isEscaped())
        continue;

      if (hasFuchsiaAttr<UseHandleAttr>(PVD) ||
          PVD->getType()->isIntegerType()) {
        if (HState->isReleased()) {
          reportUseAfterFree(Handle, Call.getArgSourceRange(Arg), C);
          return;
        }
      }
    }
  }
  C.addTransition(State);
}

void FuchsiaHandleChecker::checkPostCall(const CallEvent &Call,
                                         CheckerContext &C) const {
  const FunctionDecl *FuncDecl = dyn_cast_or_null<FunctionDecl>(Call.getDecl());
  if (!FuncDecl)
    return;

  // If we analyzed the function body, then ignore the annotations.
  if (C.wasInlined)
    return;

  ProgramStateRef State = C.getState();

  std::vector<std::function<std::string(BugReport & BR)>> Notes;
  SymbolRef ResultSymbol = nullptr;
  if (const auto *TypeDefTy = FuncDecl->getReturnType()->getAs<TypedefType>())
    if (TypeDefTy->getDecl()->getName() == ErrorTypeName)
      ResultSymbol = Call.getReturnValue().getAsSymbol();

  // Function returns an open handle.
  if (hasFuchsiaAttr<AcquireHandleAttr>(FuncDecl)) {
    SymbolRef RetSym = Call.getReturnValue().getAsSymbol();
    Notes.push_back([RetSym, FuncDecl](BugReport &BR) -> std::string {
      auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
      if (auto IsInteresting = PathBR->getInterestingnessKind(RetSym)) {
        std::string SBuf;
        llvm::raw_string_ostream OS(SBuf);
        OS << "Function '" << FuncDecl->getDeclName()
           << "' returns an open handle";
        return SBuf;
      } else
        return "";
    });
    State =
        State->set<HStateMap>(RetSym, HandleState::getMaybeAllocated(nullptr));
  } else if (hasFuchsiaUnownedAttr<AcquireHandleAttr>(FuncDecl)) {
    // Function returns an unowned handle
    SymbolRef RetSym = Call.getReturnValue().getAsSymbol();
    Notes.push_back([RetSym, FuncDecl](BugReport &BR) -> std::string {
      auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
      if (auto IsInteresting = PathBR->getInterestingnessKind(RetSym)) {
        std::string SBuf;
        llvm::raw_string_ostream OS(SBuf);
        OS << "Function '" << FuncDecl->getDeclName()
           << "' returns an unowned handle";
        return SBuf;
      } else
        return "";
    });
    State = State->set<HStateMap>(RetSym, HandleState::getUnowned());
  }

  for (unsigned Arg = 0; Arg < Call.getNumArgs(); ++Arg) {
    if (Arg >= FuncDecl->getNumParams())
      break;
    const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
    unsigned ParamDiagIdx = PVD->getFunctionScopeIndex() + 1;
    SmallVector<SymbolRef, 1024> Handles =
        getFuchsiaHandleSymbols(PVD->getType(), Call.getArgSVal(Arg), State);

    for (SymbolRef Handle : Handles) {
      const HandleState *HState = State->get<HStateMap>(Handle);
      if (HState && HState->isEscaped())
        continue;
      if (hasFuchsiaAttr<ReleaseHandleAttr>(PVD)) {
        if (HState && HState->isReleased()) {
          reportDoubleRelease(Handle, Call.getArgSourceRange(Arg), C);
          return;
        } else if (HState && HState->isUnowned()) {
          reportUnownedRelease(Handle, Call.getArgSourceRange(Arg), C);
          return;
        } else {
          Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
            auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
            if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
              std::string SBuf;
              llvm::raw_string_ostream OS(SBuf);
              OS << "Handle released through " << ParamDiagIdx
                 << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
              return SBuf;
            } else
              return "";
          });
          State = State->set<HStateMap>(Handle, HandleState::getReleased());
        }
      } else if (hasFuchsiaAttr<AcquireHandleAttr>(PVD)) {
        Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
          auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
          if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
            std::string SBuf;
            llvm::raw_string_ostream OS(SBuf);
            OS << "Handle allocated through " << ParamDiagIdx
               << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
            return SBuf;
          } else
            return "";
        });
        State = State->set<HStateMap>(
            Handle, HandleState::getMaybeAllocated(ResultSymbol));
      } else if (hasFuchsiaUnownedAttr<AcquireHandleAttr>(PVD)) {
        Notes.push_back([Handle, ParamDiagIdx](BugReport &BR) -> std::string {
          auto *PathBR = static_cast<PathSensitiveBugReport *>(&BR);
          if (auto IsInteresting = PathBR->getInterestingnessKind(Handle)) {
            std::string SBuf;
            llvm::raw_string_ostream OS(SBuf);
            OS << "Unowned handle allocated through " << ParamDiagIdx
               << llvm::getOrdinalSuffix(ParamDiagIdx) << " parameter";
            return SBuf;
          } else
            return "";
        });
        State = State->set<HStateMap>(Handle, HandleState::getUnowned());
      } else if (!hasFuchsiaAttr<UseHandleAttr>(PVD) &&
                 PVD->getType()->isIntegerType()) {
        // Working around integer by-value escapes.
        // The by-value escape would not be captured in checkPointerEscape.
        // If the function was not analyzed (otherwise wasInlined should be
        // true) and there is no annotation on the handle, we assume the handle
        // is escaped.
        State = State->set<HStateMap>(Handle, HandleState::getEscaped());
      }
    }
  }
  const NoteTag *T = nullptr;
  if (!Notes.empty()) {
    T = C.getNoteTag([this, Notes{std::move(Notes)}](
                         PathSensitiveBugReport &BR) -> std::string {
      if (&BR.getBugType() != &UseAfterReleaseBugType &&
          &BR.getBugType() != &LeakBugType &&
          &BR.getBugType() != &DoubleReleaseBugType &&
          &BR.getBugType() != &ReleaseUnownedBugType)
        return "";
      for (auto &Note : Notes) {
        std::string Text = Note(BR);
        if (!Text.empty())
          return Text;
      }
      return "";
    });
  }
  C.addTransition(State, T);
}

void FuchsiaHandleChecker::checkDeadSymbols(SymbolReaper &SymReaper,
                                            CheckerContext &C) const {
  ProgramStateRef State = C.getState();
  SmallVector<SymbolRef, 2> LeakedSyms;
  HStateMapTy TrackedHandles = State->get<HStateMap>();
  for (auto &CurItem : TrackedHandles) {
    SymbolRef ErrorSym = CurItem.second.getErrorSym();
    // Keeping zombie handle symbols. In case the error symbol is dying later
    // than the handle symbol we might produce spurious leak warnings (in case
    // we find out later from the status code that the handle allocation failed
    // in the first place).
    if (!SymReaper.isDead(CurItem.first) ||
        (ErrorSym && !SymReaper.isDead(ErrorSym)))
      continue;
    if (CurItem.second.isAllocated() || CurItem.second.maybeAllocated())
      LeakedSyms.push_back(CurItem.first);
    State = State->remove<HStateMap>(CurItem.first);
  }

  ExplodedNode *N = C.getPredecessor();
  if (!LeakedSyms.empty())
    N = reportLeaks(LeakedSyms, C, N);

  C.addTransition(State, N);
}

// Acquiring a handle is not always successful. In Fuchsia most functions
// return a status code that determines the status of the handle.
// When we split the path based on this status code we know that on one
// path we do have the handle and on the other path the acquire failed.
// This method helps avoiding false positive leak warnings on paths where
// the function failed.
// Moreover, when a handle is known to be zero (the invalid handle),
// we no longer can follow the symbol on the path, becaue the constant
// zero will be used instead of the symbol. We also do not need to release
// an invalid handle, so we remove the corresponding symbol from the state.
ProgramStateRef FuchsiaHandleChecker::evalAssume(ProgramStateRef State,
                                                 SVal Cond,
                                                 bool Assumption) const {
  // TODO: add notes about successes/fails for APIs.
  ConstraintManager &Cmr = State->getConstraintManager();
  HStateMapTy TrackedHandles = State->get<HStateMap>();
  for (auto &CurItem : TrackedHandles) {
    ConditionTruthVal HandleVal = Cmr.isNull(State, CurItem.first);
    if (HandleVal.isConstrainedTrue()) {
      // The handle is invalid. We can no longer follow the symbol on this path.
      State = State->remove<HStateMap>(CurItem.first);
    }
    SymbolRef ErrorSym = CurItem.second.getErrorSym();
    if (!ErrorSym)
      continue;
    ConditionTruthVal ErrorVal = Cmr.isNull(State, ErrorSym);
    if (ErrorVal.isConstrainedTrue()) {
      // Allocation succeeded.
      if (CurItem.second.maybeAllocated())
        State = State->set<HStateMap>(
            CurItem.first, HandleState::getAllocated(State, CurItem.second));
    } else if (ErrorVal.isConstrainedFalse()) {
      // Allocation failed.
      if (CurItem.second.maybeAllocated())
        State = State->remove<HStateMap>(CurItem.first);
    }
  }
  return State;
}

ProgramStateRef FuchsiaHandleChecker::checkPointerEscape(
    ProgramStateRef State, const InvalidatedSymbols &Escaped,
    const CallEvent *Call, PointerEscapeKind Kind) const {
  const FunctionDecl *FuncDecl =
      Call ? dyn_cast_or_null<FunctionDecl>(Call->getDecl()) : nullptr;

  llvm::DenseSet<SymbolRef> UnEscaped;
  // Not all calls should escape our symbols.
  if (FuncDecl &&
      (Kind == PSK_DirectEscapeOnCall || Kind == PSK_IndirectEscapeOnCall ||
       Kind == PSK_EscapeOutParameters)) {
    for (unsigned Arg = 0; Arg < Call->getNumArgs(); ++Arg) {
      if (Arg >= FuncDecl->getNumParams())
        break;
      const ParmVarDecl *PVD = FuncDecl->getParamDecl(Arg);
      SmallVector<SymbolRef, 1024> Handles =
          getFuchsiaHandleSymbols(PVD->getType(), Call->getArgSVal(Arg), State);
      for (SymbolRef Handle : Handles) {
        if (hasFuchsiaAttr<UseHandleAttr>(PVD) ||
            hasFuchsiaAttr<ReleaseHandleAttr>(PVD)) {
          UnEscaped.insert(Handle);
        }
      }
    }
  }

  // For out params, we have to deal with derived symbols. See
  // MacOSKeychainAPIChecker for details.
  for (auto I : State->get<HStateMap>()) {
    if (Escaped.count(I.first) && !UnEscaped.count(I.first))
      State = State->set<HStateMap>(I.first, HandleState::getEscaped());
    if (const auto *SD = dyn_cast<SymbolDerived>(I.first)) {
      auto ParentSym = SD->getParentSymbol();
      if (Escaped.count(ParentSym))
        State = State->set<HStateMap>(I.first, HandleState::getEscaped());
    }
  }

  return State;
}

ExplodedNode *
FuchsiaHandleChecker::reportLeaks(ArrayRef<SymbolRef> LeakedHandles,
                                  CheckerContext &C, ExplodedNode *Pred) const {
  ExplodedNode *ErrNode = C.generateNonFatalErrorNode(C.getState(), Pred);
  for (SymbolRef LeakedHandle : LeakedHandles) {
    reportBug(LeakedHandle, ErrNode, C, nullptr, LeakBugType,
              "Potential leak of handle");
  }
  return ErrNode;
}

void FuchsiaHandleChecker::reportDoubleRelease(SymbolRef HandleSym,
                                               const SourceRange &Range,
                                               CheckerContext &C) const {
  ExplodedNode *ErrNode = C.generateErrorNode(C.getState());
  reportBug(HandleSym, ErrNode, C, &Range, DoubleReleaseBugType,
            "Releasing a previously released handle");
}

void FuchsiaHandleChecker::reportUnownedRelease(SymbolRef HandleSym,
                                                const SourceRange &Range,
                                                CheckerContext &C) const {
  ExplodedNode *ErrNode = C.generateErrorNode(C.getState());
  reportBug(HandleSym, ErrNode, C, &Range, ReleaseUnownedBugType,
            "Releasing an unowned handle");
}

void FuchsiaHandleChecker::reportUseAfterFree(SymbolRef HandleSym,
                                              const SourceRange &Range,
                                              CheckerContext &C) const {
  ExplodedNode *ErrNode = C.generateErrorNode(C.getState());
  reportBug(HandleSym, ErrNode, C, &Range, UseAfterReleaseBugType,
            "Using a previously released handle");
}

void FuchsiaHandleChecker::reportBug(SymbolRef Sym, ExplodedNode *ErrorNode,
                                     CheckerContext &C,
                                     const SourceRange *Range,
                                     const BugType &Type, StringRef Msg) const {
  if (!ErrorNode)
    return;

  std::unique_ptr<PathSensitiveBugReport> R;
  if (Type.isSuppressOnSink()) {
    const ExplodedNode *AcquireNode = getAcquireSite(ErrorNode, Sym, C);
    if (AcquireNode) {
      PathDiagnosticLocation LocUsedForUniqueing =
          PathDiagnosticLocation::createBegin(
              AcquireNode->getStmtForDiagnostics(), C.getSourceManager(),
              AcquireNode->getLocationContext());

      R = std::make_unique<PathSensitiveBugReport>(
          Type, Msg, ErrorNode, LocUsedForUniqueing,
          AcquireNode->getLocationContext()->getDecl());
    }
  }
  if (!R)
    R = std::make_unique<PathSensitiveBugReport>(Type, Msg, ErrorNode);
  if (Range)
    R->addRange(*Range);
  R->markInteresting(Sym);
  C.emitReport(std::move(R));
}

void ento::registerFuchsiaHandleChecker(CheckerManager &mgr) {
  mgr.registerChecker<FuchsiaHandleChecker>();
}

bool ento::shouldRegisterFuchsiaHandleChecker(const CheckerManager &mgr) {
  return true;
}

void FuchsiaHandleChecker::printState(raw_ostream &Out, ProgramStateRef State,
                                      const char *NL, const char *Sep) const {

  HStateMapTy StateMap = State->get<HStateMap>();

  if (!StateMap.isEmpty()) {
    Out << Sep << "FuchsiaHandleChecker :" << NL;
    for (HStateMapTy::iterator I = StateMap.begin(), E = StateMap.end(); I != E;
         ++I) {
      I.getKey()->dumpToStream(Out);
      Out << " : ";
      I.getData().dump(Out);
      Out << NL;
    }
  }
}
