//===--------------------------------------------------------------*- 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
//
//===----------------------------------------------------------------------===//

#include "NoOwnershipChangeVisitor.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporterVisitors.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState_Fwd.h"
#include "llvm/ADT/SetOperations.h"

using namespace clang;
using namespace ento;
using OwnerSet = NoOwnershipChangeVisitor::OwnerSet;

namespace {
// Collect which entities point to the allocated memory, and could be
// responsible for deallocating it.
class OwnershipBindingsHandler : public StoreManager::BindingsHandler {
  SymbolRef Sym;
  OwnerSet &Owners;

public:
  OwnershipBindingsHandler(SymbolRef Sym, OwnerSet &Owners)
      : Sym(Sym), Owners(Owners) {}

  bool HandleBinding(StoreManager &SMgr, Store Store, const MemRegion *Region,
                     SVal Val) override {
    if (Val.getAsSymbol() == Sym)
      Owners.insert(Region);
    return true;
  }

  LLVM_DUMP_METHOD void dump() const { dumpToStream(llvm::errs()); }
  LLVM_DUMP_METHOD void dumpToStream(llvm::raw_ostream &out) const {
    out << "Owners: {\n";
    for (const MemRegion *Owner : Owners) {
      out << "  ";
      Owner->dumpToStream(out);
      out << ",\n";
    }
    out << "}\n";
  }
};
} // namespace

OwnerSet NoOwnershipChangeVisitor::getOwnersAtNode(const ExplodedNode *N) {
  OwnerSet Ret;

  ProgramStateRef State = N->getState();
  OwnershipBindingsHandler Handler{Sym, Ret};
  State->getStateManager().getStoreManager().iterBindings(State->getStore(),
                                                          Handler);
  return Ret;
}

LLVM_DUMP_METHOD std::string
NoOwnershipChangeVisitor::getFunctionName(const ExplodedNode *CallEnterN) {
  if (const CallExpr *CE = llvm::dyn_cast_or_null<CallExpr>(
          CallEnterN->getLocationAs<CallEnter>()->getCallExpr()))
    if (const FunctionDecl *FD = CE->getDirectCallee())
      return FD->getQualifiedNameAsString();
  return "";
}

bool NoOwnershipChangeVisitor::wasModifiedInFunction(
    const ExplodedNode *CallEnterN, const ExplodedNode *CallExitEndN) {
  const Decl *Callee =
      CallExitEndN->getFirstPred()->getLocationContext()->getDecl();
  if (!doesFnIntendToHandleOwnership(
          Callee,
          CallExitEndN->getState()->getAnalysisManager().getASTContext()))
    return true;

  if (hasResourceStateChanged(CallEnterN->getState(), CallExitEndN->getState()))
    return true;

  OwnerSet CurrOwners = getOwnersAtNode(CallEnterN);
  OwnerSet ExitOwners = getOwnersAtNode(CallExitEndN);

  // Owners in the current set may be purged from the analyzer later on.
  // If a variable is dead (is not referenced directly or indirectly after
  // some point), it will be removed from the Store before the end of its
  // actual lifetime.
  // This means that if the ownership status didn't change, CurrOwners
  // must be a superset of, but not necessarily equal to ExitOwners.
  return !llvm::set_is_subset(ExitOwners, CurrOwners);
}

PathDiagnosticPieceRef NoOwnershipChangeVisitor::maybeEmitNoteForParameters(
    PathSensitiveBugReport &R, const CallEvent &Call, const ExplodedNode *N) {
  // TODO: Factor the logic of "what constitutes as an entity being passed
  // into a function call" out by reusing the code in
  // NoStoreFuncVisitor::maybeEmitNoteForParameters, maybe by incorporating
  // the printing technology in UninitializedObject's FieldChainInfo.
  ArrayRef<ParmVarDecl *> Parameters = Call.parameters();
  for (unsigned I = 0; I < Call.getNumArgs() && I < Parameters.size(); ++I) {
    SVal V = Call.getArgSVal(I);
    if (V.getAsSymbol() == Sym)
      return emitNote(N);
  }
  return nullptr;
}
