diff options
author | Mark Mitchell <mark@codesourcery.com> | 2004-12-14 19:38:25 +0000 |
---|---|---|
committer | Mark Mitchell <mmitchel@gcc.gnu.org> | 2004-12-14 19:38:25 +0000 |
commit | acb3f79a4af6acc1709d001a33599bf169712c12 (patch) | |
tree | 6c2b4646df17cb5b7c481f47b94c44bffd17c4f0 | |
parent | f90ac3f0e40f8d7876f8abecc782dd0befd4e2a6 (diff) | |
download | gcc-acb3f79a4af6acc1709d001a33599bf169712c12.zip gcc-acb3f79a4af6acc1709d001a33599bf169712c12.tar.gz gcc-acb3f79a4af6acc1709d001a33599bf169712c12.tar.bz2 |
re PR c++/18793 (ICE in cp_expr_size)
PR c++/18793
* cp-objcp-common.c (cp_expr_size): Loosen assertion.
PR c++/18793
* g++.dg/init/aggr3.C: New test.
From-SVN: r92156
-rw-r--r-- | gcc/cp/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/cp/cp-objcp-common.c | 27 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/init/aggr3.C | 16 |
4 files changed, 47 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 1dd91a12..4b2f677 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2004-12-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/18793 + * cp-objcp-common.c (cp_expr_size): Loosen assertion. + 2004-12-14 Nathan Sidwell <nathan@codesourcery.com> PR c++/18949 diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c index 9938b98..d43c159 100644 --- a/gcc/cp/cp-objcp-common.c +++ b/gcc/cp/cp-objcp-common.c @@ -75,21 +75,36 @@ cxx_warn_unused_global_decl (tree decl) tree cp_expr_size (tree exp) { - if (CLASS_TYPE_P (TREE_TYPE (exp))) + tree type = TREE_TYPE (exp); + + if (CLASS_TYPE_P (type)) { /* The backend should not be interested in the size of an expression of a type with both of these set; all copies of such types must go through a constructor or assignment op. */ - gcc_assert (!TYPE_HAS_COMPLEX_INIT_REF (TREE_TYPE (exp)) - || !TYPE_HAS_COMPLEX_ASSIGN_REF (TREE_TYPE (exp)) + gcc_assert (!TYPE_HAS_COMPLEX_INIT_REF (type) + || !TYPE_HAS_COMPLEX_ASSIGN_REF (type) /* But storing a CONSTRUCTOR isn't a copy. */ - || TREE_CODE (exp) == CONSTRUCTOR); + || TREE_CODE (exp) == CONSTRUCTOR + /* And, the gimplifier will sometimes make a copy of + an aggregate. In particular, for a case like: + + struct S { S(); }; + struct X { int a; S s; }; + X x = { 0 }; + + the gimplifier will create a temporary with + static storage duration, perform static + initialization of the temporary, and then copy + the result. Since the "s" subobject is never + constructed, this is a valid transformation. */ + || CP_AGGREGATE_TYPE_P (type)); /* This would be wrong for a type with virtual bases, but they are caught by the assert above. */ - return (is_empty_class (TREE_TYPE (exp)) + return (is_empty_class (type) ? size_zero_node - : CLASSTYPE_SIZE_UNIT (TREE_TYPE (exp))); + : CLASSTYPE_SIZE_UNIT (type)); } else /* Use the default code. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 28cd86c..b92d0a5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-12-14 Mark Mitchell <mark@codesourcery.com> + + PR c++/18793 + * g++.dg/init/aggr3.C: New test. + 2004-12-14 Janis Johnson <janis187@us.ibm.com * gcc.dg/altivec-types-1.c: New test. diff --git a/gcc/testsuite/g++.dg/init/aggr3.C b/gcc/testsuite/g++.dg/init/aggr3.C new file mode 100644 index 0000000..3376897 --- /dev/null +++ b/gcc/testsuite/g++.dg/init/aggr3.C @@ -0,0 +1,16 @@ +// PR c++/18793 + +struct S { + S(); + S(const S&); + void operator=(const S&); +}; + +struct X { + int a, b, c, d, e; + S s; +}; + +void foobar () { + X x = {0}; +} |