On 7/31/25 1:58 PM, Jakub Jelinek wrote:
On Thu, Jul 31, 2025 at 11:04:56AM -0400, Jason Merrill wrote:
If the current backup handling is doing the wrong thing in this case, it
seems better to fix it rather than add more earlier in the function. Would
it be enough to move the existing CPP_PRAGMA_EOL handling into the
not_module block?
I guess either it would need to duplicate the _cpp_backup_tokens_direct call
like in the patch below (keep the eol handling just in not_module block,
otherwise have just a simple call), or I can move the eol variable to the
start of function, initialize there to false and only set it to peek->type
== CPP_PRAGMA_EOL in the not_module block, then the backup handling can be
shared (attached patch). The second (attached) is certainly shorter.
Both were just tested on the single testcase, which one do you prefer (or
something different)?
The second is OK, thanks.
Jason
2025-07-31 Jakub Jelinek <ja...@redhat.com>
PR c++/120845
libcpp/
* lex.cc (cpp_maybe_module_directive): Move backup handling into
the if substatements, in the not_module case as is, otherwise
just if (backup) _cpp_backup_tokens_direct (). Formatting fix.
gcc/testsuite/
* g++.dg/modules/cpp-21.C: New test.
--- libcpp/lex.cc.jj 2025-04-24 15:29:41.714893932 +0200
+++ libcpp/lex.cc 2025-07-31 19:39:24.549920693 +0200
@@ -3564,10 +3564,10 @@ cpp_maybe_module_directive (cpp_reader *
tokens. C++ keywords are not yet relevant. */
if (peek->type == CPP_NAME
|| peek->type == CPP_COLON
- || (header_count
- ? (peek->type == CPP_LESS
- || (peek->type == CPP_STRING && peek->val.str.text[0] != 'R')
- || peek->type == CPP_HEADER_NAME)
+ || (header_count
+ ? (peek->type == CPP_LESS
+ || (peek->type == CPP_STRING && peek->val.str.text[0] != 'R')
+ || peek->type == CPP_HEADER_NAME)
: peek->type == CPP_SEMICOLON))
{
pfile->state.pragma_allow_expansion = !CPP_OPTION (pfile, preprocessed);
@@ -3678,6 +3678,9 @@ cpp_maybe_module_directive (cpp_reader *
}
while (true);
}
+ if (backup)
+ /* Put the peeked tokens back. */
+ _cpp_backup_tokens_direct (pfile, backup);
}
else
{
@@ -3689,21 +3692,19 @@ cpp_maybe_module_directive (cpp_reader *
pfile->state.in_deferred_pragma = false;
/* Do not let this remain on. */
pfile->state.angled_headers = false;
- }
-
- /* In either case we want to backup the peeked tokens. */
- if (backup)
- {
- /* If we saw EOL, we should drop it, because this isn't a module
- control-line after all. */
- bool eol = peek->type == CPP_PRAGMA_EOL;
- if (!eol || backup > 1)
+ if (backup)
{
- /* Put put the peeked tokens back */
- _cpp_backup_tokens_direct (pfile, backup);
- /* But if the last one was an EOL, forget it. */
- if (eol)
- pfile->lookaheads--;
+ /* If we saw EOL, we should drop it, because this isn't a module
+ control-line after all. */
+ bool eol = peek->type == CPP_PRAGMA_EOL;
+ if (!eol || backup > 1)
+ {
+ /* Put the peeked tokens back. */
+ _cpp_backup_tokens_direct (pfile, backup);
+ /* But if the last one was an EOL, forget it. */
+ if (eol)
+ pfile->lookaheads--;
+ }
}
}
}
--- gcc/testsuite/g++.dg/modules/cpp-21.C.jj 2025-06-27 12:34:17.226227463
+0200
+++ gcc/testsuite/g++.dg/modules/cpp-21.C 2025-06-27 12:34:28.052088809
+0200
@@ -0,0 +1,8 @@
+// PR c++/120845
+// { dg-do compile }
+// { dg-additional-options "-fmodules" }
+
+export module pr120485
+ [[foobarbaz]];
+// { dg-error "expected ';' before end of line" "" { target *-*-* } .-2 }
+// { dg-warning "attribute ignored" "" { target *-*-* } .-2 }
Jakub