//== BasicObjCFoundationChecks.cpp - Simple Apple-Foundation checks -*- C++ -*--
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines BasicObjCFoundationChecks, a class that encapsulates
//  a set of simple checks to run on Objective-C code using Apple's Foundation
//  classes.
//
//===----------------------------------------------------------------------===//

#include "BasicObjCFoundationChecks.h"

#include "clang/Checker/PathSensitive/ExplodedGraph.h"
#include "clang/Checker/PathSensitive/GRSimpleAPICheck.h"
#include "clang/Checker/PathSensitive/GRExprEngine.h"
#include "clang/Checker/PathSensitive/GRState.h"
#include "clang/Checker/BugReporter/BugType.h"
#include "clang/Checker/PathSensitive/MemRegion.h"
#include "clang/Checker/PathSensitive/CheckerVisitor.h"
#include "clang/Checker/Checkers/LocalCheckers.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/ASTContext.h"

using namespace clang;

static const ObjCInterfaceType* GetReceiverType(const ObjCMessageExpr* ME) {
  QualType T;
  switch (ME->getReceiverKind()) {
  case ObjCMessageExpr::Instance:
    T = ME->getInstanceReceiver()->getType();
    break;

  case ObjCMessageExpr::SuperInstance:
    T = ME->getSuperType();
    break;

  case ObjCMessageExpr::Class:
  case ObjCMessageExpr::SuperClass:
    return 0;
  }

  if (const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>())
    return PT->getInterfaceType();

  return NULL;
}

static const char* GetReceiverNameType(const ObjCMessageExpr* ME) {
  if (const ObjCInterfaceType *ReceiverType = GetReceiverType(ME))
    return ReceiverType->getDecl()->getIdentifier()->getNameStart();
  return NULL;
}

namespace {

class APIMisuse : public BugType {
public:
  APIMisuse(const char* name) : BugType(name, "API Misuse (Apple)") {}
};

class BasicObjCFoundationChecks : public GRSimpleAPICheck {
  APIMisuse *BT;
  BugReporter& BR;
  ASTContext &Ctx;

  bool isNSString(const ObjCInterfaceType *T, llvm::StringRef suffix);
  bool AuditNSString(ExplodedNode* N, const ObjCMessageExpr* ME);

  bool CheckNilArg(ExplodedNode* N, unsigned Arg);

public:
  BasicObjCFoundationChecks(ASTContext& ctx, BugReporter& br)
    : BT(0), BR(br), Ctx(ctx) {}

  bool Audit(ExplodedNode* N, GRStateManager&);

private:
  void WarnNilArg(ExplodedNode* N, const ObjCMessageExpr* ME, unsigned Arg) {
    std::string sbuf;
    llvm::raw_string_ostream os(sbuf);
    os << "Argument to '" << GetReceiverNameType(ME) << "' method '"
       << ME->getSelector().getAsString() << "' cannot be nil.";

    // Lazily create the BugType object for NilArg.  This will be owned
    // by the BugReporter object 'BR' once we call BR.EmitWarning.
    if (!BT) BT = new APIMisuse("nil argument");

    RangedBugReport *R = new RangedBugReport(*BT, os.str(), N);
    R->addRange(ME->getArg(Arg)->getSourceRange());
    BR.EmitReport(R);
  }
};

} // end anonymous namespace


GRSimpleAPICheck*
clang::CreateBasicObjCFoundationChecks(ASTContext& Ctx, BugReporter& BR) {
  return new BasicObjCFoundationChecks(Ctx, BR);
}



bool BasicObjCFoundationChecks::Audit(ExplodedNode* N,
                                      GRStateManager&) {

  const ObjCMessageExpr* ME =
    cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());

  const ObjCInterfaceType *ReceiverType = GetReceiverType(ME);

  if (!ReceiverType)
    return false;

  if (isNSString(ReceiverType,
                 ReceiverType->getDecl()->getIdentifier()->getName()))
    return AuditNSString(N, ME);

  return false;
}

static inline bool isNil(SVal X) {
  return isa<loc::ConcreteInt>(X);
}

//===----------------------------------------------------------------------===//
// Error reporting.
//===----------------------------------------------------------------------===//

bool BasicObjCFoundationChecks::CheckNilArg(ExplodedNode* N, unsigned Arg) {
  const ObjCMessageExpr* ME =
    cast<ObjCMessageExpr>(cast<PostStmt>(N->getLocation()).getStmt());

  const Expr * E = ME->getArg(Arg);

  if (isNil(N->getState()->getSVal(E))) {
    WarnNilArg(N, ME, Arg);
    return true;
  }

  return false;
}

//===----------------------------------------------------------------------===//
// NSString checking.
//===----------------------------------------------------------------------===//

bool BasicObjCFoundationChecks::isNSString(const ObjCInterfaceType *T,
                                           llvm::StringRef ClassName) {
  return ClassName == "NSString" || ClassName == "NSMutableString";
}

bool BasicObjCFoundationChecks::AuditNSString(ExplodedNode* N,
                                              const ObjCMessageExpr* ME) {

  Selector S = ME->getSelector();

  if (S.isUnarySelector())
    return false;

  // FIXME: This is going to be really slow doing these checks with
  //  lexical comparisons.

  std::string NameStr = S.getAsString();
  llvm::StringRef Name(NameStr);
  assert(!Name.empty());

  // FIXME: Checking for initWithFormat: will not work in most cases
  //  yet because [NSString alloc] returns id, not NSString*.  We will
  //  need support for tracking expected-type information in the analyzer
  //  to find these errors.
  if (Name == "caseInsensitiveCompare:" ||
      Name == "compare:" ||
      Name == "compare:options:" ||
      Name == "compare:options:range:" ||
      Name == "compare:options:range:locale:" ||
      Name == "componentsSeparatedByCharactersInSet:" ||
      Name == "initWithFormat:")
    return CheckNilArg(N, 0);

  return false;
}

//===----------------------------------------------------------------------===//
// Error reporting.
//===----------------------------------------------------------------------===//

namespace {

class AuditCFNumberCreate : public GRSimpleAPICheck {
  APIMisuse* BT;

  // FIXME: Either this should be refactored into GRSimpleAPICheck, or
  //   it should always be passed with a call to Audit.  The latter
  //   approach makes this class more stateless.
  ASTContext& Ctx;
  IdentifierInfo* II;
  BugReporter& BR;

public:
  AuditCFNumberCreate(ASTContext& ctx, BugReporter& br)
  : BT(0), Ctx(ctx), II(&Ctx.Idents.get("CFNumberCreate")), BR(br){}

  ~AuditCFNumberCreate() {}

  bool Audit(ExplodedNode* N, GRStateManager&);

private:
  void AddError(const TypedRegion* R, const Expr* Ex, ExplodedNode *N,
                uint64_t SourceSize, uint64_t TargetSize, uint64_t NumberKind);
};
} // end anonymous namespace

enum CFNumberType {
  kCFNumberSInt8Type = 1,
  kCFNumberSInt16Type = 2,
  kCFNumberSInt32Type = 3,
  kCFNumberSInt64Type = 4,
  kCFNumberFloat32Type = 5,
  kCFNumberFloat64Type = 6,
  kCFNumberCharType = 7,
  kCFNumberShortType = 8,
  kCFNumberIntType = 9,
  kCFNumberLongType = 10,
  kCFNumberLongLongType = 11,
  kCFNumberFloatType = 12,
  kCFNumberDoubleType = 13,
  kCFNumberCFIndexType = 14,
  kCFNumberNSIntegerType = 15,
  kCFNumberCGFloatType = 16
};

namespace {
  template<typename T>
  class Optional {
    bool IsKnown;
    T Val;
  public:
    Optional() : IsKnown(false), Val(0) {}
    Optional(const T& val) : IsKnown(true), Val(val) {}

