[compiler-rt] d4d2b0c - sanitizer_common: support %l in format strings

Vitaly Buka via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 14 17:57:44 PDT 2021


Author: Dmitry Vyukov
Date: 2021-08-14T17:57:40-07:00
New Revision: d4d2b0c682c55f22978ff0eed743ebe882b3e735

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

LOG: sanitizer_common: support %l in format strings

Currently we only support %z and %ll width modifiers,
but surprisingly not %l. This makes it impossible to print longs
(sizeof(long) not necessary equal to sizeof(size_t)).
We had some printf's that printed longs with %zu,
but that's wrong and now with __attribute__((format)) in place
they are flagged by compiler. So we either have a choice of
doing static_cast<uptr>(long) everywhere or add %l.
Adding %l looks better, that's a standard modifier.

Reviewed By: vitalybuka

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

Added: 
    

Modified: 
    compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp
    compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp
index e25f384bb6e3..0938aa833753 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_printf.cpp
@@ -128,7 +128,7 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) {
 int VSNPrintf(char *buff, int buff_length,
               const char *format, va_list args) {
   static const char *kPrintfFormatsHelp =
-      "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; "
+      "Supported Printf formats: %([0-9]*)?(z|l|ll)?{d,u,x,X}; %p; "
       "%[-]([0-9]*)?(\\.\\*)?s; %c\n";
   RAW_CHECK(format);
   RAW_CHECK(buff_length > 0);
@@ -160,9 +160,11 @@ int VSNPrintf(char *buff, int buff_length,
     }
     bool have_z = (*cur == 'z');
     cur += have_z;
-    bool have_ll = !have_z && (cur[0] == 'l' && cur[1] == 'l');
+    bool have_l = cur[0] == 'l' && cur[1] != 'l';
+    cur += have_l;
+    bool have_ll = cur[0] == 'l' && cur[1] == 'l';
     cur += have_ll * 2;
-    const bool have_length = have_z || have_ll;
+    const bool have_length = have_z || have_l || have_ll;
     const bool have_flags = have_width || have_length;
     // At the moment only %s supports precision and left-justification.
     CHECK(!((precision >= 0 || left_justified) && *cur != 's'));
@@ -170,6 +172,7 @@ int VSNPrintf(char *buff, int buff_length,
       case 'd': {
         s64 dval = have_ll  ? va_arg(args, s64)
                    : have_z ? va_arg(args, sptr)
+                   : have_l ? va_arg(args, long)
                             : va_arg(args, int);
         result += AppendSignedDecimal(&buff, buff_end, dval, width,
                                       pad_with_zero);
@@ -180,6 +183,7 @@ int VSNPrintf(char *buff, int buff_length,
       case 'X': {
         u64 uval = have_ll  ? va_arg(args, u64)
                    : have_z ? va_arg(args, uptr)
+                   : have_l ? va_arg(args, unsigned long)
                             : va_arg(args, unsigned);
         bool uppercase = (*cur == 'X');
         result += AppendUnsigned(&buff, buff_end, uval, (*cur == 'u') ? 10 : 16,

diff  --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp
index d213d107c019..01e81fb0b6df 100644
--- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp
+++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_printf_test.cpp
@@ -115,6 +115,9 @@ TEST(Printf, MinMax) {
   TestAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX);
   TestAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX);
   TestAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX);
+  TestAgainstLibc<long>("%ld-%ld", LONG_MIN, LONG_MAX);
+  TestAgainstLibc<unsigned long>("%lu-%lu", 0, LONG_MAX);
+  TestAgainstLibc<unsigned long>("%lx-%lx", 0, LONG_MAX);
 #if !defined(_WIN32)
   // %z* format doesn't seem to be supported by MSVS.
   TestAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX);


        


More information about the llvm-commits mailing list