diff options
author | Jakub Jelinek <jakub@redhat.com> | 2001-03-22 18:00:28 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2001-03-22 18:00:28 +0100 |
commit | a1c2b86d847dd68625e9209c6a6bc73cfdf01bb7 (patch) | |
tree | 26afc3398dd6f2811e7b32647281ae6caa2dd29a | |
parent | a519fba6e8e165352aacbda14be1f410e63112bc (diff) | |
download | gcc-a1c2b86d847dd68625e9209c6a6bc73cfdf01bb7.zip gcc-a1c2b86d847dd68625e9209c6a6bc73cfdf01bb7.tar.gz gcc-a1c2b86d847dd68625e9209c6a6bc73cfdf01bb7.tar.bz2 |
method.c (do_build_assign_ref): Don't use build_modify_expr for anonymous aggregates...
* 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
-rw-r--r-- | gcc/cp/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/cp/decl.c | 27 | ||||
-rw-r--r-- | gcc/cp/method.c | 6 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/g++.old-deja/g++.other/anon8.C | 22 |
5 files changed, 66 insertions, 1 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index f1cdaa7..d2c9217 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -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 diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 67aea12..0a6296a 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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. diff --git a/gcc/cp/method.c b/gcc/cp/method.c index 5f917d5..c7e3613 100644 --- a/gcc/cp/method.c +++ b/gcc/cp/method.c @@ -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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 57583fe..e75a1e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -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 index 0000000..54d41b7 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/anon8.C @@ -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; +} |