middle-end/6994: ICE in find_function_data (VLA types and SAVE_EXPRs and clones, oh my!)
Zack Weinberg
zack@codesourcery.com
Wed Oct 9 23:47:00 GMT 2002
On Wed, Oct 09, 2002 at 04:00:59PM -0700, Janis Johnson wrote:
> At the time of the ICE in find_function_data, 'exp' in expand_expr is
> a SAVE_EXPR whose function context, 'context', is cloned from
> 'current_function_decl'. The code in expand_expr falsely assumes that
> since 'context' is different from 'current_function_decl', 'context' is
> a containing function. It calls find_function_data just to make sure
> that 'context' is for a containing function, but it's not so that
> function aborts.
This is a shortened version of the tree structure causing the problem.
<array_ref
<array_ref
type <array_type
size <plus
<mult
<save 0x401a4040
<plus
<parm_decl 0x4019fee0 i>
<integer_cst -1>>
<function_decl A>>
<integer_cst 32>>
<integer_cst 32>>
unit size <plus
<save 0x401a4320
<plus
<mult
<parm_decl 0x4019fee0 i>
<integer_cst 4>>
<integer_cst -4>>
<function_decl A>>
<integer_cst 4>>>
<var_decl ar
size <plus
<mult
<save 0x401a4900
<plus
<parm_decl 0x4019fd90 i>
<integer_cst -1>>
<function_decl __base_ctor>>
<integer_cst 32>>
<integer_cst 32>>
unit size <plus
<save 0x401a49c0
<plus
<mult
<parm_decl 0x4019fd90 i>
<integer_cst 4>>
<integer_cst -4>>
<function_decl __base_ctor>>
<integer_cst 4>>>
<integer_cst 0>>
<integer_cst 0>>
Please note the presence of SAVE_EXPRs within the size and unit size
fields of the ARRAY_TYPE at the top. Note also how very similar those
fields are to the analogous fields of the VAR_DECL just below. In
fact, this ARRAY_TYPE started out life as the type of that VAR_DECL:
int ar[1][i];
where 'i' is a parameter. The differences are precisely that the
SAVE_EXPRs and PARM_DECLs inside the type have not been updated to
point to the right nodes for the clone. Instead, they are left
referring to the progenitor, which is what causes find_function_data
to crash.
The routine responsible for updating SAVE_EXPRs in clones is
remap_save_expr, in tree-inline.c. It didn't update those SAVE_EXPRs
because it was never applied to them. The reason for this is first
that copy_trees_r explicitly assumes that TYPEs do not need copying:
/* There's no need to copy types, or anything beneath them. */
*walk_subtrees = 0;
This is clearly false for VLA types, such as the one we have here.
Disabling that is not good enough, though; walk_tree processes neither
the 'size' nor 'unit size' fields of struct tree_type. Adding them
causes this test case to be compiled successfully. Hence the appended
patch.
I am not sure if this patch is either correct or complete. It may be
that we really do want to enforce the constraint that SAVE_EXPRs or
other constructs needing fixups never appear inside TYPE nodes; it may
be that, while some TYPE nodes need copying, others must not be; and
it may be that we need to consider even more fields of struct
tree_type in walk_tree. Comments?
zw
PR middle-end/6994
* tree-inline.c (walk_tree): For nodes of class 't', walk the
TYPE_SIZE and TYPE_SIZE_UNIT fields.
(copy_tree_r): Do copy types and things beneath them.
* g++.dg/ext/vla1.C: New test case.
===================================================================
Index: tree-inline.c
--- tree-inline.c 27 Sep 2002 12:48:04 -0000 1.31
+++ tree-inline.c 10 Oct 2002 06:27:07 -0000
@@ -1516,6 +1516,11 @@ walk_tree (tp, func, data, htab_)
{
WALK_SUBTREE_TAIL (TREE_TYPE (*tp));
}
+ else if (TREE_CODE_CLASS (code) == 't')
+ {
+ WALK_SUBTREE (TYPE_SIZE (*tp));
+ WALK_SUBTREE (TYPE_SIZE_UNIT (*tp));
+ }
result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
data, htab);
@@ -1683,9 +1688,11 @@ copy_tree_r (tp, walk_subtrees, data)
TREE_CHAIN (*tp) = chain;
#endif /* INLINER_FOR_JAVA */
}
+#if 0 /* Not true in the presence of variably-sized types. */
else if (TREE_CODE_CLASS (code) == 't')
/* There's no need to copy types, or anything beneath them. */
*walk_subtrees = 0;
+#endif
return NULL_TREE;
}
===================================================================
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 10 Oct 2002 06:40:29 -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;
+}
More information about the Gcc-bugs
mailing list