On Mon, Nov 20, 2017 at 01:31:39PM -0500, Nathan Sidwell wrote:
> On 11/20/2017 02:55 AM, Jakub Jelinek wrote:
> 
> >    http://gcc.gnu.org/ml/gcc-patches/2017-11/msg00851.html
> >    C++2A P0428R2 - familiar template syntax for generic lambdas
> 
> Are there existing testcases checking this is permitted w/o warning under
> the appropriate circumstances?  That seems to be the only thing missing from
> the patch itself.

At least for check-c++-all I believe it is mostly covered.  E.g.
g++.dg/cpp1y/lambda-generic-x.C has:
// { dg-warning "lambda templates are only available with" "" { target 
c++17_down } }
which checks that with -Wpedantic there is warning emitted in -std=gnu++14
and -std=gnu++17, but not with -std=gnu++20.  Similarly several other
testcases.
And g++.dg/cpp2a/lambda-generic1.C has:
// { dg-error "lambda templates are only available with" "" { target c++17_down 
} }
that verifies that with -pedantic-errors in -std=c++14 and -std=c++17
an error is emitted and in -std=c++20 no error/warning is diagnosed.

So, what isn't tested is: 1) behavior for C++98/C++11 2) -Wno-pedantic
behavior 3) at least one test that would catch it even without check-c++-all
for -std=c++2a

Therefore, I've added 3 new small tests that are compiled by all language
variants and check -pedantic-errors, -Wpedantic and -Wno-pedantic behavior
and one that forces -std=c++2a into dg-options and thus works even without
check-c++-all and committed.  Thanks.

2017-11-21  Jakub Jelinek  <ja...@redhat.com>

        P0428R2 - familiar template syntax for generic lambdas
        * parser.c (cp_parser_lambda_declarator_opt): Don't pedwarn
        for cxx2a and above, reword pedwarn for C++14/C++17.

        * g++.dg/cpp1y/lambda-generic-x.C: Adjust warnings and limit
        to c++17_down target.
        * g++.dg/cpp1y/lambda-generic-dep.C: Likewise.
        * g++.dg/cpp1y/lambda-generic-77914.C: Adjust error and limit
        to c++17_down target.
        * g++.dg/cpp2a/lambda-generic1.C: New test.
        * g++.dg/cpp2a/lambda-generic2.C: New test.
        * g++.dg/cpp2a/lambda-generic3.C: New test.
        * g++.dg/cpp2a/lambda-generic4.C: New test.
        * g++.dg/cpp2a/lambda-generic5.C: New test.

--- gcc/cp/parser.c.jj  2017-11-20 19:56:04.787470779 +0100
+++ gcc/cp/parser.c     2017-11-21 09:15:30.127267088 +0100
@@ -10512,9 +10512,10 @@ cp_parser_lambda_declarator_opt (cp_pars
        pedwarn (parser->lexer->next_token->location, 0,
                 "lambda templates are only available with "
                 "-std=c++14 or -std=gnu++14");
-      else
+      else if (cxx_dialect < cxx2a)
        pedwarn (parser->lexer->next_token->location, OPT_Wpedantic,
-                "ISO C++ does not support lambda templates");
+                "lambda templates are only available with "
+                "-std=c++2a or -std=gnu++2a");
 
       cp_lexer_consume_token (parser->lexer);
 
--- gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C.jj    2017-11-10 
15:42:02.371152517 +0100
+++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C       2017-11-21 
09:15:30.147266840 +0100
@@ -6,17 +6,17 @@
 
 int main()
 {
-   auto glambda = [] <typename A, typename B> (A a, B&& b) { return a < b; };  
// { dg-warning "does not support lambda templates" }
+   auto glambda = [] <typename A, typename B> (A a, B&& b) { return a < b; };  
// { dg-warning "lambda templates are only available with" "" { target 
c++17_down } }
    bool b = glambda(3, 3.14); // OK
-   auto vglambda = [] <typename P> (P printer) {                               
// { dg-warning "does not support lambda templates" }
+   auto vglambda = [] <typename P> (P printer) {                               
// { dg-warning "lambda templates are only available with" "" { target 
c++17_down } }
      return [=] <typename... T> (T&& ... ts) { // OK: ts is a function 
parameter pack
-       printer(std::forward<decltype(ts)>(ts)...);                             
// { dg-warning "does not support lambda templates" "" { target *-*-* } .-1 }
+       printer(std::forward<decltype(ts)>(ts)...);                             
// { dg-warning "lambda templates are only available with" "" { target 
c++17_down } .-1 }
        return [=]() {
          printer(ts ...);
        };
      };
    };
-   auto p = vglambda( [] <typename A,                                          
// { dg-warning "does not support lambda templates" }
+   auto p = vglambda( [] <typename A,                                          
// { dg-warning "lambda templates are only available with" "" { target 
c++17_down } }
                           typename B,
                           typename C> (A v1, B v2, C v3)
      { std::cout << v1 << v2 << v3; } );
--- gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C.jj  2017-11-10 
15:42:02.394152236 +0100
+++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C     2017-11-21 
09:15:30.161266666 +0100
@@ -27,7 +27,7 @@ struct S {
 
 int main()
 {
-  auto f = [] <typename T> (T const& s) mutable {      // { dg-warning "does 
not support lambda templates" }
+  auto f = [] <typename T> (T const& s) mutable {      // { dg-warning "lambda 
templates are only available with" "" { target c++17_down } }
     typename T::N x;
     return x.test ();
   };
--- gcc/testsuite/g++.dg/cpp1y/lambda-generic-77914.C.jj        2017-11-10 
15:42:02.336152944 +0100
+++ gcc/testsuite/g++.dg/cpp1y/lambda-generic-77914.C   2017-11-21 
09:15:30.169266567 +0100
@@ -4,6 +4,6 @@
 int
 main ()
 {
-  auto l = [] <typename T> () {};      // { dg-error "does not support lambda 
templates" }
+  auto l = [] <typename T> () {};      // { dg-error "lambda templates are 
only available with" "" { target c++17_down } }
   l.operator () <void> ();
 }
--- gcc/testsuite/g++.dg/cpp2a/lambda-generic1.C.jj     2017-11-21 
09:15:30.169266567 +0100
+++ gcc/testsuite/g++.dg/cpp2a/lambda-generic1.C        2017-11-21 
09:15:30.169266567 +0100
@@ -0,0 +1,9 @@
+// P0428R2
+// { dg-do compile { target c++14 } }
+
+int i = [](int i, auto a) { return i; }(3, 4);
+int j = []<class T>(T t, int i) { return i; }(3, 4);             // { dg-error 
"lambda templates are only available with" "" { target c++17_down } }
+int k[2] = { 5, 6 };
+int l = []<typename T>(T *p) { return *p; }(k);                          // { 
dg-error "lambda templates are only available with" "" { target c++17_down } }
+int m = []<typename T, int N>(T (&a)[N]) { return a[N - 1]; }(k); // { 
dg-error "lambda templates are only available with" "" { target c++17_down } }
+int n = []<typename T>(T a, auto b) { return a + b; }(7, 8);     // { dg-error 
"lambda templates are only available with" "" { target c++17_down } }
--- gcc/testsuite/g++.dg/cpp2a/lambda-generic2.C.jj     2017-11-21 
09:16:47.745302618 +0100
+++ gcc/testsuite/g++.dg/cpp2a/lambda-generic2.C        2017-11-21 
09:20:58.655184849 +0100
@@ -0,0 +1,7 @@
+// P0428R2
+// { dg-do compile }
+
+int j = []<class T>(T t, int i) { return i; }(3, 4);
+// { dg-error "lambda templates are only available with" "" { target 
c++17_down } .-1 }
+// { dg-error "lambda expressions only available with" "" { target c++98_only 
} .-2 }
+// { dg-error "invalid use of 'auto'" "" { target c++98_only } .-3 }
--- gcc/testsuite/g++.dg/cpp2a/lambda-generic3.C.jj     2017-11-21 
09:19:59.266922799 +0100
+++ gcc/testsuite/g++.dg/cpp2a/lambda-generic3.C        2017-11-21 
09:28:13.086788078 +0100
@@ -0,0 +1,8 @@
+// P0428R2
+// { dg-do compile }
+// { dg-options "-Wpedantic" }
+
+int j = []<class T>(T t, int i) { return i; }(3, 4);
+// { dg-warning "lambda templates are only available with" "" { target 
c++17_down } .-1 }
+// { dg-warning "lambda expressions only available with" "" { target 
c++98_only } .-2 }
+// { dg-error "invalid use of 'auto'" "" { target c++98_only } .-3 }
--- gcc/testsuite/g++.dg/cpp2a/lambda-generic4.C.jj     2017-11-21 
09:28:33.928529224 +0100
+++ gcc/testsuite/g++.dg/cpp2a/lambda-generic4.C        2017-11-21 
09:30:19.146222419 +0100
@@ -0,0 +1,8 @@
+// P0428R2
+// { dg-do compile }
+// { dg-options "-Wno-pedantic" }
+
+int j = []<class T>(T t, int i) { return i; }(3, 4);
+// { dg-warning "lambda templates are only available with" "" { target 
c++11_down } .-1 }
+// { dg-warning "lambda expressions only available with" "" { target 
c++98_only } .-2 }
+// { dg-error "invalid use of 'auto'" "" { target c++98_only } .-3 }
--- gcc/testsuite/g++.dg/cpp2a/lambda-generic5.C.jj     2017-11-21 
09:21:25.785847728 +0100
+++ gcc/testsuite/g++.dg/cpp2a/lambda-generic5.C        2017-11-21 
09:31:02.871679348 +0100
@@ -0,0 +1,6 @@
+// P0428R2
+// { dg-do compile }
+// { dg-options "-std=c++2a" }
+
+int j = []<class T>(T t, int i) { return i; }(3, 4);
+// { dg-bogus "lambda templates are only available with" "" { target c++2a } 
.-1 }


        Jakub

Reply via email to