This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fix PR c++/12883
- From: Adam Nemet <anemet at lnxw dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 22 May 2004 14:05:35 -0700
- Subject: [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;
+}