https://gcc.gnu.org/g:1fa4437e3c784e5084f443e5e13e79ba0cdc3c68

commit r17-1861-g1fa4437e3c784e5084f443e5e13e79ba0cdc3c68
Author: Jakub Jelinek <[email protected]>
Date:   Thu Jun 25 19:11:32 2026 +0200

    c++: Add tests for C++29 P3847R1 - Lexical order for lambdas [PR125832]
    
    I believe we already implement the P3847R1 - Lexical order for lambdas
    paper, after all it is part of the ABI.
    So, this patch just adds tests to verify that, so that we can mark this
    as implemented (I'd say just Yes, even GCC 4.6 passes the second test
    with -std=c++0x and GCC 4.8 with -std=c++1y the first test).
    
    2026-06-25  Jakub Jelinek  <[email protected]>
    
            PR c++/125832
            * g++.dg/cpp29/lambda-order1.C: New test.
            * g++.dg/cpp29/lambda-order2.C: New test.
    
    Reviewed-by: Jason Merrill <[email protected]>

Diff:
---
 gcc/testsuite/g++.dg/cpp29/lambda-order1.C | 80 ++++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/cpp29/lambda-order2.C | 24 +++++++++
 2 files changed, 104 insertions(+)

diff --git a/gcc/testsuite/g++.dg/cpp29/lambda-order1.C 
b/gcc/testsuite/g++.dg/cpp29/lambda-order1.C
new file mode 100644
index 000000000000..bba2cd5a54ff
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/lambda-order1.C
@@ -0,0 +1,80 @@
+// P3847R1 - Lexical order for lambdas
+// { dg-do run { target c++14 } }
+
+int e;
+
+int
+foo (int x)
+{
+  if (x != e)
+    __builtin_abort ();
+  ++e;
+  return x;
+}
+
+int &
+bar (int x)
+{
+  if (x != e)
+    __builtin_abort ();
+  ++e;
+  return e;
+}
+
+int
+main ()
+{
+  int a = 1;
+  long b = 2;
+  double c = 3;
+  short d = 4;
+  foo (0);
+  auto f = [&, a0 = foo (1), a, a1 = foo (2),
+           b0 = foo (3), b, b1 = foo (4),
+           c0 = foo (5), c, c1 = foo (6)] () {
+    if (&a0 >= &a
+       || &a >= &a1
+       || (const void *) &a1 >= (const void *) &b0
+       || (const void *) &b0 >= (const void *) &b
+       /* d is captured implicitly, the ordering for
+          the d member vs. the explicitly captured
+          ones is still unspecified by C++, but part
+          of the Itanium ABI.  Just test that it doesn't
+          change the order of the explicit captures.  */
+       || d != 4
+       || (const void *) &b >= (const void *) &b1
+       || (const void *) &b1 >= (const void *) &c0
+       || (const void *) &c0 >= (const void *) &c
+       || (const void *) &c >= (const void *) &c1)
+      __builtin_abort ();
+  };
+  foo (7);
+  f ();
+  foo (8);
+  f ();
+  foo (9);
+  auto g = [=, &a0 = bar (10), &a, &a1 = bar (11),
+           &b0 = bar (12), &b, &b1 = bar (13),
+           &c0 = bar (14), &c, &c1 = bar (15)] () {
+    return a0 + a + a1 + b0 + b + b1 + c0 + c + c1;
+  };
+  foo (16);
+  g ();
+  foo (17);
+  auto h = [&, a0 = foo (18), a, a1 = foo (19),
+           b0 = foo (20), b, b1 = foo (21),
+           c0 = foo (22), c, c1 = foo (23)] () {
+    if (&a0 >= &a
+       || &a >= &a1
+       || (const void *) &a1 >= (const void *) &b0
+       || (const void *) &b0 >= (const void *) &b
+       || (const void *) &b >= (const void *) &b1
+       || (const void *) &b1 >= (const void *) &c0
+       || (const void *) &c0 >= (const void *) &c
+       || (const void *) &c >= (const void *) &c1)
+      __builtin_abort ();
+  };
+  foo (24);
+  h ();
+  foo (25);
+}
diff --git a/gcc/testsuite/g++.dg/cpp29/lambda-order2.C 
b/gcc/testsuite/g++.dg/cpp29/lambda-order2.C
new file mode 100644
index 000000000000..999825e4d116
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp29/lambda-order2.C
@@ -0,0 +1,24 @@
+// P3847R1 - Lexical order for lambdas
+// { dg-do run { target c++11 } }
+
+int
+main ()
+{
+  int a = 1;
+  long b = 2;
+  double c = 3;
+  short d = 4;
+  auto f = [&, a, b, c] () {
+    if ((const void *) &a >= (const void *) &b
+       /* d is captured implicitly, the ordering for
+          the d member vs. the explicitly captured
+          ones is still unspecified by C++, but part
+          of the Itanium ABI.  Just test that it doesn't
+          change the order of the explicit captures.  */
+       || d != 4
+       || (const void *) &b >= (const void *) &c)
+      __builtin_abort ();
+  };
+  f ();
+  f ();
+}

Reply via email to