https://gcc.gnu.org/g:4aa7bc7581a6241dc24d1ceaab7dca144ef04638

commit r15-11246-g4aa7bc7581a6241dc24d1ceaab7dca144ef04638
Author: Nathaniel Shead <[email protected]>
Date:   Sun Oct 5 21:30:56 2025 +1100

    c++: Ensure mark_lvalue_use returns an lvalue [PR122163]
    
    When processing a tentative capture of a rvalue reference, mark_use
    folds it away to the referred-to entity.  But this is an rvalue, and
    when called from an lvalue context an rvalue reference should still be
    an lvalue.
    
            PR c++/122163
    
    gcc/cp/ChangeLog:
    
            * expr.cc (mark_use): When processing a reference, always return
            an lvalue reference when !rvalue_p.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/lambda/lambda-ref3.C: New test.
    
    Signed-off-by: Nathaniel Shead <[email protected]>
    Reviewed-by: Jason Merrill <[email protected]>
    (cherry picked from commit ac524299110838ed8eafb615d100a28649af7f18)

Diff:
---
 gcc/cp/expr.cc                                  | 11 ++++++++++-
 gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref3.C | 18 ++++++++++++++++++
 2 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/expr.cc b/gcc/cp/expr.cc
index 2157cfba2ebb..d5c86ec575f7 100644
--- a/gcc/cp/expr.cc
+++ b/gcc/cp/expr.cc
@@ -180,7 +180,16 @@ mark_use (tree expr, bool rvalue_p, bool read_p,
            }
          tree r = mark_rvalue_use (ref, loc, reject_builtin);
          if (r != ref)
-           expr = convert_from_reference (r);
+           {
+             if (!rvalue_p)
+               {
+                 /* Make sure we still return an lvalue.  */
+                 gcc_assert (TREE_CODE (r) == NOP_EXPR);
+                 TREE_TYPE (r) = cp_build_reference_type (TREE_TYPE (r),
+                                                          false);
+               }
+             expr = convert_from_reference (r);
+           }
        }
       break;
 
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref3.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref3.C
new file mode 100644
index 000000000000..1e085b237968
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-ref3.C
@@ -0,0 +1,18 @@
+// { dg-do run { target c++11 } }
+
+int x;
+int main() {
+  constexpr int&& r = static_cast<int&&>(x);
+  r = 1;
+
+  auto a = [] { r = 2; };  // Not an ODR-use of 'r' so no capture needed.
+  auto b = [&] { r = 3; };
+
+  a();
+  if (r != 2)
+    __builtin_abort();
+
+  b();
+  if (r != 3)
+    __builtin_abort();
+}

Reply via email to