From f43eb7707c06e8824d07d5c87ed2019d796fa8a0 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 6 Oct 2021 10:13:51 +0200 Subject: [PATCH] libcpp: Implement C++23 P2334R1 - #elifdef/#elifndef This patch implements C++23 P2334R1, which is easy because Joseph has done all the hard work for C2X already. Unlike the C N2645 paper, the C++ P2334R1 contains one important addition (but not in the normative text): "While this is a new preprocessor feature and cannot be treated as a defect report, implementations that support older versions of the standard are encouraged to implement this feature in the older language modes as well as C++23." so there are different variants how to implement it. One is ignoring that sentence and only implementing it for -std=c++23/-std=gnu++23 like it is only implemented for -std=c2x. Another option would be to implement it also in the older GNU modes but not in the C/CXX modes (but it would be strange if we did that just for C++ and not for C). Yet another option is to enable it unconditionally. And yet another option would be to enable it unconditionally but emit a warning (or pedwarn) when it is seen. Note, when it is enabled for the older language modes, as Joseph wrote in the c11-elifdef-1.c testcase, it can result e.g. in rejecting previously valid code: #define A #undef B #if 0 #elifdef A #error "#elifdef A applied" #endif #if 0 #elifndef B #error "#elifndef B applied" #endif Note, seems clang went the enable it unconditionally in all standard versions of both C and C++, no warnings or anything whatsoever, so essentially treated it as a DR that changed behavior of e.g. the above code. After feedback, this option enables #elifdef/#elifndef for -std=c2x and -std=c++2{b,3} and enables it also for -std=gnu*, but for GNU modes older than C2X or C++23 if -pedantic it emits a pedwarn on the directives that either would be rejected in the corresponding -std=c* modes, e.g. #if 1 #elifdef A // pedwarn if -pedantic #endif or when the directives would be silently accepted, but when they are recognized it changes behavior, so e.g. #define A #if 0 #elifdef A // pedwarn if -pedantic #define M 1 #endif It won't pedwarn if the directives would be silently ignored and wouldn't change anything, like: #define A #if 0 #elifndef A #define M 1 #endif or #undef B #if 0 #elifdef B #define M 1 #endif 2021-10-06 Jakub Jelinek libcpp/ * init.c (lang_defaults): Implement P2334R1, enable elifdef for -std=c++23 and -std=gnu++23. * directives.c (_cpp_handle_directive): Support elifdef/elifndef if either CPP_OPTION (pfile, elifdef) or !CPP_OPTION (pfile, std). (do_elif): For older non-std modes if pedantic pedwarn about #elifdef/#elifndef directives that change behavior. gcc/testsuite/ * gcc.dg/cpp/gnu11-elifdef-1.c: New test. * gcc.dg/cpp/gnu11-elifdef-2.c: New test. * gcc.dg/cpp/gnu11-elifdef-3.c: New test. * gcc.dg/cpp/gnu11-elifdef-4.c: New test. * g++.dg/cpp/elifdef-1.C: New test. * g++.dg/cpp/elifdef-2.C: New test. * g++.dg/cpp/elifdef-3.C: New test. * g++.dg/cpp/elifdef-4.C: New test. * g++.dg/cpp/elifdef-5.C: New test. * g++.dg/cpp/elifdef-6.C: New test. * g++.dg/cpp/elifdef-7.C: New test. --- gcc/testsuite/g++.dg/cpp/elifdef-1.C | 3 ++ gcc/testsuite/g++.dg/cpp/elifdef-2.C | 4 ++ gcc/testsuite/g++.dg/cpp/elifdef-3.C | 62 ++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp/elifdef-4.C | 5 +++ gcc/testsuite/g++.dg/cpp/elifdef-5.C | 63 +++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp/elifdef-6.C | 65 ++++++++++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp/elifdef-7.C | 65 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c | 5 +++ gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c | 63 +++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c | 65 ++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c | 65 ++++++++++++++++++++++++++++++ libcpp/directives.c | 43 +++++++++++++++++++- libcpp/init.c | 4 +- 13 files changed, 508 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-1.C create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-2.C create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-3.C create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-4.C create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-5.C create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-6.C create mode 100644 gcc/testsuite/g++.dg/cpp/elifdef-7.C create mode 100644 gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c create mode 100644 gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c create mode 100644 gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c create mode 100644 gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-1.C b/gcc/testsuite/g++.dg/cpp/elifdef-1.C new file mode 100644 index 0000000..f7965e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-1.C @@ -0,0 +1,3 @@ +// { dg-do preprocess { target { ! c++23 } } } + +#include "../../gcc.dg/cpp/c11-elifdef-1.c" diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-2.C b/gcc/testsuite/g++.dg/cpp/elifdef-2.C new file mode 100644 index 0000000..6408271 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-2.C @@ -0,0 +1,4 @@ +// P2334R1 +// { dg-do preprocess { target c++23 } } + +#include "../../gcc.dg/cpp/c2x-elifdef-1.c" diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-3.C b/gcc/testsuite/g++.dg/cpp/elifdef-3.C new file mode 100644 index 0000000..d9acce0 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-3.C @@ -0,0 +1,62 @@ +// P2334R1 +// { dg-do preprocess { target c++23 } } + +#define A +#undef B + +#elifdef A // { dg-error "#elifdef without #if" } +#elifdef B // { dg-error "#elifdef without #if" } +#elifndef A // { dg-error "#elifndef without #if" } +#elifndef B // { dg-error "#elifndef without #if" } + +#if 1 // { dg-error "-:began here" } +#else +#elifdef A // { dg-error "#elifdef after #else" } +#endif + +#if 1 // { dg-error "-:began here" } +#else +#elifdef B // { dg-error "#elifdef after #else" } +#endif + +#if 1 // { dg-error "-:began here" } +#else +#elifndef A // { dg-error "#elifndef after #else" } +#endif + +#if 1 // { dg-error "-:began here" } +#else +#elifndef B // { dg-error "#elifndef after #else" } +#endif + +#if 0 +#elifdef A = // { dg-error "extra tokens at end of #elifdef directive" } +#endif + +#if 0 +#elifdef B = // { dg-error "extra tokens at end of #elifdef directive" } +#endif + +#if 0 +#elifndef A = // { dg-error "extra tokens at end of #elifndef directive" } +#endif + +#if 0 +#elifndef B = // { dg-error "extra tokens at end of #elifndef directive" } +#endif + +#if 0 +#elifdef // { dg-error "no macro name given in #elifdef directive" } +#endif + +#if 0 +#elifndef // { dg-error "no macro name given in #elifndef directive" } +#endif + +#if 0 +#elifdef , // { dg-error "macro names must be identifiers" } +#endif + +#if 0 +#elifndef , // { dg-error "macro names must be identifiers" } +#endif diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-4.C b/gcc/testsuite/g++.dg/cpp/elifdef-4.C new file mode 100644 index 0000000..08edf58 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-4.C @@ -0,0 +1,5 @@ +// P2334R1 +// { dg-do preprocess } +// { dg-options "" } + +#include "../../gcc.dg/cpp/c2x-elifdef-1.c" diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-5.C b/gcc/testsuite/g++.dg/cpp/elifdef-5.C new file mode 100644 index 0000000..f7d4007 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-5.C @@ -0,0 +1,63 @@ +// P2334R1 +// { dg-do preprocess } +// { dg-options "" } + +#define A +#undef B + +#elifdef A // { dg-error "#elifdef without #if" } +#elifdef B // { dg-error "#elifdef without #if" } +#elifndef A // { dg-error "#elifndef without #if" } +#elifndef B // { dg-error "#elifndef without #if" } + +#if 1 // { dg-error "-:began here" } +#else +#elifdef A // { dg-error "#elifdef after #else" } +#endif + +#if 1 // { dg-error "-:began here" } +#else +#elifdef B // { dg-error "#elifdef after #else" } +#endif + +#if 1 // { dg-error "-:began here" } +#else +#elifndef A // { dg-error "#elifndef after #else" } +#endif + +#if 1 // { dg-error "-:began here" } +#else +#elifndef B // { dg-error "#elifndef after #else" } +#endif + +#if 0 +#elifdef A = // { dg-warning "extra tokens at end of #elifdef directive" } +#endif + +#if 0 +#elifdef B = // { dg-warning "extra tokens at end of #elifdef directive" } +#endif + +#if 0 +#elifndef A = // { dg-warning "extra tokens at end of #elifndef directive" } +#endif + +#if 0 +#elifndef B = // { dg-warning "extra tokens at end of #elifndef directive" } +#endif + +#if 0 +#elifdef // { dg-error "no macro name given in #elifdef directive" } +#endif + +#if 0 +#elifndef // { dg-error "no macro name given in #elifndef directive" } +#endif + +#if 0 +#elifdef , // { dg-error "macro names must be identifiers" } +#endif + +#if 0 +#elifndef , // { dg-error "macro names must be identifiers" } +#endif diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-6.C b/gcc/testsuite/g++.dg/cpp/elifdef-6.C new file mode 100644 index 0000000..94d2118 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-6.C @@ -0,0 +1,65 @@ +// P2334R1 +// { dg-do preprocess } +// { dg-options "-pedantic" } + +#define A +#undef B + +#if 0 +#elifdef A // { dg-warning "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#define M1 1 +#endif + +#if M1 != 1 +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifdef B +#error "#elifdef B applied" +#endif + +#if 0 +#elifndef A +#error "#elifndef A applied" +#endif + +#if 0 +#elifndef B // { dg-warning "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#define M2 2 +#endif + +#if M2 != 2 +#error "#elifndef B did not apply" +#endif + +#if 0 +#elifdef A // { dg-warning "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#else +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifndef B // { dg-warning "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#else +#error "#elifndef B did not apply" +#endif + +#if 1 +#elifdef A // { dg-warning "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif + +#if 1 +#elifndef B // { dg-warning "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif + +// As with #elif, the syntax of the new directives is relaxed after a + non-skipped group. + +#if 1 +#elifdef x * y // { dg-warning "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif + +#if 1 +#elifndef ! // { dg-warning "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif diff --git a/gcc/testsuite/g++.dg/cpp/elifdef-7.C b/gcc/testsuite/g++.dg/cpp/elifdef-7.C new file mode 100644 index 0000000..bb9b8ef --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp/elifdef-7.C @@ -0,0 +1,65 @@ +// P2334R1 +// { dg-do preprocess } +// { dg-options "-pedantic-errors" } + +#define A +#undef B + +#if 0 +#elifdef A // { dg-error "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#define M1 1 +#endif + +#if M1 != 1 +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifdef B +#error "#elifdef B applied" +#endif + +#if 0 +#elifndef A +#error "#elifndef A applied" +#endif + +#if 0 +#elifndef B // { dg-error "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#define M2 2 +#endif + +#if M2 != 2 +#error "#elifndef B did not apply" +#endif + +#if 0 +#elifdef A // { dg-error "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#else +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifndef B // { dg-error "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#else +#error "#elifndef B did not apply" +#endif + +#if 1 +#elifdef A // { dg-error "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif + +#if 1 +#elifndef B // { dg-error "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif + +// As with #elif, the syntax of the new directives is relaxed after a + non-skipped group. + +#if 1 +#elifdef x * y // { dg-error "#elifdef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif + +#if 1 +#elifndef ! // { dg-error "#elifndef before C\\\+\\\+23 is a GCC extension" "" { target c++20_down } } +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c new file mode 100644 index 0000000..efcfbc9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c @@ -0,0 +1,5 @@ +/* Test #elifdef and #elifndef in GNU11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu11" } */ + +#include "c2x-elifdef-1.c" diff --git a/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c new file mode 100644 index 0000000..e5bd705 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c @@ -0,0 +1,63 @@ +/* Test #elifdef and #elifndef in GNU11: erroneous usages. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu11" } */ + +#define A +#undef B + +#elifdef A /* { dg-error "#elifdef without #if" } */ +#elifdef B /* { dg-error "#elifdef without #if" } */ +#elifndef A /* { dg-error "#elifndef without #if" } */ +#elifndef B /* { dg-error "#elifndef without #if" } */ + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifdef A /* { dg-error "#elifdef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifdef B /* { dg-error "#elifdef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifndef A /* { dg-error "#elifndef after #else" } */ +#endif + +#if 1 /* { dg-error "-:began here" } */ +#else +#elifndef B /* { dg-error "#elifndef after #else" } */ +#endif + +#if 0 +#elifdef A = /* { dg-warning "extra tokens at end of #elifdef directive" } */ +#endif + +#if 0 +#elifdef B = /* { dg-warning "extra tokens at end of #elifdef directive" } */ +#endif + +#if 0 +#elifndef A = /* { dg-warning "extra tokens at end of #elifndef directive" } */ +#endif + +#if 0 +#elifndef B = /* { dg-warning "extra tokens at end of #elifndef directive" } */ +#endif + +#if 0 +#elifdef /* { dg-error "no macro name given in #elifdef directive" } */ +#endif + +#if 0 +#elifndef /* { dg-error "no macro name given in #elifndef directive" } */ +#endif + +#if 0 +#elifdef , /* { dg-error "macro names must be identifiers" } */ +#endif + +#if 0 +#elifndef , /* { dg-error "macro names must be identifiers" } */ +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c new file mode 100644 index 0000000..0b769a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c @@ -0,0 +1,65 @@ +/* Test #elifdef and #elifndef in GNU11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu11 -pedantic" } */ + +#define A +#undef B + +#if 0 +#elifdef A /* { dg-warning "#elifdef before C2X is a GCC extension" } */ +#define M1 1 +#endif + +#if M1 != 1 +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifdef B +#error "#elifdef B applied" +#endif + +#if 0 +#elifndef A +#error "#elifndef A applied" +#endif + +#if 0 +#elifndef B /* { dg-warning "#elifndef before C2X is a GCC extension" } */ +#define M2 2 +#endif + +#if M2 != 2 +#error "#elifndef B did not apply" +#endif + +#if 0 +#elifdef A /* { dg-warning "#elifdef before C2X is a GCC extension" } */ +#else +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifndef B /* { dg-warning "#elifndef before C2X is a GCC extension" } */ +#else +#error "#elifndef B did not apply" +#endif + +#if 1 +#elifdef A /* { dg-warning "#elifdef before C2X is a GCC extension" } */ +#endif + +#if 1 +#elifndef B /* { dg-warning "#elifndef before C2X is a GCC extension" } */ +#endif + +/* As with #elif, the syntax of the new directives is relaxed after a + non-skipped group. */ + +#if 1 +#elifdef x * y /* { dg-warning "#elifdef before C2X is a GCC extension" } */ +#endif + +#if 1 +#elifndef ! /* { dg-warning "#elifndef before C2X is a GCC extension" } */ +#endif diff --git a/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c new file mode 100644 index 0000000..aba3467 --- /dev/null +++ b/gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c @@ -0,0 +1,65 @@ +/* Test #elifdef and #elifndef in GNU11. */ +/* { dg-do preprocess } */ +/* { dg-options "-std=gnu11 -pedantic-errors" } */ + +#define A +#undef B + +#if 0 +#elifdef A /* { dg-error "#elifdef before C2X is a GCC extension" } */ +#define M1 1 +#endif + +#if M1 != 1 +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifdef B +#error "#elifdef B applied" +#endif + +#if 0 +#elifndef A +#error "#elifndef A applied" +#endif + +#if 0 +#elifndef B /* { dg-error "#elifndef before C2X is a GCC extension" } */ +#define M2 2 +#endif + +#if M2 != 2 +#error "#elifndef B did not apply" +#endif + +#if 0 +#elifdef A /* { dg-error "#elifdef before C2X is a GCC extension" } */ +#else +#error "#elifdef A did not apply" +#endif + +#if 0 +#elifndef B /* { dg-error "#elifndef before C2X is a GCC extension" } */ +#else +#error "#elifndef B did not apply" +#endif + +#if 1 +#elifdef A /* { dg-error "#elifdef before C2X is a GCC extension" } */ +#endif + +#if 1 +#elifndef B /* { dg-error "#elifndef before C2X is a GCC extension" } */ +#endif + +/* As with #elif, the syntax of the new directives is relaxed after a + non-skipped group. */ + +#if 1 +#elifdef x * y /* { dg-error "#elifdef before C2X is a GCC extension" } */ +#endif + +#if 1 +#elifndef ! /* { dg-error "#elifndef before C2X is a GCC extension" } */ +#endif diff --git a/libcpp/directives.c b/libcpp/directives.c index 261a584..b4bc8b4 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -447,7 +447,11 @@ _cpp_handle_directive (cpp_reader *pfile, bool indented) if (dname->val.node.node->is_directive) { dir = &dtable[dname->val.node.node->directive_index]; - if ((dir->flags & ELIFDEF) && !CPP_OPTION (pfile, elifdef)) + if ((dir->flags & ELIFDEF) + && !CPP_OPTION (pfile, elifdef) + /* For -std=gnu* modes elifdef is supported with + a pedwarn if pedantic. */ + && CPP_OPTION (pfile, std)) dir = 0; } } @@ -2117,7 +2121,26 @@ do_elif (cpp_reader *pfile) are skipped and their controlling directives are processed as if they were in a group that is skipped." */ if (ifs->skip_elses) - pfile->state.skipping = 1; + { + /* In older GNU standards, #elifdef/#elifndef is supported + as an extension, but pedwarn if -pedantic if the presence + of the directive would be rejected. */ + if (pfile->directive != &dtable[T_ELIF] + && ! CPP_OPTION (pfile, elifdef) + && CPP_PEDANTIC (pfile) + && !pfile->state.skipping) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C++23 is a GCC extension", + pfile->directive->name); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C2X is a GCC extension", + pfile->directive->name); + } + pfile->state.skipping = 1; + } else { if (pfile->directive == &dtable[T_ELIF]) @@ -2139,6 +2162,22 @@ do_elif (cpp_reader *pfile) if (pfile->cb.used) pfile->cb.used (pfile, pfile->directive_line, node); check_eol (pfile, false); + /* In older GNU standards, #elifdef/#elifndef is supported + as an extension, but pedwarn if -pedantic if the presence + of the directive would change behavior. */ + if (! CPP_OPTION (pfile, elifdef) + && CPP_PEDANTIC (pfile) + && pfile->state.skipping != skip) + { + if (CPP_OPTION (pfile, cplusplus)) + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C++23 is a GCC extension", + pfile->directive->name); + else + cpp_error (pfile, CPP_DL_PEDWARN, + "#%s before C2X is a GCC extension", + pfile->directive->name); + } pfile->state.skipping = skip; } } diff --git a/libcpp/init.c b/libcpp/init.c index eda17a6..5a424e2 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -122,8 +122,8 @@ static const struct lang_flags lang_defaults[] = /* CXX17 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0 }, /* GNUCXX20 */ { 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0 }, /* CXX20 */ { 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0 }, - /* GNUCXX23 */ { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0 }, - /* CXX23 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0 }, + /* GNUCXX23 */ { 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 }, + /* CXX23 */ { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1 }, /* ASM */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }; -- 2.7.4