Commit 67935995 by Mark Mitchell Committed by Mark Mitchell

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
parent bba6afa6
...@@ -3823,14 +3823,6 @@ start_decl_1 (tree decl) ...@@ -3823,14 +3823,6 @@ start_decl_1 (tree decl)
instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR instantiation has occurred that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
will be set correctly. */ will be set correctly. */
maybe_push_cleanup_level (type); 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 /* 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) ...@@ -4757,9 +4749,6 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
if (type == error_mark_node) if (type == error_mark_node)
goto finish_end; goto finish_end;
if (TYPE_HAS_MUTABLE_P (type))
TREE_READONLY (decl) = 0;
if (processing_template_decl) if (processing_template_decl)
{ {
/* Add this declaration to the statement-tree. */ /* Add this declaration to the statement-tree. */
...@@ -4806,15 +4795,12 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags) ...@@ -4806,15 +4795,12 @@ cp_finish_decl (tree decl, tree init, tree asmspec_tree, int flags)
ttype = target_type (type); ttype = target_type (type);
/* Currently, GNU C++ puts constants in text space, making them /* A reference will be modified here, as it is initialized. */
impossible to initialize. In the future, one would hope for if (! DECL_EXTERNAL (decl)
an operating system which understood the difference between && TREE_READONLY (decl)
initialization and the running of a program. */ && TREE_CODE (type) == REFERENCE_TYPE)
if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl))
{ {
was_readonly = 1; was_readonly = 1;
if (TYPE_NEEDS_CONSTRUCTING (type)
|| TREE_CODE (type) == REFERENCE_TYPE)
TREE_READONLY (decl) = 0; TREE_READONLY (decl) = 0;
} }
...@@ -10959,16 +10945,11 @@ complete_vars (tree type) ...@@ -10959,16 +10945,11 @@ complete_vars (tree type)
if (same_type_p (type, TREE_PURPOSE (*list))) if (same_type_p (type, TREE_PURPOSE (*list)))
{ {
tree var = TREE_VALUE (*list); tree var = TREE_VALUE (*list);
tree type = TREE_TYPE (var);
/* Complete the type of the variable. The VAR_DECL itself /* Complete the type of the variable. The VAR_DECL itself
will be laid out in expand_expr. */ will be laid out in expand_expr. */
complete_type (TREE_TYPE (var)); complete_type (type);
/* An object declared 'const' is only readonly after it is cp_apply_type_quals_to_decl (cp_type_quals (type), var);
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;
/* Remove this entry from the list. */ /* Remove this entry from the list. */
*list = TREE_CHAIN (*list); *list = TREE_CHAIN (*list);
} }
......
...@@ -6409,6 +6409,18 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl) ...@@ -6409,6 +6409,18 @@ cp_apply_type_quals_to_decl (int type_quals, tree decl)
return; 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); c_apply_type_quals_to_decl (type_quals, decl);
} }
......
2005-02-22 Mark Mitchell <mark@codesourcery.com> 2005-02-22 Mark Mitchell <mark@codesourcery.com>
PR c++/20073
* g++.dg/init/const1.C: New test.
PR c++/19991 PR c++/19991
* g++.dg/parse/constant7.C: New test. * g++.dg/parse/constant7.C: New test.
......
// PR c++/20073
template<int> struct A
{
A();
};
const A<0> x[] = { A<0>() };
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment