public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++] PR19531 NRV is performed on volatile temporary
@ 2007-09-26 12:33 Christian BRUEL
  2007-10-26  5:27 ` Mark Mitchell
  0 siblings, 1 reply; 10+ messages in thread
From: Christian BRUEL @ 2007-09-26 12:33 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 321 bytes --]

Hello,

Here is a fix for PR 19531. testsuite tested for i686-pc-linux-gnu

thanks,

Christian

2007-09-24  Christian Bruel  <christian.bruel@st.com>

	PR c++/19531
	* cp/decl.c (finish_function): Check volatility for nrv.
	
2007-09-24  Christian Bruel  <christian.bruel@st.com>

	PR c++/19531
	* g++.dg/opt/nrv8.C: New.

[-- Attachment #2: vnrv.patch --]
[-- Type: text/plain, Size: 660 bytes --]

Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 128777)
+++ gcc/cp/decl.c	(working copy)
@@ -11729,7 +11729,9 @@
 	     return; see g++.dg/opt/nrv6.C.  We could be more flexible if
 	     we were to do this optimization in tree-ssa.  */
 	  && (outer = outer_curly_brace_block (fndecl))
-	  && chain_member (r, BLOCK_VARS (outer)))
+	  && chain_member (r, BLOCK_VARS (outer))
+	  && !TYPE_VOLATILE (TREE_TYPE (r))
+	  && !TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (fndecl))))
 	finalize_nrv (&DECL_SAVED_TREE (fndecl), r, DECL_RESULT (fndecl));
 
       current_function_return_value = NULL_TREE;

[-- Attachment #3: nrv8.C --]
[-- Type: text/x-c, Size: 409 bytes --]

// PR optimization/19531
// forbids NRV on volatile return value.
// { dg-options "-fno-inline" }
// { 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;
}

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-09-26 12:33 [C++] PR19531 NRV is performed on volatile temporary Christian BRUEL
@ 2007-10-26  5:27 ` Mark Mitchell
  2007-10-26 13:54   ` Christian BRUEL
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 2007-10-26  5:27 UTC (permalink / raw)
  To: Christian BRUEL; +Cc: gcc-patches

Christian BRUEL wrote:

> 2007-09-24  Christian Bruel  <christian.bruel@st.com>
> 
>     PR c++/19531
>     * cp/decl.c (finish_function): Check volatility for nrv.
>     
> 2007-09-24  Christian Bruel  <christian.bruel@st.com>
> 
>     PR c++/19531
>     * g++.dg/opt/nrv8.C: New.

On mainline, even the previous broken check for volatility seems to be
missing.  Does this bug still exist on mainline and does your change
still fix it?

Thanks,

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-26  5:27 ` Mark Mitchell
@ 2007-10-26 13:54   ` Christian BRUEL
  2007-10-26 17:11     ` Mark Mitchell
  0 siblings, 1 reply; 10+ messages in thread
From: Christian BRUEL @ 2007-10-26 13:54 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc-patches

Mark Mitchell wrote:
> Christian BRUEL wrote:
> 
> 
>>2007-09-24  Christian Bruel  <christian.bruel@st.com>
>>
>>    PR c++/19531
>>    * cp/decl.c (finish_function): Check volatility for nrv.
>>    
>>2007-09-24  Christian Bruel  <christian.bruel@st.com>
>>
>>    PR c++/19531
>>    * g++.dg/opt/nrv8.C: New.
> 
> 
> On mainline, even the previous broken check for volatility seems to be
> missing.  

In the testsuite there is a 'nrv7.C' and a 'nrv9.C' but no 'nrv8.C'. So 
I picked up this slot, but maybe I should have called the test 'nrv15.C' 
instead ?

Does this bug still exist on mainline and does your change
> still fix it?
> 
> Thanks,
> 

yes it still exists and my change still fixes it.

Regards,

