Bug 115745 - [C++26] P0963R3 - Structured binding declaration as a condition
Summary: [C++26] P0963R3 - Structured binding declaration as a condition
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 15.0
: P3 normal
Target Milestone: ---
Assignee: Jakub Jelinek
URL:
Keywords:
Depends on:
Blocks: c++26-core
  Show dependency treegraph
 
Reported: 2024-07-02 08:43 UTC by Jakub Jelinek
Modified: 2024-07-27 02:09 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2024-07-02 00:00:00


Attachments
gcc15-pr115745.patch (6.28 KB, patch)
2024-07-02 08:53 UTC, Jakub Jelinek
Details | Diff
gcc15-pr115745.patch (6.28 KB, patch)
2024-07-02 14:23 UTC, Jakub Jelinek
Details | Diff
gcc15-pr114745.patch (6.53 KB, patch)
2024-07-02 16:07 UTC, Jakub Jelinek
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jakub Jelinek 2024-07-02 08:43:16 UTC
See <https://wg21.link/P0963R3>.
Comment 1 Jakub Jelinek 2024-07-02 08:53:48 UTC
Created attachment 58557 [details]
gcc15-pr115745.patch

Untested implementation.
Comment 2 Jason Merrill 2024-07-02 13:47:02 UTC
(In reply to Jakub Jelinek from comment #1)
> Created attachment 58557 [details]
> gcc15-pr115745.patch
> 
> Untested implementation.

The later uses of the condition TARGET_EXPR can refer to the TARGET_EXPR_SLOT instead of using the TARGET_EXPR itself.
Comment 3 Jakub Jelinek 2024-07-02 14:23:33 UTC
Created attachment 58564 [details]
gcc15-pr115745.patch

Indeed, this worked in brief testing.  I'm currently bootstrapping/regtesting
the first versions of the 2 patches, once that is done, will test this.
Comment 4 Jakub Jelinek 2024-07-02 16:07:55 UTC
Created attachment 58566 [details]
gcc15-pr114745.patch

Bootstrap/regtest of the first patch found one testcase that needed to be adjusted, here is an updated patch with that.
Comment 5 Jason Merrill 2024-07-02 17:15:28 UTC
LGTM
Comment 6 GCC Commits 2024-07-02 20:08:19 UTC
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:

https://gcc.gnu.org/g:f30bdb1f2d79fd787e0c270039179bf80830161f

commit r15-1793-gf30bdb1f2d79fd787e0c270039179bf80830161f
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Tue Jul 2 22:07:30 2024 +0200

    c++: Implement C++26 P0963R3 - Structured binding declaration as a condition [PR115745]
    
    This C++26 paper allows structured bindings declaration in
    if/while/for/switch conditions, where the structured binding shouldn't
    be initialized by array (so in the standard only non-union class types;
    as extension _Complex will also work and vectors will be diagnosed because
    of conversion issues) and the decision variable is the artificial variable
    (e in the standard) itself contextually converted to bool or converted to
    some integer/enumeration type.
    The standard requires that the conversion is evaluated before the get calls
    in case of std::tuple* using class, so the largest part of the patch is making
    sure this can be done during instantiation without duplicating too much
    code.
    In cp_parser_condition, creating a TARGET_EXPR to hold temporarily the
    bool or int/enum result of the conversion across the get calls is easy, it
    could be just added in between cp_finish_decl and cp_finish_decomp, but for
    pt.cc there was no easy spot to add that.
    In the end, the patch uses DECL_DECOMP_BASE for this.  That tree is used
    primarily for the user vars or var proxies to point back at the
    DECL_ARTIFICIAL e variable, before this patch it has been NULL_TREE on
    the base.  In some places code was checking if DECL_DECOMP_BASE is NULL_TREE
    to find out if it is the base or user var/var proxy.
    The patch introduces DECL_DECOMP_IS_BASE macro for what used to be
    !DECL_DECOMP_BASE and can stick something else in the base's
    DECL_DECOMP_BASE as long as it is not a VAR_DECL.
    The patch uses integer_zero_node to mark if/while/for condition structured
    binding, integer_one_node to mark switch condition structured binding and
    finally cp_finish_decomp sets it to TARGET_EXPR if some get method calls are
    emitted and from there the callers can pick that up.  This way I also
    avoided code duplication between !processing_template_decl parsing and
    pt.cc.
    
    2024-07-02  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/115745
    gcc/cp/
            * cp-tree.h: Implement C++26 P0963R3 - Structured binding declaration
            as a condition.
            (DECL_DECOMP_BASE): Adjust comment.
            (DECL_DECOMP_IS_BASE): Define.
            * parser.cc (cp_parser_selection_statement): Adjust
            cp_parser_condition caller.
            (cp_parser_condition): Add KEYWORD argument.  Parse
            C++26 structured bindings in conditions.
            (cp_parser_c_for, cp_parser_iteration_statement): Adjust
            cp_parser_condition callers.
            (cp_parser_simple_declaration): Adjust
            cp_parser_decomposition_declaration caller.
            (cp_parser_decomposition_declaration): Add KEYWORD argument.
            If it is not RID_MAX, diagnose for C++23 and older rather than C++14
            and older.  Set DECL_DECOMP_BASE to integer_zero_node for structured
            bindings used in if/while/for conditions or integer_one_node for
            those used in switch conditions.
            * decl.cc (poplevel, check_array_initializer): Use DECL_DECOMP_IS_BASE
            instead of !DECL_DECOMP_BASE.
            (cp_finish_decomp): Diagnose array initializer for structured bindings
            used in conditions.  If using std::tuple_{size,element}, emit
            conversion to bool or integer/enumeration of e into a TARGET_EXPR
            before emitting get method calls.
            * decl2.cc (mark_used): Use DECL_DECOMP_IS_BASE instead of
            !DECL_DECOMP_BASE.
            * module.cc (trees_in::tree_node): Likewise.
            * typeck.cc (maybe_warn_about_returning_address_of_local): Likewise.
            * semantics.cc (maybe_convert_cond): For structured bindings with
            TARGET_EXPR DECL_DECOMP_BASE use that as condition.
            (finish_switch_cond): Likewise.
    gcc/testsuite/
            * g++.dg/cpp1z/decomp16.C: Adjust expected diagnostics.
            * g++.dg/cpp26/decomp3.C: New test.
            * g++.dg/cpp26/decomp4.C: New test.
            * g++.dg/cpp26/decomp5.C: New test.
            * g++.dg/cpp26/decomp6.C: New test.
            * g++.dg/cpp26/decomp7.C: New test.
            * g++.dg/cpp26/decomp8.C: New test.
            * g++.dg/cpp26/decomp9.C: New test.
            * g++.dg/cpp26/decomp10.C: New test.
Comment 7 Jakub Jelinek 2024-07-02 20:11:28 UTC
Implemented for 15.1+.