aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp27
1 files changed, 22 insertions, 5 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 2ae1d6ee91..b46081dc99 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -2095,11 +2095,28 @@ void CheckFormatHandler::HandleNonStandardLengthModifier(
void CheckFormatHandler::HandleNonStandardConversionSpecifier(
const analyze_format_string::ConversionSpecifier &CS,
const char *startSpecifier, unsigned specifierLen) {
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) << CS.toString()
- << 1,
- getLocationOfByte(CS.getStart()),
- /*IsStringLocation*/true,
- getSpecifierRange(startSpecifier, specifierLen));
+ using namespace analyze_format_string;
+
+ // See if we know how to fix this conversion specifier.
+ llvm::Optional<ConversionSpecifier> FixedCS = CS.getStandardSpecifier();
+ if (FixedCS) {
+ EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)
+ << CS.toString() << /*conversion specifier*/1,
+ getLocationOfByte(CS.getStart()),
+ /*IsStringLocation*/true,
+ getSpecifierRange(startSpecifier, specifierLen));
+
+ CharSourceRange CSRange = getSpecifierRange(CS.getStart(), CS.getLength());
+ S.Diag(getLocationOfByte(CS.getStart()), diag::note_format_fix_specifier)
+ << FixedCS->toString()
+ << FixItHint::CreateReplacement(CSRange, FixedCS->toString());
+ } else {
+ EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)
+ << CS.toString() << /*conversion specifier*/1,
+ getLocationOfByte(CS.getStart()),
+ /*IsStringLocation*/true,
+ getSpecifierRange(startSpecifier, specifierLen));
+ }
}
void CheckFormatHandler::HandlePosition(const char *startPos,