This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++] PR19531 NRV is performed on volatile temporary
please find attached the revisited fix.
thanks,
-c
2007-09-24 Christian Bruel <christian.bruel@st.com>
Mark Mitchell <mark@codesourcery.com>
PR c++/19531
* cp/typeck.c (check_return_expr): Don't set
named_return_value_okay_p if retval is volatile.
2007-09-24 Christian Bruel <christian.bruel@st.com>
PR c++/19531
* g++.dg/opt/nrv8.C: New.
Mark Mitchell wrote:
Christian BRUEL wrote:
it is the other way: with the nrv8.C (attached in the patch) test, only
the check on the RESULT_DECL is necessary, testing the volatility of the
*volatile A l;* object.
Oh! Right, top-level qualifiers on return types are discarded from the
point of view of the language.
But, sadly, I'm still confused. Your example is:
A bar()
{
volatile A l;
return l;
}
Why is RESULT_DECL volatile in this case, before we call finalize_nrv?
Is this is just an accident because we have only one return statement?
For example:
A bar(bool b) {
A a;
volatile A va;
if (b)
return a;
return va;
}
Is the RESULT_DECL still volatile?
It seems like it would be simpler to fix this problem by changing
check_return_expr to set named_return_value_okay_p to false if the
TREE_TYPE (retval) is volatile. What do you think about that?
Index: gcc/cp/typeck.c
===================================================================
--- gcc/cp/typeck.c (revision 129768)
+++ gcc/cp/typeck.c (working copy)
@@ -6744,7 +6744,9 @@
function. */
&& same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
(TYPE_MAIN_VARIANT
- (TREE_TYPE (TREE_TYPE (current_function_decl))))));
+ (TREE_TYPE (TREE_TYPE (current_function_decl)))))
+ /* And the returned value must be non-volatile. */
+ && !TYPE_VOLATILE (TREE_TYPE (retval)));
if (fn_returns_value_p && flag_elide_constructors)
{
// PR optimization/19531
// forbids NRV on volatile return value.
// { dg-options -O2 }
// { dg-do run }
extern "C" { void abort(); }
struct A
{
int d;
A () { d = 123; }
A (const A & o) { d = o.d; }
A (volatile const A & o) { d = o.d + 2; }
};
A bar()
{
volatile A l;
return l;
}
main()
{
A a = bar ();
if (a.d != 125)
abort();
return 0;
}