aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2024-05-14 22:55:16 -0400
committerPatrick Palka <ppalka@redhat.com>2024-05-14 22:55:16 -0400
commitc6cc6d4741a880109c4e0e64d5a189687fb526f6 (patch)
tree9498d88c819c00302bf8371a7d341f722090ff81 /gcc
parent32ff344d57d56fddb66c4976b5651345d40b7157 (diff)
downloadgcc-c6cc6d4741a880109c4e0e64d5a189687fb526f6.zip
gcc-c6cc6d4741a880109c4e0e64d5a189687fb526f6.tar.gz
gcc-c6cc6d4741a880109c4e0e64d5a189687fb526f6.tar.bz2
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 <jason@redhat.com>
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/tree.cc5
-rw-r--r--gcc/testsuite/g++.dg/template/non-dependent32.C18
2 files changed, 22 insertions, 1 deletions
diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index f1a23ff..9d37d25 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 0000000..54252c7
--- /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>();
+}