-c

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-26 13:54   ` Christian BRUEL
@ 2007-10-26 17:11     ` Mark Mitchell
  2007-10-29 11:49       ` Christian BRUEL
  0 siblings, 1 reply; 10+ messages in thread
From: Mark Mitchell @ 2007-10-26 17:11 UTC (permalink / raw)
  To: Christian BRUEL; +Cc: gcc-patches

Christian BRUEL wrote:

>> On mainline, even the previous broken check for volatility seems to be
>> missing.  
> 
> In the testsuite there is a 'nrv7.C' and a 'nrv9.C' but no 'nrv8.C'. So
> I picked up this slot, but maybe I should have called the test 'nrv15.C'
> instead ?

I'm sorry for being unclear.  I wasn't referring to the test number, but
to a line of code in your patch -- which I misread.  So, just ignore
what I said. :-)

> Does this bug still exist on mainline and does your change
>> still fix it?

> yes it still exists and my change still fixes it.

Is the check for volatility on both the return type of the function --
TREE_TYPE (TREE_TYPE (fndecl)) -- and on the RESULT_DECL -- TREE_TYPE
(r)) -- necessary?

I would expect that checking the volatility of the function return type
is sufficient; that's the language issue.  If, for whatever reason, the
compiler were to make the RESULT_DECL volatile, for a function with a
non-volatile return, I believe that the NRV would still be valid.

Would you please test removing the check on the RESULT_DECL from your patch?

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-26 17:11     ` Mark Mitchell
@ 2007-10-29 11:49       ` Christian BRUEL
  2007-10-30  4:32         ` Mark Mitchell
  0 siblings, 1 reply; 10+ messages in thread
From: Christian BRUEL @ 2007-10-29 11:49 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc-patches


Mark Mitchell wrote:
<< snap>>

> Is the check for volatility on both the return type of the function --
> TREE_TYPE (TREE_TYPE (fndecl)) -- and on the RESULT_DECL -- TREE_TYPE
> (r)) -- necessary?
> 
> I would expect that checking the volatility of the function return type
> is sufficient; that's the language issue.  If, for whatever reason, the
> compiler were to make the RESULT_DECL volatile, for a function with a
> non-volatile return, I believe that the NRV would still be valid.
> 
> Would you please test removing the check on the RESULT_DECL from your patch?
> 

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.  Without it the check doesn't pass.
I think this is what 12.8 15 was originally about, before Core DR20 
extended it to the function's return type.

I also though that there would be a language issue with the volatility 
of the function's return type, but the volatility flag is not set on the 
return type of the cpctor. Should it be ? I'm not sure since with:
A (volatile const A & o) { d = o.d + 2; }
the cpctor return type is not volatile, only the temporary object is, 
but I'd prefer to let that to the experts's hands.

So I conservatively added the check on the function's return type to 
match core dr20 extension (quoted in the bugzilla entry but I don't have 
it) although I was not able to make up a test case.

Best Regards
Christian

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-29 11:49       ` Christian BRUEL
@ 2007-10-30  4:32         ` Mark Mitchell
  2007-10-30 13:37           ` Christian BRUEL
  2007-10-30 17:44           ` Christian BRUEL
  0 siblings, 2 replies; 10+ messages in thread
From: Mark Mitchell @ 2007-10-30  4:32 UTC (permalink / raw)
  To: Christian BRUEL; +Cc: gcc-patches

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?

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-30  4:32         ` Mark Mitchell
@ 2007-10-30 13:37           ` Christian BRUEL
  2007-10-30 15:26             ` Christian BRUEL
  2007-10-30 17:44           ` Christian BRUEL
  1 sibling, 1 reply; 10+ messages in thread
From: Christian BRUEL @ 2007-10-30 13:37 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc-patches

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?
> 

In this example there are 2 retvals with 2 TREE_TYPEs, so one 
TREE_TYPE's is volatile and the other is not. But here NRV is avoided 
because there are 2 different return values, regardless of one that is 
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?
> 

yes you are right, it's would be a better place to do the check. but...

