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

--- Comment #3 from CVS 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:123b3e03c911a43054c1f88f5d3110e1d084dd4e

commit r11-8065-g123b3e03c911a43054c1f88f5d3110e1d084dd4e
Author: Patrick Palka <ppa...@redhat.com>
Date:   Thu Apr 8 13:07:43 2021 -0400

    c++: Don't substitute into constraints on lambdas [PR99874]

    We currently substitute through a lambda's constraints whenever we
    regenerate it via tsubst_lambda_expr.  This is the wrong approach
    because it can lead to hard errors due to constraints being evaluated
    out of order (as in the testcase concepts-lambda17.C below), and because
    it doesn't mesh well with the recently added REQUIRES_EXPR_EXTRA_ARGS
    mechanism for delaying substitution into requires-expressions, which is
    the cause of this PR.

    But in order to avoid substituting through a lambda's constraints during
    regeneration, we need to be able to get at all in-scope template
    parameters and corresponding template arguments during constraint
    checking of a lambda's op().  And this information is not easily
    available when we need it, it seems.

    To that end, the approach that this patch takes is to add two new fields
    to LAMBDA_EXPR (and remove one): LAMBDA_EXPR_REGENERATED_FROM
    (replacing LAMBDA_EXPR_INSTANTIATED), and LAMBDA_EXPR_REGENERATING_TARGS.
    The former allows us to obtain the complete set of template parameters
    that are in-scope for a lambda's op(), and the latter gives us all outer
    template arguments that were used to regenerate the lambda (analogous to
    the TI_TEMPLATE and TI_ARGS of a TEMPLATE_INFO, respectively).

    LAMBDA_EXPR_REGENERATING_TARGS is not strictly necessary -- in an
    earlier prototype, I walked LAMBDA_EXPR_EXTRA_SCOPE to build up this set
    of outer template arguments on demand, but it seems cleaner to do it this
    way.  (We'd need to walk LAMBDA_EXPR_EXTRA_SCOPE and not DECL/TYPE_CONTEXT
    because the latter skips over variable template scopes.)

    This patch also renames the predicate instantiated_lambda_fn_p to
    regenerated_lambda_fn_p, for sake of consistency with the rest of the
    patch which uses "regenerated" instead of "instantiated".

    gcc/cp/ChangeLog:

            PR c++/99874
            * constraint.cc (get_normalized_constraints_from_decl): Handle
            regenerated lambdas.
            (satisfy_declaration_constraints): Likewise.  Check for
            dependent args later.
            * cp-tree.h (LAMBDA_EXPR_INSTANTIATED): Replace with ...
            (LAMBDA_EXPR_REGENERATED_FROM): ... this.
            (LAMBDA_EXPR_REGENERATING_TARGS): New.
            (tree_lambda_expr::regenerated_from): New data member.
            (tree_lambda_expr::regenerating_targs): New data member.
            (add_to_template_args): Declare.
            (regenerated_lambda_fn_p): Likewise.
            (most_general_lambda): Likewise.
            * lambda.c (build_lambda_expr): Set LAMBDA_EXPR_REGENERATED_FROM
            and LAMBDA_EXPR_REGENERATING_TARGS.
            * pt.c (add_to_template_args): No longer static.
            (tsubst_function_decl): Unconditionally propagate constraints on
            the substituted function decl.
            (instantiated_lambda_fn_p): Rename to ...
            (regenerated_lambda_fn_p): ... this.  Check
            LAMBDA_EXPR_REGENERATED_FROM instead of
            LAMBDA_EXPR_INSTANTIATED.
            (most_general_lambda): Define.
            (enclosing_instantiation_of): Adjust after renaming
            instantiated_lambda_fn_p.
            (tsubst_lambda_expr): Don't set LAMBDA_EXPR_INSTANTIATED.  Set
            LAMBDA_EXPR_REGENERATED_FROM and LAMBDA_EXPR_REGENERATING_TARGS.
            Don't substitute or set constraints on the regenerated lambda.

    gcc/testsuite/ChangeLog:

            PR c++/99874
            * g++.dg/cpp2a/concepts-lambda16.C: New test.
            * g++.dg/cpp2a/concepts-lambda17.C: New test.

Reply via email to