aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2025-07-10 23:47:42 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2025-07-10 23:48:12 +0200
commit8f063b40e5b8f23cb89fee21afaa71deedbdf2aa (patch)
treee64ac55213fd19aa8ea581ed40154c412c79ea77 /gcc/testsuite
parentbcb51fe0e26bed7e2c44c4822ca6dec135ba61f3 (diff)
downloadgcc-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.C11
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/final2.C26
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/override6.C26
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 } }