<feed xmlns='http://www.w3.org/2005/Atom'>
<title>gcc.git/gcc/cp/semantics.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>OpenMP: C++ front end support for "begin declare variant"</title>
<updated>2025-11-22T17:05:22+00:00</updated>
<author>
<name>Sandra Loosemore</name>
<email>sloosemore@baylibre.com</email>
</author>
<published>2025-11-20T21:45:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=a469cf3df2ac97944a44948891e9fe22ba2f1d10'/>
<id>a469cf3df2ac97944a44948891e9fe22ba2f1d10</id>
<content type='text'>
This patch implements C++ support for the "begin declare variant"
construct.  The OpenMP specification is hazy on interaction of this
feature with C++ language features.  Variant functions in classes are
supported but must be defined as members in the class definition,
using an unqualified name for the base function which also must be
present in that class.  Similarly variant functions in a namespace can
only be defined in that namespace using an unqualified name for a base
function already declared in that namespace.  Variants for template
functions or inside template classes seem to (mostly) work.

gcc/c-family/ChangeLog
	* c-omp.cc (c_omp_directives): Uncomment "begin declare variant"
	and "end declare variant".

gcc/cp/ChangeLog
	* cp-tree.h (struct cp_omp_declare_variant_attr): New.
	(struct saved_scope): Add omp_declare_variant_attribute field.
	* decl.cc (omp_declare_variant_finalize_one): Add logic to inject
	"this" parameter for method calls.
	* parser.cc (cp_parser_skip_to_pragma_omp_end_declare_variant): New.
	(cp_parser_translation_unit): Handle leftover "begin declare variant"
	functions.
	(omp_start_variant_function): New.
	(omp_finish_variant_function): New.
	(omp_maybe_record_variant_base): New.
	(cp_parser_init_declarator): Handle variant functions.
	(cp_parser_class_specifier): Handle deferred lookup of base functions
	when the entire class has been seen.
	(cp_parser_member_declaration): Handle variant functions.
	(cp_finish_omp_declare_variant): Merge context selectors if in
	a "begin declare variant" block.
	(cp_parser_omp_begin): Match "omp begin declare variant".  Adjust
	error messages.
	(cp_parser_omp_end): Match "omp end declare variant".
	* parser.h (struct omp_begin_declare_variant_map_entry): New.
	(struct cp_parser): Add omp_begin_declare_variant_map field.
	* semantics.cc (finish_translation_unit): Detect unmatched
	"omp begin declare variant".

gcc/testsuite/ChangeLog
	* g++.dg/gomp/delim-declare-variant-1.C: New.
	* g++.dg/gomp/delim-declare-variant-2.C: New.
	* g++.dg/gomp/delim-declare-variant-3.C: New.
	* g++.dg/gomp/delim-declare-variant-4.C: New.
	* g++.dg/gomp/delim-declare-variant-5.C: New.
	* g++.dg/gomp/delim-declare-variant-6.C: New.
	* g++.dg/gomp/delim-declare-variant-7.C: New.
	* g++.dg/gomp/delim-declare-variant-40.C: New.
	* g++.dg/gomp/delim-declare-variant-41.C: New.
	* g++.dg/gomp/delim-declare-variant-50.C: New.
	* g++.dg/gomp/delim-declare-variant-51.C: New.
	* g++.dg/gomp/delim-declare-variant-52.C: New.
	* g++.dg/gomp/delim-declare-variant-70.C: New.
	* g++.dg/gomp/delim-declare-variant-71.C: New.

libgomp/
	* testsuite/libgomp.c++/bdv_module1.C: New.
	* testsuite/libgomp.c++/bdv_module1_main.C: New.
	* testsuite/libgomp.c++/bdv_module2.C: New.
	* testsuite/libgomp.c++/bdv_module2_impl.C: New.
	* testsuite/libgomp.c++/bdv_module2_main.C: New.
	* testsuite/libgomp.c++/bdv_module3.C: New.
	* testsuite/libgomp.c++/bdv_module3_impl.C: New.
	* testsuite/libgomp.c++/bdv_module3_main.C: New.
	* testsuite/libgomp.c++/delim-declare-variant-1.C: New.
	* testsuite/libgomp.c++/delim-declare-variant-2.C: New.
	* testsuite/libgomp.c++/delim-declare-variant-7.C: New.

Co-Authored-By: Julian Brown &lt;julian@codesourcery.com&gt;
Co-Authored-By: waffl3x &lt;waffl3x@baylibre.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch implements C++ support for the "begin declare variant"
construct.  The OpenMP specification is hazy on interaction of this
feature with C++ language features.  Variant functions in classes are
supported but must be defined as members in the class definition,
using an unqualified name for the base function which also must be
present in that class.  Similarly variant functions in a namespace can
only be defined in that namespace using an unqualified name for a base
function already declared in that namespace.  Variants for template
functions or inside template classes seem to (mostly) work.

gcc/c-family/ChangeLog
	* c-omp.cc (c_omp_directives): Uncomment "begin declare variant"
	and "end declare variant".

gcc/cp/ChangeLog
	* cp-tree.h (struct cp_omp_declare_variant_attr): New.
	(struct saved_scope): Add omp_declare_variant_attribute field.
	* decl.cc (omp_declare_variant_finalize_one): Add logic to inject
	"this" parameter for method calls.
	* parser.cc (cp_parser_skip_to_pragma_omp_end_declare_variant): New.
	(cp_parser_translation_unit): Handle leftover "begin declare variant"
	functions.
	(omp_start_variant_function): New.
	(omp_finish_variant_function): New.
	(omp_maybe_record_variant_base): New.
	(cp_parser_init_declarator): Handle variant functions.
	(cp_parser_class_specifier): Handle deferred lookup of base functions
	when the entire class has been seen.
	(cp_parser_member_declaration): Handle variant functions.
	(cp_finish_omp_declare_variant): Merge context selectors if in
	a "begin declare variant" block.
	(cp_parser_omp_begin): Match "omp begin declare variant".  Adjust
	error messages.
	(cp_parser_omp_end): Match "omp end declare variant".
	* parser.h (struct omp_begin_declare_variant_map_entry): New.
	(struct cp_parser): Add omp_begin_declare_variant_map field.
	* semantics.cc (finish_translation_unit): Detect unmatched
	"omp begin declare variant".

gcc/testsuite/ChangeLog
	* g++.dg/gomp/delim-declare-variant-1.C: New.
	* g++.dg/gomp/delim-declare-variant-2.C: New.
	* g++.dg/gomp/delim-declare-variant-3.C: New.
	* g++.dg/gomp/delim-declare-variant-4.C: New.
	* g++.dg/gomp/delim-declare-variant-5.C: New.
	* g++.dg/gomp/delim-declare-variant-6.C: New.
	* g++.dg/gomp/delim-declare-variant-7.C: New.
	* g++.dg/gomp/delim-declare-variant-40.C: New.
	* g++.dg/gomp/delim-declare-variant-41.C: New.
	* g++.dg/gomp/delim-declare-variant-50.C: New.
	* g++.dg/gomp/delim-declare-variant-51.C: New.
	* g++.dg/gomp/delim-declare-variant-52.C: New.
	* g++.dg/gomp/delim-declare-variant-70.C: New.
	* g++.dg/gomp/delim-declare-variant-71.C: New.

libgomp/
	* testsuite/libgomp.c++/bdv_module1.C: New.
	* testsuite/libgomp.c++/bdv_module1_main.C: New.
	* testsuite/libgomp.c++/bdv_module2.C: New.
	* testsuite/libgomp.c++/bdv_module2_impl.C: New.
	* testsuite/libgomp.c++/bdv_module2_main.C: New.
	* testsuite/libgomp.c++/bdv_module3.C: New.
	* testsuite/libgomp.c++/bdv_module3_impl.C: New.
	* testsuite/libgomp.c++/bdv_module3_main.C: New.
	* testsuite/libgomp.c++/delim-declare-variant-1.C: New.
	* testsuite/libgomp.c++/delim-declare-variant-2.C: New.
	* testsuite/libgomp.c++/delim-declare-variant-7.C: New.

