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

--- Comment #5 from GCC Commits <cvs-commit at gcc dot gnu.org> ---
The trunk branch has been updated by Marek Polacek <mpola...@gcc.gnu.org>:

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

commit r16-3195-gd2dccd1bf79b862b9989c1b62ed8c074980cd457
Author: Marek Polacek <pola...@redhat.com>
Date:   Wed Nov 13 16:56:40 2024 -0500

    c++: P2036R3 - Change scope of lambda trailing-return-type [PR102610]

    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 -> 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 ->
    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 "-> 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) <case sk_lambda>: 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 <ja...@redhat.com>
  • [Bug c++/102610] [C++23] P2036R... cvs-commit at gcc dot gnu.org via Gcc-bugs

Reply via email to