//===--- CallAndMessageChecker.cpp ------------------------------*- 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 CallAndMessageChecker, a builtin checker that checks for various
// errors of call and objc message expressions.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ExprCXX.h"
#include "clang/AST/ParentMap.h"
#include "clang/Basic/TargetInfo.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 "llvm/ADT/StringExtras.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace ento;

namespace {

class CallAndMessageChecker
    : public Checker<check::PreObjCMessage, check::ObjCMessageNil,
                     check::PreCall> {
  mutable std::unique_ptr<BugType> BT_call_null;
  mutable std::unique_ptr<BugType> BT_call_undef;
  mutable std::unique_ptr<BugType> BT_cxx_call_null;
  mutable std::unique_ptr<BugType> BT_cxx_call_undef;
  mutable std::unique_ptr<BugType> BT_call_arg;
  mutable std::unique_ptr<BugType> BT_cxx_delete_undef;
  mutable std::unique_ptr<BugType> BT_msg_undef;
  mutable std::unique_ptr<BugType> BT_objc_prop_undef;
  mutable std::unique_ptr<BugType> BT_objc_subscript_undef;
  mutable std::unique_ptr<BugType> BT_msg_arg;
  mutable std::unique_ptr<BugType> BT_msg_ret;
  mutable std::unique_ptr<BugType> BT_call_few_args;

public:
  // These correspond with the checker options. Looking at other checkers such
  // as MallocChecker and CStringChecker, this is similar as to how they pull
  // off having a modeling class, but emitting diagnostics under a smaller
  // checker's name that can be safely disabled without disturbing the
  // underlaying modeling engine.
  // The reason behind having *checker options* rather then actual *checkers*
  // here is that CallAndMessage is among the oldest checkers out there, and can
  // be responsible for the majority of the reports on any given project. This
  // is obviously not ideal, but changing checker name has the consequence of
  // changing the issue hashes associated with the reports, and databases
  // relying on this (CodeChecker, for instance) would suffer greatly.
  // If we ever end up making changes to the issue hash generation algorithm, or
  // the warning messages here, we should totally jump on the opportunity to
  // convert these to actual checkers.
  enum CheckKind {
    CK_FunctionPointer,
    CK_ParameterCount,
    CK_CXXThisMethodCall,
    CK_CXXDeallocationArg,
    CK_ArgInitializedness,
    CK_ArgPointeeInitializedness,
    CK_NilReceiver,
    CK_UndefReceiver,
    CK_NumCheckKinds
  };

  bool ChecksEnabled[CK_NumCheckKinds] = {false};
  // The original core.CallAndMessage checker name. This should rather be an
  // array, as seen in MallocChecker and CStringChecker.
  CheckerNameRef OriginalName;

  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;

  /// Fill in the return value that results from messaging nil based on the
  /// return type and architecture and diagnose if the return value will be
  /// garbage.
  void checkObjCMessageNil(const ObjCMethodCall &msg, CheckerContext &C) const;

  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;

  ProgramStateRef checkFunctionPointerCall(const CallExpr *CE,
                                           CheckerContext &C,
                                           ProgramStateRef State) const;

  ProgramStateRef checkCXXMethodCall(const CXXInstanceCall *CC,
                                     CheckerContext &C,
                                     ProgramStateRef State) const;

  ProgramStateRef checkParameterCount(const CallEvent &Call, CheckerContext &C,
                                      ProgramStateRef State) const;

  ProgramStateRef checkCXXDeallocation(const CXXDeallocatorCall *DC,
                                       CheckerContext &C,
                                       ProgramStateRef State) const;

  ProgramStateRef checkArgInitializedness(const CallEvent &Call,
                                          CheckerContext &C,
                                          ProgramStateRef State) const;

private:
  bool PreVisitProcessArg(CheckerContext &C, SVal V, SourceRange ArgRange,
                          const Expr *ArgEx, int ArgumentNumber,
                          bool CheckUninitFields, const CallEvent &Call,
                          std::unique_ptr<BugType> &BT,
                          const ParmVarDecl *ParamDecl) const;

  static void emitBadCall(BugType *BT, CheckerContext &C, const Expr *BadE);
  void emitNilReceiverBug(CheckerContext &C, const ObjCMethodCall &msg,
                          ExplodedNode *N) const;

  void HandleNilReceiver(CheckerContext &C,
                         ProgramStateRef state,
                         const ObjCMethodCall &msg) const;

  void LazyInit_BT(const char *desc, std::unique_ptr<BugType> &BT) const {
    if (!BT)
      BT.reset(new BugType(OriginalName, desc));
  }
  bool uninitRefOrPointer(CheckerContext &C, SVal V, SourceRange ArgRange,
                          const Expr *ArgEx, std::unique_ptr<BugType> &BT,
                          const ParmVarDecl *ParamDecl, const char *BD,
                          int ArgumentNumber) const;
};
} // end anonymous namespace