Co-Authored-By: Julian Brown &lt;julian@codesourcery.com&gt;
Co-Authored-By: waffl3x &lt;waffl3x@baylibre.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Implement C++26 P3920R0 - Wording for NB comment resolution on trivial relocation</title>
<updated>2025-11-10T11:52:45+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-11-10T11:52:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=bbd96065fa7e256d03c892d10813cfa4b3e609a8'/>
<id>bbd96065fa7e256d03c892d10813cfa4b3e609a8</id>
<content type='text'>
Trivial relocation was voted out of C++26, the following patch
removes it (note, the libstdc++ part was still waiting for patch review
and so doesn't need to be removed).

This isn't a mere revert of r16-2206; I've kept -Wc++26-compat option,
from earlier patches the non-terminal stays to be class-property-specifier,
and I had to partially revert also various follow-up changes, e.g. for
modules to handle the new flags and test them, for -Wkeyword-macro
etc. to diagnose the conditional keywords or the feature test macro
etc.

2025-11-10  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR c++/119064
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Revert 2025-07-11
	changes.
gcc/cp/
	* cp-tree.h (struct lang_type): Revert 2025-07-11 changes.
	(CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT): Remove.
	(CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED): Remove.
	(CLASSTYPE_REPLACEABLE_BIT): Remove.
	(CLASSTYPE_REPLACEABLE_COMPUTED): Remove.
	(enum virt_specifier): Revert 2025-07-11 changes.
	(trivially_relocatable_type_p): Remove.
	(replaceable_type_p): Remove.
	* cp-trait.def (IS_NOTHROW_RELOCATABLE): Remove.
	(IS_REPLACEABLE): Remove.
	(IS_TRIVIALLY_RELOCATABLE): Remove.
	* parser.cc (cp_parser_class_specifier, cp_parser_class_head):
	Revert 2025-07-11 changes.
	* pt.cc (instantiate_class_template): Likewise.
	* semantics.cc (trait_expr_value): Likewise.
	(finish_trait_expr): Likewise.
	* tree.cc (default_movable_type_p): Remove.
	(union_with_no_declared_special_member_fns): Remove.
	(trivially_relocatable_type_p): Remove.
	(replaceable_type_p): Remove.
	* constraint.cc (diagnose_trait_expr): Revert 2025-07-11 changes.
	* module.cc (trees_out::lang_type_bools): Revert part of
	2025-07-26 changes related to trivial relocatability.
	(trees_in::lang_type_bools): Likewise.
	* lex.cc (cxx_init): Don't call cpp_warn on
	trivially_relocatable_if_eligible and replaceable_if_eligible.
gcc/testsuite/
	* g++.dg/cpp26/feat-cxx26.C: Revert 2025-07-11 changes.
	* g++.dg/DRs/dr2581-1.C (__cpp_trivial_relocatability): Remove test.
	* g++.dg/DRs/dr2581-2.C (__cpp_trivial_relocatability): Likewise.
	* g++.dg/warn/Wkeyword-macro-1.C: Don't expect any diagnostics on
	#define or #undef of trivially_relocatable_if_eligible or
	replaceable_if_eligible.
	* g++.dg/warn/Wkeyword-macro-2.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-4.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-5.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-7.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-8.C: Likewise.
	* g++.dg/cpp26/trivially-relocatable1.C: Remove.
	* g++.dg/cpp26/trivially-relocatable2.C: Remove.
	* g++.dg/cpp26/trivially-relocatable3.C: Remove.
	* g++.dg/cpp26/trivially-relocatable4.C: Remove.
	* g++.dg/cpp26/trivially-relocatable5.C: Remove.
	* g++.dg/cpp26/trivially-relocatable6.C: Remove.
	* g++.dg/cpp26/trivially-relocatable7.C: Remove.
	* g++.dg/cpp26/trivially-relocatable8.C: Remove.
	* g++.dg/cpp26/trivially-relocatable9.C: Remove.
	* g++.dg/cpp26/trivially-relocatable10.C: Remove.
	* g++.dg/cpp26/trivially-relocatable11.C: Remove.
	* g++.dg/modules/class-11_a.H: Remove trivial relocatability
	related parts.
	* g++.dg/modules/class-11_b.C: Likewise.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Trivial relocation was voted out of C++26, the following patch
removes it (note, the libstdc++ part was still waiting for patch review
and so doesn't need to be removed).

This isn't a mere revert of r16-2206; I've kept -Wc++26-compat option,
from earlier patches the non-terminal stays to be class-property-specifier,
and I had to partially revert also various follow-up changes, e.g. for
modules to handle the new flags and test them, for -Wkeyword-macro
etc. to diagnose the conditional keywords or the feature test macro
etc.

2025-11-10  Jakub Jelinek  &lt;jakub@redhat.com&gt;

	PR c++/119064
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Revert 2025-07-11
	changes.
gcc/cp/
	* cp-tree.h (struct lang_type): Revert 2025-07-11 changes.
	(CLASSTYPE_TRIVIALLY_RELOCATABLE_BIT): Remove.
	(CLASSTYPE_TRIVIALLY_RELOCATABLE_COMPUTED): Remove.
	(CLASSTYPE_REPLACEABLE_BIT): Remove.
	(CLASSTYPE_REPLACEABLE_COMPUTED): Remove.
	(enum virt_specifier): Revert 2025-07-11 changes.
	(trivially_relocatable_type_p): Remove.
	(replaceable_type_p): Remove.
	* cp-trait.def (IS_NOTHROW_RELOCATABLE): Remove.
	(IS_REPLACEABLE): Remove.
	(IS_TRIVIALLY_RELOCATABLE): Remove.
	* parser.cc (cp_parser_class_specifier, cp_parser_class_head):
	Revert 2025-07-11 changes.
	* pt.cc (instantiate_class_template): Likewise.
	* semantics.cc (trait_expr_value): Likewise.
	(finish_trait_expr): Likewise.
	* tree.cc (default_movable_type_p): Remove.
	(union_with_no_declared_special_member_fns): Remove.
	(trivially_relocatable_type_p): Remove.
	(replaceable_type_p): Remove.
	* constraint.cc (diagnose_trait_expr): Revert 2025-07-11 changes.
	* module.cc (trees_out::lang_type_bools): Revert part of
	2025-07-26 changes related to trivial relocatability.
	(trees_in::lang_type_bools): Likewise.
	* lex.cc (cxx_init): Don't call cpp_warn on
	trivially_relocatable_if_eligible and replaceable_if_eligible.
gcc/testsuite/
	* g++.dg/cpp26/feat-cxx26.C: Revert 2025-07-11 changes.
	* g++.dg/DRs/dr2581-1.C (__cpp_trivial_relocatability): Remove test.
	* g++.dg/DRs/dr2581-2.C (__cpp_trivial_relocatability): Likewise.
	* g++.dg/warn/Wkeyword-macro-1.C: Don't expect any diagnostics on
	#define or #undef of trivially_relocatable_if_eligible or
	replaceable_if_eligible.
	* g++.dg/warn/Wkeyword-macro-2.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-4.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-5.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-7.C: Likewise.
	* g++.dg/warn/Wkeyword-macro-8.C: Likewise.
	* g++.dg/cpp26/trivially-relocatable1.C: Remove.
	* g++.dg/cpp26/trivially-relocatable2.C: Remove.
	* g++.dg/cpp26/trivially-relocatable3.C: Remove.
	* g++.dg/cpp26/trivially-relocatable4.C: Remove.
	* g++.dg/cpp26/trivially-relocatable5.C: Remove.
	* g++.dg/cpp26/trivially-relocatable6.C: Remove.
	* g++.dg/cpp26/trivially-relocatable7.C: Remove.
	* g++.dg/cpp26/trivially-relocatable8.C: Remove.
	* g++.dg/cpp26/trivially-relocatable9.C: Remove.
	* g++.dg/cpp26/trivially-relocatable10.C: Remove.
	* g++.dg/cpp26/trivially-relocatable11.C: Remove.
	* g++.dg/modules/class-11_a.H: Remove trivial relocatability
	related parts.
	* g++.dg/modules/class-11_b.C: Likewise.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Implement C++23 P2674R1 - A trait for implicit lifetime types</title>
<updated>2025-10-21T17:17:11+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-10-21T17:17:11+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=cac4bcc8b491d96cca0224534c37914f1393a9a5'/>
<id>cac4bcc8b491d96cca0224534c37914f1393a9a5</id>
<content type='text'>
The following patch attempts to implement the compiler side of the
C++23 P2674R1 paper.  As mentioned in the paper, since CWG2605
the trait isn't really implementable purely on the library side.

Because it is implemented completely on the compiler side, it
just uses SCALAR_TYPE_P and so can e.g. accept __int128 even in
-std=c++23 mode, even when std::is_scalar_v&lt;__int128&gt; is false in
that case.  And as an extention it (like Clang) accepts _Complex
types and vector types.
I must say I'm quite surprised that any array types are considered
implicit-lifetime, even if their element type is not, but perhaps
there is some reason for that.
Because std::is_array_v&lt;int[0]&gt; is false, it returns false for that
as well, dunno if that shouldn't be changed for implicit-lifetime.
It accepts also VLAs.

The library part has been split into a separate patch still pending
review; committing it now so that reflection can use it in its
std::meta::is_implicit_lifetime_type implementation.

2025-10-21  Jakub Jelinek  &lt;jakub@redhat.com&gt;

gcc/cp/
	* cp-tree.h: Implement C++23 P2674R1 - A trait for implicit lifetime
	types.
	(implicit_lifetime_type_p): Declare.
	* tree.cc (implicit_lifetime_type_p): New function.
	* cp-trait.def (IS_IMPLICIT_LIFETIME): New unary trait.
	* semantics.cc (trait_expr_value): Handle CPTK_IS_IMPLICIT_LIFETIME.
	(finish_trait_expr): Likewise.
	* constraint.cc (diagnose_trait_expr): Likewise.
gcc/testsuite/
	* g++.dg/ext/is_implicit_lifetime.C: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following patch attempts to implement the compiler side of the
C++23 P2674R1 paper.  As mentioned in the paper, since CWG2605
the trait isn't really implementable purely on the library side.

Because it is implemented completely on the compiler side, it
just uses SCALAR_TYPE_P and so can e.g. accept __int128 even in
-std=c++23 mode, even when std::is_scalar_v&lt;__int128&gt; is false in
that case.  And as an extention it (like Clang) accepts _Complex
types and vector types.
I must say I'm quite surprised that any array types are considered
implicit-lifetime, even if their element type is not, but perhaps
there is some reason for that.
Because std::is_array_v&lt;int[0]&gt; is false, it returns false for that
as well, dunno if that shouldn't be changed for implicit-lifetime.
It accepts also VLAs.

The library part has been split into a separate patch still pending
review; committing it now so that reflection can use it in its
std::meta::is_implicit_lifetime_type implementation.

2025-10-21  Jakub Jelinek  &lt;jakub@redhat.com&gt;

gcc/cp/
	* cp-tree.h: Implement C++23 P2674R1 - A trait for implicit lifetime
	types.
	(implicit_lifetime_type_p): Declare.
	* tree.cc (implicit_lifetime_type_p): New function.
	* cp-trait.def (IS_IMPLICIT_LIFETIME): New unary trait.
	* semantics.cc (trait_expr_value): Handle CPTK_IS_IMPLICIT_LIFETIME.
	(finish_trait_expr): Likewise.
	* constraint.cc (diagnose_trait_expr): Likewise.
gcc/testsuite/
	* g++.dg/ext/is_implicit_lifetime.C: New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Fix ICE with concept used as function [PR116477]</title>
<updated>2025-10-09T20:27:11+00:00</updated>
<author>
<name>Egas Ribeiro</name>
<email>egas.g.ribeiro@tecnico.ulisboa.pt</email>
</author>
<published>2025-10-07T21:48:56+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=4ee06690a47cd39b6003fc6589d4f292aeb67033'/>
<id>4ee06690a47cd39b6003fc6589d4f292aeb67033</id>
<content type='text'>
As suggested by Patrick Palka in the bug report, the diagnostic check
for concept_check_p(fn) was being done too late in finish_call_expr(),
which led to an early return inside if (processing_template_decl), which
meant that the error wouldn't be triggered when we are in a type
dependence early exit. This fix makes sure that this error is handled in
the semantic analysis phase, and avoids the failed assertion later in
tsubst_expr().

	PR c++/116477

gcc/cp/ChangeLog:

	* semantics.cc (finish_call_expr): Move concept_check_p diagnostic
	before processing_template_decl check to catch errors earlier.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/concepts-pr116477.C: New test.

Signed-off-by: Egas Ribeiro &lt;egas.g.ribeiro@tecnico.ulisboa.pt&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
As suggested by Patrick Palka in the bug report, the diagnostic check
for concept_check_p(fn) was being done too late in finish_call_expr(),
which led to an early return inside if (processing_template_decl), which
meant that the error wouldn't be triggered when we are in a type
dependence early exit. This fix makes sure that this error is handled in
the semantic analysis phase, and avoids the failed assertion later in
tsubst_expr().

	PR c++/116477

gcc/cp/ChangeLog:

	* semantics.cc (finish_call_expr): Move concept_check_p diagnostic
	before processing_template_decl check to catch errors earlier.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp2a/concepts-pr116477.C: New test.

Signed-off-by: Egas Ribeiro &lt;egas.g.ribeiro@tecnico.ulisboa.pt&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>c++, gimplify: Implement C++26 P2795R5 - Erroneous behavior for uninitialized reads [PR114457]</title>
<updated>2025-10-04T08:23:15+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-10-04T07:50:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=f256a13f8aed833fe964a2ba541b7b30ad9b4a76'/>
<id>f256a13f8aed833fe964a2ba541b7b30ad9b4a76</id>
<content type='text'>
The following patch implements the C++26 P2795R5 paper by enabling something
like -ftrivial-auto-var-init=zero by default for -std=c++26/-std=gnu++26.
There is an important difference between explicit -ftrivial-auto-var-init=zero
and the implicitly enabled one, in particular the explicit one will try to
clear padding bits on vars with explicit initializers, while the default
C++26 mode does not - C++26 says that using the padding bits for anything
but copying structures around is still undefined behavior rather than
erroneous behavior.

Users can still override the default C++26 behavior in both directions,
with -ftrivial-auto-var-init=uninitialized even C++26 will act as C++23
with treating all uninitialized var reads (except for copying) as UB rather
than EB, with -ftrivial-auto-var-init=zero it will also clear padding bits
on explicit initialization and with -ftrivial-auto-var-init=pattern it will
initialize to pattern with clearing padding bits in between.

There are other changes that had to be implemented.  First of all, we need
to magicly preinitialize also temporary objects; this is implemented for
both the C++26 implicit mode and explicit
-ftrivial-auto-var-init={zero,pattern} by emitting .DEFERRED_INIT before
construction of TARGET_EXPR temporaries (if they have void type initializers,
i.e. are initialized by code rather than some value).

Second needed change is dropping *this ={v} {CLOBBER(bob)}; statements
at the start of the constructors for -flifetime-dse=2, that says the old
content of *this is irrelevant, which is not true anymore for C++26,
where we want to treat it like that for -W*uninitialized purposes, but
at runtime actually initialize the values.  Instead for -flifetime-dse=2
we emit such {CLOBBER(bob)} before calling whole object constructor
(on TARGET_EXPR with void type initializer or on DECL_EXPR).
And a separate patch added and another one will be adding more {CLOBBER(bob)}
to new expressions.

The third needed change is about gotos and switches across vacuous
initialization.  C++26 says those are still valid, but don't make an
exception for those in the EB rules.
The patch now includes redirecting of forward/backward gotos
which cross vacuous initializations for -std=c++26 and
-ftrivial-auto-var-init={zero,pattern} by adding an artificial
if (0) { lab1: v1 = .DEFERRED_INIT (...); lab2: v2 = .DEFERRED_INIT (...); }
etc. hunk before the user label (or for case labels moving the case
label into it).  Only one per adjacent set of labels, with perhaps
multiple artificial labels in it.  I believe (and testing seems to
confirm that) that one only needs one set of such initialized vars
per the adjacent label group, if some forward or backward jump
crosses more vacuous inits, it will always cross a subset or superset
of the others and when the vars are ordered right, it can jump into
different positions in the same if (0).
Furthermore, -Wimplicit-fallthrough and -Wswitch-unreachable warnings
have been adjusted to deal with that.
These changes mean that -Wtrivial-auto-var-init warning now doesn't
make sense for C++, as there is nothing to warn about, all the switches
and all the gotos are handled right for -ftrivial-auto-var-init= and
are handled that way both for the implicit C++26 mode and for explicit
-ftrivial-auto-var-init= options.

The fourth change is to avoid regressions for code like
struct A
{
  int f, g;
  A () { f = g; // { dg-warning "g. is used uninitialized" } }
} a;
where with -flifetime-dse=2 -Wuninitialized we were able to warn
about bugs like this because of the *this ={v} {CLOBBER(bob)};
statements at the start of the constructors, but with their removal
wouldn't warn about it.  Instead we now add a magic "clobber *this"
attribute to the this PARM_DECL and use it in -W*uninitialized handling
only as an implicit *this ={v} {CLOBBER(bob)}; at the start of the
function.  If a function is inlined, this disappears, but that shouldn't
be a problem, either it is inlined into another constructor and that
should have "clobber *this" for its this argument or it is inlined into
whole object construction spot and there should be an explicit
{CLOBBER(bob)} for the variable or temporary object.

The fifth change is adding [[indeterminate]] attribute support and
using it to avoid .DEFERRED_INIT calls (like [[gnu::uninitialized]]
is handled).

Some regressions caused by this patch had bugs filed (but for cases
where those already didn't work before with explicit
-ftrivial-auto-var-init=zero), those have been xfailed for now.
See PR121975 and PR122044.

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

	PR c++/114457
gcc/
	* flag-types.h (enum auto_init_type): Add AUTO_INIT_CXX26.
	* tree.h (VACUOUS_INIT_LABEL_P): Define.
	* gimplify.cc (is_var_need_auto_init): Renamed to ...
	(var_needs_auto_init_p): ... this.  Don't return true for
	vars with "indeterminate" attribute.  Formatting fixes.
	(gimplify_decl_expr): Use var_needs_auto_init_p instead of
	is_var_need_auto_init.
	(emit_warn_switch_unreachable): Remove the flag_auto_var_init
	special cases.
	(warn_switch_unreachable_and_auto_init_r): Handle them here
	by doing just returning NULL.
	(last_stmt_in_scope): Don't skip just debug stmts to find
	the last stmt in seq, skip for
	flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED also IFN_DEFERRED_INIT
	calls.
	(collect_fallthrough_labels): For
	flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED ignore
	IFN_DEFERRED_INIT calls and GIMPLE_GOTOs to
	VACUOUS_INIT_LABEL_P.
	(should_warn_for_implicit_fallthrough): For
	flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED also skip over
	IFN_DEFERRED_INIT calls.
	(expand_FALLTHROUGH_r): Likewise, and handle GIMPLE_GOTOs
	to VACUOUS_INIT_LABEL_P.
	(gimplify_init_constructor): Use var_needs_auto_init_p instead
	of is_var_need_auto_init and for flag_auto_var_init
	AUTO_INIT_CXX26 don't call gimple_add_padding_init_for_auto_var.
	(gimplify_target_expr): If var_needs_auto_init_p and init has
	void type, call gimple_add_init_for_auto_var and for
	AUTO_INIT_PATTERN also gimple_add_padding_init_for_auto_var.
	* tree-ssa-uninit.cc (maybe_warn_operand): Handle loads from *this
	at the start of the function with "clobber *this" attribute on the
	PARM_DECL.
	* ipa-split.cc (split_function): Remove "clobber *this" attribute
	from the first PARM_DECL (if any).
	* doc/invoke.texi (ftrivial-auto-var-init=): Adjust documentation.
gcc/c-family/
	* c-opts.cc (c_common_post_options): For C++26 set
	flag_auto_var_init to AUTO_INIT_CXX26 if not specified explicitly.
	For C++ disable warn_trivial_auto_var_init.
gcc/cp/
	* cp-tree.h: Implement C++26 P2795R5 - Erroneous behavior for
	uninitialized reads.
	(IF_STMT_VACUOUS_INIT_P): Define.
	(check_goto): Change argument type from tree to tree *.
	* call.cc (build_over_call): Add indeterminate attribute to
	TARGET_EXPR slots for indeterminate parameters.
	* constexpr.cc (cxx_eval_internal_function): Handle IFN_DEFERRED_INIT.
	(cxx_eval_store_expression): Temporarily work around PR121965 bug.
	* cp-gimplify.cc (genericize_if_stmt): Handle IF_STMT_VACUOUS_INIT_P.
	(maybe_emit_clobber_object_begin): New function.
	(cp_gimplify_expr): Call it for DECL_EXPRs and TARGET_EXPRs with
	void type non-NULL TARGET_EXPR_INITIAL.
	* decl.cc (struct named_label_fwd_direct_goto,
	struct named_label_bck_direct_goto): New types.
	(struct named_label_use_entry): Add direct_goto member.  Formatting
	fix.
	(struct named_label_entry): Add direct_goto member.  Turn bool members
	into bool : 1.  Add has_bad_decls bitfield.
	(adjust_backward_gotos): New function.
	(pop_labels): For flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED
	call adjust_backward_gotos if needed.
	(poplevel_named_label_1): For decl_jump_unsafe also set
	ent-&gt;has_bad_decls, and for decl_instrument_init_bypass_p decls
	push them into ent-&gt;bad_decls vector too.
	(duplicate_decls): Complain if indeterminate attribute on function
	parameter isn't present on the first function declaration.
	(decl_instrument_init_bypass_p): New function.
	(build_deferred_init_call): Likewise.
	(maybe_add_deferred_init_calls): Likewise.
	(adjust_backward_goto): Likewise.
	(check_previous_goto_1): Add direct_goto and case_label arguments.
	For decl_instrument_init_bypass_p decls seen if
	direct_goto || case_label move case label if needed, call
	maybe_add_deferred_init_calls and adjust GOTO_EXPR operands remembered
	in direct_goto.  Change return type from bool to int, return 0 on
	error, 1 for success with no need to adjust vacuous inits and 2 for
	success with need to adjust those.
	(check_previous_goto): Adjust check_previous_goto_1 call, vec_free
	direct_goto vector.
	(check_switch_goto): Add case_label argument, adjust
	check_previous_goto_1 call.  Change return type from bool to int.
	(check_goto_1): Remove computed argument, add declp argument.  Don't
	reuse previous ent-&gt;uses if
	ent-&gt;binding_level != current_binding_level.  Push declp into
	direct_goto vectors if needed.
	(check_goto): Remove decl argument, add declp argument.  Adjust
	check_goto_1 calls.
	(finish_case_label): Call check_switch_goto up to twice, first time
	to detect errors and find out if second call will be needed, and
	after c_add_case_label second time if needed.  In the first case
	pass NULL_TREE as new argument to it, in the second case r.
	(start_preparsed_function): Don't emit CLOBBER_OBJECT_BEGIN here
	for -flifetime-dse=2, instead add "clobber *this" attribute to
	current_class_ptr.
	* parser.cc (cp_parser_asm_label_list): Call check_goto only
	after the TREE_LIST is created and pass address of its TREE_VALUE to
	it instead of the label.
	* semantics.cc (finish_goto_stmt): Call check_goto only after
	build_stmt has been called and pass it address of its first operand
	rather than destination.
	* tree.cc (handle_indeterminate_attribute): New function.
	(cxx_gnu_attributes): Add entry for indeterminate attribute.
gcc/testsuite/
	* g++.dg/cpp1y/vla-initlist1.C: Remove dg-skip-if for powerpc.
	Initialize i to 43 for ctor from initializer_list and expect value
	43 instead of 42.
	* g++.dg/cpp26/attr-indeterminate1.C: New test.
	* g++.dg/cpp26/attr-indeterminate2.C: New test.
	* g++.dg/cpp26/attr-indeterminate3.C: New test.
	* g++.dg/cpp26/attr-indeterminate4.C: New test.
	* g++.dg/cpp26/erroneous1.C: New test.
	* g++.dg/cpp26/erroneous2.C: New test.
	* g++.dg/cpp26/erroneous3.C: New test.
	* g++.dg/cpp26/erroneous4.C: New test.
	* g++.dg/opt/store-merging-1.C: Add
	-ftrivial-auto-var-init=uninitialized to dg-options.
	* g++.dg/uninit-pred-loop-1_b.C: Expect a warning for C++26.
	* g++.dg/warn/Wuninitialized-13.C: Expect warning on a different
	line.
	* c-c++-common/ubsan/vla-1.c: Add
	-ftrivial-auto-var-init=uninitialized to dg-options.
	* c-c++-common/uninit-17.c: For c++26 expect warning on a different
	line.
	* g++.dg/warn/Warray-bounds-20.C: Expect warning on a different line.
	* c-c++-common/analyzer/invalid-shift-1.c: Xfail for c++26 until
	PR122044 is fixed.
	* g++.dg/analyzer/exception-value-2.C: Skip for c++26 until PR122044
	is fixed.
	* c-c++-common/goacc-gomp/nesting-1.c: Skip for c++26 until PR121975
	is fixed.
	* c-c++-common/goacc/kernels-decompose-2.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr100400-1-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr100400-1-3.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104061-1-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104061-1-3.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104061-1-4.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104132-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104133-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104774-1.c: Likewise.
	* c-c++-common/goacc/mdc-1.c: Likewise.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following patch implements the C++26 P2795R5 paper by enabling something
like -ftrivial-auto-var-init=zero by default for -std=c++26/-std=gnu++26.
There is an important difference between explicit -ftrivial-auto-var-init=zero
and the implicitly enabled one, in particular the explicit one will try to
clear padding bits on vars with explicit initializers, while the default
C++26 mode does not - C++26 says that using the padding bits for anything
but copying structures around is still undefined behavior rather than
erroneous behavior.

Users can still override the default C++26 behavior in both directions,
with -ftrivial-auto-var-init=uninitialized even C++26 will act as C++23
with treating all uninitialized var reads (except for copying) as UB rather
than EB, with -ftrivial-auto-var-init=zero it will also clear padding bits
on explicit initialization and with -ftrivial-auto-var-init=pattern it will
initialize to pattern with clearing padding bits in between.

There are other changes that had to be implemented.  First of all, we need
to magicly preinitialize also temporary objects; this is implemented for
both the C++26 implicit mode and explicit
-ftrivial-auto-var-init={zero,pattern} by emitting .DEFERRED_INIT before
construction of TARGET_EXPR temporaries (if they have void type initializers,
i.e. are initialized by code rather than some value).

Second needed change is dropping *this ={v} {CLOBBER(bob)}; statements
at the start of the constructors for -flifetime-dse=2, that says the old
content of *this is irrelevant, which is not true anymore for C++26,
where we want to treat it like that for -W*uninitialized purposes, but
at runtime actually initialize the values.  Instead for -flifetime-dse=2
we emit such {CLOBBER(bob)} before calling whole object constructor
(on TARGET_EXPR with void type initializer or on DECL_EXPR).
And a separate patch added and another one will be adding more {CLOBBER(bob)}
to new expressions.

The third needed change is about gotos and switches across vacuous
initialization.  C++26 says those are still valid, but don't make an
exception for those in the EB rules.
The patch now includes redirecting of forward/backward gotos
which cross vacuous initializations for -std=c++26 and
-ftrivial-auto-var-init={zero,pattern} by adding an artificial
if (0) { lab1: v1 = .DEFERRED_INIT (...); lab2: v2 = .DEFERRED_INIT (...); }
etc. hunk before the user label (or for case labels moving the case
label into it).  Only one per adjacent set of labels, with perhaps
multiple artificial labels in it.  I believe (and testing seems to
confirm that) that one only needs one set of such initialized vars
per the adjacent label group, if some forward or backward jump
crosses more vacuous inits, it will always cross a subset or superset
of the others and when the vars are ordered right, it can jump into
different positions in the same if (0).
Furthermore, -Wimplicit-fallthrough and -Wswitch-unreachable warnings
have been adjusted to deal with that.
These changes mean that -Wtrivial-auto-var-init warning now doesn't
make sense for C++, as there is nothing to warn about, all the switches
and all the gotos are handled right for -ftrivial-auto-var-init= and
are handled that way both for the implicit C++26 mode and for explicit
-ftrivial-auto-var-init= options.

The fourth change is to avoid regressions for code like
struct A
{
  int f, g;
  A () { f = g; // { dg-warning "g. is used uninitialized" } }
} a;
where with -flifetime-dse=2 -Wuninitialized we were able to warn
about bugs like this because of the *this ={v} {CLOBBER(bob)};
statements at the start of the constructors, but with their removal
wouldn't warn about it.  Instead we now add a magic "clobber *this"
attribute to the this PARM_DECL and use it in -W*uninitialized handling
only as an implicit *this ={v} {CLOBBER(bob)}; at the start of the
function.  If a function is inlined, this disappears, but that shouldn't
be a problem, either it is inlined into another constructor and that
should have "clobber *this" for its this argument or it is inlined into
whole object construction spot and there should be an explicit
{CLOBBER(bob)} for the variable or temporary object.

The fifth change is adding [[indeterminate]] attribute support and
using it to avoid .DEFERRED_INIT calls (like [[gnu::uninitialized]]
is handled).

Some regressions caused by this patch had bugs filed (but for cases
where those already didn't work before with explicit
-ftrivial-auto-var-init=zero), those have been xfailed for now.
See PR121975 and PR122044.

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

	PR c++/114457
gcc/
	* flag-types.h (enum auto_init_type): Add AUTO_INIT_CXX26.
	* tree.h (VACUOUS_INIT_LABEL_P): Define.
	* gimplify.cc (is_var_need_auto_init): Renamed to ...
	(var_needs_auto_init_p): ... this.  Don't return true for
	vars with "indeterminate" attribute.  Formatting fixes.
	(gimplify_decl_expr): Use var_needs_auto_init_p instead of
	is_var_need_auto_init.
	(emit_warn_switch_unreachable): Remove the flag_auto_var_init
	special cases.
	(warn_switch_unreachable_and_auto_init_r): Handle them here
	by doing just returning NULL.
	(last_stmt_in_scope): Don't skip just debug stmts to find
	the last stmt in seq, skip for
	flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED also IFN_DEFERRED_INIT
	calls.
	(collect_fallthrough_labels): For
	flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED ignore
	IFN_DEFERRED_INIT calls and GIMPLE_GOTOs to
	VACUOUS_INIT_LABEL_P.
	(should_warn_for_implicit_fallthrough): For
	flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED also skip over
	IFN_DEFERRED_INIT calls.
	(expand_FALLTHROUGH_r): Likewise, and handle GIMPLE_GOTOs
	to VACUOUS_INIT_LABEL_P.
	(gimplify_init_constructor): Use var_needs_auto_init_p instead
	of is_var_need_auto_init and for flag_auto_var_init
	AUTO_INIT_CXX26 don't call gimple_add_padding_init_for_auto_var.
	(gimplify_target_expr): If var_needs_auto_init_p and init has
	void type, call gimple_add_init_for_auto_var and for
	AUTO_INIT_PATTERN also gimple_add_padding_init_for_auto_var.
	* tree-ssa-uninit.cc (maybe_warn_operand): Handle loads from *this
	at the start of the function with "clobber *this" attribute on the
	PARM_DECL.
	* ipa-split.cc (split_function): Remove "clobber *this" attribute
	from the first PARM_DECL (if any).
	* doc/invoke.texi (ftrivial-auto-var-init=): Adjust documentation.
gcc/c-family/
	* c-opts.cc (c_common_post_options): For C++26 set
	flag_auto_var_init to AUTO_INIT_CXX26 if not specified explicitly.
	For C++ disable warn_trivial_auto_var_init.
gcc/cp/
	* cp-tree.h: Implement C++26 P2795R5 - Erroneous behavior for
	uninitialized reads.
	(IF_STMT_VACUOUS_INIT_P): Define.
	(check_goto): Change argument type from tree to tree *.
	* call.cc (build_over_call): Add indeterminate attribute to
	TARGET_EXPR slots for indeterminate parameters.
	* constexpr.cc (cxx_eval_internal_function): Handle IFN_DEFERRED_INIT.
	(cxx_eval_store_expression): Temporarily work around PR121965 bug.
	* cp-gimplify.cc (genericize_if_stmt): Handle IF_STMT_VACUOUS_INIT_P.
	(maybe_emit_clobber_object_begin): New function.
	(cp_gimplify_expr): Call it for DECL_EXPRs and TARGET_EXPRs with
	void type non-NULL TARGET_EXPR_INITIAL.
	* decl.cc (struct named_label_fwd_direct_goto,
	struct named_label_bck_direct_goto): New types.
	(struct named_label_use_entry): Add direct_goto member.  Formatting
	fix.
	(struct named_label_entry): Add direct_goto member.  Turn bool members
	into bool : 1.  Add has_bad_decls bitfield.
	(adjust_backward_gotos): New function.
	(pop_labels): For flag_auto_var_init &gt; AUTO_INIT_UNINITIALIZED
	call adjust_backward_gotos if needed.
	(poplevel_named_label_1): For decl_jump_unsafe also set
	ent-&gt;has_bad_decls, and for decl_instrument_init_bypass_p decls
	push them into ent-&gt;bad_decls vector too.
	(duplicate_decls): Complain if indeterminate attribute on function
	parameter isn't present on the first function declaration.
	(decl_instrument_init_bypass_p): New function.
	(build_deferred_init_call): Likewise.
	(maybe_add_deferred_init_calls): Likewise.
	(adjust_backward_goto): Likewise.
	(check_previous_goto_1): Add direct_goto and case_label arguments.
	For decl_instrument_init_bypass_p decls seen if
	direct_goto || case_label move case label if needed, call
	maybe_add_deferred_init_calls and adjust GOTO_EXPR operands remembered
	in direct_goto.  Change return type from bool to int, return 0 on
	error, 1 for success with no need to adjust vacuous inits and 2 for
	success with need to adjust those.
	(check_previous_goto): Adjust check_previous_goto_1 call, vec_free
	direct_goto vector.
	(check_switch_goto): Add case_label argument, adjust
	check_previous_goto_1 call.  Change return type from bool to int.
	(check_goto_1): Remove computed argument, add declp argument.  Don't
	reuse previous ent-&gt;uses if
	ent-&gt;binding_level != current_binding_level.  Push declp into
	direct_goto vectors if needed.
	(check_goto): Remove decl argument, add declp argument.  Adjust
	check_goto_1 calls.
	(finish_case_label): Call check_switch_goto up to twice, first time
	to detect errors and find out if second call will be needed, and
	after c_add_case_label second time if needed.  In the first case
	pass NULL_TREE as new argument to it, in the second case r.
	(start_preparsed_function): Don't emit CLOBBER_OBJECT_BEGIN here
	for -flifetime-dse=2, instead add "clobber *this" attribute to
	current_class_ptr.
	* parser.cc (cp_parser_asm_label_list): Call check_goto only
	after the TREE_LIST is created and pass address of its TREE_VALUE to
	it instead of the label.
	* semantics.cc (finish_goto_stmt): Call check_goto only after
	build_stmt has been called and pass it address of its first operand
	rather than destination.
	* tree.cc (handle_indeterminate_attribute): New function.
	(cxx_gnu_attributes): Add entry for indeterminate attribute.
gcc/testsuite/
	* g++.dg/cpp1y/vla-initlist1.C: Remove dg-skip-if for powerpc.
	Initialize i to 43 for ctor from initializer_list and expect value
	43 instead of 42.
	* g++.dg/cpp26/attr-indeterminate1.C: New test.
	* g++.dg/cpp26/attr-indeterminate2.C: New test.
	* g++.dg/cpp26/attr-indeterminate3.C: New test.
	* g++.dg/cpp26/attr-indeterminate4.C: New test.
	* g++.dg/cpp26/erroneous1.C: New test.
	* g++.dg/cpp26/erroneous2.C: New test.
	* g++.dg/cpp26/erroneous3.C: New test.
	* g++.dg/cpp26/erroneous4.C: New test.
	* g++.dg/opt/store-merging-1.C: Add
	-ftrivial-auto-var-init=uninitialized to dg-options.
	* g++.dg/uninit-pred-loop-1_b.C: Expect a warning for C++26.
	* g++.dg/warn/Wuninitialized-13.C: Expect warning on a different
	line.
	* c-c++-common/ubsan/vla-1.c: Add
	-ftrivial-auto-var-init=uninitialized to dg-options.
	* c-c++-common/uninit-17.c: For c++26 expect warning on a different
	line.
	* g++.dg/warn/Warray-bounds-20.C: Expect warning on a different line.
	* c-c++-common/analyzer/invalid-shift-1.c: Xfail for c++26 until
	PR122044 is fixed.
	* g++.dg/analyzer/exception-value-2.C: Skip for c++26 until PR122044
	is fixed.
	* c-c++-common/goacc-gomp/nesting-1.c: Skip for c++26 until PR121975
	is fixed.
	* c-c++-common/goacc/kernels-decompose-2.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr100400-1-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr100400-1-3.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104061-1-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104061-1-3.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104061-1-4.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104132-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104133-1.c: Likewise.
	* c-c++-common/goacc/kernels-decompose-pr104774-1.c: Likewise.
	* c-c++-common/goacc/mdc-1.c: Likewise.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++, contracts: Simplify contracts headers [NFC].</title>
<updated>2025-09-02T15:01:33+00:00</updated>
<author>
<name>Iain Sandoe</name>
<email>iain@sandoe.co.uk</email>
</author>
<published>2025-08-30T11:14:58+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=ff9e44ee3189d24127bc754a8563be4615239730'/>
<id>ff9e44ee3189d24127bc754a8563be4615239730</id>
<content type='text'>
We have contracts-related declarations and macros split between contracts.h
and cp-tree.h, and then contracts.h is included in the latter, which means
that it is included in all c++ front end files.

This patch:
 - moves all the contracts-related material to contracts.h.
 - makes some functions that are only used in contracts.cc static.
 - tries to group the external API for contracts into related topics.
 - includes contracts.h in the front end sources that need it.

gcc/cp/ChangeLog:

	* constexpr.cc: Include contracts.h
	* coroutines.cc: Likewise.
	* cp-gimplify.cc: Likewise.
	* decl.cc: Likewise.
	* decl2.cc: Likewise.
	* mangle.cc: Likewise.
	* module.cc: Likewise.
	* pt.cc: Likewise.
	* search.cc: Likewise.
	* semantics.cc: Likewise.
	* contracts.cc (validate_contract_role, setup_default_contract_role,
	add_contract_role, get_concrete_axiom_semantic,
	get_default_contract_role): Make static.
	* cp-tree.h (make_postcondition_variable, grok_contract,
	finish_contract_condition, find_contract, set_decl_contracts,
	get_contract_semantic, set_contract_semantic): Move to contracts.h.
	* contracts.h (get_contract_role, add_contract_role,
	validate_contract_role, setup_default_contract_role,
	lookup_concrete_semantic, get_default_contract_role): Remove.

Signed-off-by: Iain Sandoe &lt;iain@sandoe.co.uk&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
We have contracts-related declarations and macros split between contracts.h
and cp-tree.h, and then contracts.h is included in the latter, which means
that it is included in all c++ front end files.

This patch:
 - moves all the contracts-related material to contracts.h.
 - makes some functions that are only used in contracts.cc static.
 - tries to group the external API for contracts into related topics.
 - includes contracts.h in the front end sources that need it.

gcc/cp/ChangeLog:

	* constexpr.cc: Include contracts.h
	* coroutines.cc: Likewise.
	* cp-gimplify.cc: Likewise.
	* decl.cc: Likewise.
	* decl2.cc: Likewise.
	* mangle.cc: Likewise.
	* module.cc: Likewise.
	* pt.cc: Likewise.
	* search.cc: Likewise.
	* semantics.cc: Likewise.
	* contracts.cc (validate_contract_role, setup_default_contract_role,
	add_contract_role, get_concrete_axiom_semantic,
	get_default_contract_role): Make static.
	* cp-tree.h (make_postcondition_variable, grok_contract,
	finish_contract_condition, find_contract, set_decl_contracts,
	get_contract_semantic, set_contract_semantic): Move to contracts.h.
	* contracts.h (get_contract_role, add_contract_role,
	validate_contract_role, setup_default_contract_role,
	lookup_concrete_semantic, get_default_contract_role): Remove.

Signed-off-by: Iain Sandoe &lt;iain@sandoe.co.uk&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Fix auto return type deduction with expansion statements [PR121583]</title>
<updated>2025-08-28T08:51:09+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-28T08:51:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=cddae3e175d078a4eef92260fe31b1144df2116f'/>
<id>cddae3e175d078a4eef92260fe31b1144df2116f</id>
<content type='text'>
The following testcase ICEs during expansion, because cfun-&gt;returns_struct
wasn't cleared, despite auto being deduced to int.

The problem is that check_return_type -&gt; apply_deduced_return_type
is called when parsing the expansion stmt body, at that time
processing_template_decl is non-zero and apply_deduced_return_type
in that case doesn't do the
     if (function *fun = DECL_STRUCT_FUNCTION (fco))
       {
         bool aggr = aggregate_value_p (result, fco);
 #ifdef PCC_STATIC_STRUCT_RETURN
         fun-&gt;returns_pcc_struct = aggr;
 #endif
         fun-&gt;returns_struct = aggr;
       }
My assumption is that !processing_template_decl in that case
is used in the sense "the fco function is not a function template",
for function templates no reason to bother with fun-&gt;returns*struct,
nothing will care about that.
When returning a type dependent expression in the expansion stmt
body, apply_deduced_return_type just won't be called during parsing,
but when instantiating the body and all will be fine.  But when
returning a non-type-dependent expression, while check_return_type
will be called again during instantiation of the body, as the return
type is no longer auto in that case apply_deduced_return_type will not
be called again and so nothing will fix up fun-&gt;returns*struct.

The following patch fixes that by using !uses_template_parms (fco)
check instead of !processing_template_decl.

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

	PR c++/121583
	* semantics.cc (apply_deduced_return_type): Adjust
	fun-&gt;returns*_struct when !uses_template_parms (fco) instead of
	when !processing_template_decl.

	* g++.dg/cpp26/expansion-stmt23.C: New test.
	* g++.dg/cpp26/expansion-stmt24.C: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following testcase ICEs during expansion, because cfun-&gt;returns_struct
wasn't cleared, despite auto being deduced to int.

The problem is that check_return_type -&gt; apply_deduced_return_type
is called when parsing the expansion stmt body, at that time
processing_template_decl is non-zero and apply_deduced_return_type
in that case doesn't do the
     if (function *fun = DECL_STRUCT_FUNCTION (fco))
       {
         bool aggr = aggregate_value_p (result, fco);
 #ifdef PCC_STATIC_STRUCT_RETURN
         fun-&gt;returns_pcc_struct = aggr;
 #endif
         fun-&gt;returns_struct = aggr;
       }
My assumption is that !processing_template_decl in that case
is used in the sense "the fco function is not a function template",
for function templates no reason to bother with fun-&gt;returns*struct,
nothing will care about that.
When returning a type dependent expression in the expansion stmt
body, apply_deduced_return_type just won't be called during parsing,
but when instantiating the body and all will be fine.  But when
returning a non-type-dependent expression, while check_return_type
will be called again during instantiation of the body, as the return
type is no longer auto in that case apply_deduced_return_type will not
be called again and so nothing will fix up fun-&gt;returns*struct.

The following patch fixes that by using !uses_template_parms (fco)
check instead of !processing_template_decl.

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

	PR c++/121583
	* semantics.cc (apply_deduced_return_type): Adjust
	fun-&gt;returns*_struct when !uses_template_parms (fco) instead of
	when !processing_template_decl.

	* g++.dg/cpp26/expansion-stmt23.C: New test.
	* g++.dg/cpp26/expansion-stmt24.C: New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Implement __builtin_structured_binding_size trait</title>
<updated>2025-08-15T20:38:41+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-15T20:38:41+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=9a8b436b005b56e5ec3d8274284ae3afb4e7ba72'/>
<id>9a8b436b005b56e5ec3d8274284ae3afb4e7ba72</id>
<content type='text'>
clang++ apparently added a SFINAE-friendly __builtin_structured_binding_size
trait to return the structured binding size (or error if not in SFINAE
contexts if a type doesn't have a structured binding size).

The expansion statement patch already anticipated this through adding
complain argument to cp_finish_decomp.

The following patch implements it.

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

gcc/
	* doc/extend.texi (Type Traits): Document
	__builtin_structured_binding_size.
gcc/cp/
	* cp-trait.def (STRUCTURED_BINDING_SIZE): New unary trait.
	* cp-tree.h (finish_structured_binding_size): Declare.
	* semantics.cc (trait_expr_value): Handle
	CPTK_STRUCTURED_BINDING_SIZE.
	(finish_structured_binding_size): New function.
	(finish_trait_expr): Handle CPTK_RANK and CPTK_TYPE_ORDER
	in the switch instead of just doing break; for those and
	ifs at the end to handle them.  Handle CPTK_STRUCTURED_BINDING_SIZE.
	* pt.cc (tsubst_expr): Likewise.
	* constraint.cc (diagnose_trait_expr): Likewise.
	* decl.cc (get_tuple_size): Use mce_true for maybe_const_value.
	(cp_decomp_size): Diagnose incomplete types not just if
	processing_template_decl, and use error_at instead of pedwarn.
	If btype is NULL, just return 0 instead of diagnosing an error.
gcc/testsuite/
	* g++.dg/cpp26/expansion-stmt15.C: Expect different diagnostics
	for zero size destructuring expansion statement.
	* g++.dg/ext/builtin-structured-binding-size1.C: New test.
	* g++.dg/ext/builtin-structured-binding-size2.C: New test.
	* g++.dg/ext/builtin-structured-binding-size3.C: New test.
	* g++.dg/ext/builtin-structured-binding-size4.C: New test.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
clang++ apparently added a SFINAE-friendly __builtin_structured_binding_size
trait to return the structured binding size (or error if not in SFINAE
contexts if a type doesn't have a structured binding size).

The expansion statement patch already anticipated this through adding
complain argument to cp_finish_decomp.

The following patch implements it.

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

gcc/
	* doc/extend.texi (Type Traits): Document
	__builtin_structured_binding_size.
gcc/cp/
	* cp-trait.def (STRUCTURED_BINDING_SIZE): New unary trait.
	* cp-tree.h (finish_structured_binding_size): Declare.
	* semantics.cc (trait_expr_value): Handle
	CPTK_STRUCTURED_BINDING_SIZE.
	(finish_structured_binding_size): New function.
	(finish_trait_expr): Handle CPTK_RANK and CPTK_TYPE_ORDER
	in the switch instead of just doing break; for those and
	ifs at the end to handle them.  Handle CPTK_STRUCTURED_BINDING_SIZE.
	* pt.cc (tsubst_expr): Likewise.
	* constraint.cc (diagnose_trait_expr): Likewise.
	* decl.cc (get_tuple_size): Use mce_true for maybe_const_value.
	(cp_decomp_size): Diagnose incomplete types not just if
	processing_template_decl, and use error_at instead of pedwarn.
	If btype is NULL, just return 0 instead of diagnosing an error.
gcc/testsuite/
	* g++.dg/cpp26/expansion-stmt15.C: Expect different diagnostics
	for zero size destructuring expansion statement.
	* g++.dg/ext/builtin-structured-binding-size1.C: New test.
	* g++.dg/ext/builtin-structured-binding-size2.C: New test.
	* g++.dg/ext/builtin-structured-binding-size3.C: New test.
	* g++.dg/ext/builtin-structured-binding-size4.C: New test.
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: P2036R3 - Change scope of lambda trailing-return-type [PR102610]</title>
<updated>2025-08-13T22:49:30+00:00</updated>
<author>
<name>Marek Polacek</name>
<email>polacek@redhat.com</email>
</author>
<published>2024-11-13T21:56:40+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=d2dccd1bf79b862b9989c1b62ed8c074980cd457'/>
<id>d2dccd1bf79b862b9989c1b62ed8c074980cd457</id>
<content type='text'>
This patch is an attempt to implement P2036R3 along with P2579R0, fixing
build breakages caused by P2036R3.

The simplest example is:

  auto counter1 = [j=0]() mutable -&gt; decltype(j) {
      return j++;
  };

which currently doesn't compile because the 'j' in the capture isn't
visible in the trailing return type.  With these proposals, the 'j'
will be in a lambda scope which spans the trailing return type, so
this test will compile.

This oughtn't be difficult but decltype and other issues made this patch
much more challenging.

We have to push the explicit captures before going into
_lambda_declarator_opt because that is what parses the trailing return
type.  Yet we can't build any captures until after _lambda_body -&gt;
start_lambda_function which creates the lambda's operator(), without
which we can't build a proxy, but _lambda_body happens only after
parsing the declarator.  This patch works around it by creating a fake
operator() and adding it to the capture and then removing it when we
have the real operator().

Another thing is that in "-&gt; decltype(j)" we don't have the right
current_function_decl yet.  If current_lambda_expr gives us a lambda,
we know this decltype appertains to a lambda.  But we have to know if we
are in a parameter-declaration-clause: as per [expr.prim.id.unqual]/4.4,
if we are, we shouldn't be adding "const".  The new LAMBDA_EXPR_CONST_QUAL_P
flag tracks this.  But it doesn't handle nested lambdas yet, specifically,
[expr.prim.id.unqual]/14.

I don't think this patch changes behavior for the tests in
"capture-default with [=]" as the paper promises; clang++ behaves the
same as gcc with this patch.

	PR c++/102610

gcc/cp/ChangeLog:

	* cp-tree.h (LAMBDA_EXPR_CONST_QUAL_P): Define.
	(maybe_add_dummy_lambda_op): Declare.
	(remove_dummy_lambda_op): Declare.
	(push_capture_proxies): Adjust.
	* lambda.cc (build_capture_proxy): No longer static.  New early_p
	parameter.  Use it.
	(add_capture): Adjust the call to build_capture_proxy.
	(resolvable_dummy_lambda): Check DECL_LAMBDA_FUNCTION_P.
	(push_capture_proxies): New.
	(start_lambda_function): Use it.
	* name-lookup.cc (check_local_shadow): Give an error for
	is_capture_proxy.
	(cp_binding_level_descriptor): Add lambda-scope.
	(begin_scope) &lt;case sk_lambda&gt;: New case.
	* name-lookup.h (enum scope_kind): Add sk_lambda.
	(struct cp_binding_level): Widen kind.
	* parser.cc (cp_parser_lambda_expression): Create a new (lambda) scope
	after the lambda-introducer.
	(cp_parser_lambda_declarator_opt): Set LAMBDA_EXPR_CONST_QUAL_P.
	Create a dummy operator() if needed.  Inject the captures into the
	lambda scope.  Remove the dummy operator().
	(make_dummy_lambda_op): New.
	(maybe_add_dummy_lambda_op): New.
	(remove_dummy_lambda_op): New.
	* pt.cc (tsubst_lambda_expr): Begin/end a lambda scope.  Push the
	capture proxies.  Build/remove a dummy operator() if needed.  Set
	LAMBDA_EXPR_CONST_QUAL_P.
	* semantics.cc (parsing_lambda_declarator): New.
	(outer_var_p): Also consider captures as outer variables if in a lambda
	declarator.
	(process_outer_var_ref): Reset containing_function when
	parsing_lambda_declarator.
	(finish_decltype_type): Process decls in the lambda-declarator as well.
	Look at LAMBDA_EXPR_CONST_QUAL_P unless we have an xobj function.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/lambda/lambda-decltype3.C: Remove xfail.
	* g++.dg/warn/Wshadow-19.C: Add -Wpedantic.  Adjust a dg-warning.
	* g++.dg/warn/Wshadow-6.C: Adjust expected diagnostics.
	* g++.dg/cpp23/lambda-scope1.C: New test.
	* g++.dg/cpp23/lambda-scope2.C: New test.
	* g++.dg/cpp23/lambda-scope3.C: New test.
	* g++.dg/cpp23/lambda-scope4.C: New test.
	* g++.dg/cpp23/lambda-scope4b.C: New test.
	* g++.dg/cpp23/lambda-scope5.C: New test.
	* g++.dg/cpp23/lambda-scope6.C: New test.
	* g++.dg/cpp23/lambda-scope7.C: New test.
	* g++.dg/cpp23/lambda-scope8.C: New test.
	* g++.dg/cpp23/lambda-scope9.C: New test.

Reviewed-by: Jason Merrill &lt;jason@redhat.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
This patch is an attempt to implement P2036R3 along with P2579R0, fixing
build breakages caused by P2036R3.

The simplest example is:

  auto counter1 = [j=0]() mutable -&gt; decltype(j) {
      return j++;
  };

which currently doesn't compile because the 'j' in the capture isn't
visible in the trailing return type.  With these proposals, the 'j'
will be in a lambda scope which spans the trailing return type, so
this test will compile.

This oughtn't be difficult but decltype and other issues made this patch
much more challenging.

We have to push the explicit captures before going into
_lambda_declarator_opt because that is what parses the trailing return
type.  Yet we can't build any captures until after _lambda_body -&gt;
start_lambda_function which creates the lambda's operator(), without
which we can't build a proxy, but _lambda_body happens only after
parsing the declarator.  This patch works around it by creating a fake
operator() and adding it to the capture and then removing it when we
have the real operator().

Another thing is that in "-&gt; decltype(j)" we don't have the right
current_function_decl yet.  If current_lambda_expr gives us a lambda,
we know this decltype appertains to a lambda.  But we have to know if we
are in a parameter-declaration-clause: as per [expr.prim.id.unqual]/4.4,
if we are, we shouldn't be adding "const".  The new LAMBDA_EXPR_CONST_QUAL_P
flag tracks this.  But it doesn't handle nested lambdas yet, specifically,
[expr.prim.id.unqual]/14.

I don't think this patch changes behavior for the tests in
"capture-default with [=]" as the paper promises; clang++ behaves the
same as gcc with this patch.

	PR c++/102610

gcc/cp/ChangeLog:

	* cp-tree.h (LAMBDA_EXPR_CONST_QUAL_P): Define.
	(maybe_add_dummy_lambda_op): Declare.
	(remove_dummy_lambda_op): Declare.
	(push_capture_proxies): Adjust.
	* lambda.cc (build_capture_proxy): No longer static.  New early_p
	parameter.  Use it.
	(add_capture): Adjust the call to build_capture_proxy.
	(resolvable_dummy_lambda): Check DECL_LAMBDA_FUNCTION_P.
	(push_capture_proxies): New.
	(start_lambda_function): Use it.
	* name-lookup.cc (check_local_shadow): Give an error for
	is_capture_proxy.
	(cp_binding_level_descriptor): Add lambda-scope.
	(begin_scope) &lt;case sk_lambda&gt;: New case.
	* name-lookup.h (enum scope_kind): Add sk_lambda.
	(struct cp_binding_level): Widen kind.
	* parser.cc (cp_parser_lambda_expression): Create a new (lambda) scope
	after the lambda-introducer.
	(cp_parser_lambda_declarator_opt): Set LAMBDA_EXPR_CONST_QUAL_P.
	Create a dummy operator() if needed.  Inject the captures into the
	lambda scope.  Remove the dummy operator().
	(make_dummy_lambda_op): New.
	(maybe_add_dummy_lambda_op): New.
	(remove_dummy_lambda_op): New.
	* pt.cc (tsubst_lambda_expr): Begin/end a lambda scope.  Push the
	capture proxies.  Build/remove a dummy operator() if needed.  Set
	LAMBDA_EXPR_CONST_QUAL_P.
	* semantics.cc (parsing_lambda_declarator): New.
	(outer_var_p): Also consider captures as outer variables if in a lambda
	declarator.
	(process_outer_var_ref): Reset containing_function when
	parsing_lambda_declarator.
	(finish_decltype_type): Process decls in the lambda-declarator as well.
	Look at LAMBDA_EXPR_CONST_QUAL_P unless we have an xobj function.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/lambda/lambda-decltype3.C: Remove xfail.
	* g++.dg/warn/Wshadow-19.C: Add -Wpedantic.  Adjust a dg-warning.
	* g++.dg/warn/Wshadow-6.C: Adjust expected diagnostics.
	* g++.dg/cpp23/lambda-scope1.C: New test.
	* g++.dg/cpp23/lambda-scope2.C: New test.
	* g++.dg/cpp23/lambda-scope3.C: New test.
	* g++.dg/cpp23/lambda-scope4.C: New test.
	* g++.dg/cpp23/lambda-scope4b.C: New test.
	* g++.dg/cpp23/lambda-scope5.C: New test.
	* g++.dg/cpp23/lambda-scope6.C: New test.
	* g++.dg/cpp23/lambda-scope7.C: New test.
	* g++.dg/cpp23/lambda-scope8.C: New test.
	* g++.dg/cpp23/lambda-scope9.C: New test.

Reviewed-by: Jason Merrill &lt;jason@redhat.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>c++: Implement C++26 P1306R5 - Expansion statements [PR120776]</title>
<updated>2025-08-13T20:10:18+00:00</updated>
<author>
<name>Jakub Jelinek</name>
<email>jakub@redhat.com</email>
</author>
<published>2025-08-13T20:07:27+00:00</published>
<link rel='alternate' type='text/html' href='https://git.belthelziquor.com/gcc.git/commit/?id=458773ac7bca792db044ad6c241f566c9ba87cb7'/>
<id>458773ac7bca792db044ad6c241f566c9ba87cb7</id>
<content type='text'>
The following patch implements the C++26 P1306R5 - Expansion statements
paper.
When expansion statements are used outside of templates, the lowering
of the statement uses push_tinst_level_loc and instantiates the body
multiple times, otherwise when the new TEMPLATE_FOR_STMT statement is
being instantiated and !processing_template_decl, it instantiates the
body several times with just local_specialization_stack around each
iteration but with the original args.
Because the lowering of these statements is mostly about instantiation,
I've put the lowering code into pt.cc rather than semantics.cc.
Only destructuring expansion statements currently use in the patch
temporary lifetime extension which matches the proposed resolution of
https://cplusplus.github.io/CWG/issues/3043.html
I'm not sure what will CWG decide about that if there will be some
temporary lifetime extension for enumerating expansion statements and if
yes, under what exact rules (e.g. whether it extends all the temporaries
across one iteration of the body, or only if a reference is initialized
or nothing at all).  And for iterating expansion statements, I think I
don't understand the P2686R4 rules well yet, I think if the
expansion-initializer is used in static constexpr rvalue reference, then
it isn't needed, but not sure if it won't be needed if static would be
dropped (whether
struct S { constexpr S () : s (0) {} constexpr ~S () {} int s; };
struct T { const S &amp;t, &amp;u; };
void foo () { constexpr T t = { S {}, S {} }; use (t.t, t.u); }
is ok under P2686R4; though without constexpr before T I see S::~S () being
called after use, not at the end of the t declaration, so maybe it is
fine also without static).
As per
https://cplusplus.github.io/CWG/issues/3044.html
the patch uses build_int_cst (ptrdiff_type_node, i) to create second
operand of begin + i and doesn't lookup overloaded comma operator (note, I'm
actually not even creating a lambda there, just using TARGET_EXPRs).
I guess my preference would be dropping those 4 static keywords from
[stmt.expand] but the patch does use those for now and it won't be possible
to change that until the rest of P2686R4 is implemented.
As per
https://cplusplus.github.io/CWG/issues/3045.html
it treats sk_template_for like sk_for for the purpose of redeclaration of
vars in the body but doesn't yet reject [[fallthrough]]; in the expansion
stmt body (when not nested in another switch).
I'm not sure if cp_perform_range_for_lookup used in the patch is exactly
what we want for the https://eel.is/c++draft/stmt.expand#3.2
- it does finish_call_expr on the perform_koenig_lookup as well, shouldn't
for the decision whether it is iterating or destructing (i.e. tf_none)
just call perform_koenig_lookup and check if it found some
FUNCTION_DECL/OVERLOAD/TEMPLATE_DECL?
cp_decomp_size in the patch has tsubst_flags_t argument and attempts to be
SFINAE friendly, even when it isn't needed strictly for this patch.
This is with PR96185 __builtin_structured_binding_size implementation in
mind (to follow clang).
The new TEMPLATE_FOR_STMT statement is expected to be lowered to something
that doesn't use the statement at all, I've implemented break/continue
discovery in the body, so all I needed was to punt on TEMPLATE_FOR_STMT
in potential_constant_expression_1 so that we don't try to constant evaluate
it when it is still dependent (and cxx_eval_constant_expression rejects
it without any extra code).
I think only enumerating and iterating expansion statements can have zero
iteration, because for destructuring ones it doesn't use a structured
binding pack and so valid structured binding has to have at least one
iteration.  Though
https://cplusplus.github.io/CWG/issues/3048.html
could change that, this patch currently rejects it though.

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

	PR c++/120776
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Predefine
	__cpp_expansion_statements=202506L for C++26.
gcc/cp/
	* cp-tree.def: Implement C++26 P1306R5 - Expansion statements.
	(TEMPLATE_FOR_STMT): New tree code.
	* cp-tree.h (struct saved_scope): Add expansion_stmt.
	(in_expansion_stmt): Define.
	(TEMPLATE_FOR_DECL, TEMPLATE_FOR_EXPR, TEMPLATE_FOR_BODY,
	TEMPLATE_FOR_SCOPE, TEMPLATE_FOR_INIT_STMT): Define.
	(struct tinst_level): Adjust comment.
	(cp_decomp_size, finish_expansion_stmt, do_pushlevel,
	cp_build_range_for_decls, build_range_temp,
	cp_perform_range_for_lookup, begin_template_for_scope): Declare.
	(finish_range_for_stmt): Remove declaration.
	* cp-objcp-common.cc (cp_common_init_ts): Handle TEMPLATE_FOR_STMT.
	* name-lookup.h (enum scope_kind): Add sk_template_for enumerator.
	(struct cp_binding_level): Enlarge kind bitfield from 4 to 5 bits.
	Adjust comment with remaining space bits.
	* name-lookup.cc (check_local_shadow): Handle sk_template_for like
	sk_for.
	(cp_binding_level_descriptor): Add entry for sk_template_for.
	(begin_scope): Handle sk_template_for.
	* parser.h (IN_EXPANSION_STMT): Define.
	* parser.cc (cp_debug_parser): Print IN_EXPANSION_STMT bit.
	(cp_parser_lambda_expression): Temporarily clear in_expansion_stmt.
	(cp_parser_statement): Handle RID_TEMPLATE followed by RID_FOR for
	C++11.
	(cp_parser_label_for_labeled_statement): Complain about named labels
	inside of expansion stmt body.
	(cp_hide_range_decl): New function.
	(cp_parser_range_for): Use it.  Adjust do_range_for_auto_deduction
	caller.  Remove second template argument from auto_vecs bindings and
	names.
	(build_range_temp): No longer static.
	(do_range_for_auto_deduction): Add expansion_stmt argument.
	(cp_build_range_for_decls): New function.
	(cp_convert_range_for): Use it.  Call cp_perform_range_for_lookup
	rather than cp_parser_perform_range_for_lookup.
	(cp_parser_perform_range_for_lookup): Rename to ...
	(cp_perform_range_for_lookup): ... this.  No longer static.  Add
	complain argument and handle it.
	(cp_parser_range_for_member_function): Rename to ...
	(cp_range_for_member_function): ... this.
	(cp_parser_expansion_statement): New function.
	(cp_parser_jump_statement): Handle IN_EXPANSION_STMT.
	(cp_convert_omp_range_for): Adjust do_range_for_auto_deduction caller.
	Call cp_perform_range_for_lookup rather than
	cp_parser_perform_range_for_lookup.
	* error.cc (print_instantiation_full_context): Handle tldcl being
	TEMPLATE_FOR_STMT.
	(print_instantiation_partial_context_line): Likewise.
	* constexpr.cc (potential_constant_expression_1): Handle
	TEMPLATE_FOR_STMT.
	* decl.cc (poplevel_named_label_1): Use obl instead of bl-&gt;level_chain.
	(finish_case_label): Diagnose case labels inside of template for.
	(find_decomp_class_base): Add complain argument, don't diagnose
	anything and just return error_mark_node if tf_none, adjust recursive
	call.
	(cp_decomp_size): New function.
	(cp_finish_decomp): Adjust find_decomp_class_base caller.
	* semantics.cc (do_pushlevel): No longer static.
	(begin_template_for_scope): New function.
	* pt.cc (push_tinst_level_loc): Handle TEMPLATE_FOR_STMT.
	(reopen_tinst_level): Likewise.
	(tsubst_stmt): Handle TEMPLATE_FOR_STMT.
	(struct expansion_stmt_bc): New type.
	(expansion_stmt_find_bc_r, finish_expansion_stmt): New functions.
	* decl2.cc (decl_dependent_p): Return true for current function's decl
	if in_expansion_stmt.
	* call.cc (extend_ref_init_temps): Don't extend_all_temps if
	TREE_STATIC (decl).
	* cxx-pretty-print.cc (cxx_pretty_printer::statement): Handle
	TEMPLATE_FOR_STMT.
gcc/testsuite/
	* g++.dg/cpp1z/decomp64.C: New test.
	* g++.dg/cpp26/expansion-stmt1.C: New test.
	* g++.dg/cpp26/expansion-stmt2.C: New test.
	* g++.dg/cpp26/expansion-stmt3.C: New test.
	* g++.dg/cpp26/expansion-stmt4.C: New test.
	* g++.dg/cpp26/expansion-stmt5.C: New test.
	* g++.dg/cpp26/expansion-stmt6.C: New test.
	* g++.dg/cpp26/expansion-stmt7.C: New test.
	* g++.dg/cpp26/expansion-stmt8.C: New test.
	* g++.dg/cpp26/expansion-stmt9.C: New test.
	* g++.dg/cpp26/expansion-stmt10.C: New test.
	* g++.dg/cpp26/expansion-stmt11.C: New test.
	* g++.dg/cpp26/expansion-stmt12.C: New test.
	* g++.dg/cpp26/expansion-stmt13.C: New test.
	* g++.dg/cpp26/expansion-stmt14.C: New test.
	* g++.dg/cpp26/expansion-stmt15.C: New test.
	* g++.dg/cpp26/expansion-stmt16.C: New test.
	* g++.dg/cpp26/expansion-stmt17.C: New test.
	* g++.dg/cpp26/expansion-stmt18.C: New test.
	* g++.dg/cpp26/expansion-stmt19.C: New test.
	* g++.dg/cpp26/feat-cxx26.C: Add __cpp_expansion_statements
	tests.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
The following patch implements the C++26 P1306R5 - Expansion statements
paper.
When expansion statements are used outside of templates, the lowering
of the statement uses push_tinst_level_loc and instantiates the body
multiple times, otherwise when the new TEMPLATE_FOR_STMT statement is
being instantiated and !processing_template_decl, it instantiates the
body several times with just local_specialization_stack around each
iteration but with the original args.
Because the lowering of these statements is mostly about instantiation,
I've put the lowering code into pt.cc rather than semantics.cc.
Only destructuring expansion statements currently use in the patch
temporary lifetime extension which matches the proposed resolution of
https://cplusplus.github.io/CWG/issues/3043.html
I'm not sure what will CWG decide about that if there will be some
temporary lifetime extension for enumerating expansion statements and if
yes, under what exact rules (e.g. whether it extends all the temporaries
across one iteration of the body, or only if a reference is initialized
or nothing at all).  And for iterating expansion statements, I think I
don't understand the P2686R4 rules well yet, I think if the
expansion-initializer is used in static constexpr rvalue reference, then
it isn't needed, but not sure if it won't be needed if static would be
dropped (whether
struct S { constexpr S () : s (0) {} constexpr ~S () {} int s; };
struct T { const S &amp;t, &amp;u; };
void foo () { constexpr T t = { S {}, S {} }; use (t.t, t.u); }
is ok under P2686R4; though without constexpr before T I see S::~S () being
called after use, not at the end of the t declaration, so maybe it is
fine also without static).
As per
https://cplusplus.github.io/CWG/issues/3044.html
the patch uses build_int_cst (ptrdiff_type_node, i) to create second
operand of begin + i and doesn't lookup overloaded comma operator (note, I'm
actually not even creating a lambda there, just using TARGET_EXPRs).
I guess my preference would be dropping those 4 static keywords from
[stmt.expand] but the patch does use those for now and it won't be possible
to change that until the rest of P2686R4 is implemented.
As per
https://cplusplus.github.io/CWG/issues/3045.html
it treats sk_template_for like sk_for for the purpose of redeclaration of
vars in the body but doesn't yet reject [[fallthrough]]; in the expansion
stmt body (when not nested in another switch).
I'm not sure if cp_perform_range_for_lookup used in the patch is exactly
what we want for the https://eel.is/c++draft/stmt.expand#3.2
- it does finish_call_expr on the perform_koenig_lookup as well, shouldn't
for the decision whether it is iterating or destructing (i.e. tf_none)
just call perform_koenig_lookup and check if it found some
FUNCTION_DECL/OVERLOAD/TEMPLATE_DECL?
cp_decomp_size in the patch has tsubst_flags_t argument and attempts to be
SFINAE friendly, even when it isn't needed strictly for this patch.
This is with PR96185 __builtin_structured_binding_size implementation in
mind (to follow clang).
The new TEMPLATE_FOR_STMT statement is expected to be lowered to something
that doesn't use the statement at all, I've implemented break/continue
discovery in the body, so all I needed was to punt on TEMPLATE_FOR_STMT
in potential_constant_expression_1 so that we don't try to constant evaluate
it when it is still dependent (and cxx_eval_constant_expression rejects
it without any extra code).
I think only enumerating and iterating expansion statements can have zero
iteration, because for destructuring ones it doesn't use a structured
binding pack and so valid structured binding has to have at least one
iteration.  Though
https://cplusplus.github.io/CWG/issues/3048.html
could change that, this patch currently rejects it though.

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

	PR c++/120776
gcc/c-family/
	* c-cppbuiltin.cc (c_cpp_builtins): Predefine
	__cpp_expansion_statements=202506L for C++26.
gcc/cp/
	* cp-tree.def: Implement C++26 P1306R5 - Expansion statements.
	(TEMPLATE_FOR_STMT): New tree code.
	* cp-tree.h (struct saved_scope): Add expansion_stmt.
	(in_expansion_stmt): Define.
	(TEMPLATE_FOR_DECL, TEMPLATE_FOR_EXPR, TEMPLATE_FOR_BODY,
	TEMPLATE_FOR_SCOPE, TEMPLATE_FOR_INIT_STMT): Define.
	(struct tinst_level): Adjust comment.
	(cp_decomp_size, finish_expansion_stmt, do_pushlevel,
	cp_build_range_for_decls, build_range_temp,
	cp_perform_range_for_lookup, begin_template_for_scope): Declare.
	(finish_range_for_stmt): Remove declaration.
	* cp-objcp-common.cc (cp_common_init_ts): Handle TEMPLATE_FOR_STMT.
	* name-lookup.h (enum scope_kind): Add sk_template_for enumerator.
	(struct cp_binding_level): Enlarge kind bitfield from 4 to 5 bits.
	Adjust comment with remaining space bits.
	* name-lookup.cc (check_local_shadow): Handle sk_template_for like
	sk_for.
	(cp_binding_level_descriptor): Add entry for sk_template_for.
	(begin_scope): Handle sk_template_for.
	* parser.h (IN_EXPANSION_STMT): Define.
	* parser.cc (cp_debug_parser): Print IN_EXPANSION_STMT bit.
	(cp_parser_lambda_expression): Temporarily clear in_expansion_stmt.
	(cp_parser_statement): Handle RID_TEMPLATE followed by RID_FOR for
	C++11.
	(cp_parser_label_for_labeled_statement): Complain about named labels
	inside of expansion stmt body.
	(cp_hide_range_decl): New function.
	(cp_parser_range_for): Use it.  Adjust do_range_for_auto_deduction
	caller.  Remove second template argument from auto_vecs bindings and
	names.
	(build_range_temp): No longer static.
	(do_range_for_auto_deduction): Add expansion_stmt argument.
	(cp_build_range_for_decls): New function.
	(cp_convert_range_for): Use it.  Call cp_perform_range_for_lookup
	rather than cp_parser_perform_range_for_lookup.
	(cp_parser_perform_range_for_lookup): Rename to ...
	(cp_perform_range_for_lookup): ... this.  No longer static.  Add
	complain argument and handle it.
	(cp_parser_range_for_member_function): Rename to ...
	(cp_range_for_member_function): ... this.
	(cp_parser_expansion_statement): New function.
	(cp_parser_jump_statement): Handle IN_EXPANSION_STMT.
	(cp_convert_omp_range_for): Adjust do_range_for_auto_deduction caller.
	Call cp_perform_range_for_lookup rather than
	cp_parser_perform_range_for_lookup.
	* error.cc (print_instantiation_full_context): Handle tldcl being
	TEMPLATE_FOR_STMT.
	(print_instantiation_partial_context_line): Likewise.
	* constexpr.cc (potential_constant_expression_1): Handle
	TEMPLATE_FOR_STMT.
	* decl.cc (poplevel_named_label_1): Use obl instead of bl-&gt;level_chain.
	(finish_case_label): Diagnose case labels inside of template for.
	(find_decomp_class_base): Add complain argument, don't diagnose
	anything and just return error_mark_node if tf_none, adjust recursive
	call.
	(cp_decomp_size): New function.
	(cp_finish_decomp): Adjust find_decomp_class_base caller.
	* semantics.cc (do_pushlevel): No longer static.
	(begin_template_for_scope): New function.
	* pt.cc (push_tinst_level_loc): Handle TEMPLATE_FOR_STMT.
	(reopen_tinst_level): Likewise.
	(tsubst_stmt): Handle TEMPLATE_FOR_STMT.
	(struct expansion_stmt_bc): New type.
	(expansion_stmt_find_bc_r, finish_expansion_stmt): New functions.
	* decl2.cc (decl_dependent_p): Return true for current function's decl
	if in_expansion_stmt.
	* call.cc (extend_ref_init_temps): Don't extend_all_temps if
	TREE_STATIC (decl).
	* cxx-pretty-print.cc (cxx_pretty_printer::statement): Handle
	TEMPLATE_FOR_STMT.
gcc/testsuite/
	* g++.dg/cpp1z/decomp64.C: New test.
	* g++.dg/cpp26/expansion-stmt1.C: New test.
	* g++.dg/cpp26/expansion-stmt2.C: New test.
	* g++.dg/cpp26/expansion-stmt3.C: New test.
	* g++.dg/cpp26/expansion-stmt4.C: New test.
	* g++.dg/cpp26/expansion-stmt5.C: New test.
	* g++.dg/cpp26/expansion-stmt6.C: New test.
	* g++.dg/cpp26/expansion-stmt7.C: New test.
	* g++.dg/cpp26/expansion-stmt8.C: New test.
	* g++.dg/cpp26/expansion-stmt9.C: New test.
	* g++.dg/cpp26/expansion-stmt10.C: New test.
	* g++.dg/cpp26/expansion-stmt11.C: New test.
	* g++.dg/cpp26/expansion-stmt12.C: New test.
	* g++.dg/cpp26/expansion-stmt13.C: New test.
	* g++.dg/cpp26/expansion-stmt14.C: New test.
	* g++.dg/cpp26/expansion-stmt15.C: New test.
	* g++.dg/cpp26/expansion-stmt16.C: New test.
	* g++.dg/cpp26/expansion-stmt17.C: New test.
	* g++.dg/cpp26/expansion-stmt18.C: New test.
	* g++.dg/cpp26/expansion-stmt19.C: New test.
	* g++.dg/cpp26/feat-cxx26.C: Add __cpp_expansion_statements
	tests.
</pre>
</div>
</content>
</entry>
</feed>