In fact the code is already there :

      /* The cv-unqualified type of the returned value must be the
         same as the cv-unqualified return type of the
         function.  */
      && same_type_p ((TYPE_MAIN_VARIANT (TREE_TYPE (retval))),
                      (TYPE_MAIN_VARIANT
                       (TREE_TYPE (TREE_TYPE(current_function_decl))))));

Indeed, I reread the parts on volatile and object copying, the standard 
states nrv is allowed if the cv-unqualified types match, so strictly 
speaking
the object
  volatile A a;
and the function
  A bar()
have the same cv-unqualified type...

so this volatile optimization is surprisingly correct !

Nevertheless, it would have been useful to have a way to force a call to 
the copy constructor...  but the standard allows this optimisation here, 
that's it.

Unless there is a consensus that this optimisation could be avoided on 
volatile objects for convenience, this is not a bug and I will update 
PR19531 accordingly.

Best Regards

Christian







^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-30 13:37           ` Christian BRUEL
@ 2007-10-30 15:26             ` Christian BRUEL
  0 siblings, 0 replies; 10+ messages in thread
From: Christian BRUEL @ 2007-10-30 15:26 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc-patches

sorry I was looking at ISO/IEC 14882 (first edition). In 14882:2003 this 
is indeed restricted to non-volatile automatic object. please ignore 
this comment. thx

Christian

> Indeed, I reread the parts on volatile and object copying, the standard 
> states nrv is allowed if the cv-unqualified types match, so strictly 
> speaking
> the object
>  volatile A a;
> and the function
>  A bar()
> have the same cv-unqualified type...
> 
> so this volatile optimization is surprisingly correct !
> 
> Nevertheless, it would have been useful to have a way to force a call to 
> the copy constructor...  but the standard allows this optimisation here, 
> that's it.
> 
> Unless there is a consensus that this optimisation could be avoided on 
> volatile objects for convenience, this is not a bug and I will update 
> PR19531 accordingly.
> 
> Best Regards
> 
> Christian
> 
> 
> 
> 
> 
> 
> 
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-30  4:32         ` Mark Mitchell
  2007-10-30 13:37           ` Christian BRUEL
@ 2007-10-30 17:44           ` Christian BRUEL
  2007-10-30 18:12             ` Mark Mitchell
  1 sibling, 1 reply; 10+ messages in thread
From: Christian BRUEL @ 2007-10-30 17:44 UTC (permalink / raw)
  To: Mark Mitchell; +Cc: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1354 bytes --]

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?
> 


[-- Attachment #2: vnrv.patch --]
[-- Type: text/plain, Size: 635 bytes --]

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)
     {

[-- Attachment #3: nrv8.C --]
[-- Type: text/x-c, Size: 399 bytes --]

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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [C++] PR19531 NRV is performed on volatile temporary
  2007-10-30 17:44           ` Christian BRUEL
@ 2007-10-30 18:12             ` Mark Mitchell
  0 siblings, 0 replies; 10+ messages in thread
From: Mark Mitchell @ 2007-10-30 18:12 UTC (permalink / raw)
  To: Christian BRUEL; +Cc: gcc-patches

Christian BRUEL wrote:

> 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.

This patch is OK, thanks.

-- 
Mark Mitchell
CodeSourcery
mark@codesourcery.com
(650) 331-3385 x713

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2007-10-30 15:26 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-09-26 12:33 [C++] PR19531 NRV is performed on volatile temporary Christian BRUEL
2007-10-26  5:27 ` Mark Mitchell
2007-10-26 13:54   ` Christian BRUEL
2007-10-26 17:11     ` Mark Mitchell
2007-10-29 11:49       ` Christian BRUEL
2007-10-30  4:32         ` Mark Mitchell
2007-10-30 13:37           ` Christian BRUEL
2007-10-30 15:26             ` Christian BRUEL
2007-10-30 17:44           ` Christian BRUEL
2007-10-30 18:12             ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).