    bool isKnown() const { return IsKnown; }

    const T& getValue() const {
      assert (isKnown());
      return Val;
    }

    operator const T&() const {
      return getValue();
    }
  };
}

static Optional<uint64_t> GetCFNumberSize(ASTContext& Ctx, uint64_t i) {
  static const unsigned char FixedSize[] = { 8, 16, 32, 64, 32, 64 };

  if (i < kCFNumberCharType)
    return FixedSize[i-1];

  QualType T;

  switch (i) {
    case kCFNumberCharType:     T = Ctx.CharTy;     break;
    case kCFNumberShortType:    T = Ctx.ShortTy;    break;
    case kCFNumberIntType:      T = Ctx.IntTy;      break;
    case kCFNumberLongType:     T = Ctx.LongTy;     break;
    case kCFNumberLongLongType: T = Ctx.LongLongTy; break;
    case kCFNumberFloatType:    T = Ctx.FloatTy;    break;
    case kCFNumberDoubleType:   T = Ctx.DoubleTy;   break;
    case kCFNumberCFIndexType:
    case kCFNumberNSIntegerType:
    case kCFNumberCGFloatType:
      // FIXME: We need a way to map from names to Type*.
    default:
      return Optional<uint64_t>();
  }

  return Ctx.getTypeSize(T);
}

#if 0
static const char* GetCFNumberTypeStr(uint64_t i) {
  static const char* Names[] = {
    "kCFNumberSInt8Type",
    "kCFNumberSInt16Type",
    "kCFNumberSInt32Type",
    "kCFNumberSInt64Type",
    "kCFNumberFloat32Type",
    "kCFNumberFloat64Type",
    "kCFNumberCharType",
    "kCFNumberShortType",
    "kCFNumberIntType",
    "kCFNumberLongType",
    "kCFNumberLongLongType",
    "kCFNumberFloatType",
    "kCFNumberDoubleType",
    "kCFNumberCFIndexType",
    "kCFNumberNSIntegerType",
    "kCFNumberCGFloatType"
  };

  return i <= kCFNumberCGFloatType ? Names[i-1] : "Invalid CFNumberType";
}
#endif

bool AuditCFNumberCreate::Audit(ExplodedNode* N,GRStateManager&){
  const CallExpr* CE =
    cast<CallExpr>(cast<PostStmt>(N->getLocation()).getStmt());
  const Expr* Callee = CE->getCallee();
  SVal CallV = N->getState()->getSVal(Callee);
  const FunctionDecl* FD = CallV.getAsFunctionDecl();

  if (!FD || FD->getIdentifier() != II || CE->getNumArgs()!=3)
    return false;

  // Get the value of the "theType" argument.
  SVal TheTypeVal = N->getState()->getSVal(CE->getArg(1));

    // FIXME: We really should allow ranges of valid theType values, and
    //   bifurcate the state appropriately.
  nonloc::ConcreteInt* V = dyn_cast<nonloc::ConcreteInt>(&TheTypeVal);

  if (!V)
    return false;

  uint64_t NumberKind = V->getValue().getLimitedValue();
  Optional<uint64_t> TargetSize = GetCFNumberSize(Ctx, NumberKind);

  // FIXME: In some cases we can emit an error.
  if (!TargetSize.isKnown())
    return false;

  // Look at the value of the integer being passed by reference.  Essentially
  // we want to catch cases where the value passed in is not equal to the
  // size of the type being created.
  SVal TheValueExpr = N->getState()->getSVal(CE->getArg(2));

  // FIXME: Eventually we should handle arbitrary locations.  We can do this
  //  by having an enhanced memory model that does low-level typing.
  loc::MemRegionVal* LV = dyn_cast<loc::MemRegionVal>(&TheValueExpr);

  if (!LV)
    return false;

  const TypedRegion* R = dyn_cast<TypedRegion>(LV->StripCasts());

  if (!R)
    return false;

  QualType T = Ctx.getCanonicalType(R->getValueType());

  // FIXME: If the pointee isn't an integer type, should we flag a warning?
  //  People can do weird stuff with pointers.

  if (!T->isIntegerType())
    return false;

  uint64_t SourceSize = Ctx.getTypeSize(T);

  // CHECK: is SourceSize == TargetSize

  if (SourceSize == TargetSize)
    return false;

  AddError(R, CE->getArg(2), N, SourceSize, TargetSize, NumberKind);

  // FIXME: We can actually create an abstract "CFNumber" object that has
  //  the bits initialized to the provided values.
  return SourceSize < TargetSize;
}

