aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom de Vries <tdevries@suse.de>2018-10-23 17:16:55 +0000
committerTom de Vries <vries@gcc.gnu.org>2018-10-23 17:16:55 +0000
commit5d72b28145d0f4f1d75518d33f77b68ada602184 (patch)
treebded6d32d919f4544818e0e4fc0cb8e3eacfca8f
parentf9da73194bdca8f5e084cad98ba005b970206db1 (diff)
downloadgcc-5d72b28145d0f4f1d75518d33f77b68ada602184.zip
gcc-5d72b28145d0f4f1d75518d33f77b68ada602184.tar.gz
gcc-5d72b28145d0f4f1d75518d33f77b68ada602184.tar.bz2
backport "[c++] Fix DECL_BY_REFERENCE of clone parms"
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 for the parm, so DECL_BY_REFERENCE is not set there either. The missing DECL_BY_REFERENCE on cloned_parm causes incorrect debug info to be generated. This patch fixes the problem by copying DECL_BY_REFERENCE in update_cloned_parm. Bootstrapped and reg-tested on x86_64. 2018-10-23 Tom de Vries <tdevries@suse.de> backport from trunk: 2018-07-31 Tom de Vries <tdevries@suse.de> PR debug/86687 * optimize.c (update_cloned_parm): Copy DECL_BY_REFERENCE. * g++.dg/guality/pr86687.C: New test. From-SVN: r265431
-rw-r--r--gcc/cp/ChangeLog8
-rw-r--r--gcc/cp/optimize.c2
-rw-r--r--gcc/testsuite/ChangeLog8
-rw-r--r--gcc/testsuite/g++.dg/guality/pr86687.C28
4 files changed, 46 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8008560..efd6b0b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,11 @@
+2018-10-23 Tom de Vries <tdevries@suse.de>
+
+ backport from trunk:
+ 2018-07-31 Tom de Vries <tdevries@suse.de>
+
+ PR debug/86687
+ * optimize.c (update_cloned_parm): Copy DECL_BY_REFERENCE.
+
2018-10-12 Jakub Jelinek <jakub@redhat.com>
Backported from mainline
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 6f80b3d..e7bfc76 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/ChangeLog b/gcc/testsuite/ChangeLog
index 51daecf..70fcb9c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,11 @@
+2018-10-23 Tom de Vries <tdevries@suse.de>
+
+ backport from trunk:
+ 2018-07-31 Tom de Vries <tdevries@suse.de>
+
+ PR debug/86687
+ * g++.dg/guality/pr86687.C: New test.
+
2018-10-17 Eric Botcazou <ebotcazou@adacore.com>
* gcc.c-torture/execute/pr87623.c: New test.
diff --git a/gcc/testsuite/g++.dg/guality/pr86687.C b/gcc/testsuite/g++.dg/guality/pr86687.C
new file mode 100644
index 0000000..b2cdaf8
--- /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 16 "dir_hint.p" 3 } }
+ }
+
+ int p;
+};
+
+int
+main (void)
+{
+ string s = 3;
+ foo bar(s);
+ return !(bar.p == 3);
+}