diff options
| author | Michael J. Spencer <bigcheesegs@gmail.com> | 2010-07-27 04:46:02 +0000 |
|---|---|---|
| committer | Michael J. Spencer <bigcheesegs@gmail.com> | 2010-07-27 04:46:02 +0000 |
| commit | 2c35bc1232d899c7dad2ca805f2986b4b79db350 (patch) | |
| tree | 27d955a6a34e1245c1bdce831cd140466f9abf00 /clang/lib/Sema | |
| parent | 1bec81a8889f58d47e505ccdfc365404868218d4 (diff) | |
| download | bcm5719-llvm-2c35bc1232d899c7dad2ca805f2986b4b79db350.tar.gz bcm5719-llvm-2c35bc1232d899c7dad2ca805f2986b4b79db350.zip | |
Revert r109428 "Hoist argument type checking into CheckFormatHandler. This is prep for scanf format"
Got errors about ASTContext being undefined with Visual Studio 2010.
llvm-svn: 109491
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 94 |
1 files changed, 41 insertions, 53 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 1b689499edf..03ca084dd89 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -1174,11 +1174,6 @@ protected: const analyze_format_string::ConversionSpecifier &CS, const char *startSpecifier, unsigned specifierLen, unsigned argIndex); - - void CheckArgType(const analyze_format_string::FormatSpecifier &FS, - const analyze_format_string::ConversionSpecifier &CS, - const char *startSpecifier, unsigned specifierLen, - unsigned argIndex); }; } @@ -1304,52 +1299,6 @@ CheckFormatHandler::CheckNumArgs( return true; } -void CheckFormatHandler::CheckArgType( - const analyze_format_string::FormatSpecifier &FS, - const analyze_format_string::ConversionSpecifier &CS, - const char *startSpecifier, unsigned specifierLen, unsigned argIndex) { - - const Expr *Ex = getDataArg(argIndex); - const analyze_format_string::ArgTypeResult &ATR = FS.getArgType(S.Context); - - if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) { - // Check if we didn't match because of an implicit cast from a 'char' - // or 'short' to an 'int'. This is done because scanf/printf are varargs - // functions. - if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex)) - if (ICE->getType() == S.Context.IntTy) - if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType())) - return; - - if (const analyze_printf::PrintfSpecifier *PFS = - dyn_cast<analyze_printf::PrintfSpecifier>(&FS)) { - // We may be able to offer a FixItHint if it is a supported type. - analyze_printf::PrintfSpecifier fixedFS(*PFS); - if (fixedFS.fixType(Ex->getType())) { - // Get the fix string from the fixed format specifier - llvm::SmallString<128> buf; - llvm::raw_svector_ostream os(buf); - fixedFS.toString(os); - - S.Diag(getLocationOfByte(CS.getStart()), - diag::warn_printf_conversion_argument_type_mismatch) - << ATR.getRepresentativeType(S.Context) << Ex->getType() - << getSpecifierRange(startSpecifier, specifierLen) - << Ex->getSourceRange() - << FixItHint::CreateReplacement( - getSpecifierRange(startSpecifier, specifierLen), os.str()); - } - else { - S.Diag(getLocationOfByte(CS.getStart()), - diag::warn_printf_conversion_argument_type_mismatch) - << ATR.getRepresentativeType(S.Context) << Ex->getType() - << getSpecifierRange(startSpecifier, specifierLen) - << Ex->getSourceRange(); - } - } - } -} - //===--- CHECK: Printf format string checking ------------------------------===// namespace { @@ -1621,8 +1570,47 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex)) return false; - CheckArgType(FS, CS, startSpecifier, specifierLen, argIndex); - + // Now type check the data expression that matches the + // format specifier. + const Expr *Ex = getDataArg(argIndex); + const analyze_printf::ArgTypeResult &ATR = FS.getArgType(S.Context); + if (ATR.isValid() && !ATR.matchesType(S.Context, Ex->getType())) { + // Check if we didn't match because of an implicit cast from a 'char' + // or 'short' to an 'int'. This is done because printf is a varargs + // function. + if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Ex)) + if (ICE->getType() == S.Context.IntTy) + if (ATR.matchesType(S.Context, ICE->getSubExpr()->getType())) + return true; + + // We may be able to offer a FixItHint if it is a supported type. + PrintfSpecifier fixedFS = FS; + bool success = fixedFS.fixType(Ex->getType()); + + if (success) { + // Get the fix string from the fixed format specifier + llvm::SmallString<128> buf; + llvm::raw_svector_ostream os(buf); + fixedFS.toString(os); + + S.Diag(getLocationOfByte(CS.getStart()), + diag::warn_printf_conversion_argument_type_mismatch) + << ATR.getRepresentativeType(S.Context) << Ex->getType() + << getSpecifierRange(startSpecifier, specifierLen) + << Ex->getSourceRange() + << FixItHint::CreateReplacement( + getSpecifierRange(startSpecifier, specifierLen), + os.str()); + } + else { + S.Diag(getLocationOfByte(CS.getStart()), + diag::warn_printf_conversion_argument_type_mismatch) + << ATR.getRepresentativeType(S.Context) << Ex->getType() + << getSpecifierRange(startSpecifier, specifierLen) + << Ex->getSourceRange(); + } + } + return true; } |

