From: Jakub Jelinek Date: Mon, 20 Aug 2007 08:17:21 +0000 (+0200) Subject: re PR c++/32992 (Incorrect code generated for anonymous union and return) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29c09e8c39ad0cbd45af948c66c8a758da32e0f8;p=thirdparty%2Fgcc.git re PR c++/32992 (Incorrect code generated for anonymous union and return) 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. From-SVN: r127641 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dcbef4721134..3d66b0ef9929 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2007-08-20 Jakub Jelinek + + PR c++/32992 + * typeck.c (check_return_expr): Don't NRV optimize vars in + anonymous unions. + * decl.c (finish_function): Comment fix. + 2007-08-18 Paolo Carlini PR c++/32112 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 32040abfa4f8..4aac4eebef37 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11058,7 +11058,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; diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index a0935272b5d4..07fc4768b996 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6439,6 +6439,7 @@ check_return_expr (tree retval, bool *no_warning) && TREE_CODE (retval) == VAR_DECL && DECL_CONTEXT (retval) == current_function_decl && ! TREE_STATIC (retval) + && ! DECL_HAS_VALUE_EXPR_P (retval) && (DECL_ALIGN (retval) >= DECL_ALIGN (DECL_RESULT (current_function_decl))) && same_type_p ((TYPE_MAIN_VARIANT diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 177640227cbf..a3c554d23219 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-08-20 Jakub Jelinek + + PR c++/32992 + * g++.dg/opt/nrv14.C: New test. + 2007-08-18 Paolo Carlini PR c++/32112 diff --git a/gcc/testsuite/g++.dg/opt/nrv14.C b/gcc/testsuite/g++.dg/opt/nrv14.C new file mode 100644 index 000000000000..22526d6b59a4 --- /dev/null +++ b/gcc/testsuite/g++.dg/opt/nrv14.C @@ -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; +}