<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gcc.git/libcpp/macro.cc, branch master</title>
<subtitle>Unnamed repository; edit this file 'description' to name the repository.
</subtitle>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/'/>
<entry>
<title>c: Implement C2Y N3457 - The __COUNTER__ predefined macro</title>
<updated>2025-09-01T19:55:49+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-09-01T19:55:49+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=a4d066f3643d3df5929425767130d68e8a775241'/>
<id>a4d066f3643d3df5929425767130d68e8a775241</id>
<content type='text'>
The following patch implements the
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3457.htm
paper without the first 3 lines in Recommended practice.
Seems GCC behavior already matches the expected behavior except for
diagnostics of more than 2147483648 __COUNTER__ expansions, so the
patch adds a diagnostic for that (but not testcase because
 #define A __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__
 #define B A A A A A A A A
 #define C B B B B B B B B
 #define D C C C C C C C C
 #define E D D D D D D D D
 #define F E E E E E E E E
 #define G F F F F F F F F
 #define H G G G G G G G G
 #define I H H H H H H H H
 #define J I I I I I I I I
 J J J J
 __COUNTER__
just takes too long to preprocess).
Plus I've included all the snippets from the paper into one testcase.

2025-09-01  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	* macro.cc: Implement C2Y N3457 - The __COUNTER__ predefined macro.
	(_cpp_builtin_macro_text): Diagnose if __COUNTER__ reaches
	2147483648 value.

	* gcc.dg/cpp/c2y-counter-1.c: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following patch implements the
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n3457.htm
paper without the first 3 lines in Recommended practice.
Seems GCC behavior already matches the expected behavior except for
diagnostics of more than 2147483648 __COUNTER__ expansions, so the
patch adds a diagnostic for that (but not testcase because
 #define A __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__ __COUNTER__
 #define B A A A A A A A A
 #define C B B B B B B B B
 #define D C C C C C C C C
 #define E D D D D D D D D
 #define F E E E E E E E E
 #define G F F F F F F F F
 #define H G G G G G G G G
 #define I H H H H H H H H
 #define J I I I I I I I I
 J J J J
 __COUNTER__
just takes too long to preprocess).
Plus I've included all the snippets from the paper into one testcase.

2025-09-01  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	* macro.cc: Implement C2Y N3457 - The __COUNTER__ predefined macro.
	(_cpp_builtin_macro_text): Diagnose if __COUNTER__ reaches
	2147483648 value.

	* gcc.dg/cpp/c2y-counter-1.c: New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Warn on #undef/#define of remaining cpp.predefined macros [PR120778]</title>
<updated>2025-08-15T20:31:27+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-15T20:31:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=cdd015c4ddbb1ae71eea1e44654cee5ca29a6c64'/>
<id>cdd015c4ddbb1ae71eea1e44654cee5ca29a6c64</id>
<content type='text'>
We already warn on #undef or pedwarn on #define (but not on #define
after #undef) of some builtin macros mentioned in cpp.predefined.

