My patch for c++/55032 fixed this crash for arrays of known bound, but the COMPLETE_TYPE_P test for when we need to copy the layout information doesn't work for arrays of unknown bound. So let's check completeness of the element type and accept that we might copy layout information more than necessary.

Tested x86_64-pc-linux-gnu, applying to trunk and 4.7. Jakub, is this also OK for 4.8.1?
commit 5635841b1d7a73efe3d731cac17608ef9aa68736
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon May 20 09:27:07 2013 -0400

    	PR c++/57325
    	* tree.c (build_cplus_array_type): Copy layout info if element
    	type is complete.

diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 9476aee..e4967c1 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -829,10 +829,12 @@ build_cplus_array_type (tree elt_type, tree index_type)
 
       if (TYPE_MAIN_VARIANT (t) != m)
 	{
-	  if (COMPLETE_TYPE_P (t) && !COMPLETE_TYPE_P (m))
+	  if (COMPLETE_TYPE_P (TREE_TYPE (t)) && !COMPLETE_TYPE_P (m))
 	    {
 	      /* m was built before the element type was complete, so we
-		 also need to copy the layout info from t.  */
+		 also need to copy the layout info from t.  We might
+	         end up doing this multiple times if t is an array of
+	         unknown bound.  */
 	      tree size = TYPE_SIZE (t);
 	      tree size_unit = TYPE_SIZE_UNIT (t);
 	      unsigned int align = TYPE_ALIGN (t);
diff --git a/gcc/testsuite/g++.dg/template/array26.C b/gcc/testsuite/g++.dg/template/array26.C
new file mode 100644
index 0000000..6692071
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/array26.C
@@ -0,0 +1,40 @@
+// PR c++/57325
+
+class valarray { int _M_data; };
+template < typename > struct SimpleJet { valarray partials; };
+
+template < class C > struct scoped_ptr_impl
+{
+    scoped_ptr_impl (C *):data_ () { }
+    struct Data
+    {
+        C ptr;
+    };
+    Data data_;
+};
+
+template < class, class = int >struct scoped_ptr;
+template < class C, class D > struct scoped_ptr <C[], D >
+{
+    scoped_ptr ():impl_ (0) { }
+    scoped_ptr_impl < C > impl_;
+};
+
+template < typename JetsT > void
+TestJets (JetsT *)
+{
+    typedef typename JetsT::JetType JetT;
+    scoped_ptr < JetT[] > a;
+}
+
+template < typename T > struct SimpleJets
+{
+    typedef SimpleJet < T > JetType;
+    scoped_ptr < SimpleJet < T >[] > vars_;
+};
+
+void fn ()
+{
+    SimpleJets < double >b;
+    TestJets (&b);
+}

Reply via email to