void AuditCFNumberCreate::AddError(const TypedRegion* R, const Expr* Ex,
                                   ExplodedNode *N,
                                   uint64_t SourceSize, uint64_t TargetSize,
                                   uint64_t NumberKind) {

  std::string sbuf;
  llvm::raw_string_ostream os(sbuf);

  os << (SourceSize == 8 ? "An " : "A ")
     << SourceSize << " bit integer is used to initialize a CFNumber "
        "object that represents "
     << (TargetSize == 8 ? "an " : "a ")
     << TargetSize << " bit integer. ";

  if (SourceSize < TargetSize)
    os << (TargetSize - SourceSize)
       << " bits of the CFNumber value will be garbage." ;
  else
    os << (SourceSize - TargetSize)
       << " bits of the input integer will be lost.";

  // Lazily create the BugType object.  This will be owned
  // by the BugReporter object 'BR' once we call BR.EmitWarning.
  if (!BT) BT = new APIMisuse("Bad use of CFNumberCreate");
  RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
  report->addRange(Ex->getSourceRange());
  BR.EmitReport(report);
}

GRSimpleAPICheck*
clang::CreateAuditCFNumberCreate(ASTContext& Ctx, BugReporter& BR) {
  return new AuditCFNumberCreate(Ctx, BR);
}

//===----------------------------------------------------------------------===//
// CFRetain/CFRelease checking for null arguments.
//===----------------------------------------------------------------------===//

namespace {
class CFRetainReleaseChecker : public CheckerVisitor<CFRetainReleaseChecker> {
  APIMisuse *BT;
  IdentifierInfo *Retain, *Release;

public:
  CFRetainReleaseChecker(ASTContext& Ctx): BT(NULL),
    Retain(&Ctx.Idents.get("CFRetain")), Release(&Ctx.Idents.get("CFRelease"))
    {}

  static void *getTag() { static int x = 0; return &x; }

  void PreVisitCallExpr(CheckerContext& C, const CallExpr* CE);
};
} // end anonymous namespace


void CFRetainReleaseChecker::PreVisitCallExpr(CheckerContext& C,
                                              const CallExpr* CE) {
  // If the CallExpr doesn't have exactly 1 argument just give up checking.
  if (CE->getNumArgs() != 1)
    return;

  // Get the function declaration of the callee.
  const GRState* state = C.getState();
  SVal X = state->getSVal(CE->getCallee());
  const FunctionDecl* FD = X.getAsFunctionDecl();

  if (!FD)
    return;

  // Check if we called CFRetain/CFRelease.
  const IdentifierInfo *FuncII = FD->getIdentifier();
  if (!(FuncII == Retain || FuncII == Release))
    return;

  // FIXME: The rest of this just checks that the argument is non-null.
  // It should probably be refactored and combined with AttrNonNullChecker.

  // Get the argument's value.
  const Expr *Arg = CE->getArg(0);
  SVal ArgVal = state->getSVal(Arg);
  DefinedSVal *DefArgVal = dyn_cast<DefinedSVal>(&ArgVal);
  if (!DefArgVal)
    return;

  // Get a NULL value.
  ValueManager &ValMgr = C.getValueManager();
  DefinedSVal Zero = cast<DefinedSVal>(ValMgr.makeZeroVal(Arg->getType()));

  // Make an expression asserting that they're equal.
  SValuator &SVator = ValMgr.getSValuator();
  DefinedOrUnknownSVal ArgIsNull = SVator.EvalEQ(state, Zero, *DefArgVal);

  // Are they equal?
  const GRState *stateTrue, *stateFalse;
  llvm::tie(stateTrue, stateFalse) = state->Assume(ArgIsNull);

  if (stateTrue && !stateFalse) {
    ExplodedNode *N = C.GenerateSink(stateTrue);
    if (!N)
      return;

    if (!BT)
      BT = new APIMisuse("null passed to CFRetain/CFRelease");

    const char *description = (FuncII == Retain)
                            ? "Null pointer argument in call to CFRetain"
                            : "Null pointer argument in call to CFRelease";

    EnhancedBugReport *report = new EnhancedBugReport(*BT, description, N);
    report->addRange(Arg->getSourceRange());
    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue, Arg);

    C.EmitReport(report);
    return;
  }

  // From here on, we know the argument is non-null.
  C.addTransition(stateFalse);
}

