diff mbox series

inliner: Copy DECL_BY_REFERENCE in copy_decl_to_var [PR93888]

Message ID 20200303201301.GC2156@tucnak
State New
Headers show
Series inliner: Copy DECL_BY_REFERENCE in copy_decl_to_var [PR93888] | expand

Commit Message

Jakub Jelinek March 3, 2020, 8:13 p.m. UTC
Hi!

In the following testcase we emit wrong debug info for the karg
parameter in the DW_TAG_inlined_subroutine into main.
The problem is that the karg PARM_DECL is DECL_BY_REFERENCE and thus
in the IL has const K & type, but in the source just const K.
When the function is inlined, we create a VAR_DECL for it, but don't
set DECL_BY_REFERENCE, so when emitting DW_AT_location, we treat it like
a const K & typed variable, but it has DW_AT_abstract_origin which has
just the const K type and thus the debugger thinks the variable has
const K type.

Fixed by copying the DECL_BY_REFERENCE flag.  Not doing it in
copy_decl_for_dup_finish, because copy_decl_no_change already copies
that flag through copy_node and in copy_result_decl_to_var it is
undesirable, as we handle DECL_BY_REFERENCE in that case instead
by changing the type.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2020-03-03  Jakub Jelinek  <jakub@redhat.com>

	PR debug/93888
	* tree-inline.c (copy_decl_to_var): Copy DECL_BY_REFERENCE flag.

	* g++.dg/guality/pr93888.C: New test.


	Jakub

Comments

Richard Biener March 3, 2020, 8:52 p.m. UTC | #1
On March 3, 2020 9:13:01 PM GMT+01:00, Jakub Jelinek <jakub@redhat.com> wrote:
>Hi!
>
>In the following testcase we emit wrong debug info for the karg
>parameter in the DW_TAG_inlined_subroutine into main.
>The problem is that the karg PARM_DECL is DECL_BY_REFERENCE and thus
>in the IL has const K & type, but in the source just const K.
>When the function is inlined, we create a VAR_DECL for it, but don't
>set DECL_BY_REFERENCE, so when emitting DW_AT_location, we treat it
>like
>a const K & typed variable, but it has DW_AT_abstract_origin which has
>just the const K type and thus the debugger thinks the variable has
>const K type.
>
>Fixed by copying the DECL_BY_REFERENCE flag.  Not doing it in
>copy_decl_for_dup_finish, because copy_decl_no_change already copies
>that flag through copy_node and in copy_result_decl_to_var it is
>undesirable, as we handle DECL_BY_REFERENCE in that case instead
>by changing the type.
>
>Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

Ok. 

Richard. 

>2020-03-03  Jakub Jelinek  <jakub@redhat.com>
>
>	PR debug/93888
>	* tree-inline.c (copy_decl_to_var): Copy DECL_BY_REFERENCE flag.
>
>	* g++.dg/guality/pr93888.C: New test.
>
>--- gcc/tree-inline.c.jj	2020-02-07 19:11:57.444981885 +0100
>+++ gcc/tree-inline.c	2020-03-03 13:27:57.811046011 +0100
>@@ -5929,6 +5929,7 @@ copy_decl_to_var (tree decl, copy_body_d
>   TREE_READONLY (copy) = TREE_READONLY (decl);
>   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
>   DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
>+  DECL_BY_REFERENCE (copy) = DECL_BY_REFERENCE (decl);
> 
>   return copy_decl_for_dup_finish (id, decl, copy);
> }
>--- gcc/testsuite/g++.dg/guality/pr93888.C.jj	2020-03-03
>13:38:16.273935942 +0100
>+++ gcc/testsuite/g++.dg/guality/pr93888.C	2020-03-03
>13:40:15.890174469 +0100
>@@ -0,0 +1,24 @@
>+// PR debug/93888
>+// { dg-do run }
>+// { dg-options "-g -fvar-tracking -fno-inline" }
>+// { dg-skip-if "" { *-*-* }  { "*" } { "-O0" } }
>+
>+struct K
>+{
>+  K () {}
>+  K (K const &rhs) { k[0] = 'C'; }
>+  char k[8] = {'B','B','B','B','B','B','B','B'};
>+};
>+
>+__attribute__((always_inline)) inline bool
>+foo (const K karg)
>+{
>+  return karg.k[0] != 'C';	// { dg-final { gdb-test 16 "karg.k[0]"
>"'C'" } }
>+}				// { dg-final { gdb-test 16 "karg.k[1]" "'B'" } }
>+
>+int
>+main ()
>+{
>+  K x;
>+  return foo (x);
>+}
>
>	Jakub
diff mbox series

Patch

--- gcc/tree-inline.c.jj	2020-02-07 19:11:57.444981885 +0100
+++ gcc/tree-inline.c	2020-03-03 13:27:57.811046011 +0100
@@ -5929,6 +5929,7 @@  copy_decl_to_var (tree decl, copy_body_d
   TREE_READONLY (copy) = TREE_READONLY (decl);
   TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
   DECL_GIMPLE_REG_P (copy) = DECL_GIMPLE_REG_P (decl);
+  DECL_BY_REFERENCE (copy) = DECL_BY_REFERENCE (decl);
 
   return copy_decl_for_dup_finish (id, decl, copy);
 }
--- gcc/testsuite/g++.dg/guality/pr93888.C.jj	2020-03-03 13:38:16.273935942 +0100
+++ gcc/testsuite/g++.dg/guality/pr93888.C	2020-03-03 13:40:15.890174469 +0100
@@ -0,0 +1,24 @@ 
+// PR debug/93888
+// { dg-do run }
+// { dg-options "-g -fvar-tracking -fno-inline" }
+// { dg-skip-if "" { *-*-* }  { "*" } { "-O0" } }
+
+struct K
+{
+  K () {}
+  K (K const &rhs) { k[0] = 'C'; }
+  char k[8] = {'B','B','B','B','B','B','B','B'};
+};
+
+__attribute__((always_inline)) inline bool
+foo (const K karg)
+{
+  return karg.k[0] != 'C';	// { dg-final { gdb-test 16 "karg.k[0]" "'C'" } }
+}				// { dg-final { gdb-test 16 "karg.k[1]" "'B'" } }
+
+int
+main ()
+{
+  K x;
+  return foo (x);
+}