diff --git a/stdio-common/Makefile b/stdio-common/Makefile index 8da164695f..da337cb4e1 100644 --- a/stdio-common/Makefile +++ b/stdio-common/Makefile @@ -314,6 +314,7 @@ tests := \ tst-popen2 \ tst-printf-binary \ tst-printf-intn \ + tst-printf-macro \ tst-printf-oct \ tst-printf-round \ tst-printfsz \ diff --git a/stdio-common/tst-printf-macro.c b/stdio-common/tst-printf-macro.c new file mode 100644 index 0000000000..100c6a4b0a --- /dev/null +++ b/stdio-common/tst-printf-macro.c @@ -0,0 +1,93 @@ +/* Test printf PRI* macro narrowing arguments. + Copyright (C) 2025 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include +#include +#include + +#include +#include + +#define CHECK_PRINTF(EXPECTED, FMT, ...) \ + do \ + { \ + int ret = snprintf (buf, sizeof buf, FMT, \ + __VA_ARGS__); \ + TEST_COMPARE_STRING (buf, EXPECTED); \ + TEST_COMPARE (ret, strlen (EXPECTED)); \ + } \ + while (0) + +_Static_assert (INT_FAST8_WIDTH == 8, "width of int_fast8_t"); +_Static_assert (UINT_FAST8_WIDTH == 8, "width of uint_fast8_t"); + +static int +do_test (void) +{ + char buf[1024]; + CHECK_PRINTF ("-121", "%" PRId8, 1234567); + CHECK_PRINTF ("-121", "%" PRIdLEAST8, 1234567); + CHECK_PRINTF ("-121", "%" PRIdFAST8, 1234567); + CHECK_PRINTF ("-10617", "%" PRId16, 1234567); + CHECK_PRINTF ("-10617", "%" PRIdLEAST16, 1234567); + CHECK_PRINTF ("-121", "%" PRIi8, 1234567); + CHECK_PRINTF ("-121", "%" PRIiLEAST8, 1234567); + CHECK_PRINTF ("-121", "%" PRIiFAST8, 1234567); + CHECK_PRINTF ("-10617", "%" PRIi16, 1234567); + CHECK_PRINTF ("-10617", "%" PRIiLEAST16, 1234567); + CHECK_PRINTF ("207", "%" PRIo8, 1234567); + CHECK_PRINTF ("207", "%" PRIoLEAST8, 1234567); + CHECK_PRINTF ("207", "%" PRIoFAST8, 1234567); + CHECK_PRINTF ("153207", "%" PRIo16, 1234567); + CHECK_PRINTF ("153207", "%" PRIoLEAST16, 1234567); + CHECK_PRINTF ("135", "%" PRIu8, 1234567); + CHECK_PRINTF ("135", "%" PRIuLEAST8, 1234567); + CHECK_PRINTF ("135", "%" PRIuFAST8, 1234567); + CHECK_PRINTF ("54919", "%" PRIu16, 1234567); + CHECK_PRINTF ("54919", "%" PRIuLEAST16, 1234567); + CHECK_PRINTF ("87", "%" PRIx8, 1234567); + CHECK_PRINTF ("87", "%" PRIxLEAST8, 1234567); + CHECK_PRINTF ("87", "%" PRIxFAST8, 1234567); + CHECK_PRINTF ("d687", "%" PRIx16, 1234567); + CHECK_PRINTF ("d687", "%" PRIxLEAST16, 1234567); + CHECK_PRINTF ("87", "%" PRIX8, 1234567); + CHECK_PRINTF ("87", "%" PRIXLEAST8, 1234567); + CHECK_PRINTF ("87", "%" PRIXFAST8, 1234567); + CHECK_PRINTF ("D687", "%" PRIX16, 1234567); + CHECK_PRINTF ("D687", "%" PRIXLEAST16, 1234567); + /* GCC does not know the %b or %B formats before GCC 12. */ + DIAG_PUSH_NEEDS_COMMENT; +#if !__GNUC_PREREQ (12, 0) + DIAG_IGNORE_NEEDS_COMMENT (11, "-Wformat"); + DIAG_IGNORE_NEEDS_COMMENT (11, "-Wformat-extra-args"); +#endif + CHECK_PRINTF ("10000111", "%" PRIb8, 1234567); + CHECK_PRINTF ("10000111", "%" PRIbLEAST8, 1234567); + CHECK_PRINTF ("10000111", "%" PRIbFAST8, 1234567); + CHECK_PRINTF ("1101011010000111", "%" PRIb16, 1234567); + CHECK_PRINTF ("1101011010000111", "%" PRIbLEAST16, 1234567); + CHECK_PRINTF ("10000111", "%" PRIB8, 1234567); + CHECK_PRINTF ("10000111", "%" PRIBLEAST8, 1234567); + CHECK_PRINTF ("10000111", "%" PRIBFAST8, 1234567); + CHECK_PRINTF ("1101011010000111", "%" PRIB16, 1234567); + CHECK_PRINTF ("1101011010000111", "%" PRIBLEAST16, 1234567); + DIAG_POP_NEEDS_COMMENT; + return 0; +} + +#include diff --git a/stdlib/inttypes.h b/stdlib/inttypes.h index 9726abf5b1..a244db0da8 100644 --- a/stdlib/inttypes.h +++ b/stdlib/inttypes.h @@ -51,97 +51,97 @@ typedef wchar_t __gwchar_t; /* Macros for printing format specifiers. */ /* Decimal notation. */ -# define PRId8 "d" -# define PRId16 "d" +# define PRId8 "hhd" +# define PRId16 "hd" # define PRId32 "d" # define PRId64 __PRI64_PREFIX "d" -# define PRIdLEAST8 "d" -# define PRIdLEAST16 "d" +# define PRIdLEAST8 "hhd" +# define PRIdLEAST16 "hd" # define PRIdLEAST32 "d" # define PRIdLEAST64 __PRI64_PREFIX "d" -# define PRIdFAST8 "d" +# define PRIdFAST8 "hhd" # define PRIdFAST16 __PRIPTR_PREFIX "d" # define PRIdFAST32 __PRIPTR_PREFIX "d" # define PRIdFAST64 __PRI64_PREFIX "d" -# define PRIi8 "i" -# define PRIi16 "i" +# define PRIi8 "hhi" +# define PRIi16 "hi" # define PRIi32 "i" # define PRIi64 __PRI64_PREFIX "i" -# define PRIiLEAST8 "i" -# define PRIiLEAST16 "i" +# define PRIiLEAST8 "hhi" +# define PRIiLEAST16 "hi" # define PRIiLEAST32 "i" # define PRIiLEAST64 __PRI64_PREFIX "i" -# define PRIiFAST8 "i" +# define PRIiFAST8 "hhi" # define PRIiFAST16 __PRIPTR_PREFIX "i" # define PRIiFAST32 __PRIPTR_PREFIX "i" # define PRIiFAST64 __PRI64_PREFIX "i" /* Octal notation. */ -# define PRIo8 "o" -# define PRIo16 "o" +# define PRIo8 "hho" +# define PRIo16 "ho" # define PRIo32 "o" # define PRIo64 __PRI64_PREFIX "o" -# define PRIoLEAST8 "o" -# define PRIoLEAST16 "o" +# define PRIoLEAST8 "hho" +# define PRIoLEAST16 "ho" # define PRIoLEAST32 "o" # define PRIoLEAST64 __PRI64_PREFIX "o" -# define PRIoFAST8 "o" +# define PRIoFAST8 "hho" # define PRIoFAST16 __PRIPTR_PREFIX "o" # define PRIoFAST32 __PRIPTR_PREFIX "o" # define PRIoFAST64 __PRI64_PREFIX "o" /* Unsigned integers. */ -# define PRIu8 "u" -# define PRIu16 "u" +# define PRIu8 "hhu" +# define PRIu16 "hu" # define PRIu32 "u" # define PRIu64 __PRI64_PREFIX "u" -# define PRIuLEAST8 "u" -# define PRIuLEAST16 "u" +# define PRIuLEAST8 "hhu" +# define PRIuLEAST16 "hu" # define PRIuLEAST32 "u" # define PRIuLEAST64 __PRI64_PREFIX "u" -# define PRIuFAST8 "u" +# define PRIuFAST8 "hhu" # define PRIuFAST16 __PRIPTR_PREFIX "u" # define PRIuFAST32 __PRIPTR_PREFIX "u" # define PRIuFAST64 __PRI64_PREFIX "u" /* lowercase hexadecimal notation. */ -# define PRIx8 "x" -# define PRIx16 "x" +# define PRIx8 "hhx" +# define PRIx16 "hx" # define PRIx32 "x" # define PRIx64 __PRI64_PREFIX "x" -# define PRIxLEAST8 "x" -# define PRIxLEAST16 "x" +# define PRIxLEAST8 "hhx" +# define PRIxLEAST16 "hx" # define PRIxLEAST32 "x" # define PRIxLEAST64 __PRI64_PREFIX "x" -# define PRIxFAST8 "x" +# define PRIxFAST8 "hhx" # define PRIxFAST16 __PRIPTR_PREFIX "x" # define PRIxFAST32 __PRIPTR_PREFIX "x" # define PRIxFAST64 __PRI64_PREFIX "x" /* UPPERCASE hexadecimal notation. */ -# define PRIX8 "X" -# define PRIX16 "X" +# define PRIX8 "hhX" +# define PRIX16 "hX" # define PRIX32 "X" # define PRIX64 __PRI64_PREFIX "X" -# define PRIXLEAST8 "X" -# define PRIXLEAST16 "X" +# define PRIXLEAST8 "hhX" +# define PRIXLEAST16 "hX" # define PRIXLEAST32 "X" # define PRIXLEAST64 __PRI64_PREFIX "X" -# define PRIXFAST8 "X" +# define PRIXFAST8 "hhX" # define PRIXFAST16 __PRIPTR_PREFIX "X" # define PRIXFAST32 __PRIPTR_PREFIX "X" # define PRIXFAST64 __PRI64_PREFIX "X" @@ -166,17 +166,17 @@ typedef wchar_t __gwchar_t; /* Binary notation. */ # if __GLIBC_USE (ISOC23) -# define PRIb8 "b" -# define PRIb16 "b" +# define PRIb8 "hhb" +# define PRIb16 "hb" # define PRIb32 "b" # define PRIb64 __PRI64_PREFIX "b" -# define PRIbLEAST8 "b" -# define PRIbLEAST16 "b" +# define PRIbLEAST8 "hhb" +# define PRIbLEAST16 "hb" # define PRIbLEAST32 "b" # define PRIbLEAST64 __PRI64_PREFIX "b" -# define PRIbFAST8 "b" +# define PRIbFAST8 "hhb" # define PRIbFAST16 __PRIPTR_PREFIX "b" # define PRIbFAST32 __PRIPTR_PREFIX "b" # define PRIbFAST64 __PRI64_PREFIX "b" @@ -184,17 +184,17 @@ typedef wchar_t __gwchar_t; # define PRIbMAX __PRI64_PREFIX "b" # define PRIbPTR __PRIPTR_PREFIX "b" -# define PRIB8 "B" -# define PRIB16 "B" +# define PRIB8 "hhB" +# define PRIB16 "hB" # define PRIB32 "B" # define PRIB64 __PRI64_PREFIX "B" -# define PRIBLEAST8 "B" -# define PRIBLEAST16 "B" +# define PRIBLEAST8 "hhB" +# define PRIBLEAST16 "hB" # define PRIBLEAST32 "B" # define PRIBLEAST64 __PRI64_PREFIX "B" -# define PRIBFAST8 "B" +# define PRIBFAST8 "hhB" # define PRIBFAST16 __PRIPTR_PREFIX "B" # define PRIBFAST32 __PRIPTR_PREFIX "B" # define PRIBFAST64 __PRI64_PREFIX "B"