public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] c++: lvalueness of non-dependent assignment [PR114994]
@ 2024-05-09 20:23 Patrick Palka
  2024-05-09 20:29 ` Patrick Palka
  2024-05-10 19:42 ` Jason Merrill
  0 siblings, 2 replies; 7+ messages in thread
From: Patrick Palka @ 2024-05-09 20:23 UTC (permalink / raw)
  To: gcc-patches; +Cc: jason, Patrick Palka

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look
OK for trunk/14?  For trunk as a follow-up I can implement the
mentionted representation change to use CALL_EXPR instead of
MODOP_EXPR for a non-dependent simple assignment expression that
resolved to an operator= overload.

-- >8 --

r14-4111 made us check non-dependent assignment expressions ahead of
time, as well as give them a type.  Unlike for compound assignment
expressions however, if a simple assignment resolves to an operator
overload we still represent it as a (typed) MODOP_EXPR instead of a
CALL_EXPR to the selected overload.  This, I reckoned, was just a
pessimization (since we'll have to repeat overload resolution at
instantiatiation time) but should be harmless.  (And it should be
easily fixable by giving cp_build_modify_expr an 'overload' parameter).

But it breaks 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 assignment expressions as CALL_EXPRs
matching what that of compound assignments, but that turns out to
require some tweaking of our -Wparentheses warning logic which seems
unsuitable for backporting.

So this patch instead more conservatively fixes this by refining
lvalue_kind to consider the type of a (simple) MODOP_EXPR as we
already do for COND_EXPR.

	PR c++/114994

gcc/cp/ChangeLog:

	* tree.cc (lvalue_kind) <case MODOP_EXPR>: Consider the
	type of a simple assignment expression.

gcc/testsuite/ChangeLog:

	* g++.dg/template/non-dependent32.C: New test.
---
 gcc/cp/tree.cc                                 |  7 +++++++
 .../g++.dg/template/non-dependent32.C          | 18 ++++++++++++++++++
 2 files changed, 25 insertions(+)
 create mode 100644 gcc/testsuite/g++.dg/template/non-dependent32.C

diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc
index f1a23ffe817..0b97b789aab 100644
--- a/gcc/cp/tree.cc
+++ b/gcc/cp/tree.cc
@@ -275,6 +275,13 @@ lvalue_kind (const_tree ref)
       /* We expect to see unlowered MODOP_EXPRs only during
 	 template processing.  */
       gcc_assert (processing_template_decl);
+      if (TREE_CODE (TREE_OPERAND (ref, 1)) == NOP_EXPR
+	  && CLASS_TYPE_P (TREE_TYPE (TREE_OPERAND (ref, 0))))
+	/* As in the COND_EXPR case, but for non-dependent assignment
+	   expressions created by build_x_modify_expr.  */
+	goto default_;
+      /* A non-dependent (simple or compound) assignment expression that
+	 resolved to a built-in assignment function.  */
       return clk_ordinary;
 
     case MODIFY_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 00000000000..54252c7dfaf
--- /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>();
+}
-- 
2.45.0.119.g0f3415f1f8


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-05-14 22:27 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-05-09 20:23 [PATCH] c++: lvalueness of non-dependent assignment [PR114994] Patrick Palka
2024-05-09 20:29 ` Patrick Palka
2024-05-10 13:36   ` Patrick Palka
2024-05-10 19:42   ` Jason Merrill
2024-05-10 19:42 ` Jason Merrill
2024-05-12  0:46   ` Patrick Palka
2024-05-14 22:27     ` Jason Merrill

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).