Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk/15?
-- >8 --
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 <[email protected]>
---
gcc/testsuite/g++.dg/modules/cpp-22.C | 6 ++++++
libcpp/lex.cc | 11 ++++++++++-
2 files changed, 16 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/g++.dg/modules/cpp-22.C
diff --git a/gcc/testsuite/g++.dg/modules/cpp-22.C
b/gcc/testsuite/g++.dg/modules/cpp-22.C
new file mode 100644
index 00000000000..9c80ab0657b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/cpp-22.C
@@ -0,0 +1,6 @@
+// PR c++/124153
+// { dg-additional-options "-fmodules -fdirectives-only -E" }
+
+// directives-only mode currently does not do error checking.
+export module hello // { dg-error "expected ';'" "" { xfail *-*-* } }
+import world;
diff --git a/libcpp/lex.cc b/libcpp/lex.cc
index 63f7a5fe5b8..aeca20ba1a0 100644
--- a/libcpp/lex.cc
+++ b/libcpp/lex.cc
@@ -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 so callers don't crash, and
+ make sure we process the EOL again correctly. */
+ 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--;
}
--
2.51.0