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

Reply via email to