aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@gcc.gnu.org>2004-12-21 17:28:35 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2004-12-21 17:28:35 +0000
commitfd749a603df6e9fb3c5b46f7d7db501cc3758efd (patch)
tree3fb71da4f415c1c54ec5075034908eef2bbeca8b
parentebef4d30443353b9cf4b2b559b2429273b60065b (diff)
downloadgcc-fd749a603df6e9fb3c5b46f7d7db501cc3758efd.zip
gcc-fd749a603df6e9fb3c5b46f7d7db501cc3758efd.tar.gz
gcc-fd749a603df6e9fb3c5b46f7d7db501cc3758efd.tar.bz2
re PR c++/18975 (Copying objects with mutable non-static data members)
cp: PR c++/18975 * method.c (do_build_copy_constructor): Refactor. Don't const qualify a mutable field. (do_build_assign_ref): Likewise. testsuite: PR c++/18975 * g++.dg/other/synth1.C: New. From-SVN: r92461
-rw-r--r--gcc/cp/ChangeLog10
-rw-r--r--gcc/cp/method.c63
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/other/synth1.C31
4 files changed, 80 insertions, 29 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ac2a9ab..cb5d4ae 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,7 +1,15 @@
+2004-12-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18975
+ * method.c (do_build_copy_constructor): Refactor. Don't const
+ qualify a mutable field.
+ (do_build_assign_ref): Likewise.
+
2004-12-20 Matt Austern <austern@apple.com>
PR c++/19044
- * decl.c (make_rtl_for_nonlocal_decl): Use set_builtin_user_assembler_name
+ * decl.c (make_rtl_for_nonlocal_decl): Use
+ set_builtin_user_assembler_name.
2004-12-19 Mark Mitchell <mark@codesourcery.com>
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 75f9816..6716a8f 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -497,7 +497,6 @@ static void
do_build_copy_constructor (tree fndecl)
{
tree parm = FUNCTION_FIRST_USER_PARM (fndecl);
- tree t;
parm = convert_from_reference (parm);
@@ -507,7 +506,7 @@ do_build_copy_constructor (tree fndecl)
if *this is a base subobject. */;
else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type))
{
- t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
+ tree t = build2 (INIT_EXPR, void_type_node, current_class_ref, parm);
finish_expr_stmt (t);
}
else
@@ -551,22 +550,20 @@ do_build_copy_constructor (tree fndecl)
for (; fields; fields = TREE_CHAIN (fields))
{
- tree init;
+ tree init = parm;
tree field = fields;
tree expr_type;
if (TREE_CODE (field) != FIELD_DECL)
continue;
- init = parm;
+ expr_type = TREE_TYPE (field);
if (DECL_NAME (field))
{
if (VFIELD_NAME_P (DECL_NAME (field)))
continue;
}
- else if ((t = TREE_TYPE (field)) != NULL_TREE
- && ANON_AGGR_TYPE_P (t)
- && TYPE_FIELDS (t) != NULL_TREE)
+ else if (ANON_AGGR_TYPE_P (expr_type) && TYPE_FIELDS (expr_type))
/* Just use the field; anonymous types can't have
nontrivial copy ctors or assignment ops. */;
else
@@ -577,14 +574,19 @@ do_build_copy_constructor (tree fndecl)
the field is "T", then the type will usually be "const
T". (There are no cv-qualified variants of reference
types.) */
- expr_type = TREE_TYPE (field);
if (TREE_CODE (expr_type) != REFERENCE_TYPE)
- expr_type = cp_build_qualified_type (expr_type, cvquals);
+ {
+ int quals = cvquals;
+
+ if (DECL_MUTABLE_P (field))
+ quals &= ~TYPE_QUAL_CONST;
+ expr_type = cp_build_qualified_type (expr_type, quals);
+ }
+
init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
init = build_tree_list (NULL_TREE, init);
- member_init_list
- = tree_cons (field, init, member_init_list);
+ member_init_list = tree_cons (field, init, member_init_list);
}
finish_mem_initializers (member_init_list);
}
@@ -639,52 +641,57 @@ do_build_assign_ref (tree fndecl)
fields;
fields = TREE_CHAIN (fields))
{
- tree comp, init, t;
+ tree comp = current_class_ref;
+ tree init = parm;
tree field = fields;
+ tree expr_type;
+ int quals;
if (TREE_CODE (field) != FIELD_DECL || DECL_ARTIFICIAL (field))
continue;
- if (CP_TYPE_CONST_P (TREE_TYPE (field)))
+ expr_type = TREE_TYPE (field);
+
+ if (CP_TYPE_CONST_P (expr_type))
{
error ("non-static const member %q#D, can't use default "
"assignment operator", field);
continue;
}
- else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE)
+ else if (TREE_CODE (expr_type) == REFERENCE_TYPE)
{
error ("non-static reference member %q#D, can't use "
"default assignment operator", field);
continue;
}
- comp = current_class_ref;
- init = parm;
-
if (DECL_NAME (field))
{
if (VFIELD_NAME_P (DECL_NAME (field)))
continue;
}
- else if ((t = TREE_TYPE (field)) != NULL_TREE
- && ANON_AGGR_TYPE_P (t)
- && TYPE_FIELDS (t) != NULL_TREE)
+ else if (ANON_AGGR_TYPE_P (expr_type)
+ && TYPE_FIELDS (expr_type) != NULL_TREE)
/* Just use the field; anonymous types can't have
nontrivial copy ctors or assignment ops. */;
else
continue;
- comp = build3 (COMPONENT_REF, TREE_TYPE (field), comp, field,
- NULL_TREE);
- init = build3 (COMPONENT_REF,
- cp_build_qualified_type (TREE_TYPE (field), cvquals),
- init, field, NULL_TREE);
+ comp = build3 (COMPONENT_REF, expr_type, comp, field, NULL_TREE);
+
+ /* Compute the type of init->field */
+ quals = cvquals;
+ if (DECL_MUTABLE_P (field))
+ quals &= ~TYPE_QUAL_CONST;
+ expr_type = cp_build_qualified_type (expr_type, quals);
+
+ init = build3 (COMPONENT_REF, expr_type, init, field, NULL_TREE);
if (DECL_NAME (field))
- finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
+ init = build_modify_expr (comp, NOP_EXPR, init);
else
- finish_expr_stmt (build2 (MODIFY_EXPR, TREE_TYPE (comp), comp,
- init));
+ init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
+ finish_expr_stmt (init);
}
}
finish_return_stmt (current_class_ref);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 99ccef8..2633376 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2004-12-21 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/18975
+ * g++.dg/other/synth1.C: New.
+
2004-12-21 James A. Morrison <phython@gcc.gnu.org>
PR c/18963
diff --git a/gcc/testsuite/g++.dg/other/synth1.C b/gcc/testsuite/g++.dg/other/synth1.C
new file mode 100644
index 0000000..5829c6c7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/other/synth1.C
@@ -0,0 +1,31 @@
+// Copyright (C) 2004 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 17 Dec 2004 <nathan@codesourcery.com>
+
+// PR 18975: Rejects legal
+// Origin: Wolfgang Roehrl <wolfgang.roehrl@de.gi-de.com>
+
+struct PTR
+{
+ PTR ();
+ PTR (PTR&);
+ PTR& operator= (PTR&);
+
+private:
+ PTR (const PTR&);
+ PTR& operator= (const PTR&);
+};
+
+
+struct XYZ
+{
+ XYZ (PTR& p) : ptr(p) {}
+
+ mutable PTR ptr;
+};
+
+
+XYZ f1 ();
+
+
+XYZ f2 (void) { return f1(); }
+void f3 (XYZ& dst, const XYZ& src) { dst = src; }