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]

Fix PR 6994


This patch fixes PR 6994, by causing VLA types (and only VLA types) to
be copied properly by copy_body_r.  It was necessary to be a bit more
invasive of walk_tree than I would have liked: getting this right
requires that walk_tree be exhaustive in descending into type
structures.

There's a risk of a performance regression here.  I will compare
bootstrap times between yesterday (after my 'move
variably_modified_type_p' patch) and this patch, after bootstrap
completes.  However, if this causes a performance problem I would
prefer to address that in a follow-on patch.

i686-linux bootstrap in progress.

zw

	PR middle-end/6994
	* tree-inline.c (walk_tree): Make sure to descend into all
	subfields of TYPE nodes.
	(copy_tree_r): If a type is variably modified (as determined
	by variably_modified_type_p) it needs to be copied.
	* tree.def: Remove stale references to TYPE_SEP and
	TYPE_SEP_UNIT.

testsuite:
	* g++.dg/ext/vla1.C: New test.

===================================================================
Index: tree-inline.c
--- tree-inline.c	23 Oct 2002 17:13:15 -0000	1.33
+++ tree-inline.c	24 Oct 2002 06:17:06 -0000
@@ -1543,6 +1543,73 @@ walk_tree (tp, func, data, htab_)
     {
       WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
     }
+  else if (TREE_CODE_CLASS (code) == 't')
+    {
+      /* The major reason to walk into types is that copy_body needs
+	 to copy them if they're dependent on variables (VLA types).
+	 So we need to cover TYPE_SIZE, TYPE_SIZE_UNIT, and all the
+	 subcomponents and/or pointed-to types of this type, but we
+	 don't need to inspect any of the 'related type' fields.  */
+      switch (code)
+	{
+	case VOID_TYPE:
+	case COMPLEX_TYPE:
+	case VECTOR_TYPE:
+	case ENUMERAL_TYPE:
+	case BOOLEAN_TYPE:
+	case CHAR_TYPE:
+	case POINTER_TYPE:
+	case REFERENCE_TYPE:
+	case FILE_TYPE:
+	case LANG_TYPE:
+	  /* no special subfields */
+	  break;
+
+	case INTEGER_TYPE:
+	case REAL_TYPE:
+	  WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
+	  WALK_SUBTREE (TYPE_MAX_VALUE (*tp));
+	  break;
+
+	case OFFSET_TYPE:
+	  WALK_SUBTREE (TYPE_OFFSET_BASETYPE (*tp));
+	  break;
+
+	case METHOD_TYPE:
+	  WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
+	  /* fall through */
+	case FUNCTION_TYPE:
+	  {
+	    tree arg;
+	    /* We never want to walk into default arguments.  */
+	    for (arg = TYPE_ARG_TYPES (*tp); arg; arg = TREE_CHAIN (arg))
+	      WALK_SUBTREE (TREE_VALUE (arg));
+	  }
+	  break;
+
+	case ARRAY_TYPE:
+	case SET_TYPE:
+	  WALK_SUBTREE (TYPE_DOMAIN (*tp));
+	  break;
+
+	case RECORD_TYPE:
+	case UNION_TYPE:
+	case QUAL_UNION_TYPE:
+	  {
+	    tree field;
+	    for (field = TYPE_FIELDS (*tp); field; field = TREE_CHAIN (field))
+	      WALK_SUBTREE (field);
+	  }
+	  break;
+
+	default:
+	  abort ();
+	}
+	  
+      WALK_SUBTREE (TYPE_SIZE (*tp));
+      WALK_SUBTREE (TYPE_SIZE_UNIT (*tp));
+      WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
+    }
 
   result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
 						      data, htab);
@@ -1559,24 +1626,11 @@ walk_tree (tp, func, data, htab_)
     case REAL_CST:
     case VECTOR_CST:
     case STRING_CST:
-    case REAL_TYPE:
-    case COMPLEX_TYPE:
-    case VECTOR_TYPE:
-    case VOID_TYPE:
-    case BOOLEAN_TYPE:
-    case UNION_TYPE:
-    case ENUMERAL_TYPE:
     case BLOCK:
