https://gcc.gnu.org/g:b3399b445ba7495b0479d43f2389e64d48de870e

commit r14-10220-gb3399b445ba7495b0479d43f2389e64d48de870e
Author: Patrick Palka <ppa...@redhat.com>
Date:   Tue May 14 22:55:16 2024 -0400

    c++: lvalueness of non-dependent assignment expr [PR114994]
    
    r14-4111-g6e92a6a2a72d3b made us check non-dependent simple assignment
    expressions ahead of time and give them a type, as was already done for
    compound assignments.  Unlike for compound assignments however, if a
    simple assignment resolves to an operator overload we represent it as a
    (typed) MODOP_EXPR instead of a CALL_EXPR to the selected overload.
    (I reckoned this was at worst a pessimization -- we'll just have to repeat
    overload resolution at instantiatiation time.)
    
    But this turns out to break the below testcase ultimately because
    MODOP_EXPR (of non-reference type) is always treated as an lvalue
    according to lvalue_kind, which is incorrect for the MODOP_EXPR
    representing x=42.
    
    We can fix this by representing such class assignment expressions as
    CALL_EXPRs as well, but this turns out to require some tweaking of our
    -Wparentheses warning logic and may introduce other fallout making it
    unsuitable for backporting.
    
    So this patch instead fixes lvalue_kind to consider the type of a
    MODOP_EXPR representing a class assignment.
    
            PR c++/114994
    
    gcc/cp/ChangeLog:
    
            * tree.cc (lvalue_kind) <case MODOP_EXPR>: For a class
            assignment, consider the result type.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/template/non-dependent32.C: New test.
    
    Reviewed-by: Jason Merrill <ja...@redhat.com>
    (cherry picked from commit c6cc6d4741a880109c4e0e64d5a189687fb526f6)

Diff:
---
 gcc/cp/tree.cc                                  |  5 ++++-
 gcc/testsuite/g++.dg/template/non-dependent32.C | 18 ++++++++++++++++++
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index f1a23ffe8179..9d37d255d8d5 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -275,7 +275,10 @@ lvalue_kind (const_tree ref)
       /* We expect to see unlowered MODOP_EXPRs only during
         template processing.  */
       gcc_assert (processing_template_decl);
-      return clk_ordinary;
+      if (CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0))))
+       goto default_;
+      else
+       return clk_ordinary;
 
     case MODIFY_EXPR:
     case TYPEID_EXPR:
diff --git a/gcc/testsuite/g++.dg/template/non-dependent32.C 
b/gcc/testsuite/g++.dg/template/non-dependent32.C
new file mode 100644
index 000000000000..54252c7dfaf9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/non-dependent32.C
@@ -0,0 +1,18 @@
+// PR c++/114994
+// { dg-do compile { target c++11 } }
+
+struct udl_arg {
+  udl_arg operator=(int);
+};
+
+void f(udl_arg&&);
+
+template<class>
+void g() {
+  udl_arg x;
+  f(x=42); // { dg-bogus "cannot bind" }
+}
+
+int main() {
+  g<int>();
+}

Reply via email to