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)

Reply via email to