//===----------------------------------------------------------------------===//
// Check for sending 'retain', 'release', or 'autorelease' directly to a Class.
//===----------------------------------------------------------------------===//

namespace {
class ClassReleaseChecker :
    public CheckerVisitor<ClassReleaseChecker> {
  Selector releaseS;
  Selector retainS;
  Selector autoreleaseS;
  Selector drainS;
  BugType *BT;
public:
  ClassReleaseChecker(ASTContext &Ctx)
    : releaseS(GetNullarySelector("release", Ctx)),
      retainS(GetNullarySelector("retain", Ctx)),
      autoreleaseS(GetNullarySelector("autorelease", Ctx)),
      drainS(GetNullarySelector("drain", Ctx)),
      BT(0) {}

  static void *getTag() { static int x = 0; return &x; }
      
  void PreVisitObjCMessageExpr(CheckerContext &C, const ObjCMessageExpr *ME);    
};
}

void ClassReleaseChecker::PreVisitObjCMessageExpr(CheckerContext &C,
                                                  const ObjCMessageExpr *ME) {
  ObjCInterfaceDecl *Class = 0;
  switch (ME->getReceiverKind()) {
  case ObjCMessageExpr::Class:
    Class = ME->getClassReceiver()->getAs<ObjCObjectType>()->getInterface();
    break;

  case ObjCMessageExpr::SuperClass:
    Class = ME->getSuperType()->getAs<ObjCObjectType>()->getInterface();
    break;

  case ObjCMessageExpr::Instance:
  case ObjCMessageExpr::SuperInstance:
    return;
  }

  Selector S = ME->getSelector();
  if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
    return;
  
  if (!BT)
    BT = new APIMisuse("message incorrectly sent to class instead of class "
                       "instance");
  
  ExplodedNode *N = C.GenerateNode();

  if (!N)
    return;
  
  llvm::SmallString<200> buf;
  llvm::raw_svector_ostream os(buf);

  os << "The '" << S.getAsString() << "' message should be sent to instances "
        "of class '" << Class->getName()
     << "' and not the class directly";
  
  RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);
  report->addRange(ME->getSourceRange());
  C.EmitReport(report);
}

//===----------------------------------------------------------------------===//
// Check registration.
//===----------------------------------------------------------------------===//

void clang::RegisterAppleChecks(GRExprEngine& Eng, const Decl &D) {
  ASTContext& Ctx = Eng.getContext();
  BugReporter &BR = Eng.getBugReporter();

  Eng.AddCheck(CreateBasicObjCFoundationChecks(Ctx, BR),
               Stmt::ObjCMessageExprClass);
  Eng.AddCheck(CreateAuditCFNumberCreate(Ctx, BR), Stmt::CallExprClass);

  RegisterNSErrorChecks(BR, Eng, D);
  RegisterNSAutoreleasePoolChecks(Eng);

  Eng.registerCheck(new CFRetainReleaseChecker(Ctx));
  Eng.registerCheck(new ClassReleaseChecker(Ctx));
}
