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

--- Comment #4 from Jan Hubicka <hubicka at gcc dot gnu.org> ---
OK, so the problem is that we analyze function body of g::f which is declared
with pure attribute:

modref analyzing 'virtual g* g::f() const/1' (ipa=0) (pure)
Analyzing flags of ssa name: this_4(D)
  Analyzing stmt: _1 = &this_4(D)->D.2861;
    Analyzing flags of ssa name: _1
      Analyzing stmt: if (_1 != e.4_2)
      current flags of _1 no_direct_clobber no_indirect_clobber
no_direct_escape no_indirect_escape not_returned_directly
not_returned_indirectly no_direct_read no_indirect_read
    flags of ssa name _1 no_direct_clobber no_indirect_clobber no_direct_escape
no_indirect_escape not_returned_directly not_returned_indirectly no_direct_read
no_indirect_read
  current flags of this_4(D) no_direct_clobber no_indirect_clobber
no_direct_escape no_indirect_escape not_returned_directly
not_returned_indirectly no_direct_read no_indirect_read
flags of ssa name this_4(D) no_direct_clobber no_indirect_clobber
no_direct_escape no_indirect_escape not_returned_directly
not_returned_indirectly no_direct_read no_indirect_read

...

  parm 0 flags: not_returned_directly not_returned_indirectly no_direct_read
no_indirect_read
__attribute__((pure))

here parm 0 is originally detected with many attributes including no_*_clobber
but they are taken away because we know they are implied by pure attribute. 
Now however function is called through thunk and ECF_FLAGS use thunk alias
while modref flags looks through the alias to actual definition, which means
that we end up with the insane combination.

So the bug is that we create aliases without the pure attribute on it or
altenratively ecf_flags may look through non-interposable aliases and merge in
the flags.

(gdb) p debug_tree (gimple_call_fndecl (call))
 <function_decl 0x7ffff77ba700 *.LTHUNK0
    type <method_type 0x7ffff77cee70
        type <pointer_type 0x7ffff77ced20 type <record_type 0x7ffff77ce9d8 g>
            sizes-gimplified public unsigned DI
            size <integer_cst 0x7ffff7620240 constant 64>
            unit-size <integer_cst 0x7ffff7620258 constant 8>
            align:64 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff77ced20>
        QI
        size <integer_cst 0x7ffff7620330 constant 8>
        unit-size <integer_cst 0x7ffff7620348 constant 1>
        align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type
0x7ffff77cee70 method basetype <record_type 0x7ffff77ce9d8 g>
        arg-types <tree_list 0x7ffff77cf258 value <pointer_type 0x7ffff77cebd0>
            chain <tree_list 0x7ffff761bd98 value <void_type 0x7ffff7627f18
void>>>
        pointer_to_this <pointer_type 0x7ffff77d1150>>
    addressable used autoinline decl_5 QI m.C:7:28 align:8 warn_if_not_align:0
context <record_type 0x7ffff77ce9d8 g> initial <error_mark 0x7ffff7620228>
    full-name "g* g::*.LTHUNK0() const">

(gdb) p cgraph_node::get (gimple_call_fndecl (call))->debug ()
*.LTHUNK0/2 (g* g::*.LTHUNK0() const)
  Type: function definition analyzed alias cpp_implicit_alias
  Visibility: semantic_interposition comdat_group:_ZNK1g1fEv
section:.text._ZNK1g1fEv (implicit_section) artificial
  Same comdat group as: _ZNK1g1fEv/1
  References: _ZNK1g1fEv/1 (alias) 
  Referring: 
  Availability: available
  Function flags: optimize_size
  Called by:

Reply via email to