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