// MacOSXAPIChecker.h - Checks proper use of various MacOS X APIs --*- 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 defines MacOSXAPIChecker, which is an assortment of checks on calls
// to various, widely used Apple APIs.
//
// FIXME: What's currently in BasicObjCFoundationChecks.cpp should be migrated
// to here, using the new Checker interface.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/Basic/TargetInfo.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/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace ento;

namespace {
class MacOSXAPIChecker : public Checker< check::PreStmt<CallExpr> > {
  mutable std::unique_ptr<BugType> BT_dispatchOnce;

  static const ObjCIvarRegion *getParentIvarRegion(const MemRegion *R);

public:
  void checkPreStmt(const CallExpr *CE, CheckerContext &C) const;

  void CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
                         StringRef FName) const;

  typedef void (MacOSXAPIChecker::*SubChecker)(CheckerContext &,
                                               const CallExpr *,
                                               StringRef FName) const;
};
} //end anonymous namespace

//===----------------------------------------------------------------------===//
// dispatch_once and dispatch_once_f
//===----------------------------------------------------------------------===//

const ObjCIvarRegion *
MacOSXAPIChecker::getParentIvarRegion(const MemRegion *R) {
  const SubRegion *SR = dyn_cast<SubRegion>(R);
  while (SR) {
    if (const ObjCIvarRegion *IR = dyn_cast<ObjCIvarRegion>(SR))
      return IR;
    SR = dyn_cast<SubRegion>(SR->getSuperRegion());
  }
  return nullptr;
}

void MacOSXAPIChecker::CheckDispatchOnce(CheckerContext &C, const CallExpr *CE,
                                         StringRef FName) const {
  if (CE->getNumArgs() < 1)
    return;

  // Check if the first argument is improperly allocated.  If so, issue a
  // warning because that's likely to be bad news.
  const MemRegion *R = C.getSVal(CE->getArg(0)).getAsRegion();
  if (!R)
    return;

  // Global variables are fine.
  const MemRegion *RB = R->getBaseRegion();
  const MemSpaceRegion *RS = RB->getMemorySpace();
  if (isa<GlobalsSpaceRegion>(RS))
    return;

  // Handle _dispatch_once.  In some versions of the OS X SDK we have the case
  // that dispatch_once is a macro that wraps a call to _dispatch_once.
  // _dispatch_once is then a function which then calls the real dispatch_once.
  // Users do not care; they just want the warning at the top-level call.
  if (CE->getBeginLoc().isMacroID()) {
    StringRef TrimmedFName = FName.ltrim('_');
    if (TrimmedFName != FName)
      FName = TrimmedFName;
  }

  SmallString<256> S;
  llvm::raw_svector_ostream os(S);
  bool SuggestStatic = false;
  os << "Call to '" << FName << "' uses";
  if (const VarRegion *VR = dyn_cast<VarRegion>(RB)) {
    const VarDecl *VD = VR->getDecl();
    // FIXME: These should have correct memory space and thus should be filtered
    // out earlier. This branch only fires when we're looking from a block,
    // which we analyze as a top-level declaration, onto a static local
    // in a function that contains the block.
    if (VD->isStaticLocal())
      return;
    // We filtered out globals earlier, so it must be a local variable
    // or a block variable which is under UnknownSpaceRegion.
    if (VR != R)
      os << " memory within";
    if (VD->hasAttr<BlocksAttr>())
      os << " the block variable '";
    else
      os << " the local variable '";
    os << VR->getDecl()->getName() << '\'';
    SuggestStatic = true;
  } else if (const ObjCIvarRegion *IVR = getParentIvarRegion(R)) {
    if (IVR != R)
      os << " memory within";
    os << " the instance variable '" << IVR->getDecl()->getName() << '\'';
  } else if (isa<HeapSpaceRegion>(RS)) {
    os << " heap-allocated memory";
  } else if (isa<UnknownSpaceRegion>(RS)) {
    // Presence of an IVar superregion has priority over this branch, because
    // ObjC objects are on the heap even if the core doesn't realize this.
    // Presence of a block variable base region has priority over this branch,
    // because block variables are known to be either on stack or on heap
    // (might actually move between the two, hence UnknownSpace).
    return;
  } else {
    os << " stack allocated memory";
  }
  os << " for the predicate value.  Using such transient memory for "
        "the predicate is potentially dangerous.";
  if (SuggestStatic)
    os << "  Perhaps you intended to declare the variable as 'static'?";

  ExplodedNode *N = C.generateErrorNode();
  if (!N)
    return;

  if (!BT_dispatchOnce)
    BT_dispatchOnce.reset(new BugType(this, "Improper use of 'dispatch_once'",
                                      "API Misuse (Apple)"));

  auto report =
      std::make_unique<PathSensitiveBugReport>(*BT_dispatchOnce, os.str(), N);
  report->addRange(CE->getArg(0)->getSourceRange());
  C.emitReport(std::move(report));
}

//===----------------------------------------------------------------------===//
// Central dispatch function.
//===----------------------------------------------------------------------===//

void MacOSXAPIChecker::checkPreStmt(const CallExpr *CE,
                                    CheckerContext &C) const {
  StringRef Name = C.getCalleeName(CE);
  if (Name.empty())
    return;

  SubChecker SC =
    llvm::StringSwitch<SubChecker>(Name)
      .Cases("dispatch_once",
             "_dispatch_once",
             "dispatch_once_f",
             &MacOSXAPIChecker::CheckDispatchOnce)
      .Default(nullptr);

  if (SC)
    (this->*SC)(C, CE, Name);
}

//===----------------------------------------------------------------------===//
// Registration.
//===----------------------------------------------------------------------===//

void ento::registerMacOSXAPIChecker(CheckerManager &mgr) {
  mgr.registerChecker<MacOSXAPIChecker>();
}

bool ento::shouldRegisterMacOSXAPIChecker(const LangOptions &LO) {
  return true;
}
