re PR c++/6994 (ICE in find_function_data)

PR middle-end/6994

	* c-objc-common.c (inline_forbidden_p): Can not inline
	functions containing structures or unions containing VLAs.
	* tree-inline.c (walk_tree): For all class 't' nodes, walk
	TYPE_SIZE and TYPE_SIZE_UNIT.
	(copy_tree_r): Copy types if they are variably modified.

	* g++.dg/ext/vla1.C, gcc.dg/vla-2.c: New tests.

From-SVN: r58535
This commit is contained in:
Zack Weinberg 2002-10-25 17:26:52 +00:00 committed by Zack Weinberg
parent 6eb359685e
commit f3763a442e
6 changed files with 92 additions and 2 deletions

View File

@ -1,3 +1,12 @@
2002-10-25 Zack Weinberg <zack@codesourcery.com>
PR middle-end/6994
* c-objc-common.c (inline_forbidden_p): Can not inline
functions containing structures or unions containing VLAs.
* tree-inline.c (walk_tree): For all class 't' nodes, walk
TYPE_SIZE and TYPE_SIZE_UNIT.
(copy_tree_r): Copy types if they are variably modified.
2002-10-25 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.md: Remove old-style peepholes.

View File

@ -133,6 +133,22 @@ inline_forbidden_p (nodep, walk_subtrees, fn)
break;
case RECORD_TYPE:
case UNION_TYPE:
/* We cannot inline a function of the form
void F (int i) { struct S { int ar[i]; } s; }
Attempting to do so produces a catch-22 in tree-inline.c.
If walk_tree examines the TYPE_FIELDS chain of RECORD_TYPE/
UNION_TYPE nodes, then it goes into infinite recursion on a
structure containing a pointer to its own type. If it doesn't,
then the type node for S doesn't get adjusted properly when
F is inlined, and we abort in find_function_data. */
for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
if (variably_modified_type_p (TREE_TYPE (t)))
return node;
default:
break;
}

View File

@ -1,3 +1,7 @@
2002-10-25 Zack Weinberg <zack@codesourcery.com>
* g++.dg/ext/vla1.C, gcc.dg/vla-2.c: New tests.
2002-10-24 Mark Mitchell <mark@codesourcery.com>
* g++.dg/abi/empty9.C: New test.

View File

@ -0,0 +1,26 @@
// { dg-do compile }
// Crash tests from PR middle-end/6994. See also gcc.dg/vla-2.c.
// A::A is acceptable extended C++ (VLA types brought over from C99);
// B::B is not, but is closely related to acceptable extended C, though
// not to acceptable C99.
class A { A (int); };
A::A (int i)
{
int ar[1][i]; // { dg-error "variable-size array" }
ar[0][0] = 0;
}
class B { B (int); };
B::B (int i)
{
struct S {
int ar[1][i]; // { dg-error "variable-size|variably modified" }
} s;
s.ar[0][0] = 0; // { dg-error "no member" }
}

View File

@ -0,0 +1,29 @@
/* { dg-do compile } */
/* { dg-options "-std=gnu99" } */
/* These are crash tests related to PR middle-end/6994; see also
g++.dg/ext/vla1.C. Note that at present A and C cannot be inlined. */
static inline void A (int i)
{
struct S { int ar[1][i]; } s;
s.ar[0][0] = 0;
}
void B(void)
{
A(23);
}
static inline void C (int i)
{
union U { int ar[1][i]; } u;
u.ar[0][0] = 0;
}
void D(void)
{
C(23);
}

View File

@ -1543,6 +1543,12 @@ 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));
/* Also examine various special fields, below. */
}
result = (*lang_hooks.tree_inlining.walk_subtrees) (tp, &walk_subtrees, func,
data, htab);
@ -1711,8 +1717,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;