aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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 7c3cfcfcf4b..66ce161252c 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 00000000000..a325591ca8e
--- /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 00000000000..cb10e37c7fc
--- /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 00000000000..10fcc77e9d5
--- /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" }
+}