From: Richard Henderson Date: Thu, 1 Apr 2004 20:45:02 +0000 (-0800) Subject: re PR c++/14804 ([unit-at-a-time] initializing const data with reinterpret_cast-ed... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6407bc6703d1a33e231e73faabffb6ba2e15ce8d;p=gcc.git re PR c++/14804 ([unit-at-a-time] initializing const data with reinterpret_cast-ed pointer-to-member function crashes) PR c++/14804 * decl.c (cp_finish_decl): Preserve TREE_READONLY more often. * typeck2.c (split_nonconstant_init): Clear TREE_READONLY. From-SVN: r80318 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 93d36842529..37d322a61f5 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-04-01 Richard Henderson + + PR c++/14804 + * decl.c (cp_finish_decl): Preserve TREE_READONLY more often. + * typeck2.c (split_nonconstant_init): Clear TREE_READONLY. + 2004-04-01 Mark Mitchell PR c++/14810 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 4570d8b7549..b228cd07748 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -4753,16 +4753,17 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) if (TREE_CODE (decl) != FUNCTION_DECL) ttype = target_type (type); - if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl) - && (TYPE_NEEDS_CONSTRUCTING (type) - || TREE_CODE (type) == REFERENCE_TYPE)) - { - /* Currently, GNU C++ puts constants in text space, making them - impossible to initialize. In the future, one would hope for - an operating system which understood the difference between - initialization and the running of a program. */ + + /* Currently, GNU C++ puts constants in text space, making them + impossible to initialize. In the future, one would hope for + an operating system which understood the difference between + initialization and the running of a program. */ + if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl)) + { was_readonly = 1; - TREE_READONLY (decl) = 0; + if (TYPE_NEEDS_CONSTRUCTING (type) + || TREE_CODE (type) == REFERENCE_TYPE) + TREE_READONLY (decl) = 0; } if (TREE_CODE (decl) == VAR_DECL) diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c index 63144565e48..0a0fdbc0311 100644 --- a/gcc/cp/typeck2.c +++ b/gcc/cp/typeck2.c @@ -380,6 +380,7 @@ split_nonconstant_init (tree dest, tree init) code = build1 (STMT_EXPR, void_type_node, code); TREE_SIDE_EFFECTS (code) = 1; DECL_INITIAL (dest) = init; + TREE_READONLY (dest) = 0; } else code = build (INIT_EXPR, TREE_TYPE (dest), dest, init); diff --git a/gcc/testsuite/g++.dg/init/static2.C b/gcc/testsuite/g++.dg/init/static2.C new file mode 100644 index 00000000000..b0344f48066 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/static2.C @@ -0,0 +1,25 @@ +// PR 14804 +// { dg-do run } + +struct A { + virtual void foo() = 0; +}; + +struct B : public A { + virtual void bar() = 0; +}; + +typedef void (A::*mfptr)(); + +struct D { + mfptr p; +}; + +static const D ds[] = { + { reinterpret_cast(&B::bar) }, +}; + +int main() +{ + return 0; +}