We didn't specifically check for a module-decl inside a header unit.
That leads to a confusing diagostic. Fixed thusly.
gcc/cp/
* lex.c (module_token_filter::resume): Ignore module-decls inside
header-unit.
* parser.c (cp_parser_module_declaration): Reject in header-unit.
gcc/testsuite/
* g++.dg/modules/pr99468.H: New.
--
Nathan Sidwell
diff --git c/gcc/cp/lex.c w/gcc/cp/lex.c
index c83346b617d..73e14b8394c 100644
--- c/gcc/cp/lex.c
+++ w/gcc/cp/lex.c
@@ -515,7 +515,7 @@ struct module_token_filter
{
module_end:;
/* End of the directive, handle the name. */
- if (import)
+ if (import && (is_import || !flag_header_unit))
if (module_state *m
= preprocess_module (import, token_loc, module != NULL,
is_import, got_export, reader))
diff --git c/gcc/cp/parser.c w/gcc/cp/parser.c
index 378e4572f8b..f636bb746d4 100644
--- c/gcc/cp/parser.c
+++ w/gcc/cp/parser.c
@@ -13745,7 +13745,13 @@ cp_parser_module_declaration (cp_parser *parser, module_parse mp_state,
parser->lexer->in_pragma = true;
cp_token *token = cp_lexer_consume_token (parser->lexer);
- if (mp_state == MP_FIRST && !exporting
+ if (flag_header_unit)
+ {
+ error_at (token->location,
+ "module-declaration not permitted in header-unit");
+ goto skip_eol;
+ }
+ else if (mp_state == MP_FIRST && !exporting
&& cp_lexer_next_token_is (parser->lexer, CPP_SEMICOLON))
{
/* Start global module fragment. */
diff --git c/gcc/testsuite/g++.dg/modules/pr99468.H w/gcc/testsuite/g++.dg/modules/pr99468.H
new file mode 100644
index 00000000000..b6be0c349d5
--- /dev/null
+++ w/gcc/testsuite/g++.dg/modules/pr99468.H
@@ -0,0 +1,7 @@
+// PR 99468, stupidly worded diagnostic
+// { dg-additional-options -fmodule-header }
+
+module M; // { dg-error "module-declaration not permitted" }
+
+int i;
+// { dg-prune-output "not writing" }