From 04a9b8d2f38573d0527edeea9e4fd9b7dfdc7983 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 14 Oct 2021 20:56:29 +0000 Subject: [PATCH] c-family: Support DFP printf/scanf formats for C2X When I enabled various decimal floating-point features for C2X / stopped them being diagnosed with -pedantic for C2X, I missed the format checking support. The DFP printf and scanf formats are included in C2X. Thus, adjust the data for those formats so that they are no longer diagnosed with -std=c2x -Wformat -pedantic. Bootstrapped with no regressions for x86_64-pc-linux-gnu. gcc/c-family/ * c-format.c (printf_length_specs, scanf_length_specs) (print_char_table, scan_char_table): Support DFP formats for C2X. * c-format.h (TEX_D32, TEX_D64, TEX_D128): Remove. (T2X_D32, T2X_D64, T2X_D128): New macros. gcc/testsuite/ * gcc.dg/format/c11-dfp-printf-1.c, gcc.dg/format/c11-dfp-scanf-1.c, gcc.dg/format/c2x-dfp-printf-1.c, gcc.dg/format/c2x-dfp-scanf-1.c: New tests. --- gcc/c-family/c-format.c | 22 ++++++++-------- gcc/c-family/c-format.h | 6 ++--- gcc/testsuite/gcc.dg/format/c11-dfp-printf-1.c | 35 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/format/c11-dfp-scanf-1.c | 35 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/format/c2x-dfp-printf-1.c | 35 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/format/c2x-dfp-scanf-1.c | 35 ++++++++++++++++++++++++++ 6 files changed, 154 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/format/c11-dfp-printf-1.c create mode 100644 gcc/testsuite/gcc.dg/format/c11-dfp-scanf-1.c create mode 100644 gcc/testsuite/gcc.dg/format/c2x-dfp-printf-1.c create mode 100644 gcc/testsuite/gcc.dg/format/c2x-dfp-scanf-1.c diff --git a/gcc/c-family/c-format.c b/gcc/c-family/c-format.c index c27faf7..e735e09 100644 --- a/gcc/c-family/c-format.c +++ b/gcc/c-family/c-format.c @@ -493,8 +493,8 @@ static const format_length_info printf_length_specs[] = { "Z", FMT_LEN_z, STD_EXT, NO_FMT, 0 }, { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 }, - { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 }, - { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 }, + { "H", FMT_LEN_H, STD_C2X, NO_FMT, 0 }, + { "D", FMT_LEN_D, STD_C2X, "DD", FMT_LEN_DD, STD_C2X, 0 }, { NO_FMT, NO_FMT, 0 } }; @@ -530,8 +530,8 @@ static const format_length_info scanf_length_specs[] = { "z", FMT_LEN_z, STD_C99, NO_FMT, 0 }, { "t", FMT_LEN_t, STD_C99, NO_FMT, 0 }, { "j", FMT_LEN_j, STD_C99, NO_FMT, 0 }, - { "H", FMT_LEN_H, STD_EXT, NO_FMT, 0 }, - { "D", FMT_LEN_D, STD_EXT, "DD", FMT_LEN_DD, STD_EXT, 0 }, + { "H", FMT_LEN_H, STD_C2X, NO_FMT, 0 }, + { "D", FMT_LEN_D, STD_C2X, "DD", FMT_LEN_DD, STD_C2X, 0 }, { NO_FMT, NO_FMT, 0 } }; @@ -703,15 +703,15 @@ static const format_char_info print_char_table[] = { "di", 0, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "-wp0 +'I", "i", NULL }, { "oxX", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, { "u", 0, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "-wp0'I", "i", NULL }, - { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL }, - { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#I", "", NULL }, + { "fgG", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#'I", "", NULL }, + { "eE", 0, STD_C89, { T89_D, BADLEN, BADLEN, T99_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#I", "", NULL }, { "c", 0, STD_C89, { T89_I, BADLEN, BADLEN, T94_WI, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "", NULL }, { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-wp", "cR", NULL }, { "p", 1, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "-w", "c", NULL }, { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* C99 conversion specifiers. */ - { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#'I", "", NULL }, - { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "-wp0 +#", "", NULL }, + { "F", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#'I", "", NULL }, + { "aA", 0, STD_C99, { T99_D, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "-wp0 +#", "", NULL }, /* C2X conversion specifiers. */ { "b", 0, STD_C2X, { T2X_UI, T2X_UC, T2X_US, T2X_UL, T2X_ULL, TEX_ULL, T2X_ST, T2X_UPD, T2X_UIM, BADLEN, BADLEN, BADLEN }, "-wp0#", "i", NULL }, /* X/Open conversion specifiers. */ @@ -870,15 +870,15 @@ static const format_char_info scan_char_table[] = { "di", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, TEX_LL, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, { "u", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w'I", "W", NULL }, { "oxX", 1, STD_C89, { T89_UI, T99_UC, T89_US, T89_UL, T9L_ULL, TEX_ULL, T99_ST, T99_UPD, T99_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, - { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, + { "efgEG", 1, STD_C89, { T89_F, BADLEN, BADLEN, T89_D, BADLEN, T89_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "*w'", "W", NULL }, { "c", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*mw", "cW", NULL }, { "s", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW", NULL }, { "[", 1, STD_C89, { T89_C, BADLEN, BADLEN, T94_W, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*amw", "cW[", NULL }, { "p", 2, STD_C89, { T89_V, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, { "n", 1, STD_C89, { T89_I, T99_SC, T89_S, T89_L, T9L_LL, BADLEN, T99_SST, T99_PD, T99_IM, BADLEN, BADLEN, BADLEN }, "", "W", NULL }, /* C99 conversion specifiers. */ - { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, - { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, TEX_D32, TEX_D64, TEX_D128 }, "*w'", "W", NULL }, + { "F", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "*w'", "W", NULL }, + { "aA", 1, STD_C99, { T99_F, BADLEN, BADLEN, T99_D, BADLEN, T99_LD, BADLEN, BADLEN, BADLEN, T2X_D32, T2X_D64, T2X_D128 }, "*w'", "W", NULL }, /* C2X conversion specifiers. */ { "b", 1, STD_C2X, { T2X_UI, T2X_UC, T2X_US, T2X_UL, T2X_ULL, TEX_ULL, T2X_ST, T2X_UPD, T2X_UIM, BADLEN, BADLEN, BADLEN }, "*w", "W", NULL }, /* X/Open conversion specifiers. */ diff --git a/gcc/c-family/c-format.h b/gcc/c-family/c-format.h index 2b5012e..dfa1e11 100644 --- a/gcc/c-family/c-format.h +++ b/gcc/c-family/c-format.h @@ -333,11 +333,11 @@ struct format_kind_info #define T99_UIM { STD_C99, "uintmax_t", T_UIM } #define T2X_UIM { STD_C2X, "uintmax_t", T_UIM } #define T_D32 &dfloat32_type_node -#define TEX_D32 { STD_EXT, "_Decimal32", T_D32 } +#define T2X_D32 { STD_C2X, "_Decimal32", T_D32 } #define T_D64 &dfloat64_type_node -#define TEX_D64 { STD_EXT, "_Decimal64", T_D64 } +#define T2X_D64 { STD_C2X, "_Decimal64", T_D64 } #define T_D128 &dfloat128_type_node -#define TEX_D128 { STD_EXT, "_Decimal128", T_D128 } +#define T2X_D128 { STD_C2X, "_Decimal128", T_D128 } /* Structure describing how format attributes such as "printf" are interpreted as "gnu_printf" or "ms_printf" on a particular system. diff --git a/gcc/testsuite/gcc.dg/format/c11-dfp-printf-1.c b/gcc/testsuite/gcc.dg/format/c11-dfp-printf-1.c new file mode 100644 index 0000000..356a23e --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/c11-dfp-printf-1.c @@ -0,0 +1,35 @@ +/* Test for printf formats: rejection of DFP formats in pedantic mode. */ +/* { dg-do compile } */ +/* { dg-require-effective-target dfp } */ +/* { dg-options "-std=gnu11 -pedantic -Wformat" } */ + +#include "format.h" + +void +foo (_Decimal32 d32, _Decimal64 d64, _Decimal128 d128) /* { dg-warning "ISO C" } */ +{ + printf ("%Ha", d32); /* { dg-warning "C" } */ + printf ("%HA", d32); /* { dg-warning "C" } */ + printf ("%He", d32); /* { dg-warning "C" } */ + printf ("%HE", d32); /* { dg-warning "C" } */ + printf ("%Hf", d32); /* { dg-warning "C" } */ + printf ("%HF", d32); /* { dg-warning "C" } */ + printf ("%Hg", d32); /* { dg-warning "C" } */ + printf ("%HG", d32); /* { dg-warning "C" } */ + printf ("%Da", d64); /* { dg-warning "C" } */ + printf ("%DA", d64); /* { dg-warning "C" } */ + printf ("%De", d64); /* { dg-warning "C" } */ + printf ("%DE", d64); /* { dg-warning "C" } */ + printf ("%Df", d64); /* { dg-warning "C" } */ + printf ("%DF", d64); /* { dg-warning "C" } */ + printf ("%Dg", d64); /* { dg-warning "C" } */ + printf ("%DG", d64); /* { dg-warning "C" } */ + printf ("%DDa", d128); /* { dg-warning "C" } */ + printf ("%DDA", d128); /* { dg-warning "C" } */ + printf ("%DDe", d128); /* { dg-warning "C" } */ + printf ("%DDE", d128); /* { dg-warning "C" } */ + printf ("%DDf", d128); /* { dg-warning "C" } */ + printf ("%DDF", d128); /* { dg-warning "C" } */ + printf ("%DDg", d128); /* { dg-warning "C" } */ + printf ("%DDG", d128); /* { dg-warning "C" } */ +} diff --git a/gcc/testsuite/gcc.dg/format/c11-dfp-scanf-1.c b/gcc/testsuite/gcc.dg/format/c11-dfp-scanf-1.c new file mode 100644 index 0000000..35bd631 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/c11-dfp-scanf-1.c @@ -0,0 +1,35 @@ +/* Test for scanf formats: rejection of DFP formats in pedantic mode. */ +/* { dg-do compile } */ +/* { dg-require-effective-target dfp } */ +/* { dg-options "-std=gnu11 -pedantic -Wformat" } */ + +#include "format.h" + +void +foo (_Decimal32 *d32, _Decimal64 *d64, _Decimal128 *d128) /* { dg-warning "ISO C" } */ +{ + scanf ("%Ha", d32); /* { dg-warning "C" } */ + scanf ("%HA", d32); /* { dg-warning "C" } */ + scanf ("%He", d32); /* { dg-warning "C" } */ + scanf ("%HE", d32); /* { dg-warning "C" } */ + scanf ("%Hf", d32); /* { dg-warning "C" } */ + scanf ("%HF", d32); /* { dg-warning "C" } */ + scanf ("%Hg", d32); /* { dg-warning "C" } */ + scanf ("%HG", d32); /* { dg-warning "C" } */ + scanf ("%Da", d64); /* { dg-warning "C" } */ + scanf ("%DA", d64); /* { dg-warning "C" } */ + scanf ("%De", d64); /* { dg-warning "C" } */ + scanf ("%DE", d64); /* { dg-warning "C" } */ + scanf ("%Df", d64); /* { dg-warning "C" } */ + scanf ("%DF", d64); /* { dg-warning "C" } */ + scanf ("%Dg", d64); /* { dg-warning "C" } */ + scanf ("%DG", d64); /* { dg-warning "C" } */ + scanf ("%DDa", d128); /* { dg-warning "C" } */ + scanf ("%DDA", d128); /* { dg-warning "C" } */ + scanf ("%DDe", d128); /* { dg-warning "C" } */ + scanf ("%DDE", d128); /* { dg-warning "C" } */ + scanf ("%DDf", d128); /* { dg-warning "C" } */ + scanf ("%DDF", d128); /* { dg-warning "C" } */ + scanf ("%DDg", d128); /* { dg-warning "C" } */ + scanf ("%DDG", d128); /* { dg-warning "C" } */ +} diff --git a/gcc/testsuite/gcc.dg/format/c2x-dfp-printf-1.c b/gcc/testsuite/gcc.dg/format/c2x-dfp-printf-1.c new file mode 100644 index 0000000..dc40f99 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/c2x-dfp-printf-1.c @@ -0,0 +1,35 @@ +/* Test for printf formats: acceptance of DFP formats in pedantic mode. */ +/* { dg-do compile } */ +/* { dg-require-effective-target dfp } */ +/* { dg-options "-std=c2x -pedantic -Wformat" } */ + +#include "format.h" + +void +foo (_Decimal32 d32, _Decimal64 d64, _Decimal128 d128) +{ + printf ("%Ha", d32); + printf ("%HA", d32); + printf ("%He", d32); + printf ("%HE", d32); + printf ("%Hf", d32); + printf ("%HF", d32); + printf ("%Hg", d32); + printf ("%HG", d32); + printf ("%Da", d64); + printf ("%DA", d64); + printf ("%De", d64); + printf ("%DE", d64); + printf ("%Df", d64); + printf ("%DF", d64); + printf ("%Dg", d64); + printf ("%DG", d64); + printf ("%DDa", d128); + printf ("%DDA", d128); + printf ("%DDe", d128); + printf ("%DDE", d128); + printf ("%DDf", d128); + printf ("%DDF", d128); + printf ("%DDg", d128); + printf ("%DDG", d128); +} diff --git a/gcc/testsuite/gcc.dg/format/c2x-dfp-scanf-1.c b/gcc/testsuite/gcc.dg/format/c2x-dfp-scanf-1.c new file mode 100644 index 0000000..81e39a9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/format/c2x-dfp-scanf-1.c @@ -0,0 +1,35 @@ +/* Test for scanf formats: acceptance of DFP formats in pedantic mode. */ +/* { dg-do compile } */ +/* { dg-require-effective-target dfp } */ +/* { dg-options "-std=c2x -pedantic -Wformat" } */ + +#include "format.h" + +void +foo (_Decimal32 *d32, _Decimal64 *d64, _Decimal128 *d128) +{ + scanf ("%Ha", d32); + scanf ("%HA", d32); + scanf ("%He", d32); + scanf ("%HE", d32); + scanf ("%Hf", d32); + scanf ("%HF", d32); + scanf ("%Hg", d32); + scanf ("%HG", d32); + scanf ("%Da", d64); + scanf ("%DA", d64); + scanf ("%De", d64); + scanf ("%DE", d64); + scanf ("%Df", d64); + scanf ("%DF", d64); + scanf ("%Dg", d64); + scanf ("%DG", d64); + scanf ("%DDa", d128); + scanf ("%DDA", d128); + scanf ("%DDe", d128); + scanf ("%DDE", d128); + scanf ("%DDf", d128); + scanf ("%DDF", d128); + scanf ("%DDg", d128); + scanf ("%DDG", d128); +} -- 2.7.4