Format strings: suggest %lld instead of %qd and %Ld with -Wformat-non-iso.
As a corollary to the previous commit, even when an extension is
available, we can still offer a fixit to the standard modifier.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163453 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index c477de8..dd1f9e1 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1941,21 +1941,16 @@
void HandleInvalidLengthModifier(
const analyze_format_string::FormatSpecifier &FS,
const analyze_format_string::ConversionSpecifier &CS,
- const char *startSpecifier, unsigned specifierLen);
+ const char *startSpecifier, unsigned specifierLen, unsigned DiagID);
void HandleNonStandardLengthModifier(
- const analyze_format_string::LengthModifier &LM,
+ const analyze_format_string::FormatSpecifier &FS,
const char *startSpecifier, unsigned specifierLen);
void HandleNonStandardConversionSpecifier(
const analyze_format_string::ConversionSpecifier &CS,
const char *startSpecifier, unsigned specifierLen);
- void HandleNonStandardConversionSpecification(
- const analyze_format_string::LengthModifier &LM,
- const analyze_format_string::ConversionSpecifier &CS,
- const char *startSpecifier, unsigned specifierLen);
-
virtual void HandlePosition(const char *startPos, unsigned posLen);
virtual void HandleInvalidPosition(const char *startSpecifier,
@@ -2036,7 +2031,7 @@
void CheckFormatHandler::HandleInvalidLengthModifier(
const analyze_format_string::FormatSpecifier &FS,
const analyze_format_string::ConversionSpecifier &CS,
- const char *startSpecifier, unsigned specifierLen) {
+ const char *startSpecifier, unsigned specifierLen, unsigned DiagID) {
using namespace analyze_format_string;
const LengthModifier &LM = FS.getLengthModifier();
@@ -2045,8 +2040,7 @@
// See if we know how to fix this length modifier.
llvm::Optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
if (FixedLM) {
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_nonsensical_length)
- << LM.toString() << CS.toString(),
+ EmitFormatDiagnostic(S.PDiag(DiagID) << LM.toString() << CS.toString(),
getLocationOfByte(LM.getStart()),
/*IsStringLocation*/true,
getSpecifierRange(startSpecifier, specifierLen));
@@ -2056,23 +2050,46 @@
<< FixItHint::CreateReplacement(LMRange, FixedLM->toString());
} else {
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_nonsensical_length)
- << LM.toString() << CS.toString(),
+ FixItHint Hint;
+ if (DiagID == diag::warn_format_nonsensical_length)
+ Hint = FixItHint::CreateRemoval(LMRange);
+
+ EmitFormatDiagnostic(S.PDiag(DiagID) << LM.toString() << CS.toString(),
getLocationOfByte(LM.getStart()),
/*IsStringLocation*/true,
getSpecifierRange(startSpecifier, specifierLen),
- FixItHint::CreateRemoval(LMRange));
+ Hint);
}
}
void CheckFormatHandler::HandleNonStandardLengthModifier(
- const analyze_format_string::LengthModifier &LM,
+ const analyze_format_string::FormatSpecifier &FS,
const char *startSpecifier, unsigned specifierLen) {
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard) << LM.toString()
- << 0,
- getLocationOfByte(LM.getStart()),
- /*IsStringLocation*/true,
- getSpecifierRange(startSpecifier, specifierLen));
+ using namespace analyze_format_string;
+
+ const LengthModifier &LM = FS.getLengthModifier();
+ CharSourceRange LMRange = getSpecifierRange(LM.getStart(), LM.getLength());
+
+ // See if we know how to fix this length modifier.
+ llvm::Optional<LengthModifier> FixedLM = FS.getCorrectedLengthModifier();
+ if (FixedLM) {
+ EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)
+ << LM.toString() << 0,
+ getLocationOfByte(LM.getStart()),
+ /*IsStringLocation*/true,
+ getSpecifierRange(startSpecifier, specifierLen));
+
+ S.Diag(getLocationOfByte(LM.getStart()), diag::note_format_fix_specifier)
+ << FixedLM->toString()
+ << FixItHint::CreateReplacement(LMRange, FixedLM->toString());
+
+ } else {
+ EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard)
+ << LM.toString() << 0,
+ getLocationOfByte(LM.getStart()),
+ /*IsStringLocation*/true,
+ getSpecifierRange(startSpecifier, specifierLen));
+ }
}
void CheckFormatHandler::HandleNonStandardConversionSpecifier(
@@ -2085,17 +2102,6 @@
getSpecifierRange(startSpecifier, specifierLen));
}
-void CheckFormatHandler::HandleNonStandardConversionSpecification(
- const analyze_format_string::LengthModifier &LM,
- const analyze_format_string::ConversionSpecifier &CS,
- const char *startSpecifier, unsigned specifierLen) {
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard_conversion_spec)
- << LM.toString() << CS.toString(),
- getLocationOfByte(LM.getStart()),
- /*IsStringLocation*/true,
- getSpecifierRange(startSpecifier, specifierLen));
-}
-
void CheckFormatHandler::HandlePosition(const char *startPos,
unsigned posLen) {
EmitFormatDiagnostic(S.PDiag(diag::warn_format_non_standard_positional_arg),
@@ -2602,14 +2608,14 @@
startSpecifier, specifierLen);
// Check the length modifier is valid with the given conversion specifier.
- const LengthModifier &LM = FS.getLengthModifier();
if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
- HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen);
+ HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
+ diag::warn_format_nonsensical_length);
else if (!FS.hasStandardLengthModifier())
- HandleNonStandardLengthModifier(LM, startSpecifier, specifierLen);
+ HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
else if (!FS.hasStandardLengthConversionCombination())
- HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
- specifierLen);
+ HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
+ diag::warn_format_non_standard_conversion_spec);
if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
@@ -2916,14 +2922,14 @@
}
// Check the length modifier is valid with the given conversion specifier.
- const LengthModifier &LM = FS.getLengthModifier();
if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
- HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen);
+ HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
+ diag::warn_format_nonsensical_length);
else if (!FS.hasStandardLengthModifier())
- HandleNonStandardLengthModifier(LM, startSpecifier, specifierLen);
+ HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
else if (!FS.hasStandardLengthConversionCombination())
- HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
- specifierLen);
+ HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
+ diag::warn_format_non_standard_conversion_spec);
if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);