This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]