[clang] 5cf37d8 - [Sema] -Wformat: recognize %lb for the printf/scanf family of functions

Fangrui Song via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 20 09:34:40 PDT 2023


Author: Fangrui Song
Date: 2023-04-20T09:34:34-07:00
New Revision: 5cf37d8bd5c05ef84fba6d6fd9d4ac8b9905c7cb

URL: https://github.com/llvm/llvm-project/commit/5cf37d8bd5c05ef84fba6d6fd9d4ac8b9905c7cb
DIFF: https://github.com/llvm/llvm-project/commit/5cf37d8bd5c05ef84fba6d6fd9d4ac8b9905c7cb.diff

LOG: [Sema] -Wformat: recognize %lb for the printf/scanf family of functions

Fix https://github.com/llvm/llvm-project/issues/62247

D131057 added `bArg` and `BArg` in the `AsLongLong` label in
`FormatSpecifier::hasValidLengthModifier`, but missed the `AsLong` label,
therefore `%llb` is allowed while `%lb` (e.g. `printf("%lb", (long)10)`) has a
spurious warning. Add the missing case labels.

Reviewed By: aaron.ballman, enh

Differential Revision: https://reviews.llvm.org/D148779

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/FormatString.cpp
    clang/test/Sema/format-strings-fixit.c
    clang/test/Sema/format-strings.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index febd47c1ef3f..7beae0324779 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -228,6 +228,9 @@ Improvements to Clang's diagnostics
 - Clang's "static assertion failed" diagnostic now points to the static assertion
   expression instead of pointing to the ``static_assert`` token.
   (`#61951 <https://github.com/llvm/llvm-project/issues/61951>`_)
+- ``-Wformat`` now recognizes ``%lb`` for the ``printf``/``scanf`` family of
+  functions.
+  (`#62247: <https://github.com/llvm/llvm-project/issues/62247>`_).
 
 Bug Fixes in This Version
 -------------------------

diff  --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp
index c7dee2d421bb..d42e4ea2ea08 100644
--- a/clang/lib/AST/FormatString.cpp
+++ b/clang/lib/AST/FormatString.cpp
@@ -848,6 +848,8 @@ bool FormatSpecifier::hasValidLengthModifier(const TargetInfo &Target,
       }
 
       switch (CS.getKind()) {
+        case ConversionSpecifier::bArg:
+        case ConversionSpecifier::BArg:
         case ConversionSpecifier::dArg:
         case ConversionSpecifier::DArg:
         case ConversionSpecifier::iArg:

diff  --git a/clang/test/Sema/format-strings-fixit.c b/clang/test/Sema/format-strings-fixit.c
index 64614e1c53fc..5e37ec76fed2 100644
--- a/clang/test/Sema/format-strings-fixit.c
+++ b/clang/test/Sema/format-strings-fixit.c
@@ -22,6 +22,7 @@ void test(void) {
   printf("abc%0f", "testing testing 123");
   printf("%u", (long) -12);
   printf("%b", (long) -13);
+  printf("%d", (long) -14);
   printf("%p", 123);
   printf("%c\n", "x");
   printf("%c\n", 1.23);
@@ -162,6 +163,7 @@ void test2(int intSAParm[static 2]) {
 
   // Preserve the original formatting.
   scanf("%b", &longVar);
+  scanf("%d", &longVar);
   scanf("%o", &longVar);
   scanf("%u", &longVar);
   scanf("%x", &longVar);
@@ -181,7 +183,8 @@ void test2(int intSAParm[static 2]) {
 // CHECK: printf("%d", (int) 123);
 // CHECK: printf("abc%s", "testing testing 123");
 // CHECK: printf("%ld", (long) -12);
-// CHECK: printf("%ld", (long) -13);
+// CHECK: printf("%lb", (long) -13);
+// CHECK: printf("%ld", (long) -14);
 // CHECK: printf("%d", 123);
 // CHECK: printf("%s\n", "x");
 // CHECK: printf("%f\n", 1.23);
@@ -249,6 +252,7 @@ void test2(int intSAParm[static 2]) {
 // CHECK: scanf("%ju", (my_uintmax_type*)&uIntmaxVar);
 // CHECK: scanf("%td", (my_ptr
diff _type*)&ptr
diff Var);
 // CHECK: scanf("%d", (my_int_type*)&intVar);
+// CHECK: scanf("%lb", &longVar);
 // CHECK: scanf("%ld", &longVar);
 // CHECK: scanf("%lo", &longVar);
 // CHECK: scanf("%lu", &longVar);

diff  --git a/clang/test/Sema/format-strings.c b/clang/test/Sema/format-strings.c
index 36dd88cea946..56d3056d5575 100644
--- a/clang/test/Sema/format-strings.c
+++ b/clang/test/Sema/format-strings.c
@@ -304,6 +304,7 @@ void test10(int x, float f, int i, long long lli) {
   printf("%qp", (void *)0); // expected-warning{{length modifier 'q' results in undefined behavior or no effect with 'p' conversion specifier}}
   printf("hhX %hhX", (unsigned char)10); // no-warning
   printf("llX %llX", (long long) 10); // no-warning
+  printf("%lb %lB", (long) 10, (long) 10); // no-warning
   printf("%llb %llB", (long long) 10, (long long) 10); // no-warning
   // This is fine, because there is an implicit conversion to an int.
   printf("%d", (unsigned char) 10); // no-warning


        


More information about the cfe-commits mailing list