diff options
author | Mark Mitchell <mark@codesourcery.com> | 2005-02-23 06:52:08 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2005-02-23 06:52:08 +0000 |
commit | 67935995351da151a966dfcaf804293be54d9617 (patch) | |
tree | 9a11503ef0327d6e92a1bee2233d9b9330f316b0 | |
parent | bba6afa6ac6703bde83f9c6b5f4a926ff107dd6d (diff) | |
download | gcc-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.c | 35 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 12 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/const1.C | 8 |
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>() }; |