This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix implicit assignment operators with anonymous aggregates
- To: Jason Merrill <jason at redhat dot com>
- Subject: Re: [C++ PATCH] Fix implicit assignment operators with anonymous aggregates
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Wed, 21 Mar 2001 10:33:48 -0500
- Cc: mark at codesourcery dot com, gcc-patches at gcc dot gnu dot org
- References: <20010320171848.E1635@sunsite.ms.mff.cuni.cz> <u9hf0o49m9.fsf@casey.cambridge.redhat.com>
- Reply-To: Jakub Jelinek <jakub at redhat dot com>
On Wed, Mar 21, 2001 at 01:58:54AM +0000, Jason Merrill wrote:
> >>>>> "Jakub" == Jakub Jelinek <jakub@redhat.com> writes:
>
> > 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.
>
> I think I'd rather handle this in build_modify_expr; it should be a simple
> matter of an additional test to avoid going to build_opfncall.
>
> > 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=
>
> Hmm, if we don't we probably should.
Is this ok? Bootstrapped, no regressions.
2001-03-21 Jakub Jelinek <jakub@redhat.com>
* decl.c (fixup_anonymous_aggr): Disallow copy assignment operators
for anonymous structure fields.
* typeck.c (build_modify_expr): Build MODIFY_EXPR directly for
anonymous aggregates, since they don't have assignment operator
method.
* g++.old-deja/g++.other/anon8.C: New test.
--- gcc/cp/decl.c.jj Tue Mar 20 20:19:11 2001
+++ gcc/cp/decl.c Wed Mar 21 12:18:54 2001
@@ -6854,6 +6854,23 @@ fixup_anonymous_aggr (t)
/* ISO C++ 9.5.3. Anonymous unions may not have function members. */
if (TYPE_METHODS (t))
cp_error_at ("an anonymous union cannot have function members", t);
+
+ /* Anonymous aggregates cannot have fields with complex assignment operators
+ (because they cannot have assignment operators themselves).
+ For anonymous unions this is already checked because they are not allowed
+ in any union, otherwise we have to check it. */
+ if (TREE_CODE (t) != UNION_TYPE)
+ {
+ tree field, type;
+
+ for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field))
+ if (TREE_CODE (field) == FIELD_DECL)
+ {
+ type = TREE_TYPE (field);
+ if (CLASS_TYPE_P (type) && TYPE_HAS_COMPLEX_ASSIGN_REF (type))
+ cp_error_at ("member %#D' with copy assignment operator not allowed in anonymous aggregate", field);
+ }
+ }
}
/* Make sure that a declaration with no declarator is well-formed, i.e.
--- gcc/cp/typeck.c.jj Mon Mar 12 11:45:35 2001
+++ gcc/cp/typeck.c Wed Mar 21 11:41:50 2001
@@ -5596,6 +5596,11 @@ build_modify_expr (lhs, modifycode, rhs)
}
else if (modifycode == NOP_EXPR)
{
+ /* Anonymous aggregates don't have any methods, so avoid calling
+ them. */
+ if (ANON_AGGR_TYPE_P (lhstype))
+ return build (MODIFY_EXPR, lhstype, lhs, rhs);
+
/* `operator=' is not an inheritable operator. */
if (! IS_AGGR_TYPE (lhstype))
/* Do the default thing */;
--- 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