diff options
| -rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 36 | ||||
| -rw-r--r-- | clang/test/Sema/format-strings-scanf.c | 4 | ||||
| -rw-r--r-- | clang/test/Sema/format-strings.c | 3 | 
3 files changed, 28 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index b02e5b598aa..5e8770888c5 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/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/clang/test/Sema/format-strings-scanf.c b/clang/test/Sema/format-strings-scanf.c index d89dbc494b7..c97da3fd921 100644 --- a/clang/test/Sema/format-strings-scanf.c +++ b/clang/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/clang/test/Sema/format-strings.c b/clang/test/Sema/format-strings.c index 341fd599080..3a95df5038c 100644 --- a/clang/test/Sema/format-strings.c +++ b/clang/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   | 

