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

--- Comment #61 from Jonathan Wakely <redi at gcc dot gnu.org> ---
(In reply to rguent...@suse.de from comment #59)
> On Mon, 27 Mar 2017, redi at gcc dot gnu.org wrote:
> 
> > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79671
> > 
> > --- Comment #58 from Jonathan Wakely <redi at gcc dot gnu.org> ---
> > But this seemingly equivalent code doesn't work:
> > 
> >   this->functor = static_cast<function_buffer&>(f.functor);
> 
> Is function_buffer may_alias?

Yes. Here's what I tested:


union function_buffer_members {
  void* p;
  void(*fp)();
};

union function_buffer {
  function_buffer_members members;
  char data[sizeof(function_buffer_members)];
} __attribute__((may_alias));

struct function_base {
  mutable function_buffer functor;
};

struct function : function_base {
  void func(const function& f) {
    const function_buffer& aliasing_ref = f.functor;
    this->functor = aliasing_ref;
  }
};

void blah(function& f1, function& f2)
{
  f1.func(f2);
}

The -fdump-tree-optimized dump is:


;; Function void blah(function&, function&) (_Z4blahR8functionS0_,
funcdef_no=1, decl_uid=2315, cgraph_uid=1, symbol_order=1)

void blah(function&, function&) (struct function & f1, struct function & f2)
{
  <bb 2> [100.00%]:
  # DEBUG this => f1_2(D)
  # DEBUG f => f2_3(D)
  # DEBUG D#1 => &MEM[(const struct function *)f2_3(D)].D.2297.functor
  # DEBUG aliasing_ref => D#1
  f1_2(D)->D.2297.functor = MEM[(const union function_buffer &
{ref-all})f2_3(D)];
  # DEBUG this => NULL
  # DEBUG f => NULL
  return;

}

This has {ref-all}.

If I use static_cast:

union function_buffer_members {
  void* p;
  void(*fp)();
};

union function_buffer {
  function_buffer_members members;
  char data[sizeof(function_buffer_members)];
} __attribute__((may_alias));

struct function_base {
  mutable function_buffer functor;
};

struct function : function_base {
  void func(const function& f) {
    this->functor = static_cast<const function_buffer&>(f.functor);
  }
};

void blah(function& f1, function& f2)
{
  f1.func(f2);
}

Then the dump doesn't have {ref-all}:


;; Function void blah(function&, function&) (_Z4blahR8functionS0_,
funcdef_no=1, decl_uid=2314, cgraph_uid=1, symbol_order=1)

void blah(function&, function&) (struct function & f1, struct function & f2)
{
  <bb 2> [100.00%]:
  # DEBUG this => f1_2(D)
  # DEBUG f => f2_3(D)
  f1_2(D)->D.2297.functor = MEM[(const struct function
*)f2_3(D)].D.2297.functor;
  # DEBUG this => NULL
  # DEBUG f => NULL
  return;

}

Reply via email to