https://gcc.gnu.org/g:4073a7927b1644f5b56b83f04f92e81b31f6517b
commit r17-1727-g4073a7927b1644f5b56b83f04f92e81b31f6517b Author: Jason Merrill <[email protected]> Date: Fri Jun 19 17:43:44 2026 -0400 c++: capture folding and lvalueness checking [PR125408] Here after the recursive mark_rvalue_use we end up with a VAR_DECL in r, so the assert fails. But in that case r is still an lvalue, so we don't need to do any adjustment. Fixed by adjusting the condition to detect the case we actually need to fix up, i.e. when ref is an lvalue and r is not. The previous !rvalue_p condition doesn't make much sense; rvalue_p indicates whether we want to do an lvalue-rvalue conversion on expr, not whether expr was already an rvalue. PR c++/125408 gcc/cp/ChangeLog: * expr.cc (mark_use): Fix condition for changing rvalue to lvalue. gcc/testsuite/ChangeLog: * g++.dg/cpp2a/lambda-targ34.C: New test. Diff: --- gcc/cp/expr.cc | 2 +- gcc/testsuite/g++.dg/cpp2a/lambda-targ34.C | 31 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/gcc/cp/expr.cc b/gcc/cp/expr.cc index 516cea084a6f..e7195631c35c 100644 --- a/gcc/cp/expr.cc +++ b/gcc/cp/expr.cc @@ -186,7 +186,7 @@ mark_use (tree expr, bool rvalue_p, bool read_p, return error_mark_node; if (r != ref) { - if (!rvalue_p) + if (DECL_P (ref) && !lvalue_p (r)) { /* Make sure we still return an lvalue. */ gcc_assert (TREE_CODE (r) == NOP_EXPR); diff --git a/gcc/testsuite/g++.dg/cpp2a/lambda-targ34.C b/gcc/testsuite/g++.dg/cpp2a/lambda-targ34.C new file mode 100644 index 000000000000..a41d24d640ba --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp2a/lambda-targ34.C @@ -0,0 +1,31 @@ +// PR c++/125408 +// { dg-do compile { target c++20 } } + +struct Role { + long id; +}; + +template <typename T> +struct StaticObj { + inline static T obj; +}; + +template<int... I> struct A { }; + +template <auto Ptr, typename Table> +constexpr int find_member_index() { + constexpr auto& t = StaticObj<Table>::obj; + + [&]<int... Idx>(A<Idx...>) { + ([&]{ + using T1 = decltype(&(t.*Ptr)); + auto p = &(t.*Ptr); + return Idx; + }(), ...); + }(A<0,1>{}); + return 42; +} + +auto p = find_member_index<&Role::id, Role>(); + +int main() {}
