]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libcpp: Fix ICE with directives-only and cpp_maybe_module_directive [PR124153]
authorNathaniel Shead <nathanieloshead@gmail.com>
Sat, 21 Feb 2026 11:32:25 +0000 (22:32 +1100)
committerNathaniel Shead <nathanieloshead@gmail.com>
Sun, 22 Feb 2026 15:25:10 +0000 (02:25 +1100)
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>
gcc/testsuite/g++.dg/modules/cpp-22.C [new file with mode: 0644]
libcpp/lex.cc

diff --git a/gcc/testsuite/g++.dg/modules/cpp-22.C b/gcc/testsuite/g++.dg/modules/cpp-22.C
new file mode 100644 (file)
index 0000000..9c80ab0
--- /dev/null
@@ -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;
index 63f7a5fe5b8a5b555bfd0ee8b0b28d8d42c30e69..9652e7d5aaefb59d936a51c36cae7fa927908e62 100644 (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--;
     }