From 59fe92745a5360e7771f9ca0b86301ff6ddb2ac1 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Wed, 15 Aug 2007 14:08:42 +0200 Subject: [PATCH] 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: r127510 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/decl.c | 2 +- gcc/cp/typeck.c | 1 + gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/opt/nrv14.C | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/opt/nrv14.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 892e8a6..6a7a4a4 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2007-08-15 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-15 Paolo Carlini PR c++/33035 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 9a9436a..b04fda3 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -11569,7 +11569,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 d2e095c..a79f6e2 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -6703,6 +6703,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))) /* The cv-unqualified type of the returned value must be the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index eef5e69..45fc15c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2007-08-15 Jakub Jelinek + + PR c++/32992 + * g++.dg/opt/nrv14.C: New test. + 2007-08-15 Paolo Carlini PR c++/33035 diff --git a/gcc/testsuite/g++.dg/opt/nrv14.C b/gcc/testsuite/g++.dg/opt/nrv14.C new file mode 100644 index 0000000..22526d6 --- /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; +} -- 2.7.4