PR middle-end/6994
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 Oct 2002 17:26:52 +0000 (17:26 +0000)
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 25 Oct 2002 17:26:52 +0000 (17:26 +0000)
* 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
gcc/c-objc-common.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ext/vla1.C [new file with mode: 0644]
gcc/testsuite/gcc.dg/vla-2.c [new file with mode: 0644]
gcc/tree-inline.c

index 636217f..dc01d93 100644 (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.
index e279911..2d67b8f 100644 (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;
     }
index 6ba32d8..e7e3cff 100644 (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.
diff --git a/gcc/testsuite/g++.dg/ext/vla1.C b/gcc/testsuite/g++.dg/ext/vla1.C
new file mode 100644 (file)
index 0000000..bac5aac
--- /dev/null
@@ -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 (file)
index 0000000..72c6465
--- /dev/null
@@ -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);
+}
index 505f0a5..898dacb 100644 (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;