re PR middle-end/9936 (ICE with local function and variable-length 2d array)
authorMark Mitchell <mark@codesourcery.com>
Tue, 1 Apr 2003 07:35:11 +0000 (07:35 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Tue, 1 Apr 2003 07:35:11 +0000 (07:35 +0000)
PR c/9936
* c-decl.c (grokdeclarator): Clear SAVE_EXPR_CONTEXT for
variably-sized arrays in parameters.
(set_save_expr_context): New function.
(c_expand_body): Use it, via walk_tree.

PR c/9936
* gcc.dg/20030331-2.c: New test.

From-SVN: r65128

gcc/ChangeLog
gcc/c-decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/20030331-2.c [new file with mode: 0644]

index 01ca1ce..a2ebf09 100644 (file)
@@ -1,3 +1,11 @@
+2003-03-31  Mark Mitchell  <mark@codesourcery.com>
+
+       PR c/9936
+       * c-decl.c (grokdeclarator): Clear SAVE_EXPR_CONTEXT for
+       variably-sized arrays in parameters.
+       (set_save_expr_context): New function.
+       (c_expand_body): Use it, via walk_tree.
+
 2003-03-31  Eric Christopher  <echristo@redhat.com>
 
        * combine.c (can_combine_p): Allow ZERO_EXTRACT and STRICT_LOW_PART.
index c9dd711..e0354f0 100644 (file)
@@ -4103,7 +4103,20 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
                    }
 
                  if (size_varies)
-                   itype = variable_size (itype);
+                   {
+                     /* We must be able to distinguish the
+                        SAVE_EXPR_CONTEXT for the variably-sized type
+                        so that we can set it correctly in
+                        set_save_expr_context.  The convention is
+                        that all SAVE_EXPRs that need to be reset
+                        have NULL_TREE for their SAVE_EXPR_CONTEXT.  */
+                     tree cfd = current_function_decl;
+                     if (decl_context == PARM)
+                       current_function_decl = NULL_TREE;
+                     itype = variable_size (itype);
+                     if (decl_context == PARM)
+                       current_function_decl = cfd;
+                   }
                  itype = build_index_type (itype);
                }
            }
@@ -6508,6 +6521,25 @@ c_expand_deferred_function (fndecl)
     }
 }
 
+/* Called to move the SAVE_EXPRs for parameter declarations in a
+   nested function into the nested function.  DATA is really the
+   nested FUNCTION_DECL.  */
+
+static tree
+set_save_expr_context (tree *tp, 
+                      int *walk_subtrees,
+                      void *data)
+{
+  if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
+    SAVE_EXPR_CONTEXT (*tp) = (tree) data;
+  /* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
+     circularity.  */
+  else if (DECL_P (*tp))
+    *walk_subtrees = 0;
+
+  return NULL_TREE;
+}
+
 /* Generate the RTL for the body of FNDECL.  If NESTED_P is nonzero,
    then we are already in the process of generating RTL for another
    function.  If can_defer_p is zero, we won't attempt to defer the
@@ -6548,6 +6580,15 @@ c_expand_body_1 (fndecl, nested_p)
   /* Set up parameters and prepare for return, for the function.  */
   expand_function_start (fndecl, 0);
 
+  /* If the function has a variably modified type, there may be
+     SAVE_EXPRs in the parameter types.  Their context must be set to
+     refer to this function; they cannot be expanded in the containing
+     function.  */
+  if (decl_function_context (fndecl)
+      && variably_modified_type_p (TREE_TYPE (fndecl)))
+    walk_tree (&TREE_TYPE (fndecl), set_save_expr_context, fndecl,
+              NULL);
+            
   /* If this function is `main', emit a call to `__main'
      to run global initializers, etc.  */
   if (DECL_NAME (fndecl)
index ec6a418..c6196fb 100644 (file)
@@ -1,5 +1,10 @@
 2003-03-31  Mark Mitchell  <mark@codesourcery.com>
 
+       PR c/9936
+       * gcc.dg/20030331-2.c: New test.
+
+2003-03-31  Mark Mitchell  <mark@codesourcery.com>
+
        PR c++/10278
        * g++.dg/parse/crash2.C: New test.
 
diff --git a/gcc/testsuite/gcc.dg/20030331-2.c b/gcc/testsuite/gcc.dg/20030331-2.c
new file mode 100644 (file)
index 0000000..210524d
--- /dev/null
@@ -0,0 +1,10 @@
+// { dg-options "" }
+
+int foo() {
+  int yd;
+  float in[1][yd];
+  static void bar() {
+    printf("%p\n",in[0]);
+  }
+}