preprocessor: Enable __VA_OPT__ for C2x
authorJoseph Myers <joseph@codesourcery.com>
Wed, 7 Dec 2022 19:18:06 +0000 (19:18 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Wed, 7 Dec 2022 19:18:06 +0000 (19:18 +0000)
C2x supports __VA_OPT__, so adjust libcpp not to pedwarn for uses of
it (or of not passing any variable arguments to a variable-arguments
macro) in standard C2x mode.

I didn't try to duplicate existing tests for the details of the
feature, just verified -pedantic-errors handling is as expected.  And
there's a reasonable argument (bug 98859) that __VA_OPT__ shouldn't be
diagnosed in older standard modes at all (as opposed to not passing
any variable arguments to a variable-arguments macro, for which older
versions of the C standard require a diagnostic as a constraint
violation); that argument applies to C as much as to C++, but I
haven't made any changes in that regard.

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

libcpp/
* init.cc (lang_defaults): Enable va_opt for STDC2X.
* lex.cc (maybe_va_opt_error): Adjust diagnostic message for C.
* macro.cc (_cpp_arguments_ok): Update comment.

gcc/testsuite/
* gcc.dg/cpp/c11-vararg-1.c, gcc.dg/cpp/c2x-va-opt-1.c: New tests.

gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c [new file with mode: 0644]
libcpp/init.cc
libcpp/lex.cc
libcpp/macro.cc

diff --git a/gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c b/gcc/testsuite/gcc.dg/cpp/c11-vararg-1.c
new file mode 100644 (file)
index 0000000..6b1bc38
--- /dev/null
@@ -0,0 +1,9 @@
+/* Test error in C11 for no arguments passed for variable arguments to a
+   macro.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#define M(X, ...) X
+
+M (x); /* { dg-error "requires at least one argument" } */
+M (x, y);
diff --git a/gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c b/gcc/testsuite/gcc.dg/cpp/c2x-va-opt-1.c
new file mode 100644 (file)
index 0000000..bd438f7
--- /dev/null
@@ -0,0 +1,11 @@
+/* Test __VA_OPT__ and no "..." arguments in a call to a variable-arguments
+   macro accepted for C2X.  */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#define CALL(F, ...) F (7 __VA_OPT__(,) __VA_ARGS__)
+#define M(X, ...) X
+
+CALL (a);
+CALL (b, 1);
+M (x);
index 5f34e35..ea683f0 100644 (file)
@@ -114,7 +114,7 @@ static const struct lang_flags lang_defaults[] =
   /* STDC99   */  { 1,  0,  1,  1,  0,  0,    1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC11   */  { 1,  0,  1,  1,  1,  0,    1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
   /* STDC17   */  { 1,  0,  1,  1,  1,  0,    1,  1,   1,   0,   0,    0,     0,     1,   0,      0,   0,     0,   0,   0,      0,      0,    0 },
-  /* STDC2X   */  { 1,  0,  1,  1,  1,  1,    1,  1,   1,   0,   0,    1,     1,     0,   1,      0,   1,     1,   0,   1,      1,      0,    1 },
+  /* STDC2X   */  { 1,  0,  1,  1,  1,  1,    1,  1,   1,   0,   0,    1,     1,     0,   1,      1,   1,     1,   0,   1,      1,      0,    1 },
   /* GNUCXX   */  { 0,  1,  1,  1,  0,  1,    0,  1,   0,   0,   0,    0,     0,     0,   0,      1,   1,     0,   0,   0,      0,      0,    1 },
   /* CXX98    */  { 0,  1,  0,  1,  0,  1,    1,  1,   0,   0,   0,    0,     0,     1,   0,      0,   1,     0,   0,   0,      0,      0,    1 },
   /* GNUCXX11 */  { 1,  1,  1,  1,  1,  1,    0,  1,   1,   1,   1,    0,     0,     0,   0,      1,   1,     0,   0,   0,      0,      0,    1 },
index b110792..9a21a3e 100644 (file)
@@ -2135,8 +2135,14 @@ maybe_va_opt_error (cpp_reader *pfile)
       /* __VA_OPT__ should not be accepted at all, but allow it in
         system headers.  */
       if (!_cpp_in_system_header (pfile))
-       cpp_error (pfile, CPP_DL_PEDWARN,
-                  "__VA_OPT__ is not available until C++20");
+       {
+         if (CPP_OPTION (pfile, cplusplus))
+           cpp_error (pfile, CPP_DL_PEDWARN,
+                      "__VA_OPT__ is not available until C++20");
+         else
+           cpp_error (pfile, CPP_DL_PEDWARN,
+                      "__VA_OPT__ is not available until C2X");
+       }
     }
   else if (!pfile->state.va_args_ok)
     {
index 7d5a0d0..452e14a 100644 (file)
@@ -1093,7 +1093,7 @@ _cpp_arguments_ok (cpp_reader *pfile, cpp_macro *macro, const cpp_hashnode *node
 
   if (argc < macro->paramc)
     {
-      /* In C++20 (here the va_opt flag is used), and also as a GNU
+      /* In C++20 and C2X (here the va_opt flag is used), and also as a GNU
         extension, variadic arguments are allowed to not appear in
         the invocation at all.
         e.g. #define debug(format, args...) something