void CallAndMessageChecker::emitBadCall(BugType *BT, CheckerContext &C,
                                        const Expr *BadE) {
  ExplodedNode *N = C.generateErrorNode();
  if (!N)
    return;

  auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
  if (BadE) {
    R->addRange(BadE->getSourceRange());
    if (BadE->isGLValue())
      BadE = bugreporter::getDerefExpr(BadE);
    bugreporter::trackExpressionValue(N, BadE, *R);
  }
  C.emitReport(std::move(R));
}

static void describeUninitializedArgumentInCall(const CallEvent &Call,
                                                int ArgumentNumber,
                                                llvm::raw_svector_ostream &Os) {
  switch (Call.getKind()) {
  case CE_ObjCMessage: {
    const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);
    switch (Msg.getMessageKind()) {
    case OCM_Message:
      Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
         << " argument in message expression is an uninitialized value";
      return;
    case OCM_PropertyAccess:
      assert(Msg.isSetter() && "Getters have no args");
      Os << "Argument for property setter is an uninitialized value";
      return;
    case OCM_Subscript:
      if (Msg.isSetter() && (ArgumentNumber == 0))
        Os << "Argument for subscript setter is an uninitialized value";
      else
        Os << "Subscript index is an uninitialized value";
      return;
    }
    llvm_unreachable("Unknown message kind.");
  }
  case CE_Block:
    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
       << " block call argument is an uninitialized value";
    return;
  default:
    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
       << " function call argument is an uninitialized value";
    return;
  }
}

bool CallAndMessageChecker::uninitRefOrPointer(
    CheckerContext &C, SVal V, SourceRange ArgRange, const Expr *ArgEx,
    std::unique_ptr<BugType> &BT, const ParmVarDecl *ParamDecl, const char *BD,
    int ArgumentNumber) const {

  // The pointee being uninitialized is a sign of code smell, not a bug, no need
  // to sink here.
  if (!ChecksEnabled[CK_ArgPointeeInitializedness])
    return false;

  // No parameter declaration available, i.e. variadic function argument.
  if(!ParamDecl)
    return false;

  // If parameter is declared as pointer to const in function declaration,
  // then check if corresponding argument in function call is
  // pointing to undefined symbol value (uninitialized memory).
  SmallString<200> Buf;
  llvm::raw_svector_ostream Os(Buf);

  if (ParamDecl->getType()->isPointerType()) {
    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
       << " function call argument is a pointer to uninitialized value";
  } else if (ParamDecl->getType()->isReferenceType()) {
    Os << (ArgumentNumber + 1) << llvm::getOrdinalSuffix(ArgumentNumber + 1)
       << " function call argument is an uninitialized value";
  } else
    return false;

  if(!ParamDecl->getType()->getPointeeType().isConstQualified())
    return false;

  if (const MemRegion *SValMemRegion = V.getAsRegion()) {
    const ProgramStateRef State = C.getState();
    const SVal PSV = State->getSVal(SValMemRegion, C.getASTContext().CharTy);
    if (PSV.isUndef()) {
      if (ExplodedNode *N = C.generateErrorNode()) {
        LazyInit_BT(BD, BT);
        auto R = std::make_unique<PathSensitiveBugReport>(*BT, Os.str(), N);
        R->addRange(ArgRange);
        if (ArgEx)
          bugreporter::trackExpressionValue(N, ArgEx, *R);

        C.emitReport(std::move(R));
      }
      return true;
    }
  }
  return false;
}

namespace {
class FindUninitializedField {
public:
  SmallVector<const FieldDecl *, 10> FieldChain;

private:
  StoreManager &StoreMgr;
  MemRegionManager &MrMgr;
  Store store;

public:
  FindUninitializedField(StoreManager &storeMgr, MemRegionManager &mrMgr,
                         Store s)
      : StoreMgr(storeMgr), MrMgr(mrMgr), store(s) {}

