Patchwork [C++,3/3] Add some generic lambda test cases.

login
register
mail settings
Submitter Adam Butcher
Date Oct. 31, 2013, 9:47 a.m.
Message ID <1383212824-5493-4-git-send-email-adam@jessamine.co.uk>
Download mbox | patch
Permalink /patch/287962/
State New
Headers show

Comments

Adam Butcher - Oct. 31, 2013, 9:47 a.m.
gcc/testsuite/g++.dg/cpp1y/
		 * lambda-generic.C: New test case.
		 * lambda-generic-cfun.C: New test case.
		 * lambda-generic-dep.C: New test case.
		 * lambda-generic-udt.C: New test case.
		 * lambda-generic-variadic.C: New test case.
		 * lambda-generic-x.C: New test case.
		 * lambda-generic-xcfun.C: New test case.
		 * lambda-generic-xudt.C: New test case.
		 * lambda-generic-mixed.C: New test case.
---
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C   | 25 +++++++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C    | 42 ++++++++++++++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C  | 10 +++++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C    | 51 ++++++++++++++++++++++
 .../g++.dg/cpp1y/lambda-generic-variadic.C         | 15 +++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C      | 25 +++++++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C  | 25 +++++++++++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C   |  4 ++
 gcc/testsuite/g++.dg/cpp1y/lambda-generic.C        | 23 ++++++++++
 9 files changed, 220 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C
 create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-generic.C

Patch

diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C
new file mode 100644
index 0000000..5e51526
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-cfun.C
@@ -0,0 +1,25 @@ 
+// Generic lambda conversion to function ptr test from N3690 5.1.2.6
+// { dg-options "-std=c++1y" }
+
+void f1(int (*)(int)) { }
+void f2(char (*)(int)) { }
+void g(int (*)(int)) { } // #1
+void g(char (*)(char)) { } // #2
+void h(int (*)(int)) { } // #3
+void h(char (*)(int)) { } // #4
+
+int main()
+{
+  auto glambda = [](auto a) { return a; };
+  int (*fp)(int) = glambda;
+  f1(glambda); // OK
+  f2(glambda); // { dg-error "invalid user-defined conversion" }
+  g(glambda); // { dg-error "ambiguous" }
+  h(glambda); // OK: calls #3 since it is convertible from ID
+  int& (*fpi)(int*) = [](auto* a) -> auto& { return *a; }; // OK
+
+  auto GL = [](auto a) { return a; };
+  int (*GL_int)(int) = GL; // OK: through conversion function template
+  GL_int(3);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C
new file mode 100644
index 0000000..bb68738
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-dep.C
@@ -0,0 +1,42 @@ 
+// Generic lambda type dependence test part from N3690 5.1.2.12
+// { dg-options "-std=c++1y" }
+
+void f(int, const int (&)[2] = {}) { } // #1
+void f(const int&, const int (&)[1]) { } // #2
+
+void test()
+{
+  const int x = 17;
+  auto g = [](auto a) {
+    f(x); // OK: calls #1, does not capture x
+  };
+  auto g2 = [=](auto a) {
+    int selector[sizeof(a) == 1 ? 1 : 2]{};
+    f(x, selector); // OK: is a dependent expression, so captures x
+  };
+}
+
+struct S {
+  struct N {
+    auto test () { return 7.f; }
+  };
+};
+
+#include <utility>
+
+int main()
+{
+  auto f = [] <typename T> (T const& s) mutable {
+    typename T::N x;
+    return x.test ();
+  };
+  auto g = [] (auto const& s) {
+    typename std::decay<decltype (s)>::type::N x;
+    return x.test ();
+  };
+
+  S i;
+  f(i);
+  g(i);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C
new file mode 100644
index 0000000..4e26fc5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-mixed.C
@@ -0,0 +1,10 @@ 
+// Mixed explicit and implicit generic lambda test.
+// { dg-options "-std=c++1y" }
+
+int main()
+{
+  auto f = [] <typename T> (T a, auto b) { return a + b; };
+  auto g = [] <typename T> (auto a, T b) { return a + b; };
+
+  return f (1.0, 3) + g (1.0, 3);
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C
new file mode 100644
index 0000000..9f6d45a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-udt.C
@@ -0,0 +1,51 @@ 
+// Ensure that generic lambdas properly construct and destroy user types.
+// { dg-options "-std=c++1y -DUSE_AUTO_SYNTAX" }
+// { dg-do run }
+
+int i = 3;
+
+struct S
+{
+  S () { ++i; }
+  S (S const&) { ++i; }
+  S (S&& old) { old.shadow = true; i += 2; }
+  ~S () { if (shadow) i -= 2; else --i; }
+
+  bool shadow = false;
+};
+
+extern "C" void printf(...);
+#define assert(e) if (e); else \
+		 printf ("%s:%d: !(%s)\n", __FILE__, __LINE__, #e), __builtin_abort ();
+
+int main ()
+{
+  assert (i == 3);
+  {
+    S s; assert (i == 4);
+
+    #if USE_AUTO_SYNTAX
+    auto byref = [] (auto& r)                   { (void) r; };
+    auto bycref = [] (auto const& r)            { (void) r; };
+    auto byval = [] (auto v, auto const x)      { assert (i == x); (void) v; };
+    auto byrval = [] (auto&& r, auto const x)   { S steal (static_cast<S&&>(r));
+		 		 		 		 		           assert (i == x); };
+
+    #elif USE_EXPLICIT_TEMPLATE_SYNTAX
+    auto byref = [] <typename T> (T& r)         { (void) r; };
+    auto bycref = [] <typename T> (T const& r)  { (void) r; };
+    auto byval = [] <typename T, typename I>
+		 		     (T v, I const x)		 		 { assert (i == x); (void) v; };
+    auto byrval = [] <typename T, typename I>
+		 		      (T&& r, I const x)		 		 { S steal (static_cast<S&&>(r));
+		 		 		 		 		           assert (i == x); };
+    #endif
+
+    byref (s); assert (i == 4);
+    bycref (s); assert (i == 4);
+    byval (s, 5); assert (i == 4);
+    byrval (static_cast<S&&>(s), 6); assert (i == 5);
+  }
+  assert (i == 3);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
new file mode 100644
index 0000000..bd41b35
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic.C
@@ -0,0 +1,15 @@ 
+// Basic generic lambda test
+// { dg-options "-std=c++1y" }
+// { dg-do run }
+
+template <typename T, typename U> struct pair {};
+template <typename... T> struct tuple {};
+
+int main()
+{
+  auto a = [] (auto, pair<auto,auto> v) { return sizeof (v); };
+  auto b = [] (auto, pair<pair<auto,auto>,auto>... v) { return sizeof... (v); };
+
+  a(1, pair<int, float>());
+  b(2, pair<pair<short,char>, double>(), pair<pair<float,long>, int>());
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C
new file mode 100644
index 0000000..48a6268
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-x.C
@@ -0,0 +1,25 @@ 
+// Explicit generic lambda test from N3690 5.1.2.5
+// { dg-options "-std=gnu++1y" }
+
+#include <iostream>
+
+int main()
+{
+   auto glambda = [] <typename A, typename B> (A a, B&& b) { return a < b; };
+   bool b = glambda(3, 3.14); // OK
+   auto vglambda = [] <typename P> (P printer) {
+     return [=] <typename... T> (T&& ... ts) { // OK: ts is a function parameter pack
+       printer(std::forward<decltype(ts)>(ts)...);
+       return [=]() {
+         printer(ts ...);
+       };
+     };
+   };
+   auto p = vglambda( [] <typename A,
+                          typename B,
+                          typename C> (A v1, B v2, C v3)
+     { std::cout << v1 << v2 << v3; } );
+   auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
+   q(); // OK: outputs 1a3.14
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C
new file mode 100644
index 0000000..d44b796
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xcfun.C
@@ -0,0 +1,25 @@ 
+// Explicit generic lambda conversion to function ptr test from N3690 5.1.2.6
+// { dg-options "-std=gnu++1y" }
+
+void f1(int (*)(int)) { }
+void f2(char (*)(int)) { }
+void g(int (*)(int)) { } // #1
+void g(char (*)(char)) { } // #2
+void h(int (*)(int)) { } // #3
+void h(char (*)(int)) { } // #4
+
+int main()
+{
+  auto glambda = [] <typename T> (T a) { return a; };
+  int (*fp)(int) = glambda;
+  f1(glambda); // OK
+  f2(glambda); // { dg-error "invalid user-defined conversion" }
+  g(glambda); // { dg-error "ambiguous" }
+  h(glambda); // OK: calls #3 since it is convertible from ID
+  int& (*fpi)(int*) = [] <typename T> (T* a) -> auto& { return *a; }; // OK
+
+  auto GL = [] <typename T> (T a) { return a; };
+  int (*GL_int)(int) = GL; // OK: through conversion function template
+  GL_int(3);
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C
new file mode 100644
index 0000000..fba864b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-xudt.C
@@ -0,0 +1,4 @@ 
+// Ensure that generic lambdas properly construct and destroy user types.
+// { dg-options "-std=gnu++1y -DUSE_EXPLICIT_TEMPLATE_SYNTAX" }
+
+#include "lambda-generic-udt.C"
diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic.C
new file mode 100644
index 0000000..1f66475
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic.C
@@ -0,0 +1,23 @@ 
+// Generic lambda test from N3690 5.1.2.5
+// { dg-options "-std=c++1y" }
+
+#include <iostream>
+
+int main()
+{
+  auto glambda = [](auto a, auto&& b) { return a < b; };
+  bool b = glambda(3, 3.14); // OK
+  auto vglambda = [](auto printer) {
+    return [=](auto&& ... ts) { // OK: ts is a function parameter pack
+      printer(std::forward<decltype(ts)>(ts)...);
+      return [=]() {
+        printer(ts ...);
+      };
+    };
+  };
+  auto p = vglambda( [](auto v1, auto v2, auto v3)
+    { std::cout << v1 << v2 << v3; } );
+  auto q = p(1, 'a', 3.14); // OK: outputs 1a3.14
+  q(); // OK: outputs 1a3.14
+}
+