re PR c++/18793 (ICE in cp_expr_size)
authorMark Mitchell <mark@codesourcery.com>
Tue, 14 Dec 2004 19:38:25 +0000 (19:38 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 14 Dec 2004 19:38:25 +0000 (19:38 +0000)
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

gcc/cp/ChangeLog
gcc/cp/cp-objcp-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/init/aggr3.C [new file with mode: 0644]

index 1dd91a12f17ecd506fbeadc1150ca82494aa63ed..4b2f677a29048a511f23e5f0c21bef91575f791f 100644 (file)
@@ -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
index 9938b98f535e6723945d2e4a8a6b07280d1311c8..d43c159c01f1ba83162f3a67db6e6ee48018cce8 100644 (file)
@@ -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.  */
index 28cd86c9452e04d4332a5808950df27b1a7d939a..b92d0a5d0abc424642575aef05d1b5aab7e33a11 100644 (file)
@@ -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 (file)
index 0000000..3376897
--- /dev/null
@@ -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}; 
+}