libcpp: Fix ICE with directives-only and cpp_maybe_module_directive [PR124153]

When doing directives-only processing (-E -fdirectives-only, or -M) we
crash if we hit an unexpected CPP_PRAGMA_EOL because we 'know' we're in
a module directive but the in_deferred_pragma flag is no longer set.

Fixed by undoing the "finished a module directive" behaviour within
cpp_maybe_module_directive if we're bailing due to an ill-formed peeked
token.

	PR c++/124153

libcpp/ChangeLog:

	* lex.cc (cpp_maybe_module_directive): Set in_deferred_pragma
	and eol when we see an unexpected CPP_PRAGMA_EOL.

gcc/testsuite/ChangeLog:

	* g++.dg/modules/cpp-22.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
Nathaniel Shead
2026-02-21 22:32:25 +11:00
parent 81b437bad0
commit deba30681d
2 changed files with 16 additions and 1 deletions

View File

@@ -3674,6 +3674,15 @@ cpp_maybe_module_directive (cpp_reader *pfile, cpp_token *result)
peek->flags |= NO_DOT_COLON;
break;
}
else if (peek->type == CPP_PRAGMA_EOL)
{
/* This is a broken module-directive; undo the clearing
of in_deferred_pragma from _cpp_lex_direct so callers
don't crash, and make sure we process the EOL again. */
pfile->state.in_deferred_pragma = true;
eol = true;
break;
}
else
break;
}
@@ -3703,7 +3712,7 @@ cpp_maybe_module_directive (cpp_reader *pfile, cpp_token *result)
{
/* Put the peeked tokens back. */
_cpp_backup_tokens_direct (pfile, backup);
/* But if the last one was an EOL in the not_module case, forget it. */
/* But if the last one was an EOL, forget it. */
if (eol)
pfile->lookaheads--;
}