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 None;
  }

  return Ctx.getTypeSize(T);
}
static bool isHigherOrderRawPtr(QualType T, ASTContext &C) {
    bool foundPointer = false;
    while (1) {
        const PointerType *PT = T->getAs<PointerType>();
        if (!PT) {
            if (!foundPointer)
                return false;

            // intptr_t* or intptr_t**, etc?
            if (T->isIntegerType() && C.getTypeSize(T) == C.getTypeSize(C.VoidPtrTy))
                return true;

            QualType X = C.getCanonicalType(T).getUnqualifiedType();
            return X == C.VoidTy;
        }

        foundPointer = true;
        T = PT->getPointeeType();
    }
}
/// Get the number of possible values that can be switched on for the type T.
///
/// \return - 0 if bitcount could not be determined
///         - numeric_limits<std::size_t>::max() when overflow appeared due to
///           more than 64 bits type size.
static std::size_t getNumberOfPossibleValues(QualType T,
                                             const ASTContext &Context) {
  // `isBooleanType` must come first because `bool` is an integral type as well
  // and would not return 2 as result.
  if (T->isBooleanType())
    return 2;
  else if (T->isIntegralType(Context))
    return twoPow(Context.getTypeSize(T));
  else
    return 1;
}
/// Returns true if ValueType is allowed to fold into InitType, i.e. if:
///   static_cast<InitType>(ValueType{some_value})
/// does not result in trucation.
static bool isValidBuiltinFold(const BuiltinType &ValueType,
                               const BuiltinType &InitType,
                               const ASTContext &Context) {
  const auto ValueTypeSize = Context.getTypeSize(&ValueType);
  const auto InitTypeSize = Context.getTypeSize(&InitType);
  // It's OK to fold a float into a float of bigger or equal size, but not OK to
  // fold into an int.
  if (ValueType.isFloatingPoint())
    return InitType.isFloatingPoint() && InitTypeSize >= ValueTypeSize;
  // It's OK to fold an int into:
  //  - an int of the same size and signedness.
  //  - a bigger int, regardless of signedness.
  //  - FIXME: should it be a warning to fold into floating point?
  if (ValueType.isInteger()) {
    if (InitType.isInteger()) {
      if (InitType.isSignedInteger() == ValueType.isSignedInteger())
        return InitTypeSize >= ValueTypeSize;
      return InitTypeSize > ValueTypeSize;
    }
    if (InitType.isFloatingPoint())
      return InitTypeSize >= ValueTypeSize;
  }
  return false;
}
Example #5
0
static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
  if (!E->isArray())
    return 0;
  
  QualType T = E->getAllocatedType();
  
  const RecordType *RT = T->getAs<RecordType>();
  if (!RT)
    return 0;
  
  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
  if (!RD)
    return 0;
  
  // Check if the class has a trivial destructor.
  if (RD->hasTrivialDestructor()) {
    // FIXME: Check for a two-argument delete.
    return 0;
  }
  
  // Padding is the maximum of sizeof(size_t) and alignof(T)
  return std::max(Ctx.getTypeSize(Ctx.getSizeType()),
                  static_cast<uint64_t>(Ctx.getTypeAlign(T))) / 8;
}