https://gcc.gnu.org/g:c246c4bcb353e8dc30e7e4d45dd27d982a21eab4

commit r15-4705-gc246c4bcb353e8dc30e7e4d45dd27d982a21eab4
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Sun Oct 27 16:44:35 2024 +0100

    genmatch: Add selftests to genmatch for diag_vfprintf
    
    The following patch adds selftests to genmatch to verify the new printing
    routine there.
    So that I can rely on HAVE_DECL_FMEMOPEN (host test), the tests are done
    solely in stage2+ where we link the host libcpp etc. to genmatch.
    The tests have been adjusted from pretty-print.cc (test_pp_format),
    and I've added to that function two new tests because I've noticed nothing
    was testing the %M$.*N$s etc. format specifiers.
    
    2024-10-27  Jakub Jelinek  <ja...@redhat.com>
    
            * configure.ac (gcc_AC_CHECK_DECLS): Add fmemopen.
            * configure: Regenerate.
            * config.in: Regenerate.
            * Makefile.in (build/genmatch.o): Add -DGENMATCH_SELFTESTS to
            BUILD_CPPFLAGS for stage2+ genmatch.
            * genmatch.cc (test_diag_vfprintf, genmatch_diag_selftests): New
            functions.
            (main): Call genmatch_diag_selftests.
            * pretty-print.cc (test_pp_format): Add two tests, one for %M$.*N$s
            and one for %M$.Ns.

Diff:
---
 gcc/Makefile.in     |   1 +
 gcc/config.in       |   7 +++
 gcc/configure       |   2 +-
 gcc/configure.ac    |   2 +-
 gcc/genmatch.cc     | 134 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 gcc/pretty-print.cc |   8 ++++
 6 files changed, 152 insertions(+), 2 deletions(-)

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 059cf2e8f79f..1be4ea02992c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3143,6 +3143,7 @@ else
 BUILD_CPPLIB = $(CPPLIB) $(LIBIBERTY)
 build/genmatch$(build_exeext): BUILD_LIBDEPS += $(LIBINTL_DEP) $(LIBICONV_DEP)
 build/genmatch$(build_exeext): BUILD_LIBS += $(LIBINTL) $(LIBICONV)
+build/genmatch.o: BUILD_CPPFLAGS += -DGENMATCH_SELFTESTS
 endif
 
 build/genmatch$(build_exeext) : $(BUILD_CPPLIB) \
diff --git a/gcc/config.in b/gcc/config.in
index 7fcabbe5061d..3fc4666d60b5 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -1018,6 +1018,13 @@
 #endif
 
 
+/* Define to 1 if we found a declaration for 'fmemopen', otherwise define to
+   0. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_DECL_FMEMOPEN
+#endif
+
+
 /* Define to 1 if we found a declaration for 'fprintf_unlocked', otherwise
    define to 0. */
 #ifndef USED_FOR_TARGET
diff --git a/gcc/configure b/gcc/configure
index 5acc42c1e4d9..47c58036530f 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -12084,7 +12084,7 @@ for ac_func in getenv atol atoll asprintf sbrk abort 
atof getcwd getwd \
        madvise stpcpy strnlen strsignal strverscmp \
        strtol strtoul strtoll strtoull setenv unsetenv \
        errno snprintf vsnprintf vasprintf malloc realloc calloc \
