* cp-tree.h (struct lang_type): Added has_mutable flag.
(CLASSTYPE_HAS_MUTABLE): New macro to access it.
(TYPE_HAS_MUTABLE_P): New macro to read it.
(cp_has_mutable_p): Prototype for new function.
* class.c (finish_struct_1): Set has_mutable from members.
* decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if
it contains a mutable.
* typeck.c (cp_has_mutable_p): New function.
Fixes g++.other/mutable1.C
From-SVN: r24701
+1999-01-16 Nathan Sidwell <nathan@acm.org>
+
+ * cp-tree.h (struct lang_type): Added has_mutable flag.
+ (CLASSTYPE_HAS_MUTABLE): New macro to access it.
+ (TYPE_HAS_MUTABLE_P): New macro to read it.
+ (cp_has_mutable_p): Prototype for new function.
+ * class.c (finish_struct_1): Set has_mutable from members.
+ * decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if
+ it contains a mutable.
+ * typeck.c (cp_has_mutable_p): New function.
+
1999-01-15 Mark Mitchell <mark@markmitchell.com>
* pt.c (process_template_parm): Ignore top-level qualifiers on
int cant_have_default_ctor;
int cant_have_const_ctor;
int no_const_asn_ref;
+ int has_mutable = 0;
/* The index of the first base class which has virtual
functions. Only applied to non-virtual baseclasses. */
if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE)
has_pointers = 1;
+ if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x)))
+ has_mutable = 1;
+
/* If any field is const, the structure type is pseudo-const. */
if (TREE_READONLY (x))
{
CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init;
CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init;
CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals;
+ CLASSTYPE_HAS_MUTABLE (t) = has_mutable;
/* Effective C++ rule 11. */
if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t)
unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1;
+ unsigned has_mutable : 1;
/* The MIPS compiler gets it wrong if this struct also
does not fill out to a multiple of 4 bytes. Add a
member `dummy' with new bits if you go over the edge. */
- unsigned dummy : 11;
+ unsigned dummy : 10;
} type_flags;
int n_ancestors;
/* Ditto, for operator=. */
#define TYPE_HAS_NONPUBLIC_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_assign_ref)
+/* Nonzero means that this type contains a mutable member */
+#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable)
+#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE))
+
/* Many routines need to cons up a list of basetypes for access
checking. This field contains a TREE_LIST node whose TREE_VALUE
is the main variant of the type, and whose TREE_VIA_PUBLIC
extern int ptr_reasonably_similar PROTO((tree, tree));
extern tree build_ptrmemfunc PROTO((tree, tree, int));
extern int cp_type_quals PROTO((tree));
+extern int cp_has_mutable_p PROTO((tree));
extern int at_least_as_qualified_p PROTO((tree, tree));
extern int more_qualified_p PROTO((tree, tree));
return;
}
+ if (TYPE_HAS_MUTABLE_P (type))
+ TREE_READONLY (decl) = 0;
+
if (processing_template_decl)
{
if (init && DECL_INITIAL (decl))
return TYPE_QUALS (type);
}
+
+/* Returns non-zero if the TYPE contains a mutable member */
+
+int
+cp_has_mutable_p (type)
+ tree type;
+{
+ while (TREE_CODE (type) == ARRAY_TYPE)
+ type = TREE_TYPE (type);
+
+ return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type);
+}