This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR 6994
- From: Zack Weinberg <zack at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 23 Oct 2002 23:19:34 -0700
- Subject: 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;
+}