[PATCH] D132266: [Clang][SemaChecking] move %hh and %h -Wformat warnings to -Wformat-pedantic

Nick Desaulniers via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Fri Aug 19 16:15:45 PDT 2022


nickdesaulniers created this revision.
nickdesaulniers added a reviewer: aaron.ballman.
Herald added a subscriber: emaste.
Herald added a project: All.
nickdesaulniers requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

Similar to
commit cc01d6421f4a ("[Sema] Don't warn on printf('%hd', [char]) (PR41467)")

warning on %hhd -> int or %hd -> int is a major source of pain wrt.
compatibility with GCC; it's making enabling -Wformat for the Linux
kernel excessively painful.

Fixes: #57102


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D132266

Files:
  clang/lib/Sema/SemaChecking.cpp
  clang/test/FixIt/format.m
  clang/test/Sema/format-strings-freebsd.c
  clang/test/Sema/format-strings-pedantic.c
  clang/test/Sema/format-strings.c


Index: clang/test/Sema/format-strings.c
===================================================================
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -830,3 +830,18 @@
   printf_arg2("foo", "%s string %i\n", "aaa", 123);
   printf_arg2("%s string\n", "foo", "bar"); // expected-warning{{data argument not used by format string}}
 }
+
+// These are handled by -Wformat-pedantic. See also
+// clang/test/Sema/format-strings-pedantic.c.
+void test_intentional_truncation(void) {
+  int x = 42;
+  printf("%hhd", x); // no-warning
+  printf("%hhu", x); // no-warning
+  printf("%hd", x); // no-warning
+  printf("%hu", x); // no-warning
+  unsigned y = 42;
+  printf("%hhd", y); // no-warning
+  printf("%hhu", y); // no-warning
+  printf("%hd", y); // no-warning
+  printf("%hu", y); // no-warning
+}
Index: clang/test/Sema/format-strings-pedantic.c
===================================================================
--- clang/test/Sema/format-strings-pedantic.c
+++ clang/test/Sema/format-strings-pedantic.c
@@ -18,3 +18,16 @@
   printf("%p", nullptr); // expected-warning {{format specifies type 'void *' but the argument has type 'std::nullptr_t'}}
 #endif
 }
+
+void test_intentional_truncation(void) {
+  int x = 42;
+  printf("%hhd", x); // expected-warning {{format specifies type 'char' but the argument has type 'int'}}
+  printf("%hhu", x); // expected-warning {{format specifies type 'unsigned char' but the argument has type 'int'}}
+  printf("%hd", x); // expected-warning {{format specifies type 'short' but the argument has type 'int'}}
+  printf("%hu", x); // expected-warning {{format specifies type 'unsigned short' but the argument has type 'int'}}
+  unsigned y = 42;
+  printf("%hhd", y); // expected-warning {{format specifies type 'char' but the argument has type 'unsigned int'}}
+  printf("%hhu", y); // expected-warning {{format specifies type 'unsigned char' but the argument has type 'unsigned int'}}
+  printf("%hd", y); // expected-warning {{format specifies type 'short' but the argument has type 'unsigned int'}}
+  printf("%hu", y); // expected-warning {{format specifies type 'unsigned short' but the argument has type 'unsigned int'}}
+}
Index: clang/test/Sema/format-strings-freebsd.c
===================================================================
--- clang/test/Sema/format-strings-freebsd.c
+++ clang/test/Sema/format-strings-freebsd.c
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -triple i386-unknown-freebsd %s
-// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-unknown-freebsd %s
-// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-scei-ps4 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-sie-ps5 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i386-unknown-freebsd %s -Wformat-pedantic
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-unknown-freebsd %s -Wformat-pedantic
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-scei-ps4 %s -Wformat-pedantic
+// RUN: %clang_cc1 -fsyntax-only -verify -triple x86_64-sie-ps5 %s -Wformat-pedantic
 
 // Test FreeBSD kernel printf extensions.
 int freebsd_kernel_printf(const char *, ...) __attribute__((__format__(__freebsd_kprintf__, 1, 2)));
Index: clang/test/FixIt/format.m
===================================================================
--- clang/test/FixIt/format.m
+++ clang/test/FixIt/format.m
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -fblocks -verify %s
-// RUN: %clang_cc1 -triple %itanium_abi_triple -fdiagnostics-parseable-fixits -fblocks %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only -fblocks -verify %s -Wformat-pedantic
+// RUN: %clang_cc1 -triple %itanium_abi_triple -fdiagnostics-parseable-fixits -fblocks %s 2>&1 -Wformat-pedantic | FileCheck %s
 
 @class NSString;
 extern void NSLog(NSString *, ...);
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -10129,6 +10129,12 @@
     IsEnum = true;
   }
 
+  // Consider %hh or %h length modifiers for ints/unsigned ints -Wpedantic.
+  LengthModifier::Kind LMK = FS.getLengthModifier().getKind();
+  if ((LMK == LengthModifier::AsChar || LMK == LengthModifier::AsShort) &&
+      (ExprTy == S.Context.IntTy || ExprTy == S.Context.UnsignedIntTy))
+    Match = ArgType::NoMatchPedantic;
+
   // %C in an Objective-C context prints a unichar, not a wchar_t.
   // If the argument is an integer of some kind, believe the %C and suggest
   // a cast instead of changing the conversion specifier.


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D132266.454131.patch
Type: text/x-patch
Size: 4643 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220819/4460f2f1/attachment-0001.bin>


More information about the cfe-commits mailing list