* 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
+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.
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;
}
+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.
--- /dev/null
+// { 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" }
+}
--- /dev/null
+/* { 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);
+}
{
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);
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;