  bool Find(const TypedValueRegion *R) {
    QualType T = R->getValueType();
    if (const RecordType *RT = T->getAsStructureType()) {
      const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
      assert(RD && "Referred record has no definition");
      for (const auto *I : RD->fields()) {
        if (I->isUnnamedBitField())
          continue;
        const FieldRegion *FR = MrMgr.getFieldRegion(I, R);
        FieldChain.push_back(I);
        T = I->getType();
        if (T->getAsStructureType()) {
          if (Find(FR))
            return true;
        } else {
          SVal V = StoreMgr.getBinding(store, loc::MemRegionVal(FR));
          if (V.isUndef())
            return true;
        }
        FieldChain.pop_back();
      }
    }

    return false;
  }
};
} // namespace

bool CallAndMessageChecker::PreVisitProcessArg(CheckerContext &C,
                                               SVal V,
                                               SourceRange ArgRange,
                                               const Expr *ArgEx,
                                               int ArgumentNumber,
                                               bool CheckUninitFields,
                                               const CallEvent &Call,
                                               std::unique_ptr<BugType> &BT,
                                               const ParmVarDecl *ParamDecl
                                               ) const {
  const char *BD = "Uninitialized argument value";

  if (uninitRefOrPointer(C, V, ArgRange, ArgEx, BT, ParamDecl, BD,
                         ArgumentNumber))
    return true;

  if (V.isUndef()) {
    if (!ChecksEnabled[CK_ArgInitializedness]) {
      C.addSink();
      return true;
    }
    if (ExplodedNode *N = C.generateErrorNode()) {
      LazyInit_BT(BD, BT);
      // Generate a report for this bug.
      SmallString<200> Buf;
      llvm::raw_svector_ostream Os(Buf);
      describeUninitializedArgumentInCall(Call, ArgumentNumber, Os);
      auto R = std::make_unique<PathSensitiveBugReport>(*BT, Os.str(), N);

      R->addRange(ArgRange);
      if (ArgEx)
        bugreporter::trackExpressionValue(N, ArgEx, *R);
      C.emitReport(std::move(R));
    }
    return true;
  }

  if (!CheckUninitFields)
    return false;

  if (auto LV = V.getAs<nonloc::LazyCompoundVal>()) {
    const LazyCompoundValData *D = LV->getCVData();
    FindUninitializedField F(C.getState()->getStateManager().getStoreManager(),
                             C.getSValBuilder().getRegionManager(),
                             D->getStore());

    if (F.Find(D->getRegion())) {
      if (!ChecksEnabled[CK_ArgInitializedness]) {
        C.addSink();
        return true;
      }
      if (ExplodedNode *N = C.generateErrorNode()) {
        LazyInit_BT(BD, BT);
        SmallString<512> Str;
        llvm::raw_svector_ostream os(Str);
        os << "Passed-by-value struct argument contains uninitialized data";

        if (F.FieldChain.size() == 1)
          os << " (e.g., field: '" << *F.FieldChain[0] << "')";
        else {
          os << " (e.g., via the field chain: '";
          bool first = true;
          for (SmallVectorImpl<const FieldDecl *>::iterator
               DI = F.FieldChain.begin(), DE = F.FieldChain.end(); DI!=DE;++DI){
            if (first)
              first = false;
            else
              os << '.';
            os << **DI;
          }
          os << "')";
        }

        // Generate a report for this bug.
        auto R = std::make_unique<PathSensitiveBugReport>(*BT, os.str(), N);
        R->addRange(ArgRange);

        if (ArgEx)
          bugreporter::trackExpressionValue(N, ArgEx, *R);
        // FIXME: enhance track back for uninitialized value for arbitrary
        // memregions
        C.emitReport(std::move(R));
      }
      return true;
    }
  }

  return false;
}

ProgramStateRef CallAndMessageChecker::checkFunctionPointerCall(
    const CallExpr *CE, CheckerContext &C, ProgramStateRef State) const {

  const Expr *Callee = CE->getCallee()->IgnoreParens();
  const LocationContext *LCtx = C.getLocationContext();
  SVal L = State->getSVal(Callee, LCtx);

  if (L.isUndef()) {
    if (!ChecksEnabled[CK_FunctionPointer]) {
      C.addSink(State);
      return nullptr;
    }
    if (!BT_call_undef)
      BT_call_undef.reset(new BugType(
          OriginalName,
          "Called function pointer is an uninitialized pointer value"));
    emitBadCall(BT_call_undef.get(), C, Callee);
    return nullptr;
  }

  ProgramStateRef StNonNull, StNull;
  std::tie(StNonNull, StNull) = State->assume(L.castAs<DefinedOrUnknownSVal>());

  if (StNull && !StNonNull) {
    if (!ChecksEnabled[CK_FunctionPointer]) {
      C.addSink(StNull);
      return nullptr;
    }
    if (!BT_call_null)
      BT_call_null.reset(new BugType(
          OriginalName, "Called function pointer is null (null dereference)"));
    emitBadCall(BT_call_null.get(), C, Callee);
    return nullptr;
  }

  return StNonNull;
}

