diff options
author | Jakub Jelinek <jakub@redhat.com> | 2025-07-10 23:47:42 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2025-07-10 23:48:12 +0200 |
commit | 8f063b40e5b8f23cb89fee21afaa71deedbdf2aa (patch) | |
tree | e64ac55213fd19aa8ea581ed40154c412c79ea77 /gcc/testsuite | |
parent | bcb51fe0e26bed7e2c44c4822ca6dec135ba61f3 (diff) | |
download | gcc-8f063b40e5b8f23cb89fee21afaa71deedbdf2aa.zip gcc-8f063b40e5b8f23cb89fee21afaa71deedbdf2aa.tar.gz gcc-8f063b40e5b8f23cb89fee21afaa71deedbdf2aa.tar.bz2 |
c++: Fix up final handling in C++98 [PR120628]
The following patch is on top of the
https://gcc.gnu.org/pipermail/gcc-patches/2025-June/686210.html
patch which stopped treating override as conditional keyword in
class properties.
This PR mentions another problem; we emit a bogus warning on code like
struct C {}; struct C final = {};
in C++98. In this case we parse final as conditional keyword in C++
(including pedwarn) but the caller then immediately aborts the tentative
parse because it isn't followed by { nor (in some cases) : .
I think we certainly shouldn't pedwarn on it, but I think we even shouldn't
warn for it say for -Wc++11-compat, because we don't actually treat the
identifier as conditional keyword even in C++11 and later.
The patch only does this if final is the only class property conditional
keyword, if one uses
struct S __final final __final = {};
one gets the warning and duplicate diagnostics and later parsing errors.
2025-07-10 Jakub Jelinek <jakub@redhat.com>
PR c++/120628
* parser.cc (cp_parser_elaborated_type_specifier): Use
cp_parser_nth_token_starts_class_definition_p with extra argument 1
instead of cp_parser_next_token_starts_class_definition_p.
(cp_parser_class_property_specifier_seq_opt): For final conditional
keyword in C++98 check if the token after it isn't
cp_parser_nth_token_starts_class_definition_p nor CPP_NAME and in
that case break without consuming it nor warning.
(cp_parser_class_head): Use
cp_parser_nth_token_starts_class_definition_p with extra argument 1
instead of cp_parser_next_token_starts_class_definition_p.
(cp_parser_next_token_starts_class_definition_p): Renamed to ...
(cp_parser_nth_token_starts_class_definition_p): ... this. Add N
argument. Use cp_lexer_peek_nth_token instead of cp_lexer_peek_token.
* g++.dg/cpp0x/final1.C: New test.
* g++.dg/cpp0x/final2.C: New test.
* g++.dg/cpp0x/override6.C: New test.
Diffstat (limited to 'gcc/testsuite')
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/final1.C | 11 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/final2.C | 26 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/override6.C | 26 |
3 files changed, 63 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/cpp0x/final1.C b/gcc/testsuite/g++.dg/cpp0x/final1.C new file mode 100644 index 0000000..1d64095 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/final1.C @@ -0,0 +1,11 @@ +// PR c++/120628 +// { dg-do compile { target c++98_only } } + +namespace A { + struct B {}; + struct B final = {}; +} +namespace C { + struct D { D (int, int); }; + struct D final (42, 0); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/final2.C b/gcc/testsuite/g++.dg/cpp0x/final2.C new file mode 100644 index 0000000..d8d5866 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/final2.C @@ -0,0 +1,26 @@ +// PR c++/120628 +// { dg-do compile } +// { dg-options "" } +// { dg-additional-options "-pedantic" { target c++14 } } + +namespace U { + struct A {}; + struct A final = {}; +} +namespace V { + template <int N> + struct B {}; + template <int N> + struct B<N> final = {}; // { dg-warning "variable templates only available with" "" { target c++11_down } } +} +struct C { + struct D {}; + static D foo (); + struct D final = foo (); // { dg-warning "non-static data member initializers only available with" "" { target c++98_only } } +}; +namespace W { + struct E { struct F {}; }; + struct E::F final = {}; +} +template <int N> +struct V::B<N> final = {}; // { dg-warning "variable templates only available with" "" { target c++11_down } } diff --git a/gcc/testsuite/g++.dg/cpp0x/override6.C b/gcc/testsuite/g++.dg/cpp0x/override6.C new file mode 100644 index 0000000..601e91d --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/override6.C @@ -0,0 +1,26 @@ +// PR c++/120628 +// { dg-do compile } +// { dg-options "" } +// { dg-additional-options "-pedantic" { target c++14 } } + +namespace U { + struct A {}; + struct A override = {}; +} +namespace V { + template <int N> + struct B {}; + template <int N> + struct B<N> override = {}; // { dg-warning "variable templates only available with" "" { target c++11_down } } +} +struct C { + struct D {}; + static D foo (); + struct D override = foo (); // { dg-warning "non-static data member initializers only available with" "" { target c++98_only } } +}; +namespace W { + struct E { struct F {}; }; + struct E::F override = {}; +} +template <int N> +struct V::B<N> override = {}; // { dg-warning "variable templates only available with" "" { target c++11_down } } |