This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] fix PR c++/12883


Hi,

The patch below fixes PR 12883.  This is long outstanding bug that
dates back to 2.95.3 and even before.  Under some circumstances, g++
fails to emit the cleanup region for a local array of a type having a
destructor.

The problem comes down to the fact that TYPE_HAS_NONTRIVIAL_DESTRUCTOR
gets never set for the array type in the testcase.  It seems that
there are two places where TYPE_HAS_NONTRIVIAL_DESTRUCTOR is set for
an array type:

  1. build_cplus_aray_type_1() if the underlying type is already
     complete.  This is not the case here because the underlying type
     is a template instantiation waiting to be instantiated.

  2. complete_type() if the array type has known bounds (TYPE_DOMAIN
     is not null).  This does not help this situation either as the
     testcase chooses to specify the bounds through the initializer
     which is only processed later.

The fix adds a third case that updates TYPE_HAS_NONTRIVIAL_DESTRUCTOR
after the initializer is processed in complete_array_type().  This
function is called from maybe_deduce_size_from_array_init().  The same
logic is used as in complete_type().

The patch was regression tested on i686-pc-linux-gnu.

OK to apply?

Adam

cp/ChangeLog:

2004-05-22  Adam Nemet  <anemet@lnxw.com> 
 
        PR c++/12883 
        * decl.c (complete_array_type): Set TYPE_NEEDS_CONSTRUCTING and 
        TYPE_HAS_NONTRIVIAL_DESTRUCTOR based on the underlying type. 

testsuite/ChangeLog:

2004-05-22  Adam Nemet  <anemet@lnxw.com> 
 
        PR c++/12883 
        * g++.dg/init/array14.C: New test. 

Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1206
diff -u -p -r1.1206 decl.c
--- cp/decl.c	13 May 2004 06:40:16 -0000	1.1206
+++ cp/decl.c	22 May 2004 20:50:19 -0000
@@ -5338,6 +5338,7 @@ complete_array_type (tree type, tree ini
     {
       tree itype;
       tree domain;
+      tree elt_type;
 
       domain = build_index_type (maxindex);
       TYPE_DOMAIN (type) = domain;
@@ -5355,6 +5356,12 @@ complete_array_type (tree type, tree ini
 	 size of the array.  */
       if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)))
 	TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = domain;
+
+      elt_type = TREE_TYPE (type);
+      TYPE_NEEDS_CONSTRUCTING (type)
+	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type));
+      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type));      
     }
 
   /* Lay out the type now that we can get the real answer.  */
Index: testsuite/g++.dg/init/array14.C
===================================================================
RCS file: testsuite/g++.dg/init/array14.C
diff -N testsuite/g++.dg/init/array14.C
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/init/array14.C	22 May 2004 20:50:19 -0000
@@ -0,0 +1,21 @@
+// PR c++/12883
+// Bug: Destructor of array object not called if no prior
+// instantiation of the template has happened.
+
+// { dg-do run }
+
+int ret = 1;
+
+template <int> struct X
+{
+  X(int) { }
+  ~X() { ret = 0; }
+}; 
+ 
+int main()
+{
+  { 
+    X<0> array[] = { 0 };
+  }
+  return ret;
+}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]