ProgramStateRef CallAndMessageChecker::checkParameterCount(
    const CallEvent &Call, CheckerContext &C, ProgramStateRef State) const {

  // If we have a function or block declaration, we can make sure we pass
  // enough parameters.
  unsigned Params = Call.parameters().size();
  if (Call.getNumArgs() >= Params)
    return State;

  if (!ChecksEnabled[CK_ParameterCount]) {
    C.addSink(State);
    return nullptr;
  }

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

  LazyInit_BT("Function call with too few arguments", BT_call_few_args);

  SmallString<512> Str;
  llvm::raw_svector_ostream os(Str);
  if (isa<AnyFunctionCall>(Call)) {
    os << "Function ";
  } else {
    assert(isa<BlockCall>(Call));
    os << "Block ";
  }
  os << "taking " << Params << " argument" << (Params == 1 ? "" : "s")
     << " is called with fewer (" << Call.getNumArgs() << ")";

  C.emitReport(
      std::make_unique<PathSensitiveBugReport>(*BT_call_few_args, os.str(), N));
  return nullptr;
}

ProgramStateRef CallAndMessageChecker::checkCXXMethodCall(
    const CXXInstanceCall *CC, CheckerContext &C, ProgramStateRef State) const {

  SVal V = CC->getCXXThisVal();
  if (V.isUndef()) {
    if (!ChecksEnabled[CK_CXXThisMethodCall]) {
      C.addSink(State);
      return nullptr;
    }
    if (!BT_cxx_call_undef)
      BT_cxx_call_undef.reset(new BugType(
          OriginalName, "Called C++ object pointer is uninitialized"));
    emitBadCall(BT_cxx_call_undef.get(), C, CC->getCXXThisExpr());
    return nullptr;
  }

  ProgramStateRef StNonNull, StNull;
  std::tie(StNonNull, StNull) = State->assume(V.castAs<DefinedOrUnknownSVal>());

  if (StNull && !StNonNull) {
    if (!ChecksEnabled[CK_CXXThisMethodCall]) {
      C.addSink(StNull);
      return nullptr;
    }
    if (!BT_cxx_call_null)
      BT_cxx_call_null.reset(
          new BugType(OriginalName, "Called C++ object pointer is null"));
    emitBadCall(BT_cxx_call_null.get(), C, CC->getCXXThisExpr());
    return nullptr;
  }

  return StNonNull;
}

ProgramStateRef
CallAndMessageChecker::checkCXXDeallocation(const CXXDeallocatorCall *DC,
                                            CheckerContext &C,
                                            ProgramStateRef State) const {
  const CXXDeleteExpr *DE = DC->getOriginExpr();
  assert(DE);
  SVal Arg = C.getSVal(DE->getArgument());
  if (!Arg.isUndef())
    return State;

  if (!ChecksEnabled[CK_CXXDeallocationArg]) {
    C.addSink(State);
    return nullptr;
  }

  StringRef Desc;
  ExplodedNode *N = C.generateErrorNode();
  if (!N)
    return nullptr;
  if (!BT_cxx_delete_undef)
    BT_cxx_delete_undef.reset(
        new BugType(OriginalName, "Uninitialized argument value"));
  if (DE->isArrayFormAsWritten())
    Desc = "Argument to 'delete[]' is uninitialized";
  else
    Desc = "Argument to 'delete' is uninitialized";
  auto R =
      std::make_unique<PathSensitiveBugReport>(*BT_cxx_delete_undef, Desc, N);
  bugreporter::trackExpressionValue(N, DE, *R);
  C.emitReport(std::move(R));
  return nullptr;
}

