diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-07-19 22:01:06 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-07-19 22:01:06 +0000 |
commit | baa400654bd6f8396f9a07188445ae7955b060a3 (patch) | |
tree | 03ee1509fbb2d3ceb336f9c4c37b01e401ce3ccb /lib/Sema/SemaChecking.cpp | |
parent | abc563f554951259bbe0315055cad92ee14d87e4 (diff) |
Don't warn when a '%%' or '%*d' (scanf) is used in a format string with positional arguments, since
these don't actually consume an argument.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@108757 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaChecking.cpp')
-rw-r--r-- | lib/Sema/SemaChecking.cpp | 48 |
1 files changed, 26 insertions, 22 deletions
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index f36a9ed938..72939e6e59 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -1434,16 +1434,18 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier using namespace analyze_printf; const ConversionSpecifier &CS = FS.getConversionSpecifier(); - if (atFirstArg) { - atFirstArg = false; - usesPositionalArgs = FS.usesPositionalArg(); - } - else if (usesPositionalArgs != FS.usesPositionalArg()) { - // Cannot mix-and-match positional and non-positional arguments. - S.Diag(getLocationOfByte(CS.getStart()), - diag::warn_format_mix_positional_nonpositional_args) - << getSpecifierRange(startSpecifier, specifierLen); - return false; + if (FS.consumesDataArgument()) { + if (atFirstArg) { + atFirstArg = false; + usesPositionalArgs = FS.usesPositionalArg(); + } + else if (usesPositionalArgs != FS.usesPositionalArg()) { + // Cannot mix-and-match positional and non-positional arguments. + S.Diag(getLocationOfByte(CS.getStart()), + diag::warn_format_mix_positional_nonpositional_args) + << getSpecifierRange(startSpecifier, specifierLen); + return false; + } } // First check if the field width, precision, and conversion specifier @@ -1653,18 +1655,20 @@ bool CheckScanfHandler::HandleScanfSpecifier( const ConversionSpecifier &CS = FS.getConversionSpecifier(); - // FIXME: Handle case where '%' and '*' don't consume an argument. - // This needs to be done for the printf case as well. - if (atFirstArg) { - atFirstArg = false; - usesPositionalArgs = FS.usesPositionalArg(); - } - else if (usesPositionalArgs != FS.usesPositionalArg()) { - // Cannot mix-and-match positional and non-positional arguments. - S.Diag(getLocationOfByte(CS.getStart()), - diag::warn_format_mix_positional_nonpositional_args) - << getSpecifierRange(startSpecifier, specifierLen); - return false; + // Handle case where '%' and '*' don't consume an argument. These shouldn't + // be used to decide if we are using positional arguments consistently. + if (FS.consumesDataArgument()) { + if (atFirstArg) { + atFirstArg = false; + usesPositionalArgs = FS.usesPositionalArg(); + } + else if (usesPositionalArgs != FS.usesPositionalArg()) { + // Cannot mix-and-match positional and non-positional arguments. + S.Diag(getLocationOfByte(CS.getStart()), + diag::warn_format_mix_positional_nonpositional_args) + << getSpecifierRange(startSpecifier, specifierLen); + return false; + } } // Check if the field with is non-zero. |