mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-27 02:05:36 +08:00
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 <jakub@redhat.com> 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.
This commit is contained in:
parent
ece8b0fce6
commit
f43eb7707c
3
gcc/testsuite/g++.dg/cpp/elifdef-1.C
Normal file
3
gcc/testsuite/g++.dg/cpp/elifdef-1.C
Normal file
@ -0,0 +1,3 @@
|
||||
// { dg-do preprocess { target { ! c++23 } } }
|
||||
|
||||
#include "../../gcc.dg/cpp/c11-elifdef-1.c"
|
4
gcc/testsuite/g++.dg/cpp/elifdef-2.C
Normal file
4
gcc/testsuite/g++.dg/cpp/elifdef-2.C
Normal file
@ -0,0 +1,4 @@
|
||||
// P2334R1
|
||||
// { dg-do preprocess { target c++23 } }
|
||||
|
||||
#include "../../gcc.dg/cpp/c2x-elifdef-1.c"
|
62
gcc/testsuite/g++.dg/cpp/elifdef-3.C
Normal file
62
gcc/testsuite/g++.dg/cpp/elifdef-3.C
Normal file
@ -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
|
5
gcc/testsuite/g++.dg/cpp/elifdef-4.C
Normal file
5
gcc/testsuite/g++.dg/cpp/elifdef-4.C
Normal file
@ -0,0 +1,5 @@
|
||||
// P2334R1
|
||||
// { dg-do preprocess }
|
||||
// { dg-options "" }
|
||||
|
||||
#include "../../gcc.dg/cpp/c2x-elifdef-1.c"
|
63
gcc/testsuite/g++.dg/cpp/elifdef-5.C
Normal file
63
gcc/testsuite/g++.dg/cpp/elifdef-5.C
Normal file
@ -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
|
65
gcc/testsuite/g++.dg/cpp/elifdef-6.C
Normal file
65
gcc/testsuite/g++.dg/cpp/elifdef-6.C
Normal file
@ -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
|
65
gcc/testsuite/g++.dg/cpp/elifdef-7.C
Normal file
65
gcc/testsuite/g++.dg/cpp/elifdef-7.C
Normal file
@ -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
|
5
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c
Normal file
5
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-1.c
Normal file
@ -0,0 +1,5 @@
|
||||
/* Test #elifdef and #elifndef in GNU11. */
|
||||
/* { dg-do preprocess } */
|
||||
/* { dg-options "-std=gnu11" } */
|
||||
|
||||
#include "c2x-elifdef-1.c"
|
63
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c
Normal file
63
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-2.c
Normal file
@ -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
|
65
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c
Normal file
65
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-3.c
Normal file
@ -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
|
65
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c
Normal file
65
gcc/testsuite/gcc.dg/cpp/gnu11-elifdef-4.c
Normal file
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 }
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user