diff options
author | Jakub Jelinek <jakub@redhat.com> | 2016-06-14 21:55:08 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2016-06-14 21:55:08 +0200 |
commit | a09c81b4ba40aac99fd4c37654e1231f4836f891 (patch) | |
tree | c8460492a50fc58991906faba6ea819144b06b7d | |
parent | 5618c53ff334bff75cad40cf9ac03cbaf32da218 (diff) | |
download | gcc-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
-rw-r--r-- | gcc/cp/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/cp/decl.c | 8 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/opt/pr71528.C | 23 |
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; |