method.c (do_build_assign_ref): Don't use build_modify_expr for anonymous aggregates...
authorJakub Jelinek <jakub@redhat.com>
Thu, 22 Mar 2001 17:00:28 +0000 (18:00 +0100)
committerJakub Jelinek <jakub@gcc.gnu.org>
Thu, 22 Mar 2001 17:00:28 +0000 (18:00 +0100)
* method.c (do_build_assign_ref): Don't use build_modify_expr for
anonymous aggregates, since they don't have assignment operator
method.
* decl.c (fixup_anonymous_aggr): Disallow ctors, dtors and copy
assignment operators for anonymous structure fields.

* g++.old-deja/g++.other/anon8.C: New test.

From-SVN: r40746

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/method.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.old-deja/g++.other/anon8.C [new file with mode: 0644]

index f1cdaa755bd73a4865fed168c671a67b82ac2dd2..d2c9217b29ea6ac11e12baab026344bc9b129a29 100644 (file)
@@ -1,3 +1,11 @@
+2001-03-22  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.
+       * decl.c (fixup_anonymous_aggr): Disallow ctors, dtors and copy
+       assignment operators for anonymous structure fields.
+
 2001-03-21  Jason Merrill  <jason@redhat.com>
 
        * pt.c (instantiate_decl): Abort if we see a member constant
index 67aea126f48fa427542498dfdbe102a3701bc629..0a6296a47a0c44952a16e281aa19c10f10a315dc 100644 (file)
@@ -6815,6 +6815,33 @@ 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 ctors, dtors or complex
+     assignment operators (because they cannot have these methods 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))
+             {
+               if (TYPE_NEEDS_CONSTRUCTING (type))
+                 cp_error_at ("member %#D' with constructor not allowed in anonymous aggregate",
+                              field);
+               if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
+                 cp_error_at ("member %#D' with destructor not allowed in anonymous aggregate",
+                              field);
+               if (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.
index 5f917d5aabb6b7b5a8f85f14f8b37f6bc3bc822b..c7e36132f57c78db8473f424e1613473dee006b6 100644 (file)
@@ -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);
index 57583fe4fc92a27e37fbab44b0ce1dfa5e4d447c..e75a1e01be484fce828606ce5b1d4d3392f70a05 100644 (file)
@@ -1,3 +1,7 @@
+2001-03-22  Jakub Jelinek  <jakub@redhat.com>
+
+       * g++.old-deja/g++.other/anon8.C: New test.
+
 2001-03-20  Philip Blundell  <philb@gnu.org>
 
        * gcc.c-torture/compile/20010320-1.c: New test.
diff --git a/gcc/testsuite/g++.old-deja/g++.other/anon8.C b/gcc/testsuite/g++.old-deja/g++.other/anon8.C
new file mode 100644 (file)
index 0000000..54d41b7
--- /dev/null
@@ -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;
+}