diff options
author | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2013-04-08 18:45:10 +0000 |
commit | c72c57c9e9b69944e3e009cd5e209634839581d3 (patch) | |
tree | 4fc2f184c499d106f29a386c452b49e5197bf63d /lib/Analysis/PrintfFormatString.cpp | |
parent | 5b20025c30d23d521e12c1f33ec8fa6b821952cd (diff) | |
download | FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.zip FreeBSD-src-c72c57c9e9b69944e3e009cd5e209634839581d3.tar.gz |
Vendor import of clang trunk r178860:
http://llvm.org/svn/llvm-project/cfe/trunk@178860
Diffstat (limited to 'lib/Analysis/PrintfFormatString.cpp')
-rw-r--r-- | lib/Analysis/PrintfFormatString.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp index 2fa5a88..8f151b9 100644 --- a/lib/Analysis/PrintfFormatString.cpp +++ b/lib/Analysis/PrintfFormatString.cpp @@ -13,8 +13,8 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/Analyses/FormatString.h" -#include "clang/Basic/TargetInfo.h" #include "FormatStringParsing.h" +#include "clang/Basic/TargetInfo.h" using clang::analyze_format_string::ArgType; using clang::analyze_format_string::FormatStringHandler; @@ -359,17 +359,19 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx, case ConversionSpecifier::sArg: if (LM.getKind() == LengthModifier::AsWideChar) { if (IsObjCLiteral) - return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()); + return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), + "const unichar *"); return ArgType(ArgType::WCStrTy, "wchar_t *"); } return ArgType::CStrTy; case ConversionSpecifier::SArg: if (IsObjCLiteral) - return Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()); + return ArgType(Ctx.getPointerType(Ctx.UnsignedShortTy.withConst()), + "const unichar *"); return ArgType(ArgType::WCStrTy, "wchar_t *"); case ConversionSpecifier::CArg: if (IsObjCLiteral) - return Ctx.UnsignedShortTy; + return ArgType(Ctx.UnsignedShortTy, "unichar"); return ArgType(Ctx.WCharTy, "wchar_t"); case ConversionSpecifier::pArg: return ArgType::CPointerTy; @@ -494,11 +496,29 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, } // Handle size_t, ptrdiff_t, etc. that have dedicated length modifiers in C99. - if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus0x)) + if (isa<TypedefType>(QT) && (LangOpt.C99 || LangOpt.CPlusPlus11)) namedTypeToLengthModifier(QT, LM); - // If fixing the length modifier was enough, we are done. + // If fixing the length modifier was enough, we might be done. if (hasValidLengthModifier(Ctx.getTargetInfo())) { + // If we're going to offer a fix anyway, make sure the sign matches. + switch (CS.getKind()) { + case ConversionSpecifier::uArg: + case ConversionSpecifier::UArg: + if (QT->isSignedIntegerType()) + CS.setKind(clang::analyze_format_string::ConversionSpecifier::dArg); + break; + case ConversionSpecifier::dArg: + case ConversionSpecifier::DArg: + case ConversionSpecifier::iArg: + if (QT->isUnsignedIntegerType() && !HasPlusPrefix) + CS.setKind(clang::analyze_format_string::ConversionSpecifier::uArg); + break; + default: + // Other specifiers do not have signed/unsigned variants. + break; + } + const analyze_printf::ArgType &ATR = getArgType(Ctx, IsObjCLiteral); if (ATR.isValid() && ATR.matchesType(Ctx, QT)) return true; @@ -506,7 +526,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt, // 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()) { + if (!isa<TypedefType>(QT) && QT->isCharType()) { CS.setKind(ConversionSpecifier::cArg); LM.setKind(LengthModifier::None); Precision.setHowSpecified(OptionalAmount::NotSpecified); |