ProgramStateRef CallAndMessageChecker::checkArgInitializedness(
    const CallEvent &Call, CheckerContext &C, ProgramStateRef State) const {

  const Decl *D = Call.getDecl();

  // Don't check for uninitialized field values in arguments if the
  // caller has a body that is available and we have the chance to inline it.
  // This is a hack, but is a reasonable compromise betweens sometimes warning
  // and sometimes not depending on if we decide to inline a function.
  const bool checkUninitFields =
      !(C.getAnalysisManager().shouldInlineCall() && (D && D->getBody()));

  std::unique_ptr<BugType> *BT;
  if (isa<ObjCMethodCall>(Call))
    BT = &BT_msg_arg;
  else
    BT = &BT_call_arg;

  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
  for (unsigned i = 0, e = Call.getNumArgs(); i != e; ++i) {
    const ParmVarDecl *ParamDecl = nullptr;
    if (FD && i < FD->getNumParams())
      ParamDecl = FD->getParamDecl(i);
    if (PreVisitProcessArg(C, Call.getArgSVal(i), Call.getArgSourceRange(i),
                           Call.getArgExpr(i), i, checkUninitFields, Call, *BT,
                           ParamDecl))
      return nullptr;
  }
  return State;
}

void CallAndMessageChecker::checkPreCall(const CallEvent &Call,
                                         CheckerContext &C) const {
  ProgramStateRef State = C.getState();

  if (const CallExpr *CE = dyn_cast_or_null<CallExpr>(Call.getOriginExpr()))
    State = checkFunctionPointerCall(CE, C, State);

  if (!State)
    return;

  if (Call.getDecl())
    State = checkParameterCount(Call, C, State);

  if (!State)
    return;

  if (const auto *CC = dyn_cast<CXXInstanceCall>(&Call))
    State = checkCXXMethodCall(CC, C, State);

  if (!State)
    return;

  if (const auto *DC = dyn_cast<CXXDeallocatorCall>(&Call))
    State = checkCXXDeallocation(DC, C, State);

  if (!State)
    return;

  State = checkArgInitializedness(Call, C, State);

  // If we make it here, record our assumptions about the callee.
  C.addTransition(State);
}

void CallAndMessageChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                CheckerContext &C) const {
  SVal recVal = msg.getReceiverSVal();
  if (recVal.isUndef()) {
    if (!ChecksEnabled[CK_UndefReceiver]) {
      C.addSink();
      return;
    }
    if (ExplodedNode *N = C.generateErrorNode()) {
      BugType *BT = nullptr;
      switch (msg.getMessageKind()) {
      case OCM_Message:
        if (!BT_msg_undef)
          BT_msg_undef.reset(new BugType(OriginalName,
                                         "Receiver in message expression "
                                         "is an uninitialized value"));
        BT = BT_msg_undef.get();
        break;
      case OCM_PropertyAccess:
        if (!BT_objc_prop_undef)
          BT_objc_prop_undef.reset(new BugType(
              OriginalName,
              "Property access on an uninitialized object pointer"));
        BT = BT_objc_prop_undef.get();
        break;
      case OCM_Subscript:
        if (!BT_objc_subscript_undef)
          BT_objc_subscript_undef.reset(new BugType(
              OriginalName,
              "Subscript access on an uninitialized object pointer"));
        BT = BT_objc_subscript_undef.get();
        break;
      }
      assert(BT && "Unknown message kind.");

      auto R = std::make_unique<PathSensitiveBugReport>(*BT, BT->getDescription(), N);
      const ObjCMessageExpr *ME = msg.getOriginExpr();
      R->addRange(ME->getReceiverRange());

      // FIXME: getTrackNullOrUndefValueVisitor can't handle "super" yet.
      if (const Expr *ReceiverE = ME->getInstanceReceiver())
        bugreporter::trackExpressionValue(N, ReceiverE, *R);
      C.emitReport(std::move(R));
    }
    return;
  }
}

void CallAndMessageChecker::checkObjCMessageNil(const ObjCMethodCall &msg,
                                                CheckerContext &C) const {
  HandleNilReceiver(C, C.getState(), msg);
}

void CallAndMessageChecker::emitNilReceiverBug(CheckerContext &C,
                                               const ObjCMethodCall &msg,
                                               ExplodedNode *N) const {
  if (!ChecksEnabled[CK_NilReceiver]) {
    C.addSink();
    return;
  }

  if (!BT_msg_ret)
    BT_msg_ret.reset(
        new BugType(OriginalName, "Receiver in message expression is 'nil'"));

  const ObjCMessageExpr *ME = msg.getOriginExpr();

  QualType ResTy = msg.getResultType();

  SmallString<200> buf;
  llvm::raw_svector_ostream os(buf);
  os << "The receiver of message '";
  ME->getSelector().print(os);
  os << "' is nil";
  if (ResTy->isReferenceType()) {
    os << ", which results in forming a null reference";
  } else {
    os << " and returns a value of type '";
    msg.getResultType().print(os, C.getLangOpts());
    os << "' that will be garbage";
  }

  auto report =
      std::make_unique<PathSensitiveBugReport>(*BT_msg_ret, os.str(), N);
  report->addRange(ME->getReceiverRange());
  // FIXME: This won't track "self" in messages to super.
  if (const Expr *receiver = ME->getInstanceReceiver()) {
    bugreporter::trackExpressionValue(N, receiver, *report);
  }
  C.emitReport(std::move(report));
}

