OK.
On Tue, Jul 31, 2018 at 7:22 PM, Richard Biener <rguent...@suse.de> wrote: > 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)