https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116756

--- Comment #2 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Patrick Palka <ppa...@gcc.gnu.org>:

https://gcc.gnu.org/g:303cc73182db5ed367b184df813cd50864c55f83

commit r15-7118-g303cc73182db5ed367b184df813cd50864c55f83
Author: Patrick Palka <ppa...@redhat.com>
Date:   Tue Jan 21 21:57:02 2025 -0500

    c++: 'this' capture clobbered during recursive inst [PR116756]

    Here during instantiation of generic lambda's op() [with I = 0] we
    substitute into the call self(self, cst<1>{}) which requires recursive
    instantiation of the same op() [with I = 1] (which isn't deferred due to
    lambda's deduced return type.  During this recursive instantiation, the
    DECL_EXPR case of tsubst_stmt clobbers LAMBDA_EXPR_THIS_CAPTURE to point
    to the child op()'s specialized capture proxy instead of the parent's,
    and the original value is never restored.

    So later when substituting into the openSeries call in the parent op()
    maybe_resolve_dummy uses the 'this' proxy belonging to the child op(),
    which leads to a context mismatch ICE during gimplification of the
    proxy.

    An earlier version of this patch fixed this by making instantiate_body
    save/restore LAMBDA_EXPR_THIS_CAPTURE during a lambda op() instantiation.
    But it seems cleaner to avoid overwriting LAMBDA_EXPR_THIS_CAPTURE in the
    first place by making it point to the non-specialized capture proxy, and
    instead call retrieve_local_specialization as needed, which is what this
    patch implements.  It's natural then to not clear LAMBDA_EXPR_THIS_CAPTURE
    after parsing/regenerating a lambda.

            PR c++/116756

    gcc/cp/ChangeLog:

            * lambda.cc (lambda_expr_this_capture): Call
            retrieve_local_specialization on the result of
            LAMBDA_EXPR_THIS_CAPTURE for a generic lambda.
            * parser.cc (cp_parser_lambda_expression): Don't clear
            LAMBDA_EXPR_THIS_CAPTURE.
            * pt.cc (tsubst_stmt) <case DECL_EXPR>: Don't overwrite
            LAMBDA_EXPR_THIS_CAPTURE with the specialized capture.
            (tsubst_lambda_expr): Don't clear LAMBDA_EXPR_THIS_CAPTURE
            afterward.

    gcc/testsuite/ChangeLog:

            * g++.dg/cpp1z/constexpr-if-lambda7.C: New test.

    Reviewed-by: Jason Merrill <ja...@redhat.com>

Reply via email to