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]

[patch, fortran-exp] Restore large array constructor check


Hi folks,

This patch restores the check for large constructors and allows gfortran to compile the first test case in pr34554. The patch also does some cleanup.

After committing this patch to the branch. I plan to do a final merge of trunk into the branch. I will then submit a merge to trunk patch for approval.

Regression tested on x86-64-linux-gnu.

OK to commit to fortran-exp branch?

Regards,

Jerry

2010-04-11 Jerry DeLisle <jvdelisle@gcc.gnu.org>

	* array.c (extract_element): Restore function from trunk.
	(gfc_get_array_element): Restore function from trunk.
	(gfc_expand_constructor): Restore check against
	flag_max_array_constructor.
	* constructor.c (node_copy_and_append): Delete unused.
	* gfortran.h: Delete comment and extra include.
	* constructor.h: Bump copyright and clean up TODO comments.
	* resolve.c: Whitespace.
Index: array.c
===================================================================
--- array.c	(revision 158202)
+++ array.c	(working copy)
@@ -1063,6 +1063,29 @@ count_elements (gfc_expr *e)
 }
 
 
+/* Work function that extracts a particular element from an array
+   constructor, freeing the rest.  */
+
+static gfc_try
+extract_element (gfc_expr *e)
+{
+  if (e->rank != 0)
+    {				/* Something unextractable */
+      gfc_free_expr (e);
+      return FAILURE;
+    }
+
+  if (current_expand.extract_count == current_expand.extract_n)
+    current_expand.extracted = e;
+  else
+    gfc_free_expr (e);
+
+  current_expand.extract_count++;
+  
+  return SUCCESS;
+}
+
+
 /* Work function that constructs a new constructor out of the old one,
    stringing new elements together.  */
 
@@ -1246,6 +1269,39 @@ expand_constructor (gfc_constructor_base base)
 }
 
 
+/* Given an array expression and an element number (starting at zero),
+   return a pointer to the array element.  NULL is returned if the
+   size of the array has been exceeded.  The expression node returned
+   remains a part of the array and should not be freed.  Access is not
+   efficient at all, but this is another place where things do not
+   have to be particularly fast.  */
+
+static gfc_expr *
+gfc_get_array_element (gfc_expr *array, int element)
+{
+  expand_info expand_save;
+  gfc_expr *e;
+  gfc_try rc;
+
+  expand_save = current_expand;
+  current_expand.extract_n = element;
+  current_expand.expand_work_function = extract_element;
+  current_expand.extracted = NULL;
+  current_expand.extract_count = 0;
+
+  iter_stack = NULL;
+
+  rc = expand_constructor (array->value.constructor);
+  e = current_expand.extracted;
+  current_expand = expand_save;
+
+  if (rc == FAILURE)
+    return NULL;
+
+  return e;
+}
+
+
 /* Top level subroutine for expanding constructors.  We only expand
    constructor if they are small enough.  */
 
@@ -1253,11 +1309,19 @@ gfc_try
 gfc_expand_constructor (gfc_expr *e)
 {
   expand_info expand_save;
+  gfc_expr *f;
   gfc_try rc;
 
-  /* TODO: Removed check against flag_max_array_constructor.
-     Might be necessary to re-introduce it later?!  */
+  /* If we can successfully get an array element at the max array size then
+     the array is too big to expand, so we just return.  */
+  f = gfc_get_array_element (e, gfc_option.flag_max_array_constructor);
+  if (f != NULL)
+    {
+      gfc_free_expr (f);
+      return SUCCESS;
+    }
 
+  /* We now know the array is not too big so go ahead and try to expand it.  */
   expand_save = current_expand;
   current_expand.base = NULL;
 
Index: constructor.c
===================================================================
--- constructor.c	(revision 158202)
+++ constructor.c	(working copy)
@@ -41,6 +41,7 @@ node_free (splay_tree_value value)
   gfc_free (c);
 }
 
+
 static gfc_constructor *
 node_copy (splay_tree_node node, void *base)
 {
@@ -59,13 +60,6 @@ node_copy (splay_tree_node node, void *base)
   return c;
 }
 
-/*static int
-node_copy_and_append (splay_tree_node node, void *base)
-{
-  gfc_constructor_append ((gfc_constructor_base*)base,
-			  node_copy (node, base));
-  return 0;
-}*/
 
 static int
 node_copy_and_insert (splay_tree_node node, void *base)
Index: gfortran.h
===================================================================
--- gfortran.h	(revision 158202)
+++ gfortran.h	(working copy)
@@ -1632,8 +1632,6 @@ gfc_class_esym_list;
 #define GFC_RND_MODE GMP_RNDN
 #define GFC_MPC_RND_MODE MPC_RNDNN
 
-/*#define gfc_constructor_base struct gfc_constructor* */
-#include "splay-tree.h"
 typedef splay_tree gfc_constructor_base;
 
 typedef struct gfc_expr
Index: constructor.h
===================================================================
--- constructor.h	(revision 158202)
+++ constructor.h	(working copy)
@@ -1,5 +1,5 @@
 /* Array and structure constructors
-   Copyright (C) 2009
+   Copyright (C) 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -59,10 +59,8 @@ gfc_constructor *gfc_constructor_insert_expr (gfc_
 /* Given an array constructor expression and an element number (starting
    at zero), return a pointer to the array element.  NULL is returned if
    the size of the array has been exceeded. The expression node returned
-   remains a part of the array and should not be freed.
-   TODO: remove array.c (gfc_get_array_element)
-   TODO: remove expr.c (find_array_element)
-   TODO: ???    data.c (get_array_index).  */
+   remains a part of the array and should not be freed.  */
+
 gfc_constructor *gfc_constructor_lookup (gfc_constructor_base base, int n);
 
 /* Convenience function. Same as ...
Index: resolve.c
===================================================================
--- resolve.c	(revision 158202)
+++ resolve.c	(working copy)
@@ -5563,12 +5563,12 @@ gfc_is_expandable_expr (gfc_expr *e)
       for (; con; con = gfc_constructor_next (con))
 	{
 	  if (con->expr->expr_type == EXPR_VARIABLE
-	  && con->expr->symtree
-	  && (con->expr->symtree->n.sym->attr.flavor == FL_PARAMETER
+	      && con->expr->symtree
+	      && (con->expr->symtree->n.sym->attr.flavor == FL_PARAMETER
 	      || con->expr->symtree->n.sym->attr.flavor == FL_VARIABLE))
 	    return true;
 	  if (con->expr->expr_type == EXPR_ARRAY
-	    && gfc_is_expandable_expr (con->expr))
+	      && gfc_is_expandable_expr (con->expr))
 	    return true;
 	}
     }

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