-    case RECORD_TYPE:
       /* None of thse have subtrees other than those already walked
          above.  */
       break;
 
-    case POINTER_TYPE:
-    case REFERENCE_TYPE:
-      WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
-      break;
-
     case TREE_LIST:
       WALK_SUBTREE (TREE_VALUE (*tp));
       WALK_SUBTREE_TAIL (TREE_CHAIN (*tp));
@@ -1604,33 +1658,6 @@ walk_tree (tp, func, data, htab_)
     case CONSTRUCTOR:
       WALK_SUBTREE_TAIL (CONSTRUCTOR_ELTS (*tp));
 
-    case METHOD_TYPE:
-      WALK_SUBTREE (TYPE_METHOD_BASETYPE (*tp));
-      /* Fall through.  */
-
-    case FUNCTION_TYPE:
-      WALK_SUBTREE (TREE_TYPE (*tp));
-      {
-	tree arg = TYPE_ARG_TYPES (*tp);
-
-	/* We never want to walk into default arguments.  */
-	for (; arg; arg = TREE_CHAIN (arg))
-	  WALK_SUBTREE (TREE_VALUE (arg));
-      }
-      break;
-
-    case ARRAY_TYPE:
-      WALK_SUBTREE (TREE_TYPE (*tp));
-      WALK_SUBTREE_TAIL (TYPE_DOMAIN (*tp));
-
-    case INTEGER_TYPE:
-      WALK_SUBTREE (TYPE_MIN_VALUE (*tp));
-      WALK_SUBTREE_TAIL (TYPE_MAX_VALUE (*tp));
-
-    case OFFSET_TYPE:
-      WALK_SUBTREE (TREE_TYPE (*tp));
-      WALK_SUBTREE_TAIL (TYPE_OFFSET_BASETYPE (*tp));
-
 #ifdef INLINER_FOR_JAVA
     case EXIT_BLOCK_EXPR:
       WALK_SUBTREE_TAIL (TREE_OPERAND (*tp, 1));
@@ -1711,8 +1738,8 @@ copy_tree_r (tp, walk_subtrees, data)
 	TREE_CHAIN (*tp) = chain;
 #endif /* INLINER_FOR_JAVA */
     }
-  else if (TREE_CODE_CLASS (code) == 't')
-    /* There's no need to copy types, or anything beneath them.  */
+  else if (TREE_CODE_CLASS (code) == 't' && !variably_modified_type_p (*tp))
+    /* Types only need to be copied if they are variably modified.  */
     *walk_subtrees = 0;
 
   return NULL_TREE;
===================================================================
Index: tree.def
--- tree.def	29 Sep 2002 13:16:42 -0000	1.54
+++ tree.def	24 Oct 2002 06:17:06 -0000
@@ -199,8 +199,6 @@ DEFTREECODE (FILE_TYPE, "file_type", 't'
    TREE_TYPE		  Type of an array element.
    TYPE_DOMAIN		  Type to index by.
 			    Its range of values specifies the array length.
-   TYPE_SEP		  Expression for units from one elt to the next.
-   TYPE_SEP_UNIT	  Number of bits in a unit for previous.
  The field TYPE_POINTER_TO (TREE_TYPE (array_type)) is always nonzero
  and holds the type to coerce a value of that array type to in C.
  TYPE_STRING_FLAG indicates a string (in contrast to an array of chars)
===================================================================
Index: testsuite/g++.dg/ext/vla1.C
--- testsuite/g++.dg/ext/vla1.C	1 Jan 1970 00:00:00 -0000
+++ testsuite/g++.dg/ext/vla1.C	24 Oct 2002 06:17:07 -0000
@@ -0,0 +1,16 @@
+// { dg-do compile }
+
+// Check that (a) the VLA declaration provokes an error, and
+// (b) the compiler does not crash.  See PR middle-end/6994.
+
+class A
+{
+  A (int);
+};
+
+A::A (int i)
+{
+  int ar[1][i];  // { dg-error "variable-size array" }
+
+  ar[0][0] = 0;
+}


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