On Mon, 30 Jul 2018, Tom de Vries wrote: > Hi, > > Consider test.C compiled at -O0 -g: > ... > class string { > public: > string (const char *p) { this->p = p ; } > string (const string &s) { this->p = s.p; } > > private: > const char *p; > }; > > class foo { > public: > foo (string dir_hint) {} > }; > > int > main (void) > { > std::string s = "This is just a string"; > foo bar(s); > return 0; > } > ... > > When parsing foo::foo, the dir_hint parameter gets a DECL_ARG_TYPE of > 'struct string & restrict'. Then during finish_struct, we call > clone_constructors_and_destructors and create clones for foo::foo, and > set the DECL_ARG_TYPE in the same way. > > Later on, during finish_function, cp_genericize is called for the original > foo::foo, which sets the type of parm dir_hint to DECL_ARG_TYPE, and sets > DECL_BY_REFERENCE of dir_hint to 1. > > After that, during maybe_clone_body update_cloned_parm is called with: > ... > (gdb) call debug_generic_expr (parm.typed.type) > struct string & restrict > (gdb) call debug_generic_expr (cloned_parm.typed.type) > struct string > ... > The type of the cloned_parm is then set to the type of parm, but > DECL_BY_REFERENCE is not set. > > When doing cp_genericize for the clone later on, > TREE_ADDRESSABLE (TREE_TYPE ()) is no longer true for the updated type of > the parm, so DECL_BY_REFERENCE is not set there either. > > This patch fixes the problem by copying DECL_BY_REFERENCE in > update_cloned_parm. > > Build and reg-tested on x86_64. > > OK for trunk?
Thanks for tracking this down. It looks OK to me but please leave Jason and Nathan a day to comment. Otherwise OK for trunk and also for branches after a while. Thanks, Richard. > Thanks, > - Tom > > [c++] Fix DECL_BY_REFERENCE of clone parms > > 2018-07-30 Tom de Vries <tdevr...@suse.de> > > PR debug/86687 > * optimize.c (update_cloned_parm): Copy DECL_BY_REFERENCE. > > * g++.dg/guality/pr86687.C: New test. > > --- > gcc/cp/optimize.c | 2 ++ > gcc/testsuite/g++.dg/guality/pr86687.C | 28 ++++++++++++++++++++++++++++ > 2 files changed, 30 insertions(+) > > diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c > index 0e9b84ed8a4..3923a5fc6c4 100644 > --- a/gcc/cp/optimize.c > +++ b/gcc/cp/optimize.c > @@ -46,6 +46,8 @@ update_cloned_parm (tree parm, tree cloned_parm, bool first) > /* We may have taken its address. */ > TREE_ADDRESSABLE (cloned_parm) = TREE_ADDRESSABLE (parm); > > + DECL_BY_REFERENCE (cloned_parm) = DECL_BY_REFERENCE (parm); > + > /* The definition might have different constness. */ > TREE_READONLY (cloned_parm) = TREE_READONLY (parm); > > diff --git a/gcc/testsuite/g++.dg/guality/pr86687.C > b/gcc/testsuite/g++.dg/guality/pr86687.C > new file mode 100644 > index 00000000000..140a6fce596 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/guality/pr86687.C > @@ -0,0 +1,28 @@ > +// PR debug/86687 > +// { dg-do run } > +// { dg-options "-g" } > + > +class string { > +public: > + string (int p) { this->p = p ; } > + string (const string &s) { this->p = s.p; } > + > + int p; > +}; > + > +class foo { > +public: > + foo (string dir_hint) { > + p = dir_hint.p; // { dg-final { gdb-test . "dir_hint.p" 3 } } > + } > + > + int p; > +}; > + > +int > +main (void) > +{ > + string s = 3; > + foo bar(s); > + return !(bar.p == 3); > +} > > -- Richard Biener <rguent...@suse.de> SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)