Beispiel #1
0
bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt)
{
  if (!QT->isPointerType())
    return false;

  QualType PT = QT->getPointeeType();
  const BuiltinType *BT = PT->getAs<BuiltinType>();
  if (!BT)
    return false;

  // Pointer to a character.
  if (PT->isAnyCharacterType()) {
    CS.setKind(ConversionSpecifier::sArg);
    if (PT->isWideCharType())
      LM.setKind(LengthModifier::AsWideChar);
    else
      LM.setKind(LengthModifier::None);
    return true;
  }

  // Figure out the length modifier.
  switch (BT->getKind()) {
    // no modifier
    case BuiltinType::UInt:
    case BuiltinType::Int:
    case BuiltinType::Float:
      LM.setKind(LengthModifier::None);
      break;

    // hh
    case BuiltinType::Char_U:
    case BuiltinType::UChar:
    case BuiltinType::Char_S:
    case BuiltinType::SChar:
      LM.setKind(LengthModifier::AsChar);
      break;

    // h
    case BuiltinType::Short:
    case BuiltinType::UShort:
      LM.setKind(LengthModifier::AsShort);
      break;

    // l
    case BuiltinType::Long:
    case BuiltinType::ULong:
    case BuiltinType::Double:
      LM.setKind(LengthModifier::AsLong);
      break;

    // ll
    case BuiltinType::LongLong:
    case BuiltinType::ULongLong:
      LM.setKind(LengthModifier::AsLongLong);
      break;

    // L
    case BuiltinType::LongDouble:
      LM.setKind(LengthModifier::AsLongDouble);
      break;

    // Don't know.
    default:
      return false;
  }

  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
  if (isa<TypedefType>(PT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
    const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
    if (Identifier->getName() == "size_t") {
      LM.setKind(LengthModifier::AsSizeT);
    } else if (Identifier->getName() == "ssize_t") {
      // Not C99, but common in Unix.
      LM.setKind(LengthModifier::AsSizeT);
    } else if (Identifier->getName() == "intmax_t") {
      LM.setKind(LengthModifier::AsIntMax);
    } else if (Identifier->getName() == "uintmax_t") {
      LM.setKind(LengthModifier::AsIntMax);
    } else if (Identifier->getName() == "ptrdiff_t") {
      LM.setKind(LengthModifier::AsPtrDiff);
    }
  }

  // Figure out the conversion specifier.
  if (PT->isRealFloatingType())
    CS.setKind(ConversionSpecifier::fArg);
  else if (PT->isSignedIntegerType())
    CS.setKind(ConversionSpecifier::dArg);
  else if (PT->isUnsignedIntegerType()) {
    // Preserve the original formatting, e.g. 'X', 'o'.
    if (!CS.isUIntArg()) {
      CS.setKind(ConversionSpecifier::uArg);
    }
  } else
    llvm_unreachable("Unexpected type");

  return true;
}
Beispiel #2
0
bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt) {
  // Handle strings first (char *, wchar_t *)
  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
    CS.setKind(ConversionSpecifier::sArg);

    // Disable irrelevant flags
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;

    // Set the long length modifier for wide characters
    if (QT->getPointeeType()->isWideCharType())
      LM.setKind(LengthModifier::AsWideChar);
    else
      LM.setKind(LengthModifier::None);

    return true;
  }

  // We can only work with builtin types.
  const BuiltinType *BT = QT->getAs<BuiltinType>();
  if (!BT)
    return false;

  // Set length modifier
  switch (BT->getKind()) {
  case BuiltinType::Bool:
  case BuiltinType::WChar_U:
  case BuiltinType::WChar_S:
  case BuiltinType::Char16:
  case BuiltinType::Char32:
  case BuiltinType::UInt128:
  case BuiltinType::Int128:
  case BuiltinType::Half:
    // Various types which are non-trivial to correct.
    return false;

#define SIGNED_TYPE(Id, SingletonId)
#define UNSIGNED_TYPE(Id, SingletonId)
#define FLOATING_TYPE(Id, SingletonId)
#define BUILTIN_TYPE(Id, SingletonId) \
  case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
    // Misc other stuff which doesn't make sense here.
    return false;

  case BuiltinType::UInt:
  case BuiltinType::Int:
  case BuiltinType::Float:
  case BuiltinType::Double:
    LM.setKind(LengthModifier::None);
    break;

  case BuiltinType::Char_U:
  case BuiltinType::UChar:
  case BuiltinType::Char_S:
  case BuiltinType::SChar:
    LM.setKind(LengthModifier::AsChar);
    break;

  case BuiltinType::Short:
  case BuiltinType::UShort:
    LM.setKind(LengthModifier::AsShort);
    break;

  case BuiltinType::Long:
  case BuiltinType::ULong:
    LM.setKind(LengthModifier::AsLong);
    break;

  case BuiltinType::LongLong:
  case BuiltinType::ULongLong:
    LM.setKind(LengthModifier::AsLongLong);
    break;

  case BuiltinType::LongDouble:
    LM.setKind(LengthModifier::AsLongDouble);
    break;
  }

  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
  if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) {
    const IdentifierInfo *Identifier = QT.getBaseTypeIdentifier();
    if (Identifier->getName() == "size_t") {
      LM.setKind(LengthModifier::AsSizeT);
    } else if (Identifier->getName() == "ssize_t") {
      // Not C99, but common in Unix.
      LM.setKind(LengthModifier::AsSizeT);
    } else if (Identifier->getName() == "intmax_t") {
      LM.setKind(LengthModifier::AsIntMax);
    } else if (Identifier->getName() == "uintmax_t") {
      LM.setKind(LengthModifier::AsIntMax);
    } else if (Identifier->getName() == "ptrdiff_t") {
      LM.setKind(LengthModifier::AsPtrDiff);
    }
  }

  // Set conversion specifier and disable any flags which do not apply to it.
  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
  if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {
    CS.setKind(ConversionSpecifier::cArg);
    LM.setKind(LengthModifier::None);
    Precision.setHowSpecified(OptionalAmount::NotSpecified);
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;
    HasPlusPrefix = 0;
  }
  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
  else if (QT->isRealFloatingType()) {
    CS.setKind(ConversionSpecifier::fArg);
  }
  else if (QT->isSignedIntegerType()) {
    CS.setKind(ConversionSpecifier::dArg);
    HasAlternativeForm = 0;
  }
  else if (QT->isUnsignedIntegerType()) {
    // Preserve the original formatting, e.g. 'X', 'o'.
    if (!cast<PrintfConversionSpecifier>(CS).isUIntArg())
      CS.setKind(ConversionSpecifier::uArg);
    HasAlternativeForm = 0;
    HasPlusPrefix = 0;
  } else {
    llvm_unreachable("Unexpected type");
  }

  return true;
}
bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
                             ASTContext &Ctx) {
  if (!QT->isPointerType())
    return false;

  // %n is different from other conversion specifiers; don't try to fix it.
  if (CS.getKind() == ConversionSpecifier::nArg)
    return false;

  QualType PT = QT->getPointeeType();

  // If it's an enum, get its underlying type.
  if (const EnumType *ETy = QT->getAs<EnumType>())
    QT = ETy->getDecl()->getIntegerType();
  
  const BuiltinType *BT = PT->getAs<BuiltinType>();
  if (!BT)
    return false;

  // Pointer to a character.
  if (PT->isAnyCharacterType()) {
    CS.setKind(ConversionSpecifier::sArg);
    if (PT->isWideCharType())
      LM.setKind(LengthModifier::AsWideChar);
    else
      LM.setKind(LengthModifier::None);
    return true;
  }

  // Figure out the length modifier.
  switch (BT->getKind()) {
    // no modifier
    case BuiltinType::UInt:
    case BuiltinType::Int:
    case BuiltinType::Float:
      LM.setKind(LengthModifier::None);
      break;

    // hh
    case BuiltinType::Char_U:
    case BuiltinType::UChar:
    case BuiltinType::Char_S:
    case BuiltinType::SChar:
      LM.setKind(LengthModifier::AsChar);
      break;

    // h
    case BuiltinType::Short:
    case BuiltinType::UShort:
      LM.setKind(LengthModifier::AsShort);
      break;

    // l
    case BuiltinType::Long:
    case BuiltinType::ULong:
    case BuiltinType::Double:
      LM.setKind(LengthModifier::AsLong);
      break;

    // ll
    case BuiltinType::LongLong:
    case BuiltinType::ULongLong:
      LM.setKind(LengthModifier::AsLongLong);
      break;

    // L
    case BuiltinType::LongDouble:
      LM.setKind(LengthModifier::AsLongDouble);
      break;

    // Don't know.
    default:
      return false;
  }

  // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
  if (isa<TypedefType>(PT) && (LangOpt.F90 || LangOpt.F90))
    namedTypeToLengthModifier(PT, LM);

  // If fixing the length modifier was enough, we are done.
  if (hasValidLengthModifier(Ctx.getTargetInfo())) {
    const analyze_scanf::ArgType &AT = getArgType(Ctx);
    if (AT.isValid() && AT.matchesType(Ctx, QT))
      return true;
  }

  // Figure out the conversion specifier.
  if (PT->isRealFloatingType())
    CS.setKind(ConversionSpecifier::fArg);
  else if (PT->isSignedIntegerType())
    CS.setKind(ConversionSpecifier::dArg);
  else if (PT->isUnsignedIntegerType())
    CS.setKind(ConversionSpecifier::uArg);
  else
    llvm_unreachable("Unexpected type");

  return true;
}
Beispiel #4
0
bool PrintfSpecifier::fixType(QualType QT) {
  // Handle strings first (char *, wchar_t *)
  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
    CS.setKind(ConversionSpecifier::sArg);

    // Disable irrelevant flags
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;

    // Set the long length modifier for wide characters
    if (QT->getPointeeType()->isWideCharType())
      LM.setKind(LengthModifier::AsWideChar);

    return true;
  }

  // We can only work with builtin types.
  if (!QT->isBuiltinType())
    return false;

  // Everything else should be a base type
  const BuiltinType *BT = QT->getAs<BuiltinType>();

  // Set length modifier
  switch (BT->getKind()) {
  default:
    // The rest of the conversions are either optional or for non-builtin types
    LM.setKind(LengthModifier::None);
    break;

  case BuiltinType::WChar:
  case BuiltinType::Long:
  case BuiltinType::ULong:
    LM.setKind(LengthModifier::AsLong);
    break;

  case BuiltinType::LongLong:
  case BuiltinType::ULongLong:
    LM.setKind(LengthModifier::AsLongLong);
    break;

  case BuiltinType::LongDouble:
    LM.setKind(LengthModifier::AsLongDouble);
    break;
  }

  // Set conversion specifier and disable any flags which do not apply to it.
  if (QT->isAnyCharacterType()) {
    CS.setKind(ConversionSpecifier::cArg);
    Precision.setHowSpecified(OptionalAmount::NotSpecified);
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;
    HasPlusPrefix = 0;
  }
  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
  else if (QT->isRealFloatingType()) {
    CS.setKind(ConversionSpecifier::fArg);
  }
  else if (QT->isPointerType()) {
    CS.setKind(ConversionSpecifier::pArg);
    Precision.setHowSpecified(OptionalAmount::NotSpecified);
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;
    HasPlusPrefix = 0;
  }
  else if (QT->isSignedIntegerType()) {
    CS.setKind(ConversionSpecifier::dArg);
    HasAlternativeForm = 0;
  }
  else if (QT->isUnsignedIntegerType()) {
    CS.setKind(ConversionSpecifier::uArg);
    HasAlternativeForm = 0;
    HasPlusPrefix = 0;
  }
  else {
    return false;
  }

  return true;
}
Beispiel #5
0
bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
                              ASTContext &Ctx, bool IsObjCLiteral) {
    // %n is different from other conversion specifiers; don't try to fix it.
    if (CS.getKind() == ConversionSpecifier::nArg)
        return false;

    // Handle Objective-C objects first. Note that while the '%@' specifier will
    // not warn for structure pointer or void pointer arguments (because that's
    // how CoreFoundation objects are implemented), we only show a fixit for '%@'
    // if we know it's an object (block, id, class, or __attribute__((NSObject))).
    if (QT->isObjCRetainableType()) {
        if (!IsObjCLiteral)
            return false;

        CS.setKind(ConversionSpecifier::ObjCObjArg);

        // Disable irrelevant flags
        HasThousandsGrouping = false;
        HasPlusPrefix = false;
        HasSpacePrefix = false;
        HasAlternativeForm = false;
        HasLeadingZeroes = false;
        Precision.setHowSpecified(OptionalAmount::NotSpecified);
        LM.setKind(LengthModifier::None);

        return true;
    }

    // Handle strings next (char *, wchar_t *)
    if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
        CS.setKind(ConversionSpecifier::sArg);

        // Disable irrelevant flags
        HasAlternativeForm = 0;
        HasLeadingZeroes = 0;

        // Set the long length modifier for wide characters
        if (QT->getPointeeType()->isWideCharType())
            LM.setKind(LengthModifier::AsWideChar);
        else
            LM.setKind(LengthModifier::None);

        return true;
    }

    // If it's an enum, get its underlying type.
    if (const EnumType *ETy = QT->getAs<EnumType>())
        QT = ETy->getDecl()->getIntegerType();

    // We can only work with builtin types.
    const BuiltinType *BT = QT->getAs<BuiltinType>();
    if (!BT)
        return false;

    // Set length modifier
    switch (BT->getKind()) {
    case BuiltinType::Bool:
    case BuiltinType::WChar_U:
    case BuiltinType::WChar_S:
    case BuiltinType::Char16:
    case BuiltinType::Char32:
    case BuiltinType::UInt128:
    case BuiltinType::Int128:
    case BuiltinType::Half:
        // Various types which are non-trivial to correct.
        return false;

#define SIGNED_TYPE(Id, SingletonId)
#define UNSIGNED_TYPE(Id, SingletonId)
#define FLOATING_TYPE(Id, SingletonId)
#define BUILTIN_TYPE(Id, SingletonId) \
  case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
        // Misc other stuff which doesn't make sense here.
        return false;

    case BuiltinType::UInt:
    case BuiltinType::Int:
    case BuiltinType::Float:
    case BuiltinType::Double:
        LM.setKind(LengthModifier::None);
        break;

    case BuiltinType::Char_U:
    case BuiltinType::UChar:
    case BuiltinType::Char_S:
    case BuiltinType::SChar:
        LM.setKind(LengthModifier::AsChar);
        break;

    case BuiltinType::Short:
    case BuiltinType::UShort:
        LM.setKind(LengthModifier::AsShort);
        break;

    case BuiltinType::Long:
    case BuiltinType::ULong:
        LM.setKind(LengthModifier::AsLong);
        break;

    case BuiltinType::LongLong:
    case BuiltinType::ULongLong:
        LM.setKind(LengthModifier::AsLongLong);
        break;

    case BuiltinType::LongDouble:
        LM.setKind(LengthModifier::AsLongDouble);
        break;
    }

    // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99.
    if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x))
        namedTypeToLengthModifier(QT, LM);

    // If fixing the length modifier was enough, we are done.
    if (hasValidLengthModifier(Ctx.getTargetInfo())) {
        const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
        if (ATR.isValid() && ATR.matchesType(Ctx, QT))
            return true;
    }

    // Set conversion specifier and disable any flags which do not apply to it.
    // Let typedefs to char fall through to int, as %c is silly for uint8_t.
    if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {
        CS.setKind(ConversionSpecifier::cArg);
        LM.setKind(LengthModifier::None);
        Precision.setHowSpecified(OptionalAmount::NotSpecified);
        HasAlternativeForm = 0;
        HasLeadingZeroes = 0;
        HasPlusPrefix = 0;
    }
    // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
    else if (QT->isRealFloatingType()) {
        CS.setKind(ConversionSpecifier::fArg);
    }
    else if (QT->isSignedIntegerType()) {
        CS.setKind(ConversionSpecifier::dArg);
        HasAlternativeForm = 0;
    }
    else if (QT->isUnsignedIntegerType()) {
        CS.setKind(ConversionSpecifier::uArg);
        HasAlternativeForm = 0;
        HasPlusPrefix = 0;
    } else {
        llvm_unreachable("Unexpected type");
    }

    return true;
}
Beispiel #6
0
bool PrintfSpecifier::fixType(QualType QT) {
  // Handle strings first (char *, wchar_t *)
  if (QT->isPointerType() && (QT->getPointeeType()->isAnyCharacterType())) {
    CS.setKind(ConversionSpecifier::sArg);

    // Disable irrelevant flags
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;

    // Set the long length modifier for wide characters
    if (QT->getPointeeType()->isWideCharType())
      LM.setKind(LengthModifier::AsWideChar);

    return true;
  }

  // We can only work with builtin types.
  if (!QT->isBuiltinType())
    return false;

  // Everything else should be a base type
  const BuiltinType *BT = QT->getAs<BuiltinType>();

  // Set length modifier
  switch (BT->getKind()) {
  case BuiltinType::Bool:
  case BuiltinType::WChar_U:
  case BuiltinType::WChar_S:
  case BuiltinType::Char16:
  case BuiltinType::Char32:
  case BuiltinType::UInt128:
  case BuiltinType::Int128:
    // Integral types which are non-trivial to correct.
    return false;

  case BuiltinType::Void:
  case BuiltinType::NullPtr:
  case BuiltinType::ObjCId:
  case BuiltinType::ObjCClass:
  case BuiltinType::ObjCSel:
  case BuiltinType::Dependent:
  case BuiltinType::Overload:
  case BuiltinType::BoundMember:
  case BuiltinType::UnknownAny:
    // Misc other stuff which doesn't make sense here.
    return false;

  case BuiltinType::UInt:
  case BuiltinType::Int:
  case BuiltinType::Float:
  case BuiltinType::Double:
    LM.setKind(LengthModifier::None);
    break;

  case BuiltinType::Char_U:
  case BuiltinType::UChar:
  case BuiltinType::Char_S:
  case BuiltinType::SChar:
    LM.setKind(LengthModifier::AsChar);
    break;

  case BuiltinType::Short:
  case BuiltinType::UShort:
    LM.setKind(LengthModifier::AsShort);
    break;

  case BuiltinType::Long:
  case BuiltinType::ULong:
    LM.setKind(LengthModifier::AsLong);
    break;

  case BuiltinType::LongLong:
  case BuiltinType::ULongLong:
    LM.setKind(LengthModifier::AsLongLong);
    break;

  case BuiltinType::LongDouble:
    LM.setKind(LengthModifier::AsLongDouble);
    break;
  }

  // Set conversion specifier and disable any flags which do not apply to it.
  // Let typedefs to char fall through to int, as %c is silly for uint8_t.
  if (isa<TypedefType>(QT) && QT->isAnyCharacterType()) {
    CS.setKind(ConversionSpecifier::cArg);
    LM.setKind(LengthModifier::None);
    Precision.setHowSpecified(OptionalAmount::NotSpecified);
    HasAlternativeForm = 0;
    HasLeadingZeroes = 0;
    HasPlusPrefix = 0;
  }
  // Test for Floating type first as LongDouble can pass isUnsignedIntegerType
  else if (QT->isRealFloatingType()) {
    CS.setKind(ConversionSpecifier::fArg);
  }
  else if (QT->isSignedIntegerType()) {
    CS.setKind(ConversionSpecifier::dArg);
    HasAlternativeForm = 0;
  }
  else if (QT->isUnsignedIntegerType()) {
    // Preserve the original formatting, e.g. 'X', 'o'.
    if (!cast<PrintfConversionSpecifier>(CS).isUIntArg())
      CS.setKind(ConversionSpecifier::uArg);
    HasAlternativeForm = 0;
    HasPlusPrefix = 0;
  } else {
    llvm_unreachable("Unexpected type");
  }

  return true;
}