[C++ PATCH] Don't set TREE_READONLY on two or more diminsional arrays if they need constructing (PR c++/24780)

Jakub Jelinek jakub@redhat.com
Sat Nov 12 12:17:00 GMT 2005


Hi!

The following testcase ICEs, because TREE_READONLY flag has been set on
a decl that needs constructing.
The problem here is that complete_type doesn't ensure
TYPE_NEEDS_CONSTRUCTING flag is accurate for two or more dimensional
arrays and complete_vars relies on the flags being accurate.
complete_type copies these flags from the inner type, but not from
the exact type used in it, but from its main variant, and sets it
just on the type passed to complete_type.  So, for 2 dimensional arrays
where the inner array type is not its main variant, the flag is copied from
a type on which the recursive complete_type hasn't updated it.

The following patch fixes it by setting the flags on all variants
(similarly how layout_type sets the sizes on all variants).
Bootstrapped/regtested on i686-linux.

Ok for HEAD/4.0?

2005-11-12  Jakub Jelinek  <jakub@redhat.com>

	PR c++/24780
	* typeck.c (complete_type): Set TYPE_NEEDS_CONSTRUCTING
	and TYPE_HAS_NONTRIVIAL_DESTRUCTOR flags for all variants
	of array type.

	* g++.dg/opt/pr24780.C: New test.

--- gcc/cp/typeck.c.jj	2005-11-06 07:28:17.000000000 -0500
+++ gcc/cp/typeck.c	2005-11-12 03:59:25.237034141 -0500
@@ -107,12 +107,18 @@ complete_type (tree type)
   else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
     {
       tree t = complete_type (TREE_TYPE (type));
+      unsigned int needs_constructing, has_nontrivial_dtor;
       if (COMPLETE_TYPE_P (t) && !dependent_type_p (type))
 	layout_type (type);
-      TYPE_NEEDS_CONSTRUCTING (type)
+      needs_constructing
 	= TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t));
-      TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)
+      has_nontrivial_dtor
 	= TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TYPE_MAIN_VARIANT (t));
+      for (t = TYPE_MAIN_VARIANT (type); t; t = TYPE_NEXT_VARIANT (t))
+	{
+	  TYPE_NEEDS_CONSTRUCTING (t) = needs_constructing;
+	  TYPE_HAS_NONTRIVIAL_DESTRUCTOR (t) = has_nontrivial_dtor;
+	}
     }
   else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type))
     instantiate_class_template (TYPE_MAIN_VARIANT (type));
--- gcc/testsuite/g++.dg/opt/pr24780.C.jj	2005-11-12 04:02:55.579730758 -0500
+++ gcc/testsuite/g++.dg/opt/pr24780.C	2005-11-12 04:01:10.975779026 -0500
@@ -0,0 +1,14 @@
+// PR c++/24780
+// { dg-do compile }
+
+template<typename S=int>
+struct Move {
+  Move();
+  static Move<S> const MOVES[2][2];
+};
+template<typename S>
+  Move<S> const Move<S>::MOVES[2][2]={};
+typedef Move<int> const MoveClass;
+void moves(int x, int y) {
+  &MoveClass::MOVES[x][y];
+}

	Jakub



More information about the Gcc-patches mailing list