aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2016-06-14 21:55:08 +0200
committerJakub Jelinek <jakub@gcc.gnu.org>2016-06-14 21:55:08 +0200
commita09c81b4ba40aac99fd4c37654e1231f4836f891 (patch)
treec8460492a50fc58991906faba6ea819144b06b7d /gcc
parent5618c53ff334bff75cad40cf9ac03cbaf32da218 (diff)
downloadgcc-a09c81b4ba40aac99fd4c37654e1231f4836f891.zip
gcc-a09c81b4ba40aac99fd4c37654e1231f4836f891.tar.gz
gcc-a09c81b4ba40aac99fd4c37654e1231f4836f891.tar.bz2
re PR c++/71528 (multiple extern reference declarations produce uninitialized access)
PR c++/71528 * decl.c (duplicate_decls): For DECL_INITIALIZED_P non-external olddecl vars, preserve their TREE_READONLY bit. * g++.dg/opt/pr71528.C: New test. From-SVN: r237458
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog4
-rw-r--r--gcc/cp/decl.c8
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/opt/pr71528.C23
4 files changed, 38 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index d006305..cd5996b 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,5 +1,9 @@
2016-06-14 Jakub Jelinek <jakub@redhat.com>
+ PR c++/71528
+ * decl.c (duplicate_decls): For DECL_INITIALIZED_P non-external
+ olddecl vars, preserve their TREE_READONLY bit.
+
PR c++/71516
* decl.c (complete_vars): Handle gracefully type == error_mark_node.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 20e7307..a03e48f 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -2066,6 +2066,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
if (VAR_P (newdecl))
{
DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl);
+ /* For already initialized vars, TREE_READONLY could have been
+ cleared in cp_finish_decl, because the var needs runtime
+ initialization or destruction. Make sure not to set
+ TREE_READONLY on it again. */
+ if (DECL_INITIALIZED_P (olddecl)
+ && !DECL_EXTERNAL (olddecl)
+ && !TREE_READONLY (olddecl))
+ TREE_READONLY (newdecl) = 0;
DECL_INITIALIZED_P (newdecl) |= DECL_INITIALIZED_P (olddecl);
DECL_NONTRIVIALLY_INITIALIZED_P (newdecl)
|= DECL_NONTRIVIALLY_INITIALIZED_P (olddecl);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0e3c9cd..4a55801 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,8 @@
2016-06-14 Jakub Jelinek <jakub@redhat.com>
+ PR c++/71528
+ * g++.dg/opt/pr71528.C: New test.
+
PR c++/71516
* g++.dg/init/pr71516.C: New test.
diff --git a/gcc/testsuite/g++.dg/opt/pr71528.C b/gcc/testsuite/g++.dg/opt/pr71528.C
new file mode 100644
index 0000000..bfe0622
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr71528.C
@@ -0,0 +1,23 @@
+// PR c++/71528
+// { dg-do run }
+// { dg-options "-O2" }
+
+extern int &x;
+int y;
+
+int &
+foo ()
+{
+ return y;
+}
+
+int &x = foo ();
+
+int
+main ()
+{
+ if (&x != &y)
+ __builtin_abort ();
+}
+
+extern int &x;