summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog5
-rw-r--r--gcc/cp/cp-objcp-common.c27
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/init/aggr3.C16
4 files changed, 47 insertions, 6 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 1dd91a12f17..4b2f677a290 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 9938b98f535..d43c159c01f 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 28cd86c9452..b92d0a5d0ab 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 00000000000..3376897e105
--- /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};
+}