aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorTom Care <tcare@apple.com>2010-06-09 04:11:11 +0000
committerTom Care <tcare@apple.com>2010-06-09 04:11:11 +0000
commit3bfc5f49e0e37e235bb0d33bcbcb36af9d1f84ab (patch)
tree960b5940e2de8f95be43445f90a38040dcb0eb00 /lib/Sema/SemaChecking.cpp
parent5a57efd7bf88a4a13018e0471ded8063a4abe8af (diff)
Added FixIt support to printf format string checking.
- Refactored LengthModifier to be a class. - Added toString methods in all member classes of FormatSpecifier. - FixIt suggestions keep user specified flags unless incorrect. Limitations: - The suggestions are not conversion specifier sensitive. For example, if we have a 'pad with zeroes' flag, and the correction is a string conversion specifier, we do not remove the flag. Clang will warn us on the next compilation. A test/Sema/format-strings-fixit.c M include/clang/Analysis/Analyses/PrintfFormatString.h M lib/Analysis/PrintfFormatString.cpp M lib/Sema/SemaChecking.cpp git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@105680 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 6e54dab113..dbc33430fb 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -26,6 +26,7 @@
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/raw_ostream.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TargetInfo.h"
#include <limits>
@@ -1404,11 +1405,32 @@ CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier
if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType()))
return true;
- S.Diag(getLocationOfByte(CS.getStart()),
- diag::warn_printf_conversion_argument_type_mismatch)
- << ATR.getRepresentativeType(S.Context) << Ex->getType()
- << getFormatSpecifierRange(startSpecifier, specifierLen)
- << Ex->getSourceRange();
+ // We may be able to offer a FixItHint if it is a supported type.
+ FormatSpecifier fixedFS = FS;
+ bool success = fixedFS.fixType(Ex->getType());
+
+ if (success) {
+ // Get the fix string from the fixed format specifier
+ llvm::SmallString<128> buf;
+ llvm::raw_svector_ostream os(buf);
+ fixedFS.toString(os);
+
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_printf_conversion_argument_type_mismatch)
+ << ATR.getRepresentativeType(S.Context) << Ex->getType()
+ << getFormatSpecifierRange(startSpecifier, specifierLen)
+ << Ex->getSourceRange()
+ << FixItHint::CreateReplacement(
+ getFormatSpecifierRange(startSpecifier, specifierLen),
+ os.str());
+ }
+ else {
+ S.Diag(getLocationOfByte(CS.getStart()),
+ diag::warn_printf_conversion_argument_type_mismatch)
+ << ATR.getRepresentativeType(S.Context) << Ex->getType()
+ << getFormatSpecifierRange(startSpecifier, specifierLen)
+ << Ex->getSourceRange();
+ }
}
return true;