This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: [C++ PATCH] Fix implicit assignment operators with anonymous aggregates


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]