re PR c++/14804 ([unit-at-a-time] initializing const data with reinterpret_cast-ed...
authorRichard Henderson <rth@redhat.com>
Thu, 1 Apr 2004 20:45:02 +0000 (12:45 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Thu, 1 Apr 2004 20:45:02 +0000 (12:45 -0800)
        PR c++/14804
        * decl.c (cp_finish_decl): Preserve TREE_READONLY more often.
        * typeck2.c (split_nonconstant_init): Clear TREE_READONLY.

From-SVN: r80318

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/typeck2.c
gcc/testsuite/g++.dg/init/static2.C [new file with mode: 0644]

index 93d3684252993d445ec5342c6291ac04723a005d..37d322a61f5658a22ff6f71dc95f630c65a6d72c 100644 (file)
@@ -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
index 4570d8b7549a1d5e7e724c4db2558e8aea5882f5..b228cd07748edc36f40d8d7d2580800bb62ee633 100644 (file)
@@ -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)
index 63144565e48b84c962ce9cbd3adc469b1b9795e9..0a0fdbc03112ef9141e202c20c35e8fb8f5879f0 100644 (file)
@@ -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 (file)
index 0000000..b0344f4
--- /dev/null
@@ -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;
+}