This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Avoid NRV optimization for members of anon union (PR c++/32992)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 13 Aug 2007 14:31:02 -0400
- Subject: [C++ PATCH] Avoid NRV optimization for members of anon union (PR c++/32992)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Until GCC 3.4.x the fields of anon unions were represented as ALIAS_DECL
and thus check_return_expr wouldn't consider them for NRV. Since 4.0.x
they are represented using VAR_DECL with DECL_ANON_UNION_VAR_P
and DECL_VALUE_EXPR.
This patch restores the 3.4.x behavior where anon union fields aren't
considered for NRV.
Tested on x86_64-linux, ok for 4.3/4.2/4.1?
2007-08-13 Jakub Jelinek <jakub@redhat.com>
PR c++/32992
* typeck.c (check_return_expr): Don't NRV optimize vars in
anonymous unions.
* decl.c (finish_function): Comment fix.
* g++.dg/opt/nrv14.C: New test.
--- gcc/cp/typeck.c.jj 2007-08-13 15:10:19.000000000 +0200
+++ gcc/cp/typeck.c 2007-08-13 18:00:15.000000000 +0200
@@ -6701,6 +6701,7 @@ check_return_expr (tree retval, bool *no
&& TREE_CODE (retval) == VAR_DECL
&& DECL_CONTEXT (retval) == current_function_decl
&& ! TREE_STATIC (retval)
+ && ! DECL_ANON_UNION_VAR_P (retval)
&& (DECL_ALIGN (retval)
>= DECL_ALIGN (DECL_RESULT (current_function_decl)))
/* The cv-unqualified type of the returned value must be the
--- gcc/cp/decl.c.jj 2007-08-13 15:10:19.000000000 +0200
+++ gcc/cp/decl.c 2007-08-13 18:09:33.000000000 +0200
@@ -11566,7 +11566,7 @@ finish_function (int flags)
gcc_assert (stmts_are_full_exprs_p ());
/* Set up the named return value optimization, if we can. Candidate
- variables are selected in check_return_value. */
+ variables are selected in check_return_expr. */
if (current_function_return_value)
{
tree r = current_function_return_value;
--- gcc/testsuite/g++.dg/opt/nrv14.C.jj 2007-08-13 18:07:09.000000000 +0200
+++ gcc/testsuite/g++.dg/opt/nrv14.C 2007-08-13 18:07:46.000000000 +0200
@@ -0,0 +1,39 @@
+// PR c++/32992
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern "C" void abort (void);
+
+struct A
+{
+ long int a1;
+ long int a2;
+ long int a3;
+};
+
+struct B
+{
+ long int f[3];
+ operator A ()
+ {
+ union
+ {
+ long int t[3];
+ A a;
+ };
+ for (int i = 0; i < 3; i++)
+ t[i] = f[i];
+ return a;
+ }
+};
+
+int
+main ()
+{
+ B b = { {1, 3, 5} };
+ A a = b;
+
+ if (a.a1 != b.f[0] || a.a2 != b.f[1] || a.a3 != b.f[2])
+ abort ();
+ return 0;
+}
Jakub