https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98499

Jan Hubicka <hubicka at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Assignee|unassigned at gcc dot gnu.org      |hubicka at gcc dot 
gnu.org
                 CC|                            |hubicka at gcc dot gnu.org
             Status|NEW                         |ASSIGNED

--- Comment #9 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
Thanks for all the detailed analysis and sorry for getting into this late.

> Oh, thank you! Only after many printf() attempts it sunk in that 
> `036t.ealias` is using data from seemingly later `043t.modref1` pass. It is 
> so confusing!

This is because it is an inter-procedural analysis.  We compile in topological
order and propagate info from function to callers.

Here I think poblem is:

void Importer::Importer (struct Importer * const this)                          
{                                                                               
  struct string * _1;                                                           

  <bb 2> :                                                                      
  *this_3(D) ={v} {CLOBBER};                                                    
  *this_3(D).base_path = dir_name (); [return slot optimization]                
  return;                                                                       

}                                                                               

We get parm 0 flags: direct noescape nodirectescape

While dir_name does:

struct string dir_name ()                                                       
{                                                                               
  <bb 2> :                                                                      
  string::string (_2(D));                                                       
  return _2(D);                                                                 

}
and that gets to                                                                
void string::string (struct string * const this)                                
{                                                                               
  char[16] * _1;                                                                

  <bb 2> :                                                                      
  *this_3(D) ={v} {CLOBBER};                                                    
  _1 = &this_3(D)->_M_local_buf;                                                
  *this_3(D)._M_buf = _1;                                                       
  return;                                                                       

}                                                                               
which indeed conflict with noescape.

So problem here is that return slot optimized variables are behaving kind of
like parameters.  Since modref does not track EAF flags for them I think your
conservative fix makes sense.

It is also relatively easy to track the EAF flags here, I will try to get quick
stats on how often this makes difference (and whether we want to add trakcing
now or next stage1).

Honza

Reply via email to