From a09c81b4ba40aac99fd4c37654e1231f4836f891 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 14 Jun 2016 21:55:08 +0200 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 4 ++++ gcc/cp/decl.c | 8 ++++++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/g++.dg/opt/pr71528.C | 23 +++++++++++++++++++++++ 4 files changed, 38 insertions(+) create mode 100644 gcc/testsuite/g++.dg/opt/pr71528.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index d006305bdc0..cd5996bdd1d 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,9 @@ 2016-06-14 Jakub Jelinek + 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 20e7307ddad..a03e48ff618 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 0e3c9cd7738..4a55801352e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2016-06-14 Jakub Jelinek + 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 00000000000..bfe06220472 --- /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; -- 2.30.2