diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Analysis/ScanfFormatString.cpp | 44 | ||||
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 14 |
2 files changed, 34 insertions, 24 deletions
diff --git a/lib/Analysis/ScanfFormatString.cpp b/lib/Analysis/ScanfFormatString.cpp index 493a3c8df2..61af1d6737 100644 --- a/lib/Analysis/ScanfFormatString.cpp +++ b/lib/Analysis/ScanfFormatString.cpp @@ -19,6 +19,7 @@ using clang::analyze_format_string::ArgTypeResult; using clang::analyze_format_string::FormatStringHandler; using clang::analyze_format_string::LengthModifier; using clang::analyze_format_string::OptionalAmount; +using clang::analyze_format_string::ConversionSpecifier; using clang::analyze_scanf::ScanfConversionSpecifier; using clang::analyze_scanf::ScanfSpecifier; @@ -146,27 +147,28 @@ static ScanfSpecifierResult ParseScanfSpecifier(FormatStringHandler &H, switch (*conversionPosition) { default: break; - case '%': k = ScanfConversionSpecifier::PercentArg; break; - case 'A': k = ScanfConversionSpecifier::AArg; break; - case 'E': k = ScanfConversionSpecifier::EArg; break; - case 'F': k = ScanfConversionSpecifier::FArg; break; - case 'G': k = ScanfConversionSpecifier::GArg; break; - case 'X': k = ScanfConversionSpecifier::XArg; break; - case 'a': k = ScanfConversionSpecifier::aArg; break; - case 'd': k = ScanfConversionSpecifier::dArg; break; - case 'e': k = ScanfConversionSpecifier::eArg; break; - case 'f': k = ScanfConversionSpecifier::fArg; break; - case 'g': k = ScanfConversionSpecifier::gArg; break; - case 'i': k = ScanfConversionSpecifier::iArg; break; - case 'n': k = ScanfConversionSpecifier::nArg; break; - case 'c': k = ScanfConversionSpecifier::cArg; break; - case 'C': k = ScanfConversionSpecifier::CArg; break; - case 'S': k = ScanfConversionSpecifier::SArg; break; - case '[': k = ScanfConversionSpecifier::ScanListArg; break; - case 'u': k = ScanfConversionSpecifier::uArg; break; - case 'x': k = ScanfConversionSpecifier::xArg; break; - case 'o': k = ScanfConversionSpecifier::oArg; break; - case 's': k = ScanfConversionSpecifier::sArg; break; + case '%': k = ConversionSpecifier::PercentArg; break; + case 'A': k = ConversionSpecifier::AArg; break; + case 'E': k = ConversionSpecifier::EArg; break; + case 'F': k = ConversionSpecifier::FArg; break; + case 'G': k = ConversionSpecifier::GArg; break; + case 'X': k = ConversionSpecifier::XArg; break; + case 'a': k = ConversionSpecifier::aArg; break; + case 'd': k = ConversionSpecifier::dArg; break; + case 'e': k = ConversionSpecifier::eArg; break; + case 'f': k = ConversionSpecifier::fArg; break; + case 'g': k = ConversionSpecifier::gArg; break; + case 'i': k = ConversionSpecifier::iArg; break; + case 'n': k = ConversionSpecifier::nArg; break; + case 'c': k = ConversionSpecifier::cArg; break; + case 'C': k = ConversionSpecifier::CArg; break; + case 'S': k = ConversionSpecifier::SArg; break; + case '[': k = ConversionSpecifier::ScanListArg; break; + case 'u': k = ConversionSpecifier::uArg; break; + case 'x': k = ConversionSpecifier::xArg; break; + case 'o': k = ConversionSpecifier::oArg; break; + case 's': k = ConversionSpecifier::sArg; break; + case 'p': k = ConversionSpecifier::pArg; break; } ScanfConversionSpecifier CS(conversionPosition, k); if (k == ScanfConversionSpecifier::ScanListArg) { diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 8846c25724..2887a50d52 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1701,9 +1701,17 @@ bool CheckScanfHandler::HandleScanfSpecifier( CoveredArgs.set(argIndex); } - // FIXME: Check that the length modifier is valid with the given - // conversion specifier. - + // Check the length modifier is valid with the given conversion specifier. + const LengthModifier &LM = FS.getLengthModifier(); + if (!FS.hasValidLengthModifier()) { + S.Diag(getLocationOfByte(LM.getStart()), + diag::warn_format_nonsensical_length) + << LM.toString() << CS.toString() + << getSpecifierRange(startSpecifier, specifierLen) + << FixItHint::CreateRemoval(getSpecifierRange(LM.getStart(), + LM.getLength())); + } + // The remaining checks depend on the data arguments. if (HasVAListArg) return true; |