On 5/9/24 16:23, Patrick Palka wrote:
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_;

This seems overly specific, I'd think the same thing would apply to += and such?

Jason

Reply via email to