static bool supportsNilWithFloatRet(const llvm::Triple &triple) {
  return (triple.getVendor() == llvm::Triple::Apple &&
          (triple.isiOS() || triple.isWatchOS() ||
           !triple.isMacOSXVersionLT(10,5)));
}

void CallAndMessageChecker::HandleNilReceiver(CheckerContext &C,
                                              ProgramStateRef state,
                                              const ObjCMethodCall &Msg) const {
  ASTContext &Ctx = C.getASTContext();

  // Check the return type of the message expression.  A message to nil will
  // return different values depending on the return type and the architecture.
  QualType RetTy = Msg.getResultType();
  CanQualType CanRetTy = Ctx.getCanonicalType(RetTy);
  const LocationContext *LCtx = C.getLocationContext();

  if (CanRetTy->isStructureOrClassType()) {
    // Structure returns are safe since the compiler zeroes them out.
    SVal V = C.getSValBuilder().makeZeroVal(RetTy);
    C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V));
    return;
  }

  // Other cases: check if sizeof(return type) > sizeof(void*)
  if (CanRetTy != Ctx.VoidTy && C.getLocationContext()->getParentMap()
                                  .isConsumedExpr(Msg.getOriginExpr())) {
    // Compute: sizeof(void *) and sizeof(return type)
    const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
    const uint64_t returnTypeSize = Ctx.getTypeSize(CanRetTy);

    if (CanRetTy.getTypePtr()->isReferenceType()||
        (voidPtrSize < returnTypeSize &&
         !(supportsNilWithFloatRet(Ctx.getTargetInfo().getTriple()) &&
           (Ctx.FloatTy == CanRetTy ||
            Ctx.DoubleTy == CanRetTy ||
            Ctx.LongDoubleTy == CanRetTy ||
            Ctx.LongLongTy == CanRetTy ||
            Ctx.UnsignedLongLongTy == CanRetTy)))) {
      if (ExplodedNode *N = C.generateErrorNode(state))
        emitNilReceiverBug(C, Msg, N);
      return;
    }

    // Handle the safe cases where the return value is 0 if the
    // receiver is nil.
    //
    // FIXME: For now take the conservative approach that we only
    // return null values if we *know* that the receiver is nil.
    // This is because we can have surprises like:
    //
    //   ... = [[NSScreens screens] objectAtIndex:0];
    //
    // What can happen is that [... screens] could return nil, but
    // it most likely isn't nil.  We should assume the semantics
    // of this case unless we have *a lot* more knowledge.
    //
    SVal V = C.getSValBuilder().makeZeroVal(RetTy);
    C.addTransition(state->BindExpr(Msg.getOriginExpr(), LCtx, V));
    return;
  }

  C.addTransition(state);
}

void ento::registerCallAndMessageModeling(CheckerManager &mgr) {
  mgr.registerChecker<CallAndMessageChecker>();
}

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

void ento::registerCallAndMessageChecker(CheckerManager &mgr) {
  CallAndMessageChecker *checker = mgr.getChecker<CallAndMessageChecker>();

  checker->OriginalName = mgr.getCurrentCheckerName();

#define QUERY_CHECKER_OPTION(OPTION)                                           \
  checker->ChecksEnabled[CallAndMessageChecker::CK_##OPTION] =                 \
      mgr.getAnalyzerOptions().getCheckerBooleanOption(                        \
          mgr.getCurrentCheckerName(), #OPTION);

  QUERY_CHECKER_OPTION(FunctionPointer)
  QUERY_CHECKER_OPTION(ParameterCount)
  QUERY_CHECKER_OPTION(CXXThisMethodCall)
  QUERY_CHECKER_OPTION(CXXDeallocationArg)
  QUERY_CHECKER_OPTION(ArgInitializedness)
  QUERY_CHECKER_OPTION(ArgPointeeInitializedness)
  QUERY_CHECKER_OPTION(NilReceiver)
  QUERY_CHECKER_OPTION(UndefReceiver)
}

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