PR c++/20073
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 23 Feb 2005 06:52:08 +0000 (06:52 +0000)
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 23 Feb 2005 06:52:08 +0000 (06:52 +0000)
* decl.c (start_decl_1): Don't clear TREE_READONLY.
(cp_finish_decl): Likewise.
(complete_vars): Call cp_apply_type_quals_to_decl.
* typeck.c (cp_apply_type_quals): Avoid setting TREE_READONLY in
cases where that's not valid.

PR c++/20073
* g++.dg/init/const1.C: New test.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95441 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 1613488..a224efc 100644 (file)
@@ -3823,14 +3823,6 @@ start_decl_1 (tree decl)
      instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
      will be set correctly.  */
   maybe_push_cleanup_level (type);
-
-  /* An object declared 'const' is only readonly after it is
-     initialized.  We don't have any way of expressing this currently,
-     so we need to be conservative and unset TREE_READONLY for types
-     with constructors.  Otherwise aliasing code will ignore stores in
-     an inline constructor.  */
-   if (type != error_mark_node && TYPE_NEEDS_CONSTRUCTING (type))
-     TREE_READONLY (decl) = 0;
 }
 
 /* Handle initialization of references.  DECL, TYPE, and INIT have the
@@ -4757,9 +4749,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
   if (type == error_mark_node)
     goto finish_end;
 
-  if (TYPE_HAS_MUTABLE_P (type))
-    TREE_READONLY (decl) = 0;
-
   if (processing_template_decl)
     {
       /* Add this declaration to the statement-tree.  */
@@ -4806,16 +4795,13 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
     ttype = target_type (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.  */
-  if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
+  /* A reference will be modified here, as it is initialized.  */
+  if (! DECL_EXTERNAL (decl) 
+      && TREE_READONLY (decl)
+      && TREE_CODE (type) == REFERENCE_TYPE)
     {
       was_readonly = 1;
-      if (TYPE_NEEDS_CONSTRUCTING (type)
-         || TREE_CODE (type) == REFERENCE_TYPE)
-       TREE_READONLY (decl) = 0;
+      TREE_READONLY (decl) = 0;
     }
 
   if (TREE_CODE (decl) == VAR_DECL)
@@ -10959,16 +10945,11 @@ complete_vars (tree type)
       if (same_type_p (type, TREE_PURPOSE (*list)))
        {
          tree var = TREE_VALUE (*list);
+         tree type = TREE_TYPE (var);
          /* Complete the type of the variable.  The VAR_DECL itself
             will be laid out in expand_expr.  */
-         complete_type (TREE_TYPE (var));
-         /* An object declared 'const' is only readonly after it is
-            initialized.  We don't have any way of expressing this currently,
-            so we need to be conservative and unset TREE_READONLY for types
-            with constructors.  Otherwise aliasing code will ignore stores in
-            an inline constructor.  */
-         if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (var)))
-           TREE_READONLY (var) = 0;
+         complete_type (type);
+         cp_apply_type_quals_to_decl (cp_type_quals (type), var);
          /* Remove this entry from the list.  */
          *list = TREE_CHAIN (*list);
        }
index 4a6ded4..330e8f1 100644 (file)
@@ -6409,6 +6409,18 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
       return;
     }
 
+  /* Avoid setting TREE_READONLY incorrectly.  */
+  if (/* If the object has a constructor, the constructor may modify
+        the object.  */
+      TYPE_NEEDS_CONSTRUCTING (type)
+      /* If the type isn't complete, we don't know yet if it will need
+        constructing.  */
+      || !COMPLETE_TYPE_P (type) 
+      /* If the type has a mutable component, that component might be
+        modified.  */
+      || TYPE_HAS_MUTABLE_P (type))
+    type_quals &= ~TYPE_QUAL_CONST;
+
   c_apply_type_quals_to_decl (type_quals, decl);
 }
 
index c72149c..5edbd14 100644 (file)
@@ -1,5 +1,8 @@
 2005-02-22  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c++/20073
+       * g++.dg/init/const1.C: New test.
+
        PR c++/19991
        * g++.dg/parse/constant7.C: New test.
 
diff --git a/gcc/testsuite/g++.dg/init/const1.C b/gcc/testsuite/g++.dg/init/const1.C
new file mode 100644 (file)
index 0000000..af4427d
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/20073
+
+template<int> struct A
+{
+    A();
+};
+
+const A<0> x[] = { A<0>() };