aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@redhat.com>2004-04-01 12:45:02 -0800
committerRichard Henderson <rth@gcc.gnu.org>2004-04-01 12:45:02 -0800
commit6407bc6703d1a33e231e73faabffb6ba2e15ce8d (patch)
tree5efbbd81037c2b7cc8dfa82daa715f56b0d77fb7
parent54fdc910cf23c0f0c658db8f9d9e30f006e97513 (diff)
downloadgcc-6407bc6703d1a33e231e73faabffb6ba2e15ce8d.zip
gcc-6407bc6703d1a33e231e73faabffb6ba2e15ce8d.tar.gz
gcc-6407bc6703d1a33e231e73faabffb6ba2e15ce8d.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c19
-rw-r--r--gcc/cp/typeck2.c1
-rw-r--r--gcc/testsuite/g++.dg/init/static2.C25
4 files changed, 42 insertions, 9 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 93d3684..37d322a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2004-04-01 Richard Henderson <rth@redhat.com>
+
+ 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 <mark@codesourcery.com>
PR c++/14810
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 4570d8b..b228cd0 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 6314456..0a0fdbc 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 0000000..b0344f4
--- /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<mfptr>(&B::bar) },
+};
+
+int main()
+{
+ return 0;
+}