From: Patrick Palka Date: Wed, 15 May 2024 02:55:16 +0000 (-0400) Subject: c++: lvalueness of non-dependent assignment expr [PR114994] X-Git-Tag: basepoints/gcc-16~9055 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c6cc6d4741a880109c4e0e64d5a189687fb526f6;p=thirdparty%2Fgcc.git 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) : For a class assignment, consider the result type. gcc/testsuite/ChangeLog: * g++.dg/template/non-dependent32.C: New test. Reviewed-by: Jason Merrill --- diff --git a/gcc/cp/tree.cc b/gcc/cp/tree.cc index f1a23ffe817..9d37d255d8d 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 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 +void g() { + udl_arg x; + f(x=42); // { dg-bogus "cannot bind" } +} + +int main() { + g(); +}