aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2005-02-23 06:52:08 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2005-02-23 06:52:08 +0000
commit67935995351da151a966dfcaf804293be54d9617 (patch)
tree9a11503ef0327d6e92a1bee2233d9b9330f316b0
parentbba6afa6ac6703bde83f9c6b5f4a926ff107dd6d (diff)
downloadgcc-67935995351da151a966dfcaf804293be54d9617.zip
gcc-67935995351da151a966dfcaf804293be54d9617.tar.gz
gcc-67935995351da151a966dfcaf804293be54d9617.tar.bz2
re PR c++/20073 (ICE initializing const array)
PR c++/20073 * 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. From-SVN: r95441
-rw-r--r--gcc/cp/decl.c35
-rw-r--r--gcc/cp/typeck.c12
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/g++.dg/init/const1.C8
4 files changed, 31 insertions, 27 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 1613488..a224efc 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
}
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 4a6ded4..330e8f1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c72149c..5edbd14 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 0000000..af4427d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/init/const1.C
@@ -0,0 +1,8 @@
+// PR c++/20073
+
+template<int> struct A
+{
+ A();
+};
+
+const A<0> x[] = { A<0>() };