summaryrefslogtreecommitdiffstats
path: root/clang/lib/Analysis/PrintfFormatString.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-01-17 18:47:16 +0000
committerJordan Rose <jordan_rose@apple.com>2013-01-17 18:47:16 +0000
commitaa7a3b3e75e806591f629a4a85155958235625ce (patch)
treecb0635422e1003cc7500dca90d4298760564e320 /clang/lib/Analysis/PrintfFormatString.cpp
parentb169ccc118f0f9845672272b0668334870b24d07 (diff)
downloadbcm5719-llvm-aa7a3b3e75e806591f629a4a85155958235625ce.tar.gz
bcm5719-llvm-aa7a3b3e75e806591f629a4a85155958235625ce.zip
Format strings: correct signedness if already correcting width (%d,%u).
It is valid to do this: printf("%u", (int)x); But if we see this: printf("%lu", (int)x); ...our fixit should suggest %d, not %u. llvm-svn: 172739
Diffstat (limited to 'clang/lib/Analysis/PrintfFormatString.cpp')
-rw-r--r--clang/lib/Analysis/PrintfFormatString.cpp20
1 files changed, 19 insertions, 1 deletions
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp
index b52433a0a4e..5d37de362a4 100644
--- a/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/clang/lib/Analysis/PrintfFormatString.cpp
@@ -499,8 +499,26 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
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())
+ 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;
OpenPOWER on IntegriCloud