aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-09-08 04:00:03 +0000
committerJordan Rose <jordan_rose@apple.com>2012-09-08 04:00:03 +0000
commitbbb6bb4952b77e57b842b4d3096848123ae690e7 (patch)
treed818e14d06c2b7cc7f7b0164f31e6bb5f40c8388 /lib/Sema/SemaChecking.cpp
parent7ac9ef1c82c779a5348ed11b3d10e01c58803b35 (diff)
Format strings: %Ld isn't available on Darwin or Windows.
This seems to be a GNU libc extension; we offer a fixit to %lld on these platforms. <rdar://problem/11518237> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163452 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r--lib/Sema/SemaChecking.cpp78
1 files changed, 51 insertions, 27 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 9bddfdc6f0..c477de8531 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1938,6 +1938,11 @@ public:
void HandleIncompleteSpecifier(const char *startSpecifier,
unsigned specifierLen);
+ void HandleInvalidLengthModifier(
+ const analyze_format_string::FormatSpecifier &FS,
+ const analyze_format_string::ConversionSpecifier &CS,
+ const char *startSpecifier, unsigned specifierLen);
+
void HandleNonStandardLengthModifier(
const analyze_format_string::LengthModifier &LM,
const char *startSpecifier, unsigned specifierLen);
@@ -2028,6 +2033,38 @@ void CheckFormatHandler::HandleIncompleteSpecifier(const char *startSpecifier,
getSpecifierRange(startSpecifier, specifierLen));
}
+void CheckFormatHandler::HandleInvalidLengthModifier(
+ const analyze_format_string::FormatSpecifier &FS,
+ const analyze_format_string::ConversionSpecifier &CS,
+ const char *startSpecifier, unsigned 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_nonsensical_length)
+ << LM.toString() << CS.toString(),
+ 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_nonsensical_length)
+ << LM.toString() << CS.toString(),
+ getLocationOfByte(LM.getStart()),
+ /*IsStringLocation*/true,
+ getSpecifierRange(startSpecifier, specifierLen),
+ FixItHint::CreateRemoval(LMRange));
+ }
+}
+
void CheckFormatHandler::HandleNonStandardLengthModifier(
const analyze_format_string::LengthModifier &LM,
const char *startSpecifier, unsigned specifierLen) {
@@ -2566,23 +2603,17 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier
// Check the length modifier is valid with the given conversion specifier.
const LengthModifier &LM = FS.getLengthModifier();
- if (!FS.hasValidLengthModifier())
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_nonsensical_length)
- << LM.toString() << CS.toString(),
- getLocationOfByte(LM.getStart()),
- /*IsStringLocation*/true,
- getSpecifierRange(startSpecifier, specifierLen),
- FixItHint::CreateRemoval(
- getSpecifierRange(LM.getStart(),
- LM.getLength())));
- if (!FS.hasStandardLengthModifier())
+ if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
+ HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen);
+ else if (!FS.hasStandardLengthModifier())
HandleNonStandardLengthModifier(LM, startSpecifier, specifierLen);
- if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
- HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
- if (!FS.hasStandardLengthConversionCombination())
+ else if (!FS.hasStandardLengthConversionCombination())
HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
specifierLen);
+ if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
+ HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
+
// The remaining checks depend on the data arguments.
if (HasVAListArg)
return true;
@@ -2886,24 +2917,17 @@ bool CheckScanfHandler::HandleScanfSpecifier(
// Check the length modifier is valid with the given conversion specifier.
const LengthModifier &LM = FS.getLengthModifier();
- if (!FS.hasValidLengthModifier()) {
- const CharSourceRange &R = getSpecifierRange(LM.getStart(), LM.getLength());
- EmitFormatDiagnostic(S.PDiag(diag::warn_format_nonsensical_length)
- << LM.toString() << CS.toString()
- << getSpecifierRange(startSpecifier, specifierLen),
- getLocationOfByte(LM.getStart()),
- /*IsStringLocation*/true, R,
- FixItHint::CreateRemoval(R));
- }
-
- if (!FS.hasStandardLengthModifier())
+ if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))
+ HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen);
+ else if (!FS.hasStandardLengthModifier())
HandleNonStandardLengthModifier(LM, startSpecifier, specifierLen);
- if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
- HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
- if (!FS.hasStandardLengthConversionCombination())
+ else if (!FS.hasStandardLengthConversionCombination())
HandleNonStandardConversionSpecification(LM, CS, startSpecifier,
specifierLen);
+ if (!FS.hasStandardConversionSpecifier(S.getLangOpts()))
+ HandleNonStandardConversionSpecifier(CS, startSpecifier, specifierLen);
+
// The remaining checks depend on the data arguments.
if (HasVAListArg)
return true;