From 64df2c88f96ff10cc75d8e21121e72a020468a44 Mon Sep 17 00:00:00 2001 From: zack Date: Fri, 25 Oct 2002 17:26:52 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@58535 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++++ gcc/c-objc-common.c | 16 ++++++++++++++++ gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/ext/vla1.C | 26 ++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/vla-2.c | 29 +++++++++++++++++++++++++++++ gcc/tree-inline.c | 10 ++++++++-- 6 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ext/vla1.C create mode 100644 gcc/testsuite/gcc.dg/vla-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 636217f..dc01d93 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-10-25 Zack Weinberg + + 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 * config/s390/s390.md: Remove old-style peepholes. diff --git a/gcc/c-objc-common.c b/gcc/c-objc-common.c index e279911..2d67b8f 100644 --- a/gcc/c-objc-common.c +++ b/gcc/c-objc-common.c @@ -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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6ba32d8..e7e3cff 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2002-10-25 Zack Weinberg + + * g++.dg/ext/vla1.C, gcc.dg/vla-2.c: New tests. + 2002-10-24 Mark Mitchell * g++.dg/abi/empty9.C: New test. diff --git a/gcc/testsuite/g++.dg/ext/vla1.C b/gcc/testsuite/g++.dg/ext/vla1.C new file mode 100644 index 0000000..bac5aac --- /dev/null +++ b/gcc/testsuite/g++.dg/ext/vla1.C @@ -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" } +} diff --git a/gcc/testsuite/gcc.dg/vla-2.c b/gcc/testsuite/gcc.dg/vla-2.c new file mode 100644 index 0000000..72c6465 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vla-2.c @@ -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); +} diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 505f0a5..898dacb 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -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; -- 2.7.4