summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-02-01 19:28:15 +0000
committerTed Kremenek <kremenek@apple.com>2010-02-01 19:28:15 +0000
commitcd83106151285041c4e5f492bb80e9cb22276db2 (patch)
tree3b296156e9fdf18df4c6821b71bb6c2b8f184d4b /clang/lib
parent973f2eb0cd69d3d331ce66c3395d9fea696875dd (diff)
downloadbcm5719-llvm-cd83106151285041c4e5f492bb80e9cb22276db2.tar.gz
bcm5719-llvm-cd83106151285041c4e5f492bb80e9cb22276db2.zip
Format string checking: selectively ignore implicit casts to 'int'
when checking if the format specifier matches the type of the data argument and the length modifier indicates the data type is 'char' or 'short'. llvm-svn: 94992
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp23
1 files changed, 17 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 4e2e9c7376b..5db7038405c 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -1280,14 +1280,25 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
// format specifier.
const Expr *Ex = getDataArg(NumConversions);
const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context);
-
+
if (const QualType *T = ATR.getSpecificType()) {
if (!MatchType(*T, Ex->getType(), true)) {
- S.Diag(getLocationOfByte(CS.getStart()),
- diag::warn_printf_conversion_argument_type_mismatch)
- << *T << Ex->getType()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
- << Ex->getSourceRange();
+ // Check if we didn't match because of an implicit cast from a 'char'
+ // or 'short' to an 'int'. This is done because printf is a varargs
+ // function.
+ bool hasError = true;
+ if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex))
+ if (ICE->getType() == S.Context.IntTy) {
+ Ex = ICE->getSubExpr();
+ hasError = !MatchType(*T, Ex->getType(), true);
+ }
+
+ if (hasError)
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_printf_conversion_argument_type_mismatch)
+ << *T << Ex->getType()
+ << getFormatSpecifierRange(startSpecifier, specifierLen)
+ << Ex->getSourceRange();
}
return true;
}
OpenPOWER on IntegriCloud