From 7880033a227a225e74c51bfbba05153f53670194 Mon Sep 17 00:00:00 2001 From: nathan Date: Tue, 21 Dec 2004 17:28:35 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@92461 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 10 +++++- gcc/cp/method.c | 63 ++++++++++++++++++++----------------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/g++.dg/other/synth1.C | 31 ++++++++++++++++++ 4 files changed, 80 insertions(+), 29 deletions(-) create mode 100644 gcc/testsuite/g++.dg/other/synth1.C 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 + + 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 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 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 + + PR c++/18975 + * g++.dg/other/synth1.C: New. + 2004-12-21 James A. Morrison 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 + +// PR 18975: Rejects legal +// Origin: Wolfgang Roehrl + +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; } -- 2.7.4