This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C PATCH: PR 9936


This patch fixes PR 9936, a regression in the C front end involving
the GNU VLA extension in combination with the nested function
extension.  (Extensions just continue to cause problems...)

Tested on i686-pc-linux-gnu, applied on the mainline and on the
branch.

--
Mark Mitchell
CodeSourcery, LLC
mark at codesourcery dot com

2003-03-31  Mark Mitchell  <mark at codesourcery dot 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  Mark Mitchell  <mark at codesourcery dot com>

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

Index: c-decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v
retrieving revision 1.356.2.3
diff -c -5 -p -r1.356.2.3 c-decl.c
*** c-decl.c	12 Mar 2003 09:59:51 -0000	1.356.2.3
--- c-decl.c	1 Apr 2003 01:21:23 -0000
*************** grokdeclarator (declarator, declspecs, d
*** 4070,4080 ****
  		      type = error_mark_node;
  		      continue;
  		    }
  
  		  if (size_varies)
! 		    itype = variable_size (itype);
  		  itype = build_index_type (itype);
  		}
  	    }
  	  else if (decl_context == FIELD)
  	    {
--- 4070,4093 ----
  		      type = error_mark_node;
  		      continue;
  		    }
  
  		  if (size_varies)
! 		    {
! 		      /* 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);
  		}
  	    }
  	  else if (decl_context == FIELD)
  	    {
*************** c_expand_deferred_function (fndecl)
*** 6424,6433 ****
--- 6437,6465 ----
        c_expand_body (fndecl, 0, 0);
        current_function_decl = NULL;
      }
  }
  
+ /* 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
     generation of RTL.  */
  
*************** c_expand_body (fndecl, nested_p, can_def
*** 6495,6504 ****
--- 6527,6545 ----
    cfun->x_dont_save_pending_sizes_p = 1;
  
    /* 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)
        && MAIN_NAME_P (DECL_NAME (fndecl))
        && DECL_CONTEXT (fndecl) == NULL_TREE)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]