forked from OSchip/llvm-project
Rename analyze_format_string::ArgTypeResult to ArgType
Also remove redundant constructors and unused member functions. llvm-svn: 161403
This commit is contained in:
parent
c5062dc91a
commit
c3b3da0bb2
|
@ -201,7 +201,7 @@ protected:
|
|||
Kind kind;
|
||||
};
|
||||
|
||||
class ArgTypeResult {
|
||||
class ArgType {
|
||||
public:
|
||||
enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
|
||||
AnyCharTy, CStrTy, WCStrTy, WIntTy };
|
||||
|
@ -209,26 +209,17 @@ private:
|
|||
const Kind K;
|
||||
QualType T;
|
||||
const char *Name;
|
||||
ArgTypeResult(bool) : K(InvalidTy), Name(0) {}
|
||||
public:
|
||||
ArgTypeResult(Kind k = UnknownTy) : K(k), Name(0) {}
|
||||
ArgTypeResult(Kind k, const char *n) : K(k), Name(n) {}
|
||||
ArgTypeResult(QualType t) : K(SpecificTy), T(t), Name(0) {}
|
||||
ArgTypeResult(QualType t, const char *n) : K(SpecificTy), T(t), Name(n) {}
|
||||
ArgTypeResult(CanQualType t) : K(SpecificTy), T(t), Name(0) {}
|
||||
ArgType(Kind k = UnknownTy, const char *n = 0) : K(k), Name(n) {}
|
||||
ArgType(QualType t, const char *n = 0) : K(SpecificTy), T(t), Name(n) {}
|
||||
ArgType(CanQualType t) : K(SpecificTy), T(t), Name(0) {}
|
||||
|
||||
static ArgTypeResult Invalid() { return ArgTypeResult(true); }
|
||||
static ArgType Invalid() { return ArgType(InvalidTy); }
|
||||
|
||||
bool isValid() const { return K != InvalidTy; }
|
||||
|
||||
const QualType *getSpecificType() const {
|
||||
return K == SpecificTy ? &T : 0;
|
||||
}
|
||||
|
||||
bool matchesType(ASTContext &C, QualType argTy) const;
|
||||
|
||||
bool matchesAnyObjCObjectRef() const { return K == ObjCPointerTy; }
|
||||
|
||||
QualType getRepresentativeType(ASTContext &C) const;
|
||||
|
||||
std::string getRepresentativeTypeName(ASTContext &C) const;
|
||||
|
@ -279,7 +270,7 @@ public:
|
|||
return length + UsesDotPrefix;
|
||||
}
|
||||
|
||||
ArgTypeResult getArgType(ASTContext &Ctx) const;
|
||||
ArgType getArgType(ASTContext &Ctx) const;
|
||||
|
||||
void toString(raw_ostream &os) const;
|
||||
|
||||
|
@ -392,7 +383,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
using analyze_format_string::ArgTypeResult;
|
||||
using analyze_format_string::ArgType;
|
||||
using analyze_format_string::LengthModifier;
|
||||
using analyze_format_string::OptionalAmount;
|
||||
using analyze_format_string::OptionalFlag;
|
||||
|
@ -467,7 +458,7 @@ public:
|
|||
/// will return null if the format specifier does not have
|
||||
/// a matching data argument or the matching argument matches
|
||||
/// more than one type.
|
||||
ArgTypeResult getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
|
||||
ArgType getArgType(ASTContext &Ctx, bool IsObjCLiteral) const;
|
||||
|
||||
const OptionalFlag &hasThousandsGrouping() const {
|
||||
return HasThousandsGrouping;
|
||||
|
@ -521,27 +512,27 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
using analyze_format_string::ArgTypeResult;
|
||||
using analyze_format_string::ArgType;
|
||||
using analyze_format_string::LengthModifier;
|
||||
using analyze_format_string::OptionalAmount;
|
||||
using analyze_format_string::OptionalFlag;
|
||||
|
||||
class ScanfArgTypeResult : public ArgTypeResult {
|
||||
class ScanfArgType : public ArgType {
|
||||
public:
|
||||
enum Kind { UnknownTy, InvalidTy, CStrTy, WCStrTy, PtrToArgTypeResultTy };
|
||||
enum Kind { UnknownTy, InvalidTy, CStrTy, WCStrTy, PtrToArgTypeTy };
|
||||
private:
|
||||
Kind K;
|
||||
ArgTypeResult A;
|
||||
ArgType A;
|
||||
const char *Name;
|
||||
QualType getRepresentativeType(ASTContext &C) const;
|
||||
public:
|
||||
ScanfArgTypeResult(Kind k = UnknownTy, const char* n = 0) : K(k), Name(n) {}
|
||||
ScanfArgTypeResult(ArgTypeResult a, const char *n = 0)
|
||||
: K(PtrToArgTypeResultTy), A(a), Name(n) {
|
||||
ScanfArgType(Kind k = UnknownTy, const char* n = 0) : K(k), Name(n) {}
|
||||
ScanfArgType(ArgType a, const char *n = 0)
|
||||
: K(PtrToArgTypeTy), A(a), Name(n) {
|
||||
assert(A.isValid());
|
||||
}
|
||||
|
||||
static ScanfArgTypeResult Invalid() { return ScanfArgTypeResult(InvalidTy); }
|
||||
static ScanfArgType Invalid() { return ScanfArgType(InvalidTy); }
|
||||
|
||||
bool isValid() const { return K != InvalidTy; }
|
||||
|
||||
|
@ -578,7 +569,7 @@ public:
|
|||
return CS.consumesDataArgument() && !SuppressAssignment;
|
||||
}
|
||||
|
||||
ScanfArgTypeResult getArgType(ASTContext &Ctx) const;
|
||||
ScanfArgType getArgType(ASTContext &Ctx) const;
|
||||
|
||||
bool fixType(QualType QT, const LangOptions &LangOpt, ASTContext &Ctx);
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "FormatStringParsing.h"
|
||||
#include "clang/Basic/LangOptions.h"
|
||||
|
||||
using clang::analyze_format_string::ArgTypeResult;
|
||||
using clang::analyze_format_string::ArgType;
|
||||
using clang::analyze_format_string::FormatStringHandler;
|
||||
using clang::analyze_format_string::FormatSpecifier;
|
||||
using clang::analyze_format_string::LengthModifier;
|
||||
|
@ -229,13 +229,13 @@ clang::analyze_format_string::ParseLengthModifier(FormatSpecifier &FS,
|
|||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Methods on ArgTypeResult.
|
||||
// Methods on ArgType.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
|
||||
bool ArgType::matchesType(ASTContext &C, QualType argTy) const {
|
||||
switch (K) {
|
||||
case InvalidTy:
|
||||
llvm_unreachable("ArgTypeResult must be valid");
|
||||
llvm_unreachable("ArgType must be valid");
|
||||
|
||||
case UnknownTy:
|
||||
return true;
|
||||
|
@ -371,13 +371,13 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const {
|
|||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid ArgTypeResult Kind!");
|
||||
llvm_unreachable("Invalid ArgType Kind!");
|
||||
}
|
||||
|
||||
QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const {
|
||||
QualType ArgType::getRepresentativeType(ASTContext &C) const {
|
||||
switch (K) {
|
||||
case InvalidTy:
|
||||
llvm_unreachable("No representative type for Invalid ArgTypeResult");
|
||||
llvm_unreachable("No representative type for Invalid ArgType");
|
||||
case UnknownTy:
|
||||
return QualType();
|
||||
case AnyCharTy:
|
||||
|
@ -397,10 +397,10 @@ QualType ArgTypeResult::getRepresentativeType(ASTContext &C) const {
|
|||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid ArgTypeResult Kind!");
|
||||
llvm_unreachable("Invalid ArgType Kind!");
|
||||
}
|
||||
|
||||
std::string ArgTypeResult::getRepresentativeTypeName(ASTContext &C) const {
|
||||
std::string ArgType::getRepresentativeTypeName(ASTContext &C) const {
|
||||
std::string S = getRepresentativeType(C).getAsString();
|
||||
if (Name && S != Name)
|
||||
return std::string("'") + Name + "' (aka '" + S + "')";
|
||||
|
@ -412,7 +412,7 @@ std::string ArgTypeResult::getRepresentativeTypeName(ASTContext &C) const {
|
|||
// Methods on OptionalAmount.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ArgTypeResult
|
||||
ArgType
|
||||
analyze_format_string::OptionalAmount::getArgType(ASTContext &Ctx) const {
|
||||
return Ctx.IntTy;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "clang/Analysis/Analyses/FormatString.h"
|
||||
#include "FormatStringParsing.h"
|
||||
|
||||
using clang::analyze_format_string::ArgTypeResult;
|
||||
using clang::analyze_format_string::ArgType;
|
||||
using clang::analyze_format_string::FormatStringHandler;
|
||||
using clang::analyze_format_string::LengthModifier;
|
||||
using clang::analyze_format_string::OptionalAmount;
|
||||
|
@ -241,20 +241,20 @@ bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
|
|||
// Methods on PrintfSpecifier.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
||||
bool IsObjCLiteral) const {
|
||||
ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
|
||||
bool IsObjCLiteral) const {
|
||||
const PrintfConversionSpecifier &CS = getConversionSpecifier();
|
||||
|
||||
if (!CS.consumesDataArgument())
|
||||
return ArgTypeResult::Invalid();
|
||||
return ArgType::Invalid();
|
||||
|
||||
if (CS.getKind() == ConversionSpecifier::cArg)
|
||||
switch (LM.getKind()) {
|
||||
case LengthModifier::None: return Ctx.IntTy;
|
||||
case LengthModifier::AsLong:
|
||||
return ArgTypeResult(ArgTypeResult::WIntTy, "wint_t");
|
||||
return ArgType(ArgType::WIntTy, "wint_t");
|
||||
default:
|
||||
return ArgTypeResult::Invalid();
|
||||
return ArgType::Invalid();
|
||||
}
|
||||
|
||||
if (CS.isIntArg())
|
||||
|
@ -263,22 +263,22 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
|||
// GNU extension.
|
||||
return Ctx.LongLongTy;
|
||||
case LengthModifier::None: return Ctx.IntTy;
|
||||
case LengthModifier::AsChar: return ArgTypeResult::AnyCharTy;
|
||||
case LengthModifier::AsChar: return ArgType::AnyCharTy;
|
||||
case LengthModifier::AsShort: return Ctx.ShortTy;
|
||||
case LengthModifier::AsLong: return Ctx.LongTy;
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return Ctx.LongLongTy;
|
||||
case LengthModifier::AsIntMax:
|
||||
return ArgTypeResult(Ctx.getIntMaxType(), "intmax_t");
|
||||
return ArgType(Ctx.getIntMaxType(), "intmax_t");
|
||||
case LengthModifier::AsSizeT:
|
||||
// FIXME: How to get the corresponding signed version of size_t?
|
||||
return ArgTypeResult();
|
||||
return ArgType();
|
||||
case LengthModifier::AsPtrDiff:
|
||||
return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t");
|
||||
return ArgType(Ctx.getPointerDiffType(), "ptrdiff_t");
|
||||
case LengthModifier::AsAllocate:
|
||||
case LengthModifier::AsMAllocate:
|
||||
return ArgTypeResult::Invalid();
|
||||
return ArgType::Invalid();
|
||||
}
|
||||
|
||||
if (CS.isUIntArg())
|
||||
|
@ -294,16 +294,16 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
|||
case LengthModifier::AsQuad:
|
||||
return Ctx.UnsignedLongLongTy;
|
||||
case LengthModifier::AsIntMax:
|
||||
return ArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t");
|
||||
return ArgType(Ctx.getUIntMaxType(), "uintmax_t");
|
||||
case LengthModifier::AsSizeT:
|
||||
return ArgTypeResult(Ctx.getSizeType(), "size_t");
|
||||
return ArgType(Ctx.getSizeType(), "size_t");
|
||||
case LengthModifier::AsPtrDiff:
|
||||
// FIXME: How to get the corresponding unsigned
|
||||
// version of ptrdiff_t?
|
||||
return ArgTypeResult();
|
||||
return ArgType();
|
||||
case LengthModifier::AsAllocate:
|
||||
case LengthModifier::AsMAllocate:
|
||||
return ArgTypeResult::Invalid();
|
||||
return ArgType::Invalid();
|
||||
}
|
||||
|
||||
if (CS.isDoubleArg()) {
|
||||
|
@ -317,29 +317,29 @@ ArgTypeResult PrintfSpecifier::getArgType(ASTContext &Ctx,
|
|||
if (LM.getKind() == LengthModifier::AsWideChar) {
|
||||
if (IsObjCLiteral)
|
||||
return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
|
||||
return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
|
||||
return ArgType(ArgType::WCStrTy, "wchar_t *");
|
||||
}
|
||||
return ArgTypeResult::CStrTy;
|
||||
return ArgType::CStrTy;
|
||||
case ConversionSpecifier::SArg:
|
||||
if (IsObjCLiteral)
|
||||
return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst());
|
||||
return ArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t *");
|
||||
return ArgType(ArgType::WCStrTy, "wchar_t *");
|
||||
case ConversionSpecifier::CArg:
|
||||
if (IsObjCLiteral)
|
||||
return Ctx.UnsignedShortTy;
|
||||
return ArgTypeResult(Ctx.WCharTy, "wchar_t");
|
||||
return ArgType(Ctx.WCharTy, "wchar_t");
|
||||
case ConversionSpecifier::pArg:
|
||||
return ArgTypeResult::CPointerTy;
|
||||
return ArgType::CPointerTy;
|
||||
case ConversionSpecifier::nArg:
|
||||
return Ctx.getPointerType(Ctx.IntTy);
|
||||
case ConversionSpecifier::ObjCObjArg:
|
||||
return ArgTypeResult::ObjCPointerTy;
|
||||
return ArgType::ObjCPointerTy;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME: Handle other cases.
|
||||
return ArgTypeResult();
|
||||
return ArgType();
|
||||
}
|
||||
|
||||
bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
|
||||
|
@ -457,7 +457,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
|
|||
namedTypeToLengthModifier(QT, LM);
|
||||
|
||||
// If fixing the length modifier was enough, we are done.
|
||||
const analyze_printf::ArgTypeResult &ATR = getArgType(Ctx, IsObjCLiteral);
|
||||
const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral);
|
||||
if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT))
|
||||
return true;
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
#include "clang/Analysis/Analyses/FormatString.h"
|
||||
#include "FormatStringParsing.h"
|
||||
|
||||
using clang::analyze_format_string::ArgTypeResult;
|
||||
using clang::analyze_format_string::ArgType;
|
||||
using clang::analyze_format_string::FormatStringHandler;
|
||||
using clang::analyze_format_string::LengthModifier;
|
||||
using clang::analyze_format_string::OptionalAmount;
|
||||
using clang::analyze_format_string::ConversionSpecifier;
|
||||
using clang::analyze_scanf::ScanfArgTypeResult;
|
||||
using clang::analyze_scanf::ScanfArgType;
|
||||
using clang::analyze_scanf::ScanfConversionSpecifier;
|
||||
using clang::analyze_scanf::ScanfSpecifier;
|
||||
using clang::UpdateOnReturn;
|
||||
|
@ -194,37 +194,37 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H,
|
|||
return ScanfSpecifierResult(Start, FS);
|
||||
}
|
||||
|
||||
ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
||||
ScanfArgType ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
||||
const ScanfConversionSpecifier &CS = getConversionSpecifier();
|
||||
|
||||
if (!CS.consumesDataArgument())
|
||||
return ScanfArgTypeResult::Invalid();
|
||||
return ScanfArgType::Invalid();
|
||||
|
||||
switch(CS.getKind()) {
|
||||
// Signed int.
|
||||
case ConversionSpecifier::dArg:
|
||||
case ConversionSpecifier::iArg:
|
||||
switch (LM.getKind()) {
|
||||
case LengthModifier::None: return ArgTypeResult(Ctx.IntTy);
|
||||
case LengthModifier::None: return ArgType(Ctx.IntTy);
|
||||
case LengthModifier::AsChar:
|
||||
return ArgTypeResult(ArgTypeResult::AnyCharTy);
|
||||
case LengthModifier::AsShort: return ArgTypeResult(Ctx.ShortTy);
|
||||
case LengthModifier::AsLong: return ArgTypeResult(Ctx.LongTy);
|
||||
return ArgType(ArgType::AnyCharTy);
|
||||
case LengthModifier::AsShort: return ArgType(Ctx.ShortTy);
|
||||
case LengthModifier::AsLong: return ArgType(Ctx.LongTy);
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return ArgTypeResult(Ctx.LongLongTy);
|
||||
return ArgType(Ctx.LongLongTy);
|
||||
case LengthModifier::AsIntMax:
|
||||
return ScanfArgTypeResult(Ctx.getIntMaxType(), "intmax_t *");
|
||||
return ScanfArgType(Ctx.getIntMaxType(), "intmax_t *");
|
||||
case LengthModifier::AsSizeT:
|
||||
// FIXME: ssize_t.
|
||||
return ScanfArgTypeResult();
|
||||
return ScanfArgType();
|
||||
case LengthModifier::AsPtrDiff:
|
||||
return ScanfArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t *");
|
||||
return ScanfArgType(Ctx.getPointerDiffType(), "ptrdiff_t *");
|
||||
case LengthModifier::AsLongDouble:
|
||||
// GNU extension.
|
||||
return ArgTypeResult(Ctx.LongLongTy);
|
||||
case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid();
|
||||
case LengthModifier::AsMAllocate: return ScanfArgTypeResult::Invalid();
|
||||
return ArgType(Ctx.LongLongTy);
|
||||
case LengthModifier::AsAllocate: return ScanfArgType::Invalid();
|
||||
case LengthModifier::AsMAllocate: return ScanfArgType::Invalid();
|
||||
}
|
||||
|
||||
// Unsigned int.
|
||||
|
@ -233,25 +233,25 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
|||
case ConversionSpecifier::xArg:
|
||||
case ConversionSpecifier::XArg:
|
||||
switch (LM.getKind()) {
|
||||
case LengthModifier::None: return ArgTypeResult(Ctx.UnsignedIntTy);
|
||||
case LengthModifier::AsChar: return ArgTypeResult(Ctx.UnsignedCharTy);
|
||||
case LengthModifier::AsShort: return ArgTypeResult(Ctx.UnsignedShortTy);
|
||||
case LengthModifier::AsLong: return ArgTypeResult(Ctx.UnsignedLongTy);
|
||||
case LengthModifier::None: return ArgType(Ctx.UnsignedIntTy);
|
||||
case LengthModifier::AsChar: return ArgType(Ctx.UnsignedCharTy);
|
||||
case LengthModifier::AsShort: return ArgType(Ctx.UnsignedShortTy);
|
||||
case LengthModifier::AsLong: return ArgType(Ctx.UnsignedLongTy);
|
||||
case LengthModifier::AsLongLong:
|
||||
case LengthModifier::AsQuad:
|
||||
return ArgTypeResult(Ctx.UnsignedLongLongTy);
|
||||
return ArgType(Ctx.UnsignedLongLongTy);
|
||||
case LengthModifier::AsIntMax:
|
||||
return ScanfArgTypeResult(Ctx.getUIntMaxType(), "uintmax_t *");
|
||||
return ScanfArgType(Ctx.getUIntMaxType(), "uintmax_t *");
|
||||
case LengthModifier::AsSizeT:
|
||||
return ScanfArgTypeResult(Ctx.getSizeType(), "size_t *");
|
||||
return ScanfArgType(Ctx.getSizeType(), "size_t *");
|
||||
case LengthModifier::AsPtrDiff:
|
||||
// FIXME: Unsigned version of ptrdiff_t?
|
||||
return ScanfArgTypeResult();
|
||||
return ScanfArgType();
|
||||
case LengthModifier::AsLongDouble:
|
||||
// GNU extension.
|
||||
return ArgTypeResult(Ctx.UnsignedLongLongTy);
|
||||
case LengthModifier::AsAllocate: return ScanfArgTypeResult::Invalid();
|
||||
case LengthModifier::AsMAllocate: return ScanfArgTypeResult::Invalid();
|
||||
return ArgType(Ctx.UnsignedLongLongTy);
|
||||
case LengthModifier::AsAllocate: return ScanfArgType::Invalid();
|
||||
case LengthModifier::AsMAllocate: return ScanfArgType::Invalid();
|
||||
}
|
||||
|
||||
// Float.
|
||||
|
@ -264,12 +264,12 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
|||
case ConversionSpecifier::gArg:
|
||||
case ConversionSpecifier::GArg:
|
||||
switch (LM.getKind()) {
|
||||
case LengthModifier::None: return ArgTypeResult(Ctx.FloatTy);
|
||||
case LengthModifier::AsLong: return ArgTypeResult(Ctx.DoubleTy);
|
||||
case LengthModifier::None: return ArgType(Ctx.FloatTy);
|
||||
case LengthModifier::AsLong: return ArgType(Ctx.DoubleTy);
|
||||
case LengthModifier::AsLongDouble:
|
||||
return ArgTypeResult(Ctx.LongDoubleTy);
|
||||
return ArgType(Ctx.LongDoubleTy);
|
||||
default:
|
||||
return ScanfArgTypeResult::Invalid();
|
||||
return ScanfArgType::Invalid();
|
||||
}
|
||||
|
||||
// Char, string and scanlist.
|
||||
|
@ -277,40 +277,40 @@ ScanfArgTypeResult ScanfSpecifier::getArgType(ASTContext &Ctx) const {
|
|||
case ConversionSpecifier::sArg:
|
||||
case ConversionSpecifier::ScanListArg:
|
||||
switch (LM.getKind()) {
|
||||
case LengthModifier::None: return ScanfArgTypeResult::CStrTy;
|
||||
case LengthModifier::None: return ScanfArgType::CStrTy;
|
||||
case LengthModifier::AsLong:
|
||||
return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *");
|
||||
return ScanfArgType(ScanfArgType::WCStrTy, "wchar_t *");
|
||||
case LengthModifier::AsAllocate:
|
||||
case LengthModifier::AsMAllocate:
|
||||
return ScanfArgTypeResult(ArgTypeResult::CStrTy);
|
||||
return ScanfArgType(ArgType::CStrTy);
|
||||
default:
|
||||
return ScanfArgTypeResult::Invalid();
|
||||
return ScanfArgType::Invalid();
|
||||
}
|
||||
case ConversionSpecifier::CArg:
|
||||
case ConversionSpecifier::SArg:
|
||||
// FIXME: Mac OS X specific?
|
||||
switch (LM.getKind()) {
|
||||
case LengthModifier::None:
|
||||
return ScanfArgTypeResult(ScanfArgTypeResult::WCStrTy, "wchar_t *");
|
||||
return ScanfArgType(ScanfArgType::WCStrTy, "wchar_t *");
|
||||
case LengthModifier::AsAllocate:
|
||||
case LengthModifier::AsMAllocate:
|
||||
return ScanfArgTypeResult(ArgTypeResult::WCStrTy, "wchar_t **");
|
||||
return ScanfArgType(ArgType::WCStrTy, "wchar_t **");
|
||||
default:
|
||||
return ScanfArgTypeResult::Invalid();
|
||||
return ScanfArgType::Invalid();
|
||||
}
|
||||
|
||||
// Pointer.
|
||||
case ConversionSpecifier::pArg:
|
||||
return ScanfArgTypeResult(ArgTypeResult(ArgTypeResult::CPointerTy));
|
||||
return ScanfArgType(ArgType(ArgType::CPointerTy));
|
||||
|
||||
case ConversionSpecifier::nArg:
|
||||
return ArgTypeResult(Ctx.IntTy);
|
||||
return ArgType(Ctx.IntTy);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ScanfArgTypeResult();
|
||||
return ScanfArgType();
|
||||
}
|
||||
|
||||
bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
|
||||
|
@ -393,7 +393,7 @@ bool ScanfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
|
|||
namedTypeToLengthModifier(PT, LM);
|
||||
|
||||
// If fixing the length modifier was enough, we are done.
|
||||
const analyze_scanf::ScanfArgTypeResult &ATR = getArgType(Ctx);
|
||||
const analyze_scanf::ScanfArgType &ATR = getArgType(Ctx);
|
||||
if (hasValidLengthModifier() && ATR.isValid() && ATR.matchesType(Ctx, QT))
|
||||
return true;
|
||||
|
||||
|
@ -452,7 +452,7 @@ bool clang::analyze_format_string::ParseScanfString(FormatStringHandler &H,
|
|||
return false;
|
||||
}
|
||||
|
||||
bool ScanfArgTypeResult::matchesType(ASTContext& C, QualType argTy) const {
|
||||
bool ScanfArgType::matchesType(ASTContext& C, QualType argTy) const {
|
||||
// It has to be a pointer type.
|
||||
const PointerType *PT = argTy->getAs<PointerType>();
|
||||
if (!PT)
|
||||
|
@ -464,39 +464,39 @@ bool ScanfArgTypeResult::matchesType(ASTContext& C, QualType argTy) const {
|
|||
|
||||
switch (K) {
|
||||
case InvalidTy:
|
||||
llvm_unreachable("ArgTypeResult must be valid");
|
||||
llvm_unreachable("ArgType must be valid");
|
||||
case UnknownTy:
|
||||
return true;
|
||||
case CStrTy:
|
||||
return ArgTypeResult(ArgTypeResult::CStrTy).matchesType(C, argTy);
|
||||
return ArgType(ArgType::CStrTy).matchesType(C, argTy);
|
||||
case WCStrTy:
|
||||
return ArgTypeResult(ArgTypeResult::WCStrTy).matchesType(C, argTy);
|
||||
case PtrToArgTypeResultTy: {
|
||||
return ArgType(ArgType::WCStrTy).matchesType(C, argTy);
|
||||
case PtrToArgTypeTy: {
|
||||
return A.matchesType(C, PT->getPointeeType());
|
||||
}
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid ScanfArgTypeResult Kind!");
|
||||
llvm_unreachable("Invalid ScanfArgType Kind!");
|
||||
}
|
||||
|
||||
QualType ScanfArgTypeResult::getRepresentativeType(ASTContext &C) const {
|
||||
QualType ScanfArgType::getRepresentativeType(ASTContext &C) const {
|
||||
switch (K) {
|
||||
case InvalidTy:
|
||||
llvm_unreachable("No representative type for Invalid ArgTypeResult");
|
||||
llvm_unreachable("No representative type for Invalid ArgType");
|
||||
case UnknownTy:
|
||||
return QualType();
|
||||
case CStrTy:
|
||||
return C.getPointerType(C.CharTy);
|
||||
case WCStrTy:
|
||||
return C.getPointerType(C.getWCharType());
|
||||
case PtrToArgTypeResultTy:
|
||||
case PtrToArgTypeTy:
|
||||
return C.getPointerType(A.getRepresentativeType(C));
|
||||
}
|
||||
|
||||
llvm_unreachable("Invalid ScanfArgTypeResult Kind!");
|
||||
llvm_unreachable("Invalid ScanfArgType Kind!");
|
||||
}
|
||||
|
||||
std::string ScanfArgTypeResult::getRepresentativeTypeName(ASTContext& C) const {
|
||||
std::string ScanfArgType::getRepresentativeTypeName(ASTContext& C) const {
|
||||
std::string S = getRepresentativeType(C).getAsString();
|
||||
if (!Name)
|
||||
return std::string("'") + S + "'";
|
||||
|
|
|
@ -2271,7 +2271,7 @@ public:
|
|||
const analyze_printf::OptionalFlag &ignoredFlag,
|
||||
const analyze_printf::OptionalFlag &flag,
|
||||
const char *startSpecifier, unsigned specifierLen);
|
||||
bool checkForCStrMembers(const analyze_printf::ArgTypeResult &ATR,
|
||||
bool checkForCStrMembers(const analyze_printf::ArgType &AT,
|
||||
const Expr *E, const CharSourceRange &CSR);
|
||||
|
||||
};
|
||||
|
@ -2320,12 +2320,12 @@ bool CheckPrintfHandler::HandleAmount(
|
|||
|
||||
QualType T = Arg->getType();
|
||||
|
||||
const analyze_printf::ArgTypeResult &ATR = Amt.getArgType(S.Context);
|
||||
assert(ATR.isValid());
|
||||
const analyze_printf::ArgType &AT = Amt.getArgType(S.Context);
|
||||
assert(AT.isValid());
|
||||
|
||||
if (!ATR.matchesType(S.Context, T)) {
|
||||
if (!AT.matchesType(S.Context, T)) {
|
||||
EmitFormatDiagnostic(S.PDiag(diag::warn_printf_asterisk_wrong_type)
|
||||
<< k << ATR.getRepresentativeTypeName(S.Context)
|
||||
<< k << AT.getRepresentativeTypeName(S.Context)
|
||||
<< T << Arg->getSourceRange(),
|
||||
getLocationOfByte(Amt.getStart()),
|
||||
/*IsStringLocation*/true,
|
||||
|
@ -2424,10 +2424,10 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) {
|
|||
}
|
||||
|
||||
// Check if a (w)string was passed when a (w)char* was needed, and offer a
|
||||
// better diagnostic if so. ATR is assumed to be valid.
|
||||
// better diagnostic if so. AT is assumed to be valid.
|
||||
// Returns true when a c_str() conversion method is found.
|
||||
bool CheckPrintfHandler::checkForCStrMembers(
|
||||
const analyze_printf::ArgTypeResult &ATR, const Expr *E,
|
||||
const analyze_printf::ArgType &AT, const Expr *E,
|
||||
const CharSourceRange &CSR) {
|
||||
typedef llvm::SmallPtrSet<CXXMethodDecl*, 1> MethodSet;
|
||||
|
||||
|
@ -2438,7 +2438,7 @@ bool CheckPrintfHandler::checkForCStrMembers(
|
|||
MI != ME; ++MI) {
|
||||
const CXXMethodDecl *Method = *MI;
|
||||
if (Method->getNumParams() == 0 &&
|
||||
ATR.matchesType(S.Context, Method->getResultType())) {
|
||||
AT.matchesType(S.Context, Method->getResultType())) {
|
||||
// FIXME: Suggest parens if the expression needs them.
|
||||
SourceLocation EndLoc =
|
||||
S.getPreprocessor().getLocForEndOfToken(E->getLocEnd());
|
||||
|
@ -2584,9 +2584,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
|
|||
using namespace analyze_printf;
|
||||
// Now type check the data expression that matches the
|
||||
// format specifier.
|
||||
const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context,
|
||||
ObjCContext);
|
||||
if (ATR.isValid() && !ATR.matchesType(S.Context, E->getType())) {
|
||||
const analyze_printf::ArgType &AT = FS.getArgType(S.Context,
|
||||
ObjCContext);
|
||||
if (AT.isValid() && !AT.matchesType(S.Context, E->getType())) {
|
||||
// Look through argument promotions for our error message's reported type.
|
||||
// This includes the integral and floating promotions, but excludes array
|
||||
// and function pointer decay; seeing that an argument intended to be a
|
||||
|
@ -2602,7 +2602,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
|
|||
if (ICE->getType() == S.Context.IntTy ||
|
||||
ICE->getType() == S.Context.UnsignedIntTy) {
|
||||
// All further checking is done on the subexpression.
|
||||
if (ATR.matchesType(S.Context, E->getType()))
|
||||
if (AT.matchesType(S.Context, E->getType()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2621,7 +2621,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
|
|||
|
||||
EmitFormatDiagnostic(
|
||||
S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
|
||||
<< ATR.getRepresentativeTypeName(S.Context) << E->getType()
|
||||
<< AT.getRepresentativeTypeName(S.Context) << E->getType()
|
||||
<< E->getSourceRange(),
|
||||
E->getLocStart(),
|
||||
/*IsStringLocation*/false,
|
||||
|
@ -2647,16 +2647,16 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
|
|||
<< S.getLangOpts().CPlusPlus0x
|
||||
<< E->getType()
|
||||
<< CallType
|
||||
<< ATR.getRepresentativeTypeName(S.Context)
|
||||
<< AT.getRepresentativeTypeName(S.Context)
|
||||
<< CSR
|
||||
<< E->getSourceRange(),
|
||||
E->getLocStart(), /*IsStringLocation*/false, CSR);
|
||||
|
||||
checkForCStrMembers(ATR, E, CSR);
|
||||
checkForCStrMembers(AT, E, CSR);
|
||||
} else
|
||||
EmitFormatDiagnostic(
|
||||
S.PDiag(diag::warn_printf_conversion_argument_type_mismatch)
|
||||
<< ATR.getRepresentativeTypeName(S.Context) << E->getType()
|
||||
<< AT.getRepresentativeTypeName(S.Context) << E->getType()
|
||||
<< CSR
|
||||
<< E->getSourceRange(),
|
||||
E->getLocStart(), /*IsStringLocation*/false, CSR);
|
||||
|
@ -2800,7 +2800,7 @@ bool CheckScanfHandler::HandleScanfSpecifier(
|
|||
if (!Ex)
|
||||
return true;
|
||||
|
||||
const analyze_scanf::ScanfArgTypeResult &ATR = FS.getArgType(S.Context);
|
||||
const analyze_scanf::ScanfArgType &ATR = FS.getArgType(S.Context);
|
||||
if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) {
|
||||
ScanfSpecifier fixedFS = FS;
|
||||
bool success = fixedFS.fixType(Ex->getType(), S.getLangOpts(),
|
||||
|
|
Loading…
Reference in New Issue