Add strftime format checking support for C2x %OB and %Ob (bug 82752).
authorJoseph Myers <joseph@codesourcery.com>
Fri, 4 Oct 2019 21:56:14 +0000 (22:56 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Fri, 4 Oct 2019 21:56:14 +0000 (22:56 +0100)
C2x adds strftime %OB and %Ob formats, for alternative forms of month
names (for mainly Slavic languages where a month name on its own is
declined differently from a month name together with a date within
that month).  This patch adds corresponding format checking support.
(glibc support for these formats was added in glibc 2.27.)

Bootstrapped with no regressions on x86_64-pc-linux-gnu.

PR c/82752
gcc/c-family:
* c-format.c (C_STD_VER): Handle C2x.
(C_STD_NAME): Likewise.
(strftime_flag_specs): Add 'O' modifier with 'p' flag.
(time_char_table): Use separate entry for 'B' and 'b', with 'O'
modifier allowed and 'p' flag.
* c-format.h (enum format_std_version): Add STD_C2X.
(struct format_char_info): Mention 'p' in comment on flags2.

gcc/testsuite:
* gcc.dg/format/c2x-strftime-1.c: New test.

From-SVN: r276605

gcc/c-family/ChangeLog
gcc/c-family/c-format.c
gcc/c-family/c-format.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/format/c2x-strftime-1.c [new file with mode: 0644]

index 0eade3cf8d8baa5f2bbe5bc030735c9df69c0d14..1ebc4d9f764e1460d8d0b671aa869f882ee967bf 100644 (file)
@@ -1,3 +1,14 @@
+2019-10-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/82752
+       * c-format.c (C_STD_VER): Handle C2x.
+       (C_STD_NAME): Likewise.
+       (strftime_flag_specs): Add 'O' modifier with 'p' flag.
+       (time_char_table): Use separate entry for 'B' and 'b', with 'O'
+       modifier allowed and 'p' flag.
+       * c-format.h (enum format_std_version): Add STD_C2X.
+       (struct format_char_info): Mention 'p' in comment on flags2.
+
 2019-10-01  David Malcolm  <dmalcolm@redhat.com>
 
        * c-opts.c (c_diagnostic_finalizer): Temporarily clear prefix when
index 91bae3d6096f580feeba794e6ef58a719b40ee8d..3c291ca45003904a6713d5d16fa468285da13d2e 100644 (file)
@@ -404,9 +404,11 @@ decode_format_attr (const_tree fntype, tree atname, tree args,
 /* The C standard version we are checking formats against when pedantic.  */
 #define C_STD_VER              ((int) (c_dialect_cxx ()                   \
                                 ? CPLUSPLUS_STD_VER                       \
-                                : (flag_isoc99                            \
-                                   ? STD_C99                              \
-                                   : (flag_isoc94 ? STD_C94 : STD_C89))))
+                                : (flag_isoc2x                            \
+                                   ? STD_C2X                              \
+                                   : (flag_isoc99                         \
+                                      ? STD_C99                           \
+                                      : (flag_isoc94 ? STD_C94 : STD_C89)))))
 /* The name to give to the standard version we are warning about when
    pedantic.  FEATURE_VER is the version in which the feature warned out
    appeared, which is higher than C_STD_VER.  */
@@ -415,7 +417,9 @@ decode_format_attr (const_tree fntype, tree atname, tree args,
                                    : "ISO C++11")              \
                                 : ((FEATURE_VER) == STD_EXT    \
                                    ? "ISO C"                   \
-                                   : "ISO C90"))
+                                   : ((FEATURE_VER) == STD_C2X \
+                                      ? "ISO C17"              \
+                                      : "ISO C90")))
 /* Adjust a C standard version, which may be STD_C9L, to account for
    -Wno-long-long.  Returns other standard versions unchanged.  */
 #define ADJ_STD(VER)           ((int) ((VER) == STD_C9L                      \
@@ -653,6 +657,7 @@ static const format_flag_spec strftime_flag_specs[] =
   { 'E', 0,   0, 0, N_("'E' modifier"), N_("the 'E' strftime modifier"),      STD_C99 },
   { 'O', 0,   0, 0, N_("'O' modifier"), N_("the 'O' strftime modifier"),      STD_C99 },
   { 'O', 'o', 0, 0, NULL,               N_("the 'O' modifier"),               STD_EXT },
+  { 'O', 'p', 0, 0, NULL,               N_("the 'O' modifier"),               STD_C2X },
   { 0, 0, 0, 0, NULL, NULL, STD_C89 }
 };
 
@@ -887,7 +892,8 @@ static const format_char_info scan_char_table[] =
 static const format_char_info time_char_table[] =
 {
   /* C89 conversion specifiers.  */
-  { "ABZab",           0, STD_C89, NOLENGTHS, "^#",     "",   NULL },
+  { "AZa",             0, STD_C89, NOLENGTHS, "^#",     "",   NULL },
+  { "Bb",              0, STD_C89, NOLENGTHS, "O^#",    "p",  NULL },
   { "cx",              0, STD_C89, NOLENGTHS, "E",      "3",  NULL },
   { "HIMSUWdmw",       0, STD_C89, NOLENGTHS, "-_0Ow",  "",   NULL },
   { "j",               0, STD_C89, NOLENGTHS, "-_0Ow",  "o",  NULL },
index 6aa68dfe88364c1d421c0dd7d2a108a126b94cd0..15a3153cfd3bdff571c2951c0481d545798a47ff 100644 (file)
@@ -48,6 +48,7 @@ enum format_std_version
   STD_C94,
   STD_C9L, /* C99, but treat as C89 if -Wno-long-long.  */
   STD_C99,
+  STD_C2X,
   STD_EXT
 };
 
@@ -149,6 +150,7 @@ struct format_char_info
      two digit year formats, "3" for strftime formats giving two digit
      years in some locales, "4" for "2" which becomes "3" with an "E" modifier,
      "o" if use of strftime "O" is a GNU extension beyond C99,
+     "p" if use of strftime "O" is a C2x feature,
      "W" if the argument is a pointer which is dereferenced and written into,
      "R" if the argument is a pointer which is dereferenced and read from,
      "i" for printf integer formats where the '0' flag is ignored with
index d8987cabc3dc6f0379f7e57d17f5f059383eae34..46245216b9066bb10f293fe252f340ab9fd96837 100644 (file)
@@ -1,3 +1,8 @@
+2019-10-04  Joseph Myers  <joseph@codesourcery.com>
+
+       PR c/82752
+       * gcc.dg/format/c2x-strftime-1.c: New test.
+
 2019-10-04  Martin Sebor  <msebor@redhat.com>
 
        PR middle-end/91977
diff --git a/gcc/testsuite/gcc.dg/format/c2x-strftime-1.c b/gcc/testsuite/gcc.dg/format/c2x-strftime-1.c
new file mode 100644 (file)
index 0000000..c6e7619
--- /dev/null
@@ -0,0 +1,15 @@
+/* Test for strftime formats.  Formats using C2x features.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic -Wformat" } */
+
+#include "format.h"
+
+void
+foo (char *s, size_t m, const struct tm *tp)
+{
+  strftime (s, m, "%Ob", tp);
+  strftime (s, m, "%OB", tp);
+  /* It's not clear that %h equivalence to %b means %Oh is equivalent
+     to %Ob; here we expect %Oh to be diagnosed.  */
+  strftime (s, m, "%Oh", tp); /* { dg-warning "flag|modifier" "bad %Oh" } */
+}