OK.

On Thu, Jun 14, 2018 at 9:00 AM, Jakub Jelinek <ja...@redhat.com> wrote:
> Hi!
>
> The following patch implements P0624R2, where stateless lambdas don't have
> deleted default ctor and copy assignment operator anymore.
>
> Tested on x86_64-linux with check-c++-all and libstdc++ testsuite, ok for
> trunk?
>
> 2018-06-14  Jakub Jelinek  <ja...@redhat.com>
>
>         P0624R2 - Default constructible and assignable stateless lambdas
>         * method.c (synthesized_method_walk): For C++2a don't mark
>         sfk_constructor or sfk_copy_assignment as deleted if lambda has
>         no lambda-captures.
>
>         * g++.dg/cpp2a/lambda1.C: New test.
>         * g++.dg/cpp0x/lambda/lambda-ice2.C: Adjust expected diagnostics
>         for -std=c++2a.
>
> --- gcc/cp/method.c.jj  2018-05-21 13:15:33.519575351 +0200
> +++ gcc/cp/method.c     2018-06-14 13:48:58.825585083 +0200
> @@ -1539,10 +1539,15 @@ synthesized_method_walk (tree ctype, spe
>      {
>        /* "The closure type associated with a lambda-expression has a deleted
>          default constructor and a deleted copy assignment operator."
> -         This is diagnosed in maybe_explain_implicit_delete.  */
> +        This is diagnosed in maybe_explain_implicit_delete.
> +        In C++2a, only lambda-expressions with lambda-captures have those
> +        deleted.  */
>        if (LAMBDA_TYPE_P (ctype)
> -         && (sfk == sfk_constructor
> -             || sfk == sfk_copy_assignment))
> +         && (sfk == sfk_constructor || sfk == sfk_copy_assignment)
> +         && (cxx_dialect < cxx2a
> +             || LAMBDA_EXPR_CAPTURE_LIST (CLASSTYPE_LAMBDA_EXPR (ctype))
> +             || LAMBDA_EXPR_DEFAULT_CAPTURE_MODE
> +                               (CLASSTYPE_LAMBDA_EXPR (ctype)) != CPLD_NONE))
>         {
>           *deleted_p = true;
>           return;
> --- gcc/testsuite/g++.dg/cpp2a/lambda1.C.jj     2018-06-14 14:27:29.903602374 
> +0200
> +++ gcc/testsuite/g++.dg/cpp2a/lambda1.C        2018-06-14 14:26:51.462571226 
> +0200
> @@ -0,0 +1,58 @@
> +// P0624R2
> +// { dg-do compile { target c++11 } }
> +
> +#if __cplusplus >= 201402L
> +#define A auto
> +#else
> +#define A int
> +#endif
> +
> +void
> +f1 ()
> +{
> +  auto greater = [](A x, A y) { return x > y; };       // { dg-message "a 
> lambda closure type has a deleted (default constructor|copy assignment 
> operator)" "" { target c++17_down } }
> +  decltype (greater) gt;       // { dg-error "use of deleted function" "" { 
> target c++17_down } }
> +  gt = greater;                        // { dg-error "use of deleted 
> function" "" { target c++17_down } }
> +}
> +
> +void
> +f2 ()
> +{
> +  auto greater = [&](A x, A y) { return x > y; };      // { dg-message "a 
> lambda closure type has a deleted (default constructor|copy assignment 
> operator)" }
> +  decltype (greater) gt;       // { dg-error "use of deleted function" }
> +  gt = greater;                        // { dg-error "use of deleted 
> function" }
> +}
> +
> +void
> +f3 ()
> +{
> +  auto greater = [=](A x, A y) { return x > y; };      // { dg-message "a 
> lambda closure type has a deleted (default constructor|copy assignment 
> operator)" }
> +  decltype (greater) gt;       // { dg-error "use of deleted function" }
> +  gt = greater;                        // { dg-error "use of deleted 
> function" }
> +}
> +
> +void
> +f4 (int i)
> +{
> +  auto greater = [i](A x, A y) { return x > y; };      // { dg-message "a 
> lambda closure type has a deleted (default constructor|copy assignment 
> operator)" }
> +  decltype (greater) gt;       // { dg-error "use of deleted function" }
> +  gt = greater;                        // { dg-error "use of deleted 
> function" }
> +}
> +
> +#if __cplusplus > 201703L
> +void
> +f5 ()
> +{
> +  auto greater = [](auto x, auto y) constexpr { return x > y; };
> +  decltype (greater) gt;
> +  static_assert (!gt (1, 2));
> +  static_assert (gt (4, 3));
> +  static_assert (!gt (3.5, 3.75));
> +  static_assert (gt (3.5, 3.25));
> +  gt = greater;
> +  static_assert (!gt (1, 2));
> +  static_assert (gt (4, 3));
> +  static_assert (!gt (3.5, 3.75));
> +  static_assert (gt (3.5, 3.25));
> +}
> +#endif
> --- gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C.jj  2014-05-15 
> 11:58:42.000000000 +0200
> +++ gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ice2.C     2018-06-14 
> 14:32:03.760824236 +0200
> @@ -2,15 +2,15 @@
>  // { dg-do compile { target c++11 } }
>
>  template<typename F>
> -decltype(F()) run(F f) // { dg-message "note" }
> +decltype(F()) run(F f) // { dg-message "note" "" { target c++17_down } }
>  {
> -  return f();
> +  return f();  // { dg-error "could not convert" "" { target c++2a } }
>  }
>
>  int main()
>  {
> -  auto l = []() { return 5; }; // { dg-message "lambda closure type" }
> +  auto l = []() { return 5; }; // { dg-message "lambda closure type" "" { 
> target c++17_down } }
>
> -  run(l); // { dg-error "no match" }
> -  // { dg-error "use of deleted function" "candidate explanation" { target 
> *-*-* } 5 }
> +  run(l); // { dg-error "no match" "" { target c++17_down } }
> +  // { dg-error "use of deleted function" "candidate explanation" { target 
> c++17_down } 5 }
>  }
>
>         Jakub

Reply via email to