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