From 220947bd5a66b0f25f5e74d6029769dfb34f07b4 Mon Sep 17 00:00:00 2001 From: Jean-Daniel Dupas Date: Tue, 31 Jan 2012 18:12:08 +0000 Subject: [PATCH] FormatCheckers should emit all diagnostics using EmitFormatDiagnostic(). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149394 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaChecking.cpp | 36 +++++++++++++++++++------------- test/Sema/format-strings-scanf.c | 4 ++++ test/Sema/format-strings.c | 3 +++ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index b02e5b598a..5e8770888c 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2198,11 +2198,14 @@ CheckPrintfHandler::HandlePrintfSpecifier(const analyze_printf::PrintfSpecifier os.str())); } else { - S.Diag(getLocationOfByte(CS.getStart()), - diag::warn_printf_conversion_argument_type_mismatch) - << ATR.getRepresentativeTypeName(S.Context) << Ex->getType() - << getSpecifierRange(startSpecifier, specifierLen) - << Ex->getSourceRange(); + EmitFormatDiagnostic( + S.PDiag(diag::warn_printf_conversion_argument_type_mismatch) + << ATR.getRepresentativeTypeName(S.Context) << Ex->getType() + << getSpecifierRange(startSpecifier, specifierLen) + << Ex->getSourceRange(), + getLocationOfByte(CS.getStart()), + true, + getSpecifierRange(startSpecifier, specifierLen)); } } @@ -2313,12 +2316,13 @@ bool CheckScanfHandler::HandleScanfSpecifier( // 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())); + 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)); } // The remaining checks depend on the data arguments. @@ -2352,11 +2356,13 @@ bool CheckScanfHandler::HandleScanfSpecifier( getSpecifierRange(startSpecifier, specifierLen), os.str())); } else { - S.Diag(getLocationOfByte(CS.getStart()), - diag::warn_printf_conversion_argument_type_mismatch) + EmitFormatDiagnostic( + S.PDiag(diag::warn_printf_conversion_argument_type_mismatch) << ATR.getRepresentativeTypeName(S.Context) << Ex->getType() - << getSpecifierRange(startSpecifier, specifierLen) - << Ex->getSourceRange(); + << Ex->getSourceRange(), + getLocationOfByte(CS.getStart()), + /*IsStringLocation*/true, + getSpecifierRange(startSpecifier, specifierLen)); } } diff --git a/test/Sema/format-strings-scanf.c b/test/Sema/format-strings-scanf.c index d89dbc494b..c97da3fd92 100644 --- a/test/Sema/format-strings-scanf.c +++ b/test/Sema/format-strings-scanf.c @@ -53,6 +53,10 @@ void pr9751() { const char kFormat2[] = "%["; // expected-note{{format string is defined here}}} scanf(kFormat2, str); // expected-warning{{no closing ']' for '%[' in scanf format string}} scanf("%[", str); // expected-warning{{no closing ']' for '%[' in scanf format string}} + const char kFormat3[] = "%hu"; // expected-note{{format string is defined here}}} + scanf(kFormat3, &i); // expected-warning {{format specifies type 'unsigned short *' but the argument}} + const char kFormat4[] = "%lp"; // expected-note{{format string is defined here}}} + scanf(kFormat4, &i); // expected-warning {{length modifier 'l' results in undefined behavior or no effect with 'p' conversion specifier}} } void test_variants(int *i, const char *s, ...) { diff --git a/test/Sema/format-strings.c b/test/Sema/format-strings.c index 341fd59908..3a95df5038 100644 --- a/test/Sema/format-strings.c +++ b/test/Sema/format-strings.c @@ -468,6 +468,9 @@ void pr9751() { // Make sure that the "format string is defined here" note is not emitted // when the original string is within the argument expression. printf(1 ? "yes %d" : "no %d"); // expected-warning 2{{more '%' conversions than data arguments}} + + const char kFormat17[] = "%hu"; // expected-note{{format string is defined here}}} + printf(kFormat17, (int[]){0}); // expected-warning{{format specifies type 'unsigned short' but the argument}} } // PR 9466: clang: doesn't know about %Lu, %Ld, and %Lx -- 2.50.1