-       free getopt clock getpagesize ffs clearerr_unlocked feof_unlocked   
ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked   fileno_unlocked 
fprintf_unlocked fputc_unlocked fputs_unlocked   fread_unlocked fwrite_unlocked 
getchar_unlocked getc_unlocked   putchar_unlocked putc_unlocked
+       free getopt clock getpagesize ffs fmemopen clearerr_unlocked 
feof_unlocked   ferror_unlocked fflush_unlocked fgetc_unlocked fgets_unlocked   
fileno_unlocked fprintf_unlocked fputc_unlocked fputs_unlocked   fread_unlocked 
fwrite_unlocked getchar_unlocked getc_unlocked   putchar_unlocked putc_unlocked
 do
   ac_tr_decl=`$as_echo "HAVE_DECL_$ac_func" | $as_tr_cpp`
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $ac_func is 
declared" >&5
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 23f4884eff9e..dc8346a7b823 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1629,7 +1629,7 @@ gcc_AC_CHECK_DECLS(getenv atol atoll asprintf sbrk abort 
atof getcwd getwd \
        madvise stpcpy strnlen strsignal strverscmp \
        strtol strtoul strtoll strtoull setenv unsetenv \
        errno snprintf vsnprintf vasprintf malloc realloc calloc \
-       free getopt clock getpagesize ffs gcc_UNLOCKED_FUNCS, , ,[
+       free getopt clock getpagesize ffs fmemopen gcc_UNLOCKED_FUNCS, , ,[
 #include "ansidecl.h"
 #include "system.h"])
 
diff --git a/gcc/genmatch.cc b/gcc/genmatch.cc
index 1acd9216b3b0..170bf6162b5d 100644
--- a/gcc/genmatch.cc
+++ b/gcc/genmatch.cc
@@ -585,6 +585,138 @@ diag_vfprintf (FILE *f, int err_no, const char *msg, 
va_list *ap)
   fprintf (f, "%s", q);
 }
 
+#if defined(GENMATCH_SELFTESTS) && defined(HAVE_DECL_FMEMOPEN)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wsuggest-attribute=format"
+
+static void
+test_diag_vfprintf (const char *expected, const char *msg, ...)
+{
+  char buf[256];
+  va_list ap;
+  FILE *f = fmemopen (buf, 256, "w");
+  gcc_assert (f != NULL);
+  va_start (ap, msg);
+  diag_vfprintf (f, 0, msg, &ap);
+  va_end (ap);
+  fclose (f);
+  gcc_assert (strcmp (buf, expected) == 0);
+}
+
+#pragma GCC diagnostic pop
+
+static void
+genmatch_diag_selftests (void)
+{
+  /* Verify that plain text is passed through unchanged.  */
+  test_diag_vfprintf ("unformatted", "unformatted");
+
+  /* Verify various individual format codes, in the order listed in the
+     comment for pp_format above.  For each code, we append a second
+     argument with a known bit pattern (0x12345678), to ensure that we
+     are consuming arguments correctly.  */
+  test_diag_vfprintf ("-27 12345678", "%d %x", -27, 0x12345678);
+  test_diag_vfprintf ("-5 12345678", "%i %x", -5, 0x12345678);
+  test_diag_vfprintf ("10 12345678", "%u %x", 10, 0x12345678);
+  test_diag_vfprintf ("17 12345678", "%o %x", 15, 0x12345678);
+  test_diag_vfprintf ("cafebabe 12345678", "%x %x", 0xcafebabe, 0x12345678);
+  test_diag_vfprintf ("-27 12345678", "%ld %x", (long)-27, 0x12345678);
+  test_diag_vfprintf ("-5 12345678", "%li %x", (long)-5, 0x12345678);
+  test_diag_vfprintf ("10 12345678", "%lu %x", (long)10, 0x12345678);
+  test_diag_vfprintf ("17 12345678", "%lo %x", (long)15, 0x12345678);
+  test_diag_vfprintf ("cafebabe 12345678", "%lx %x", (long)0xcafebabe,
+                     0x12345678);
+  test_diag_vfprintf ("-27 12345678", "%lld %x", (long long)-27, 0x12345678);
+  test_diag_vfprintf ("-5 12345678", "%lli %x", (long long)-5, 0x12345678);
+  test_diag_vfprintf ("10 12345678", "%llu %x", (long long)10, 0x12345678);
+  test_diag_vfprintf ("17 12345678", "%llo %x", (long long)15, 0x12345678);
+  test_diag_vfprintf ("cafebabe 12345678", "%llx %x", (long long)0xcafebabe,
+                     0x12345678);
+  test_diag_vfprintf ("-27 12345678", "%wd %x", HOST_WIDE_INT_C (-27),
+                     0x12345678);
+  test_diag_vfprintf ("-5 12345678", "%wi %x", HOST_WIDE_INT_C (-5),
+                     0x12345678);
+  test_diag_vfprintf ("10 12345678", "%wu %x", HOST_WIDE_INT_UC (10),
+                     0x12345678);
+  test_diag_vfprintf ("17 12345678", "%wo %x", HOST_WIDE_INT_C (15),
+                     0x12345678);
+  test_diag_vfprintf ("0xcafebabe 12345678", "%wx %x",
+                     HOST_WIDE_INT_C (0xcafebabe), 0x12345678);
+  test_diag_vfprintf ("-27 12345678", "%zd %x", (ssize_t)-27, 0x12345678);
+  test_diag_vfprintf ("-5 12345678", "%zi %x", (ssize_t)-5, 0x12345678);
+  test_diag_vfprintf ("10 12345678", "%zu %x", (size_t)10, 0x12345678);
+  test_diag_vfprintf ("17 12345678", "%zo %x", (size_t)15, 0x12345678);
+  test_diag_vfprintf ("cafebabe 12345678", "%zx %x", (size_t)0xcafebabe,
+                     0x12345678);
+  test_diag_vfprintf ("-27 12345678", "%td %x", (ptrdiff_t)-27, 0x12345678);
+  test_diag_vfprintf ("-5 12345678", "%ti %x", (ptrdiff_t)-5, 0x12345678);
+  test_diag_vfprintf ("10 12345678", "%tu %x", (ptrdiff_t)10, 0x12345678);
+  test_diag_vfprintf ("17 12345678", "%to %x", (ptrdiff_t)15, 0x12345678);
+  test_diag_vfprintf ("1afebabe 12345678", "%tx %x", (ptrdiff_t)0x1afebabe,
+                     0x12345678);
+  test_diag_vfprintf ("1.000000 12345678", "%f %x", 1.0, 0x12345678);
+  test_diag_vfprintf ("A 12345678", "%c %x", 'A', 0x12345678);
+  test_diag_vfprintf ("hello world 12345678", "%s %x", "hello world",
+                     0x12345678);
+
+  /* Not nul-terminated.  */
+  char arr[5] = { '1', '2', '3', '4', '5' };
+  test_diag_vfprintf ("123 12345678", "%.*s %x", 3, arr, 0x12345678);
+  test_diag_vfprintf ("1234 12345678", "%.*s %x", -1, "1234", 0x12345678);
+  test_diag_vfprintf ("12345 12345678", "%.*s %x", 7, "12345", 0x12345678);
+
+  /* We can't test for %p; the pointer is printed in an implementation-defined
+     manner.  */
+  test_diag_vfprintf ("normal colored normal 12345678",
+                     "normal %rcolored%R normal %x",
+                     "error", 0x12345678);
+
+  /* TODO:
+     %m: strerror(text->err_no) - does not consume a value *ap.  */
+  test_diag_vfprintf ("% 12345678", "%% %x", 0x12345678);
+  test_diag_vfprintf ("' 12345678", "%< %x", 0x12345678);
+  test_diag_vfprintf ("' 12345678", "%> %x", 0x12345678);
+  test_diag_vfprintf ("' 12345678", "%' %x", 0x12345678);
+  test_diag_vfprintf ("abc 12345678", "%.*s %x", 3, "abcdef", 0x12345678);
+  test_diag_vfprintf ("abc 12345678", "%.3s %x", "abcdef", 0x12345678);
+
+  /* Verify flag 'q'.  */
+  test_diag_vfprintf ("'foo' 12345678", "%qs %x", "foo", 0x12345678);
+
+  /* Verify %Z.  */
+  int v[] = { 1, 2, 3 }; 
+  test_diag_vfprintf ("1, 2, 3 12345678", "%Z %x", v, 3, 0x12345678);
+
+  int v2[] = { 0 }; 
+  test_diag_vfprintf ("0 12345678", "%Z %x", v2, 1, 0x12345678);
+
+  /* Verify that combinations work, along with unformatted text.  */
+  test_diag_vfprintf ("the quick brown fox jumps over the lazy dog",
+                     "the %s %s %s jumps over the %s %s",
+                     "quick", "brown", "fox", "lazy", "dog");
+  test_diag_vfprintf ("item 3 of 7", "item %i of %i", 3, 7);
+  test_diag_vfprintf ("problem with 'bar' at line 10",
+                     "problem with %qs at line %i", "bar", 10);
+
+  /* Verified numbered args.  */
+  test_diag_vfprintf ("foo: second bar: first",
+                     "foo: %2$s bar: %1$s", "first", "second");
+  test_diag_vfprintf ("foo: 1066 bar: 1776",
+                     "foo: %2$i bar: %1$i", 1776, 1066);
+  test_diag_vfprintf ("foo: second bar: 1776",
+                     "foo: %2$s bar: %1$i", 1776, "second");
+  test_diag_vfprintf ("foo: sec bar: 3360",
+                     "foo: %3$.*2$s bar: %1$o", 1776, 3, "second");
+  test_diag_vfprintf ("foo: seco bar: 3360",
+                     "foo: %2$.4s bar: %1$o", 1776, "second");
+}
+#else
+static void
+genmatch_diag_selftests (void)
+{
+}
+#endif
+
 static bool
 #if GCC_VERSION >= 4001
 __attribute__((format (gcc_diag, 5, 0)))
@@ -6082,6 +6214,8 @@ main (int argc, char **argv)
       return 1;
     }
 
+  genmatch_diag_selftests ();
+
   if (!s_include_file)
     s_include_file = s_header_file;
 
diff --git a/gcc/pretty-print.cc b/gcc/pretty-print.cc
index 6f36d4a2015e..a3f369132dd0 100644
--- a/gcc/pretty-print.cc
+++ b/gcc/pretty-print.cc
@@ -3474,6 +3474,14 @@ test_pp_format ()
                    "foo: second bar: 1776",
                    "foo: %2$s bar: %1$i",
                    1776, "second");
+  assert_pp_format (SELFTEST_LOCATION,
+                   "foo: sec bar: 3360",
+                   "foo: %3$.*2$s bar: %1$o",
+                   1776, 3, "second");
+  assert_pp_format (SELFTEST_LOCATION,
+                   "foo: seco bar: 3360",
+                   "foo: %2$.4s bar: %1$o",
+                   1776, "second");
 }
 
 static void

Reply via email to