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 (); +}
