aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-05-02 12:55:24 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2024-05-02 23:52:44 +1000
commit7317d62a1200dbd3685015e5d6b811497a27fe5f (patch)
treeb85d523902cb77ced9b47eb2e0983494ac29addf
parent67e66c973ce31e375caa9611b2db290fbfc1904d (diff)
downloadgcc-7317d62a1200dbd3685015e5d6b811497a27fe5f.zip
gcc-7317d62a1200dbd3685015e5d6b811497a27fe5f.tar.gz
gcc-7317d62a1200dbd3685015e5d6b811497a27fe5f.tar.bz2
c++: Clear is_unbraced_* when parsing declaration_seq_opt [PR114917]
Currently we incorrectly retain "in_unbraced_linkage_specification_p" and "in_unbraced_export_declaration_p" when parsing a (braced) declaration-seq. This patch ensures that we clear these flags before parsing the toplevel declarations. Strictly speaking we don't need to save and restore the flags around the parsing because there's currently no way to provide new declarations within the unbraced context after the closing brace, but this patch does it anyway in case this ever changes and for consistency with other places that these flags are adjusted. PR c++/114917 gcc/cp/ChangeLog: * parser.cc (cp_parser_declaration_seq_opt): Clear parser->in_unbraced_* flags when parsing toplevel declarations. gcc/testsuite/ChangeLog: * g++.dg/modules/export-5_a.C: New test. * g++.dg/modules/export-5_b.C: New test. * g++.dg/parse/linkage4.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
-rw-r--r--gcc/cp/parser.cc15
-rw-r--r--gcc/testsuite/g++.dg/modules/export-5_a.C17
-rw-r--r--gcc/testsuite/g++.dg/modules/export-5_b.C13
-rw-r--r--gcc/testsuite/g++.dg/parse/linkage4.C11
4 files changed, 56 insertions, 0 deletions
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index 7c3cfcf..66ce161 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -15341,6 +15341,16 @@ cp_parser_module_export (cp_parser *parser)
static void
cp_parser_declaration_seq_opt (cp_parser* parser)
{
+ bool saved_in_unbraced_linkage_specification_p
+ = parser->in_unbraced_linkage_specification_p;
+ bool saved_in_unbraced_export_declaration_p
+ = parser->in_unbraced_export_declaration_p;
+
+ /* We're not in an unbraced linkage-specification
+ or export-declaration anymore. */
+ parser->in_unbraced_linkage_specification_p = false;
+ parser->in_unbraced_export_declaration_p = false;
+
while (true)
{
cp_token *token = cp_lexer_peek_token (parser->lexer);
@@ -15351,6 +15361,11 @@ cp_parser_declaration_seq_opt (cp_parser* parser)
else
cp_parser_toplevel_declaration (parser);
}
+
+ parser->in_unbraced_linkage_specification_p
+ = saved_in_unbraced_linkage_specification_p;
+ parser->in_unbraced_export_declaration_p
+ = saved_in_unbraced_export_declaration_p;
}
/* Parse a declaration. The distinction between name-declaration
diff --git a/gcc/testsuite/g++.dg/modules/export-5_a.C b/gcc/testsuite/g++.dg/modules/export-5_a.C
new file mode 100644
index 0000000..a325591
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/export-5_a.C
@@ -0,0 +1,17 @@
+// PR c++/114917
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi M }
+
+export module M;
+
+export namespace ns {
+ template <typename T> struct S {};
+ template <typename T> struct S<T*> { using a = int; };
+ template <> struct S<int*> { using b = int; };
+ template struct S<int>;
+};
+
+export extern "C++" namespace ns {
+ template <typename T> void foo() {}
+ template <> void foo<int>() {}
+}
diff --git a/gcc/testsuite/g++.dg/modules/export-5_b.C b/gcc/testsuite/g++.dg/modules/export-5_b.C
new file mode 100644
index 0000000..cb10e37
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/export-5_b.C
@@ -0,0 +1,13 @@
+// PR c++/114917
+// { dg-additional-options "-fmodules-ts" }
+
+import M;
+
+int main() {
+ ns::S<double*>::a x{};
+ ns::S<int*>::b y{};
+ ns::S<int> z{};
+
+ ns::foo<double>();
+ ns::foo<int>();
+}
diff --git a/gcc/testsuite/g++.dg/parse/linkage4.C b/gcc/testsuite/g++.dg/parse/linkage4.C
new file mode 100644
index 0000000..10fcc77
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/linkage4.C
@@ -0,0 +1,11 @@
+// PR c++/114917
+// { dg-do compile }
+
+extern "C++" namespace ns {
+ struct Incomplete;
+ Incomplete foo; // { dg-error "incomplete type" }
+}
+
+extern "C" extern "C" {
+ static int bar; // { dg-bogus "invalid" }
+}