The C++26 P2843R3 paper changes it from (compile time) undefined behavior
to ill-formed.  The following patch arranges for warning (for #undef)
and pedwarn (on #define) for the remaining cpp.predefined macros.
__cpp_* feature test macros only for C++20 which added some of them
to cpp.predefined, in earlier C++ versions it was just an extension and
for pedantic diagnostic I think we don't need to diagnose anything,
__STDCPP_* and __cplusplus macros for all C++ versions where they appeared.

Like the earlier posted -Wkeyword-macro diagnostics (which is done
regardless whether the identifier is defined as a macro or not, obviously
most likely none of the keywords are defined as macros initially), this
one also warns on #undef when a macro isn't defined or later #define
after #undef.

2025-08-15  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
	PR target/121520
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Implement C++26 DR 2581.  Add
	cpp_define_warn lambda and use it as well as cpp_warn where needed.
	In the if (c_dialect_cxx ()) block with __cpp_* predefinitions add
	cpp_define lambda.  Formatting fixes.
gcc/c/
	* c-decl.cc (c_init_decl_processing): Use cpp_warn instead of
	cpp_lookup and NODE_WARN bit setting.
gcc/cp/
	* lex.cc (cxx_init): Remove warn_on lambda.  Use cpp_warn instead of
	cpp_lookup and NODE_WARN bit setting or warn_on.
gcc/testsuite/
	* g++.dg/DRs/dr2581-1.C: New test.
	* g++.dg/DRs/dr2581-2.C: New test.
	* c-c++-common/cpp/pr92296-2.c: Expect warnings also on defining
	special macros after undefining them.
libcpp/
	* include/cpplib.h (struct cpp_options): Add
	suppress_builtin_macro_warnings member.
	(cpp_warn): New inline functions.
	* init.cc (cpp_create_reader): Clear suppress_builtin_macro_warnings.
	(cpp_init_builtins): Call cpp_warn on __cplusplus, __STDC__,
	__STDC_VERSION__, __STDC_MB_MIGHT_NEQ_WC__ and
	__STDCPP_STRICT_POINTER_SAFETY__ when appropriate.
	* directives.cc (do_undef): Warn on undefining NODE_WARN macros if
	not cpp_keyword_p.  Don't emit any NODE_WARN related diagnostics
	if CPP_OPTION (pfile, suppress_builtin_macro_warnings).
	(cpp_define, _cpp_define_builtin, cpp_undef): Temporarily set
	CPP_OPTION (pfile, suppress_builtin_macro_warnings) around
	run_directive calls.
	* macro.cc (_cpp_create_definition): Warn on defining NODE_WARN
	macros if they weren't previously defined and not cpp_keyword_p.
	Ignore NODE_WARN for diagnostics if
	CPP_OPTION (pfile, suppress_builtin_macro_warnings).
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We already warn on #undef or pedwarn on #define (but not on #define
after #undef) of some builtin macros mentioned in cpp.predefined.

The C++26 P2843R3 paper changes it from (compile time) undefined behavior
to ill-formed.  The following patch arranges for warning (for #undef)
and pedwarn (on #define) for the remaining cpp.predefined macros.
__cpp_* feature test macros only for C++20 which added some of them
to cpp.predefined, in earlier C++ versions it was just an extension and
for pedantic diagnostic I think we don't need to diagnose anything,
__STDCPP_* and __cplusplus macros for all C++ versions where they appeared.

Like the earlier posted -Wkeyword-macro diagnostics (which is done
regardless whether the identifier is defined as a macro or not, obviously
most likely none of the keywords are defined as macros initially), this
one also warns on #undef when a macro isn't defined or later #define
after #undef.

2025-08-15  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
	PR target/121520
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Implement C++26 DR 2581.  Add
	cpp_define_warn lambda and use it as well as cpp_warn where needed.
	In the if (c_dialect_cxx ()) block with __cpp_* predefinitions add
	cpp_define lambda.  Formatting fixes.
gcc/c/
	* c-decl.cc (c_init_decl_processing): Use cpp_warn instead of
	cpp_lookup and NODE_WARN bit setting.
gcc/cp/
	* lex.cc (cxx_init): Remove warn_on lambda.  Use cpp_warn instead of
	cpp_lookup and NODE_WARN bit setting or warn_on.
gcc/testsuite/
	* g++.dg/DRs/dr2581-1.C: New test.
	* g++.dg/DRs/dr2581-2.C: New test.
	* c-c++-common/cpp/pr92296-2.c: Expect warnings also on defining
	special macros after undefining them.
libcpp/
	* include/cpplib.h (struct cpp_options): Add
	suppress_builtin_macro_warnings member.
	(cpp_warn): New inline functions.
	* init.cc (cpp_create_reader): Clear suppress_builtin_macro_warnings.
	(cpp_init_builtins): Call cpp_warn on __cplusplus, __STDC__,
	__STDC_VERSION__, __STDC_MB_MIGHT_NEQ_WC__ and
	__STDCPP_STRICT_POINTER_SAFETY__ when appropriate.
	* directives.cc (do_undef): Warn on undefining NODE_WARN macros if
	not cpp_keyword_p.  Don't emit any NODE_WARN related diagnostics
	if CPP_OPTION (pfile, suppress_builtin_macro_warnings).
	(cpp_define, _cpp_define_builtin, cpp_undef): Temporarily set
	CPP_OPTION (pfile, suppress_builtin_macro_warnings) around
	run_directive calls.
	* macro.cc (_cpp_create_definition): Warn on defining NODE_WARN
	macros if they weren't previously defined and not cpp_keyword_p.
	Ignore NODE_WARN for diagnostics if
	CPP_OPTION (pfile, suppress_builtin_macro_warnings).
</pre>
</div>
</content>
</entry>
<entry>
<title>c++, c: Introduce -Wkeyword-macro warning/pedwarn - part of C++26 P2843R3 [PR120778]</title>
<updated>2025-08-07T06:47:44+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-07T06:47:44+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=64859dc6e2948616439b500b5d9ffb2635b45ae8'/>
<id>64859dc6e2948616439b500b5d9ffb2635b45ae8</id>
<content type='text'>
The following patch introduces a -Wkeyword-macro warning that clang has
since 2014 to implement part of C++26 P2843R3 Preprocessing is never undefined
paper.
The relevant change in the paper is moving [macro.names]/2 paragraph to
https://eel.is/c++draft/cpp.replace.general#9 :
"A translation unit shall not #define or #undef names lexically identical to
keywords, to the identifiers listed in Table 4, or to the attribute-tokens
described in [dcl.attr], except that the names likely and unlikely may be
defined as function-like macros."

Now, my understanding of the paper is that in [macro.names] and surrounding
sections the word shall bears different meaning from [cpp.replace.general],
where only the latter location implies ill-formed, diagnostic required.

The warning in clang when introduced diagnosed all #define/#undef directives
on keywords, but shortly after introduction has been changed not to
diagnose #undef at all (with "#undef a keyword is generally harmless but used
often in configuration scripts" message) and later on even the #define
part tweaked - not warn about say
  #define inline
(or const, extern, static), or
  #define keyword keyword
or
  #define keyword __keyword
or
  #define keyword __keyword__
Later on the warning has been moved to be only pedantic diagnostic unless
requested by users.  Clearly some code in the wild does e.g.
  #define private public
and similar games, or e.g. Linux kernel (sure, C) does
  #define inline __inline__ __attribute__((__always_inline__))
etc.
Now, I believe at least with the current C++26 wording such exceptions
aren't allowed (unless it is changed to IFNDR).  But given that this is just
pedantic stuff, the following patch makes the warning off by default for
C and C++ before C++26 and even for C++26 it enables it by default only
if -pedantic/-pedantic-errors (in that case it pedwarns, otherwise it
warns).  And it diagnoses both #define and #undef without exceptions.

From what I can see, all the current NODE_WARN cases are macros starting
with __ with one exception (_Pragma).  As the NODE_* flags seem to be a
limited resource, I chose to just use NODE_WARN as well and differentiate
on the node names (if they don't start with __ or _P, they are considered
to be -Wkeyword-macro registered ones, otherwise old NODE_WARN cases,
typically builtin macros or __STDC* macros).

2025-08-07  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
gcc/
	* doc/invoke.texi (Wkeyword-macro): Document.
gcc/c-family/
	* c.opt (Wkeyword-macro): New option.
	* c.opt.urls: Regenerate.
	* c-common.h (cxx_dialect): Comment formatting fix.
	* c-opts.cc (c_common_post_options): Default to
	-Wkeyword-macro for C++26 if pedantic.
gcc/c/
	* c-decl.cc (c_init_decl_processing): Mark cpp nodes corresponding
	to keywords as NODE_WARN if warn_keyword_macro.
gcc/cp/
	* lex.cc (cxx_init): Mark cpp nodes corresponding
	to keywords, identifiers with special meaning and standard
	attribute identifiers as NODE_WARN if warn_keyword_macro.
gcc/testsuite/
	* gcc.dg/Wkeyword-macro-1.c: New test.
	* gcc.dg/Wkeyword-macro-2.c: New test.
	* gcc.dg/Wkeyword-macro-3.c: New test.
	* gcc.dg/Wkeyword-macro-4.c: New test.
	* gcc.dg/Wkeyword-macro-5.c: New test.
	* gcc.dg/Wkeyword-macro-6.c: New test.
	* gcc.dg/Wkeyword-macro-7.c: New test.
	* gcc.dg/Wkeyword-macro-8.c: New test.
	* gcc.dg/Wkeyword-macro-9.c: New test.
	* g++.dg/warn/Wkeyword-macro-1.C: New test.
	* g++.dg/warn/Wkeyword-macro-2.C: New test.
	* g++.dg/warn/Wkeyword-macro-3.C: New test.
	* g++.dg/warn/Wkeyword-macro-4.C: New test.
	* g++.dg/warn/Wkeyword-macro-5.C: New test.
	* g++.dg/warn/Wkeyword-macro-6.C: New test.
	* g++.dg/warn/Wkeyword-macro-7.C: New test.
	* g++.dg/warn/Wkeyword-macro-8.C: New test.
	* g++.dg/warn/Wkeyword-macro-9.C: New test.
	* g++.dg/warn/Wkeyword-macro-10.C: New test.
	* g++.dg/opt/pr82577.C: Don't #define register to nothing for
	C++17 and later.  Instead define reg macro to nothing for C++17
	and later or to register and use it instead of register.
	* g++.dg/modules/atom-preamble-3.C: Add -Wno-keyword-macro to
	dg-additional-options.
	* g++.dg/template/sfinae17.C (static_assert): Rename macro to ...
	(my_static_assert): ... this.
	(main): Use my_static_assert instead of static_assert.
libcpp/
	* include/cpplib.h (struct cpp_options): Add cpp_warn_keyword_macro.
	(enum cpp_warning_reason): Add CPP_W_KEYWORD_MACRO enumerator.
	(cpp_keyword_p): New inline function.
	* directives.cc (do_undef): Support -Wkeyword-macro diagnostics.
	* macro.cc (warn_of_redefinition): Ignore NODE_WARN flag on nodes
	registered for -Wkeyword-macro.
	(_cpp_create_definition): Support -Wkeyword-macro diagnostics.
	Formatting fixes.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following patch introduces a -Wkeyword-macro warning that clang has
since 2014 to implement part of C++26 P2843R3 Preprocessing is never undefined
paper.
The relevant change in the paper is moving [macro.names]/2 paragraph to
https://eel.is/c++draft/cpp.replace.general#9 :
"A translation unit shall not #define or #undef names lexically identical to
keywords, to the identifiers listed in Table 4, or to the attribute-tokens
described in [dcl.attr], except that the names likely and unlikely may be
defined as function-like macros."

Now, my understanding of the paper is that in [macro.names] and surrounding
sections the word shall bears different meaning from [cpp.replace.general],
where only the latter location implies ill-formed, diagnostic required.

The warning in clang when introduced diagnosed all #define/#undef directives
on keywords, but shortly after introduction has been changed not to
diagnose #undef at all (with "#undef a keyword is generally harmless but used
often in configuration scripts" message) and later on even the #define
part tweaked - not warn about say
  #define inline
(or const, extern, static), or
  #define keyword keyword
or
  #define keyword __keyword
or
  #define keyword __keyword__
Later on the warning has been moved to be only pedantic diagnostic unless
requested by users.  Clearly some code in the wild does e.g.
  #define private public
and similar games, or e.g. Linux kernel (sure, C) does
  #define inline __inline__ __attribute__((__always_inline__))
etc.
Now, I believe at least with the current C++26 wording such exceptions
aren't allowed (unless it is changed to IFNDR).  But given that this is just
pedantic stuff, the following patch makes the warning off by default for
C and C++ before C++26 and even for C++26 it enables it by default only
if -pedantic/-pedantic-errors (in that case it pedwarns, otherwise it
warns).  And it diagnoses both #define and #undef without exceptions.

From what I can see, all the current NODE_WARN cases are macros starting
with __ with one exception (_Pragma).  As the NODE_* flags seem to be a
limited resource, I chose to just use NODE_WARN as well and differentiate
on the node names (if they don't start with __ or _P, they are considered
to be -Wkeyword-macro registered ones, otherwise old NODE_WARN cases,
typically builtin macros or __STDC* macros).

2025-08-07  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
gcc/
	* doc/invoke.texi (Wkeyword-macro): Document.
gcc/c-family/
	* c.opt (Wkeyword-macro): New option.
	* c.opt.urls: Regenerate.
	* c-common.h (cxx_dialect): Comment formatting fix.
	* c-opts.cc (c_common_post_options): Default to
	-Wkeyword-macro for C++26 if pedantic.
gcc/c/
	* c-decl.cc (c_init_decl_processing): Mark cpp nodes corresponding
	to keywords as NODE_WARN if warn_keyword_macro.
gcc/cp/
	* lex.cc (cxx_init): Mark cpp nodes corresponding
	to keywords, identifiers with special meaning and standard
	attribute identifiers as NODE_WARN if warn_keyword_macro.
gcc/testsuite/
	* gcc.dg/Wkeyword-macro-1.c: New test.
	* gcc.dg/Wkeyword-macro-2.c: New test.
	* gcc.dg/Wkeyword-macro-3.c: New test.
	* gcc.dg/Wkeyword-macro-4.c: New test.
	* gcc.dg/Wkeyword-macro-5.c: New test.
	* gcc.dg/Wkeyword-macro-6.c: New test.
	* gcc.dg/Wkeyword-macro-7.c: New test.
	* gcc.dg/Wkeyword-macro-8.c: New test.
	* gcc.dg/Wkeyword-macro-9.c: New test.
	* g++.dg/warn/Wkeyword-macro-1.C: New test.
	* g++.dg/warn/Wkeyword-macro-2.C: New test.
	* g++.dg/warn/Wkeyword-macro-3.C: New test.
	* g++.dg/warn/Wkeyword-macro-4.C: New test.
	* g++.dg/warn/Wkeyword-macro-5.C: New test.
	* g++.dg/warn/Wkeyword-macro-6.C: New test.
	* g++.dg/warn/Wkeyword-macro-7.C: New test.
	* g++.dg/warn/Wkeyword-macro-8.C: New test.
	* g++.dg/warn/Wkeyword-macro-9.C: New test.
	* g++.dg/warn/Wkeyword-macro-10.C: New test.
	* g++.dg/opt/pr82577.C: Don't #define register to nothing for
	C++17 and later.  Instead define reg macro to nothing for C++17
	and later or to register and use it instead of register.
	* g++.dg/modules/atom-preamble-3.C: Add -Wno-keyword-macro to
	dg-additional-options.
	* g++.dg/template/sfinae17.C (static_assert): Rename macro to ...
	(my_static_assert): ... this.
	(main): Use my_static_assert instead of static_assert.
libcpp/
	* include/cpplib.h (struct cpp_options): Add cpp_warn_keyword_macro.
	(enum cpp_warning_reason): Add CPP_W_KEYWORD_MACRO enumerator.
	(cpp_keyword_p): New inline function.
	* directives.cc (do_undef): Support -Wkeyword-macro diagnostics.
	* macro.cc (warn_of_redefinition): Ignore NODE_WARN flag on nodes
	registered for -Wkeyword-macro.
	(_cpp_create_definition): Support -Wkeyword-macro diagnostics.
	Formatting fixes.
</pre>
</div>
</content>
</entry>
<entry>
<title>libcpp: Add testcase for CWG2579 [PR120778]</title>
<updated>2025-08-05T06:21:55+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-05T06:21:55+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=ab7c16990fca6b456156895d8d0d5e1a37476d38'/>
<id>ab7c16990fca6b456156895d8d0d5e1a37476d38</id>
<content type='text'>
Another easy part from the paper.

Part of the CWG2579 has been already done in an earlier paper (with
test commits by Marek) and the remaining part is implemented correctly,
we diagnose as error when token pasting doesn't form a valid token.

Except that message
pasting """" and """" does not give a valid preprocessing token
looked weird and so I've updated the message to use %&lt; and %&gt; instead
of \" quoting.

2025-08-05  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
	* macro.cc (paste_tokens): Use %&lt; and %&gt; instead of \" in
	diagnostics around %.*s.

	* g++.dg/DRs/dr2579.C: New test.
	* c-c++-common/cpp/va-opt-6.c: Expect ' rather than \" around
	tokens in incorrect pasting diagnostics.
	* gcc.dg/c23-attr-syntax-6.c: Likewise.
	* gcc.dg/cpp/paste12.c: Likewise.
	* gcc.dg/cpp/paste12-2.c: Likewise.
	* gcc.dg/cpp/paste14.c: Likewise.
	* gcc.dg/cpp/paste14-2.c: Likewise.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Another easy part from the paper.

Part of the CWG2579 has been already done in an earlier paper (with
test commits by Marek) and the remaining part is implemented correctly,
we diagnose as error when token pasting doesn't form a valid token.

Except that message
pasting """" and """" does not give a valid preprocessing token
looked weird and so I've updated the message to use %&lt; and %&gt; instead
of \" quoting.

2025-08-05  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
	* macro.cc (paste_tokens): Use %&lt; and %&gt; instead of \" in
	diagnostics around %.*s.

	* g++.dg/DRs/dr2579.C: New test.
	* c-c++-common/cpp/va-opt-6.c: Expect ' rather than \" around
	tokens in incorrect pasting diagnostics.
	* gcc.dg/c23-attr-syntax-6.c: Likewise.
	* gcc.dg/cpp/paste12.c: Likewise.
	* gcc.dg/cpp/paste12-2.c: Likewise.
	* gcc.dg/cpp/paste14.c: Likewise.
	* gcc.dg/cpp/paste14-2.c: Likewise.
</pre>
</div>
</content>
</entry>
<entry>
<title>libcpp: Use pedwarn instead of warning for CWG2578 diagnostics [PR120778]</title>
<updated>2025-08-04T12:27:14+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-04T12:27:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=b9f443b6177881c490fbce9ba65b86a7cd65f11f'/>
<id>b9f443b6177881c490fbce9ba65b86a7cd65f11f</id>
<content type='text'>
This is another case which changed from compile time undefined behavior
to ill-formed, diagnostic required.  Now, we warn on this, so pedantically
that is good enough, maybe all we need is a testcase, but the following
patch changes it to a pedwarn for C++26.

2025-08-04  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
	* macro.cc (stringify_arg): For C++26 emit a pedarn instead of warning
	for \ at the end of stringification.

	* g++.dg/DRs/dr2578.C: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is another case which changed from compile time undefined behavior
to ill-formed, diagnostic required.  Now, we warn on this, so pedantically
that is good enough, maybe all we need is a testcase, but the following
patch changes it to a pedwarn for C++26.

2025-08-04  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/120778
	* macro.cc (stringify_arg): For C++26 emit a pedarn instead of warning
	for \ at the end of stringification.

	* g++.dg/DRs/dr2578.C: New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>libcpp: Fix error recovery after use of __VA_ARGS__ as macro argument [PR118674]</title>
<updated>2025-04-09T10:27:38+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-04-09T10:27:38+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=6e77a83ffbe4253c306b5b3750cf4ee38e5ce071'/>
<id>6e77a83ffbe4253c306b5b3750cf4ee38e5ce071</id>
<content type='text'>
The following testcase ICEs after emitting one pedwarn (about using
__VA_ARGS__ in a place where it shouldn't be used) and one error.
The error is emitted by _cpp_save_parameter where it sees the node
has been used already earlier.  But unlike the other _cpp_save_parameter
caller which does goto out; if it returns false, this call with explicit
__VA_ARGS__ doesn't and if it increments number of parameters etc. after
the error, we then try to unsave it twice.

The following patch fixes it by doing the goto out in that case too,
the macro will then not be considered as variable arguments macro,
but for error recovery I think that is fine.
The other option would be before the other _cpp_save_parameter caller
check if the node is pfile-&gt;spec_nodes.n__VA_ARGS__ and in that case
also error and goto out, but that seems more expensive than this for
the common case that the macro definition is correct.

2025-04-09  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/118674
	* macro.cc (parse_params) &lt;case CPP_ELLIPSIS&gt;: If _cpp_save_parameter
	failed for __VA_ARGS__, goto out.

	* gcc.dg/cpp/pr118674.c: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following testcase ICEs after emitting one pedwarn (about using
__VA_ARGS__ in a place where it shouldn't be used) and one error.
The error is emitted by _cpp_save_parameter where it sees the node
has been used already earlier.  But unlike the other _cpp_save_parameter
caller which does goto out; if it returns false, this call with explicit
__VA_ARGS__ doesn't and if it increments number of parameters etc. after
the error, we then try to unsave it twice.

The following patch fixes it by doing the goto out in that case too,
the macro will then not be considered as variable arguments macro,
but for error recovery I think that is fine.
The other option would be before the other _cpp_save_parameter caller
check if the node is pfile-&gt;spec_nodes.n__VA_ARGS__ and in that case
also error and goto out, but that seems more expensive than this for
the common case that the macro definition is correct.

2025-04-09  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR preprocessor/118674
	* macro.cc (parse_params) &lt;case CPP_ELLIPSIS&gt;: If _cpp_save_parameter
	failed for __VA_ARGS__, goto out.

	* gcc.dg/cpp/pr118674.c: New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>Update copyright years.</title>
<updated>2025-01-02T10:59:57+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-01-02T10:59:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=6441eb6dc020faae0672ea724dfdb38c6a9bf6a1'/>
<id>6441eb6dc020faae0672ea724dfdb38c6a9bf6a1</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>libcpp: Fix overly large buffer allocation</title>
<updated>2024-12-24T01:24:30+00:00</updated>
<author>
<name>Lewis Hyatt</name>
<email>lhyatt@gmail.com</email>
</author>
<published>2024-10-22T19:23:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=27af1a14f3a0c897f5da3fc36cd2f9fe5ca4b0ed'/>
<id>27af1a14f3a0c897f5da3fc36cd2f9fe5ca4b0ed</id>
<content type='text'>
It seems that tokens_buff_new() has always been allocating the virtual
location buffer 4 times larger than intended, and now that location_t is
64-bit, it is 8 times larger. Fixed.

libcpp/ChangeLog:

	* macro.cc (tokens_buff_new): Fix length argument to XNEWVEC.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
It seems that tokens_buff_new() has always been allocating the virtual
location buffer 4 times larger than intended, and now that location_t is
64-bit, it is 8 times larger. Fixed.

libcpp/ChangeLog:

	* macro.cc (tokens_buff_new): Fix length argument to XNEWVEC.
</pre>
</div>
</content>
</entry>
<entry>
<title>Support for 64-bit location_t: libcpp preliminaries</title>
<updated>2024-11-23T18:44:37+00:00</updated>
<author>
<name>Lewis Hyatt</name>
<email>lhyatt@gmail.com</email>
</author>
<published>2024-10-28T17:19:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=927625d007f47377a091d541de42c7840a4a5af6'/>
<id>927625d007f47377a091d541de42c7840a4a5af6</id>
<content type='text'>
Prepare libcpp to support 64-bit location_t, without yet making
any functional changes, by adding new typedefs that enable code to be
written such that it works with any size location_t. Update the usage of
line maps within libcpp accordingly.

Subsequent patches will prepare the rest of the codebase similarly, and then
afterwards, location_t will be changed to uint64_t.

libcpp/ChangeLog:

	* include/line-map.h (line_map_uint_t): New typedef, the same type
	as location_t.
	(location_diff_t): New typedef.
	(line_map_suggested_range_bits): New constant.
	(struct maps_info_ordinary): Change member types from "unsigned int"
	to "line_map_uint_t".
	(struct maps_info_macro): Likewise.
	(struct location_adhoc_data_map): Likewise.
	(LINEMAPS_ALLOCATED): Change return type from "unsigned int" to
	"line_map_uint_t".
	(LINEMAPS_ORDINARY_ALLOCATED): Likewise.
	(LINEMAPS_MACRO_ALLOCATED): Likewise.
	(LINEMAPS_USED): Likewise.
	(LINEMAPS_ORDINARY_USED): Likewise.
	(LINEMAPS_MACRO_USED): Likewise.
	(linemap_lookup_macro_index): Likewise.
	(LINEMAPS_MAP_AT): Change argument type from "unsigned int" to
	"line_map_uint_t".
	(LINEMAPS_ORDINARY_MAP_AT): Likewise.
	(LINEMAPS_MACRO_MAP_AT): Likewise.
	(line_map_new_raw): Likewise.
	(linemap_module_restore): Likewise.
	(linemap_dump): Likewise.
	(line_table_dump): Likewise.
	(LINEMAPS_LAST_MAP): Add a linemap_assert() for safety.
	(SOURCE_COLUMN): Use a cast to ensure correctness if location_t
	becomes a 64-bit type.
	* line-map.cc (location_adhoc_data_hash): Don't truncate to 32-bit
	prematurely when hashing.
	(line_maps::get_or_create_combined_loc): Adapt types to support
	potentially 64-bit location_t. Use MAX_LOCATION_T rather than a
	hard-coded constant.
	(line_maps::get_range_from_loc): Adapt types and constants to
	support potentially 64-bit location_t.
	(line_maps::pure_location_p): Likewise.
	(line_maps::get_pure_location): Likewise.
	(line_map_new_raw): Likewise.
	(LAST_SOURCE_LINE_LOCATION): Likewise.
	(linemap_add): Likewise.
	(linemap_module_restore): Likewise.
	(linemap_line_start): Likewise.
	(linemap_position_for_column): Likewise.
	(linemap_position_for_line_and_column): Likewise.
	(linemap_position_for_loc_and_offset): Likewise.
	(linemap_ordinary_map_lookup): Likewise.
	(linemap_lookup_macro_index): Likewise.
	(linemap_dump): Likewise.
	(linemap_dump_location): Likewise.
	(linemap_get_file_highest_location): Likewise.
	(line_table_dump): Likewise.
	(linemap_compare_locations): Avoid signed int overflow in the result.
	* macro.cc (num_expanded_macros_counter): Change type of global
	variable from "unsigned int" to "line_map_uint_t".
	(num_macro_tokens_counter): Likewise.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Prepare libcpp to support 64-bit location_t, without yet making
any functional changes, by adding new typedefs that enable code to be
written such that it works with any size location_t. Update the usage of
line maps within libcpp accordingly.

Subsequent patches will prepare the rest of the codebase similarly, and then
afterwards, location_t will be changed to uint64_t.

libcpp/ChangeLog:

	* include/line-map.h (line_map_uint_t): New typedef, the same type
	as location_t.
	(location_diff_t): New typedef.
	(line_map_suggested_range_bits): New constant.
	(struct maps_info_ordinary): Change member types from "unsigned int"
	to "line_map_uint_t".
	(struct maps_info_macro): Likewise.
	(struct location_adhoc_data_map): Likewise.
	(LINEMAPS_ALLOCATED): Change return type from "unsigned int" to
	"line_map_uint_t".
	(LINEMAPS_ORDINARY_ALLOCATED): Likewise.
	(LINEMAPS_MACRO_ALLOCATED): Likewise.
	(LINEMAPS_USED): Likewise.
	(LINEMAPS_ORDINARY_USED): Likewise.
	(LINEMAPS_MACRO_USED): Likewise.
	(linemap_lookup_macro_index): Likewise.
	(LINEMAPS_MAP_AT): Change argument type from "unsigned int" to
	"line_map_uint_t".
	(LINEMAPS_ORDINARY_MAP_AT): Likewise.
	(LINEMAPS_MACRO_MAP_AT): Likewise.
	(line_map_new_raw): Likewise.
	(linemap_module_restore): Likewise.
	(linemap_dump): Likewise.
	(line_table_dump): Likewise.
	(LINEMAPS_LAST_MAP): Add a linemap_assert() for safety.
	(SOURCE_COLUMN): Use a cast to ensure correctness if location_t
	becomes a 64-bit type.
	* line-map.cc (location_adhoc_data_hash): Don't truncate to 32-bit
	prematurely when hashing.
	(line_maps::get_or_create_combined_loc): Adapt types to support
	potentially 64-bit location_t. Use MAX_LOCATION_T rather than a
	hard-coded constant.
	(line_maps::get_range_from_loc): Adapt types and constants to
	support potentially 64-bit location_t.
	(line_maps::pure_location_p): Likewise.
	(line_maps::get_pure_location): Likewise.
	(line_map_new_raw): Likewise.
	(LAST_SOURCE_LINE_LOCATION): Likewise.
	(linemap_add): Likewise.
	(linemap_module_restore): Likewise.
	(linemap_line_start): Likewise.
	(linemap_position_for_column): Likewise.
	(linemap_position_for_line_and_column): Likewise.
	(linemap_position_for_loc_and_offset): Likewise.
	(linemap_ordinary_map_lookup): Likewise.
	(linemap_lookup_macro_index): Likewise.
	(linemap_dump): Likewise.
	(linemap_dump_location): Likewise.
	(linemap_get_file_highest_location): Likewise.
	(line_table_dump): Likewise.
	(linemap_compare_locations): Avoid signed int overflow in the result.
	* macro.cc (num_expanded_macros_counter): Change type of global
	variable from "unsigned int" to "line_map_uint_t".
	(num_macro_tokens_counter): Likewise.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Attempt to implement C++26 P3034R1 - Module Declarations Shouldn't be Macros [PR114461]</title>
<updated>2024-11-01T18:42:28+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2024-11-01T18:42:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=1ae24f7e0bdbdeaef9265a053a737af11f8393d2'/>
<id>1ae24f7e0bdbdeaef9265a053a737af11f8393d2</id>
<content type='text'>
This is an attempt to implement the https://wg21.link/p3034r1 paper,
but I'm afraid the wording in the paper is bad for multiple reasons.
I think I understand the intent, that the module name and partition
if any shouldn't come from macros so that they can be scanned for
without preprocessing, but on the other side doesn't want to disable
macro expansion in pp-module altogether, because e.g. the optional
attribute in module-declaration would be nice to come from macros
as which exact attribute is needed might need to be decided based on
preprocessor checks.
The paper added https://eel.is/c++draft/cpp.module#2
which uses partly the wording from https://eel.is/c++draft/cpp.module#1

The first issue I see is that using that "defined as an object-like macro"
from there means IMHO something very different in those 2 paragraphs.
As per https://eel.is/c++draft/cpp.pre#7.sentence-1 preprocessing tokens
in preprocessing directives aren't subject to macro expansion unless
otherwise stated, and so the export and module tokens aren't expanded
and so the requirement that they aren't defined as an object-like macro
makes perfect sense.  The problem with the new paragraph is that
https://eel.is/c++draft/cpp.module#3.sentence-1 says that the rest of
the tokens are macro expanded and after macro expansion none of the
tokens can be defined as an object-like macro, if they would be, they'd
be expanded to that.  So, I think either the wording needs to change
such that not all preprocessing tokens after module are macro expanded,
only those which are after the pp-module-name and if any pp-module-partition
tokens, or all tokens after module are macro expanded but none of the tokens in
pp-module-name and pp-module-partition if any must come from macro
expansion.  The patch below implements it as if the former would be
specified (but see later), so essentially scans the preprocessing tokens
after module without expansion, if the first one is an identifier, it
disables expansion for it and then if followed by . or : expects another
such identifier (again with disabled expansion), but stops after second
: is seen.

Second issue is that while the global-module-fragment start is fine, matches
the syntax of the new paragraph where the pp-tokens[opt] aren't present,
there is also private-module-fragment in the syntax where module is
followed by : private ; and in that case the colon doesn't match the
pp-module-name grammar and appears now to be invalid.  I think the
https://eel.is/c++draft/cpp.module#2
paragraph needs to change so that it allows also that pp-tokens of
a pp-module may also be : pp-tokens[opt] (and in that case, I think
the colon shouldn't come from a macro and private and/or ; can).

Third issue is that there are too many pp-tokens in
https://eel.is/c++draft/cpp.module , one is all the tokens between
module keyword and the semicolon and one is the optional extra tokens
after pp-module-partition (if any, if missing, after pp-module).
Perhaps introducing some other non-terminal would help talking about it?
So in "where the pp-tokens (if any) shall not begin with a ( preprocessing
token" it isn't obvious which pp-tokens it is talking about (my assumption
is the latter) and also whether ( can't appear there just before macro
expansion or also after expansion.  The patch expects only before expansion,
so
 #define F ();
 export module foo F
would be valid during preprocessing but obviously invalid during
compilation, but
 #define foo(n) n;
 export module foo (3)
would be invalid already during preprocessing.

The last issue applies only if the first issue is resolved to allow
expansion of tokens after : if first token, or after pp-module-partition
if present or after pp-module-name if present.  When non-preprocessing
scanner sees
 export module foo.bar:baz.qux;
it knows nothing can come from preprocessing macros and is ok, but if it
sees
 export module foo.bar:baz qux
then it can't know whether it will be
 export module foo.bar:baz;
or
 export module foo.bar:baz [[]];
or
 export module foo.bar:baz.freddy.garply;
because qux could be validly a macro, which expands to ; or [[]];
or .freddy.garply; etc.  So, either the non-preprocessing scanner would
need to note it as possible export of foo.bar:baz* module partitions
and preprocess if it needs to know the details or just compile, or if that
is not ok, the wording would need to rule out that the expansion of (the
second) pp-tokens if any can't start with . or : (colon would be only
problematic if it isn't present in the tokens before it already).
So, if e.g. defining qux above to . whatever is invalid, then the scanner
can rely it sees the whole module name and partition.

The patch below implements what is above described as the first variant
of the first issue resolution, i.e. disables expansion of as many tokens
as could be in the valid module name and module partition syntax, but
as soon as it e.g. sees two adjacent identifiers, the second one can be
macro expanded.  If it is macro expanded though, the expansion can't
start with . or :, and if it expands to nothing, tokens after it (whether
they come from macro expansion or not) can't start with . or :.
So, effectively:
 #define SEMI ;
 export module SEMI
used to be valid and isn't anymore,
 #define FOO bar
 export module FOO;
isn't valid,
 #define COLON :
 export module COLON private;
isn't valid,
 #define BAR baz
 export module foo.bar:baz.qux.BAR;
isn't valid,
 #define BAZ .qux
 export module foo BAZ;
isn't valid,
 #define FREDDY :garply
 export module foo FREDDY;
isn't valid,
while
 #define QUX [[]]
 export module foo QUX;
or
 #define GARPLY private
 module : GARPLY;
etc. is.

2024-11-01  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR c++/114461
libcpp/
	* include/cpplib.h: Implement C++26 P3034R1
	- Module Declarations Shouldn’t be Macros (or more precisely
	its expected intent).
	(NO_DOT_COLON): Define.
	* internal.h (struct cpp_reader): Add diagnose_dot_colon_from_macro_p
	member.
	* lex.cc (cpp_maybe_module_directive): For pp-module, if
	module keyword is followed by CPP_NAME, ensure all CPP_NAME
	tokens possibly matching module name and module partition
	syntax aren't expanded and aren't defined as object-like macros.
	Verify first token after that doesn't start with open paren.
	If the next token after module name/partition is CPP_NAME defined
	as macro, set NO_DOT_COLON flag on it.
	* macro.cc (cpp_get_token_1): Set
	pfile-&gt;diagnose_dot_colon_from_macro_p if token to be expanded has
	NO_DOT_COLON bit set in flags.  Before returning, if
	pfile-&gt;diagnose_dot_colon_from_macro_p is true and not returning
	CPP_PADDING or CPP_COMMENT and not during macro expansion preparation,
	set pfile-&gt;diagnose_dot_colon_from_macro_p to false and diagnose
	if returning CPP_DOT or CPP_COLON.
gcc/testsuite/
	* g++.dg/modules/cpp-7.C: New test.
	* g++.dg/modules/cpp-8.C: New test.
	* g++.dg/modules/cpp-9.C: New test.
	* g++.dg/modules/cpp-10.C: New test.
	* g++.dg/modules/cpp-11.C: New test.
	* g++.dg/modules/cpp-12.C: New test.
	* g++.dg/modules/cpp-13.C: New test.
	* g++.dg/modules/cpp-14.C: New test.
	* g++.dg/modules/cpp-15.C: New test.
	* g++.dg/modules/cpp-16.C: New test.
	* g++.dg/modules/cpp-17.C: New test.
	* g++.dg/modules/cpp-18.C: New test.
	* g++.dg/modules/cpp-19.C: New test.
	* g++.dg/modules/cpp-20.C: New test.
	* g++.dg/modules/pmp-4.C: New test.
	* g++.dg/modules/pmp-5.C: New test.
	* g++.dg/modules/pmp-6.C: New test.
	* g++.dg/modules/token-6.C: New test.
	* g++.dg/modules/token-7.C: New test.
	* g++.dg/modules/token-8.C: New test.
	* g++.dg/modules/token-9.C: New test.
	* g++.dg/modules/token-10.C: New test.
	* g++.dg/modules/token-11.C: New test.
	* g++.dg/modules/token-12.C: New test.
	* g++.dg/modules/token-13.C: New test.
	* g++.dg/modules/token-14.C: New test.
	* g++.dg/modules/token-15.C: New test.
	* g++.dg/modules/token-16.C: New test.
	* g++.dg/modules/dir-only-3.C: Expect an error.
	* g++.dg/modules/dir-only-4.C: Expect an error.
	* g++.dg/modules/dir-only-5.C: New test.
	* g++.dg/modules/atom-preamble-2_a.C: In export module malcolm;
	replace malcolm with kevin.  Don't define malcolm macro.
	* g++.dg/modules/atom-preamble-4.C: Expect an error.
	* g++.dg/modules/atom-preamble-5.C: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This is an attempt to implement the https://wg21.link/p3034r1 paper,
but I'm afraid the wording in the paper is bad for multiple reasons.
I think I understand the intent, that the module name and partition
if any shouldn't come from macros so that they can be scanned for
without preprocessing, but on the other side doesn't want to disable
macro expansion in pp-module altogether, because e.g. the optional
attribute in module-declaration would be nice to come from macros
as which exact attribute is needed might need to be decided based on
preprocessor checks.
The paper added https://eel.is/c++draft/cpp.module#2
which uses partly the wording from https://eel.is/c++draft/cpp.module#1

The first issue I see is that using that "defined as an object-like macro"
from there means IMHO something very different in those 2 paragraphs.
As per https://eel.is/c++draft/cpp.pre#7.sentence-1 preprocessing tokens
in preprocessing directives aren't subject to macro expansion unless
otherwise stated, and so the export and module tokens aren't expanded
and so the requirement that they aren't defined as an object-like macro
makes perfect sense.  The problem with the new paragraph is that
https://eel.is/c++draft/cpp.module#3.sentence-1 says that the rest of
the tokens are macro expanded and after macro expansion none of the
tokens can be defined as an object-like macro, if they would be, they'd
be expanded to that.  So, I think either the wording needs to change
such that not all preprocessing tokens after module are macro expanded,
only those which are after the pp-module-name and if any pp-module-partition
tokens, or all tokens after module are macro expanded but none of the tokens in
pp-module-name and pp-module-partition if any must come from macro
expansion.  The patch below implements it as if the former would be
specified (but see later), so essentially scans the preprocessing tokens
after module without expansion, if the first one is an identifier, it
disables expansion for it and then if followed by . or : expects another
such identifier (again with disabled expansion), but stops after second
: is seen.

Second issue is that while the global-module-fragment start is fine, matches
the syntax of the new paragraph where the pp-tokens[opt] aren't present,
there is also private-module-fragment in the syntax where module is
followed by : private ; and in that case the colon doesn't match the
pp-module-name grammar and appears now to be invalid.  I think the
https://eel.is/c++draft/cpp.module#2
paragraph needs to change so that it allows also that pp-tokens of
a pp-module may also be : pp-tokens[opt] (and in that case, I think
the colon shouldn't come from a macro and private and/or ; can).

Third issue is that there are too many pp-tokens in
https://eel.is/c++draft/cpp.module , one is all the tokens between
module keyword and the semicolon and one is the optional extra tokens
after pp-module-partition (if any, if missing, after pp-module).
Perhaps introducing some other non-terminal would help talking about it?
So in "where the pp-tokens (if any) shall not begin with a ( preprocessing
token" it isn't obvious which pp-tokens it is talking about (my assumption
is the latter) and also whether ( can't appear there just before macro
expansion or also after expansion.  The patch expects only before expansion,
so
 #define F ();
 export module foo F
would be valid during preprocessing but obviously invalid during
compilation, but
 #define foo(n) n;
 export module foo (3)
would be invalid already during preprocessing.

The last issue applies only if the first issue is resolved to allow
expansion of tokens after : if first token, or after pp-module-partition
if present or after pp-module-name if present.  When non-preprocessing
scanner sees
 export module foo.bar:baz.qux;
it knows nothing can come from preprocessing macros and is ok, but if it
sees
 export module foo.bar:baz qux
then it can't know whether it will be
 export module foo.bar:baz;
or
 export module foo.bar:baz [[]];
or
 export module foo.bar:baz.freddy.garply;
because qux could be validly a macro, which expands to ; or [[]];
or .freddy.garply; etc.  So, either the non-preprocessing scanner would
need to note it as possible export of foo.bar:baz* module partitions
and preprocess if it needs to know the details or just compile, or if that
is not ok, the wording would need to rule out that the expansion of (the
second) pp-tokens if any can't start with . or : (colon would be only
problematic if it isn't present in the tokens before it already).
So, if e.g. defining qux above to . whatever is invalid, then the scanner
can rely it sees the whole module name and partition.

The patch below implements what is above described as the first variant
of the first issue resolution, i.e. disables expansion of as many tokens
as could be in the valid module name and module partition syntax, but
as soon as it e.g. sees two adjacent identifiers, the second one can be
macro expanded.  If it is macro expanded though, the expansion can't
start with . or :, and if it expands to nothing, tokens after it (whether
they come from macro expansion or not) can't start with . or :.
So, effectively:
 #define SEMI ;
 export module SEMI
used to be valid and isn't anymore,
 #define FOO bar
 export module FOO;
isn't valid,
 #define COLON :
 export module COLON private;
isn't valid,
 #define BAR baz
 export module foo.bar:baz.qux.BAR;
isn't valid,
 #define BAZ .qux
 export module foo BAZ;
isn't valid,
 #define FREDDY :garply
 export module foo FREDDY;
isn't valid,
while
 #define QUX [[]]
 export module foo QUX;
or
 #define GARPLY private
 module : GARPLY;
etc. is.

2024-11-01  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR c++/114461
libcpp/
	* include/cpplib.h: Implement C++26 P3034R1
	- Module Declarations Shouldn’t be Macros (or more precisely
	its expected intent).
	(NO_DOT_COLON): Define.
	* internal.h (struct cpp_reader): Add diagnose_dot_colon_from_macro_p
	member.
	* lex.cc (cpp_maybe_module_directive): For pp-module, if
	module keyword is followed by CPP_NAME, ensure all CPP_NAME
	tokens possibly matching module name and module partition
	syntax aren't expanded and aren't defined as object-like macros.
	Verify first token after that doesn't start with open paren.
	If the next token after module name/partition is CPP_NAME defined
	as macro, set NO_DOT_COLON flag on it.
	* macro.cc (cpp_get_token_1): Set
	pfile-&gt;diagnose_dot_colon_from_macro_p if token to be expanded has
	NO_DOT_COLON bit set in flags.  Before returning, if
	pfile-&gt;diagnose_dot_colon_from_macro_p is true and not returning
	CPP_PADDING or CPP_COMMENT and not during macro expansion preparation,
	set pfile-&gt;diagnose_dot_colon_from_macro_p to false and diagnose
	if returning CPP_DOT or CPP_COLON.
gcc/testsuite/
	* g++.dg/modules/cpp-7.C: New test.
	* g++.dg/modules/cpp-8.C: New test.
	* g++.dg/modules/cpp-9.C: New test.
	* g++.dg/modules/cpp-10.C: New test.
	* g++.dg/modules/cpp-11.C: New test.
	* g++.dg/modules/cpp-12.C: New test.
	* g++.dg/modules/cpp-13.C: New test.
	* g++.dg/modules/cpp-14.C: New test.
	* g++.dg/modules/cpp-15.C: New test.
	* g++.dg/modules/cpp-16.C: New test.
	* g++.dg/modules/cpp-17.C: New test.
	* g++.dg/modules/cpp-18.C: New test.
	* g++.dg/modules/cpp-19.C: New test.
	* g++.dg/modules/cpp-20.C: New test.
	* g++.dg/modules/pmp-4.C: New test.
	* g++.dg/modules/pmp-5.C: New test.
	* g++.dg/modules/pmp-6.C: New test.
	* g++.dg/modules/token-6.C: New test.
	* g++.dg/modules/token-7.C: New test.
	* g++.dg/modules/token-8.C: New test.
	* g++.dg/modules/token-9.C: New test.
	* g++.dg/modules/token-10.C: New test.
	* g++.dg/modules/token-11.C: New test.
	* g++.dg/modules/token-12.C: New test.
	* g++.dg/modules/token-13.C: New test.
	* g++.dg/modules/token-14.C: New test.
	* g++.dg/modules/token-15.C: New test.
	* g++.dg/modules/token-16.C: New test.
	* g++.dg/modules/dir-only-3.C: Expect an error.
	* g++.dg/modules/dir-only-4.C: Expect an error.
	* g++.dg/modules/dir-only-5.C: New test.
	* g++.dg/modules/atom-preamble-2_a.C: In export module malcolm;
	replace malcolm with kevin.  Don't define malcolm macro.
	* g++.dg/modules/atom-preamble-4.C: Expect an error.
	* g++.dg/modules/atom-preamble-5.C: New test.
</pre>
</div>
</content>
</entry>
</feed>
