From: Jakub Jelinek Date: Mon, 20 Aug 2007 08:10:54 +0000 (+0200) Subject: re PR c++/32992 (Incorrect code generated for anonymous union and return) X-Git-Tag: releases/gcc-4.2.2~139 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c00d7caf0acb1154860d92a964f426e9f36f980d;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: r127640 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 953f47eb81d9..6601d8055949 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 28e653b0751e..b837b1451538 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11273,7 +11273,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 4ae2f073abde..6f0777274cef 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6604,6 +6604,7 @@ check_return_expr (tree retval, bool *no_warning) && 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))) && same_type_p ((TYPE_MAIN_VARIANT diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 50cf8c961482..b78ef3f76185 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; +}