This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix implicit assignment operators with anonymous aggregates
- To: jason at redhat dot com, mark at codesourcery dot com
- Subject: [C++ PATCH] Fix implicit assignment operators with anonymous aggregates
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Tue, 20 Mar 2001 17:18:48 +0100
- Cc: gcc-patches at gcc dot gnu dot org
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
Hi!
The testcase below results in error (and it did not in g++ 2.95.x), while I
think it is completely valid. It B does not have a trivial assignment
operator, everything compiles fine (A's assignment operator ends up
immediate call to build (MODIFY_EXPR, ...)). The problem is that
fixup_anonymous_aggr removes the assignment operator method, but
build_modify_expr requires it, so it dies on anonymous union's operator= not
being accessible.
This patch fixes it (bootstrapped on i386, no regressions), another approach
might be not to delete the artificial operator= of anonymous aggregates.
For anonymous unions both should IMHO work right, I'm not sure about
anonymous structures:
I don't think we disallow anonymous structure's members to have explicit
operator=, which won't be called now (well, g++ will either error or simply
pretend there are none) nor with the patch below (g++ will pretend there are
none) - to fix that either fixup_anonymous_aggr would have to keep implicit
operator= or do_build_assign_ref would have to build_modify_expr for each of
anonymous structure's fields.
2001-03-20 Jakub Jelinek <jakub@redhat.com>
* method.c (do_build_assign_ref): Don't use build_modify_expr for
anonymous aggregates, since they don't have assignment operator
method.
* g++.old-deja/g++.other/anon8.C: New test.
--- gcc/cp/method.c.jj Tue Mar 20 13:45:06 2001
+++ gcc/cp/method.c Tue Mar 20 13:55:01 2001
@@ -703,7 +703,11 @@ do_build_assign_ref (fndecl)
build_qualified_type (TREE_TYPE (field), cvquals),
init, field);
- finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
+ if (DECL_NAME (field))
+ finish_expr_stmt (build_modify_expr (comp, NOP_EXPR, init));
+ else
+ finish_expr_stmt (build (MODIFY_EXPR, TREE_TYPE (comp), comp,
+ init));
}
}
finish_return_stmt (current_class_ref);
--- gcc/testsuite/g++.old-deja/g++.other/anon8.C.jj Mon Mar 19 17:13:30 2001
+++ gcc/testsuite/g++.old-deja/g++.other/anon8.C Tue Mar 20 17:01:57 2001
@@ -0,0 +1,22 @@
+// Build don't link:
+
+struct B
+{
+ int a;
+ B & operator= (const B &);
+};
+
+struct A
+{
+ union {
+ int a;
+ };
+ B b;
+};
+
+A x;
+
+void foo (const A &y)
+{
+ x = y;
+}
Jakub