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]

Re: Infamous PR fortran/19925


On Sun, Sep 14, 2008 at 11:20:57AM +0200, Paul Richard Thomas wrote:
> Steve,
> 
> On Sun, Sep 14, 2008 at 7:17 AM, Steve Kargl
> <sgk@troutmask.apl.washington.edu> wrote:
> > Well, I spent some time last week thinking about PR
> > fortran/19925 and have decided that the best option
> > may be to punt.  Consider the somewhat far fetched
> > but legal Fortran,
> 
> I concur with you completely on this.  I have visited this PR on one
> or two occasions and have failed to come up with any better
> alternative.  Maybe a warning like that at the head of module files
> should be emitted? :-)
> 
> OK for trunk
> 

I no longer have commit access to the tree, so someone will need
to do the commit.

Here's a new patch that adds twoi testcases and it changes an error
message from "Error: Initialization expression didn't reduce (1)"
to "Error: Initialization expression didn't reduce (1).  The
-fmax-array-constructor option may be required"

troutmask:sgk[204] cat g.f90
INTEGER, PARAMETER :: N=70000
INTEGER, PARAMETER :: I(N)=(/(MOD(K,2),K=1,N)/)
INTEGER, PARAMETER :: M(N)=I(N:1:-1)
print *, i(5)
END

troutmask:sgk[205] gfc4x -o z g.f90
g.f90:3.36:

INTEGER, PARAMETER :: M(N)=I(N:1:-1)
                                   1
Error: Initialization expression didn't reduce (1).  The -fmax-array-constructor option may be required
troutmask:sgk[206] gfc4x -o z -fmax-array-constructor=70000 g.f90


2008-09-19  Steven G. Kargl  <kargls@comcast.net>

	PR fortran/19925
	* gfortran.dg/initialization_20.f90: New test.
	* gfortran.dg/initialization_21.f90: Ditto.

2008-09-19  Steven G. Kargl  <kargls@comcast.net>

	PR fortran/19925
	* trans-array.c (gfc_trans_array_constructor_value): Fix comment.
	(gfc_conv_array_initializer): Convert internal_error() to gfc_error_now.
	* array.c: Remove GFC_MAX_AC_EXPAND macro.
	(gfc_expand_constructor): Use gfc_option.flag_max_array_constructor.
	* gfortran.h (gfc_option): Add flag_max_array_constructor member.
	* lang.opt: Add -fmax-array-constructor option.
	* expr.c (gfc_match_init_expr): Fix error message to mention new option.
	* invoke.texi: Document new option.
	* options.c(gfc_init_options): Set default value for new option.
	(gfc_handle_option): Deal with commandline.

-- 
Steve
Index: gcc/testsuite/gfortran.dg/initialization_20.f90
===================================================================
--- gcc/testsuite/gfortran.dg/initialization_20.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/initialization_20.f90	(revision 0)
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! Test for PR19925
+!
+program pr19925
+  implicit none
+  integer j
+  integer, parameter :: n = 100000
+  integer, parameter :: i(n)=(/(j,j=1,n)/) ! { dg-error "number of elements" }
+  print *, i(5)
+end program pr19925
Index: gcc/testsuite/gfortran.dg/initialization_21.f90
===================================================================
--- gcc/testsuite/gfortran.dg/initialization_21.f90	(revision 0)
+++ gcc/testsuite/gfortran.dg/initialization_21.f90	(revision 0)
@@ -0,0 +1,11 @@
+! { dg-do compile }
+! { dg-options "-fmax-array-constructor=100000" }
+! Test for PR19925
+!
+program pr19925
+  implicit none
+  integer j
+  integer, parameter :: n = 100000
+  integer, parameter :: i(n) = (/ (j, j=1, n) /)
+  print *, i(5)
+end program pr19925
Index: gcc/fortran/trans-array.c
===================================================================
--- gcc/fortran/trans-array.c	(revision 140462)
+++ gcc/fortran/trans-array.c	(working copy)
@@ -1246,7 +1246,7 @@ gfc_trans_array_constructor_value (stmtb
             }
 	}
 
-      /* The frontend should already have done any expansions possible
+      /* The frontend should already have done any expansions
 	 at compile-time.  */
       if (!c->iterator)
 	{
@@ -3898,10 +3898,13 @@ gfc_conv_array_initializer (tree type, g
           if (c->iterator)
             {
               /* Problems occur when we get something like
-                 integer :: a(lots) = (/(i, i=1,lots)/)  */
-              /* TODO: Unexpanded array initializers.  */
-              internal_error
-                ("Possible frontend bug: array constructor not expanded");
+                 integer :: a(lots) = (/(i, i=1, lots)/)  */
+              gfc_error_now ("The number of elements in the array constructor "
+			     "at %L requires an increase of the allowed %d "
+			     "upper limit.   See -fmax-array-constructor "
+			     "option", &expr->where,
+			     gfc_option.flag_max_array_constructor);
+	      return NULL_TREE;
 	    }
           if (mpz_cmp_si (c->n.offset, 0) != 0)
             index = gfc_conv_mpz_to_tree (c->n.offset, gfc_index_integer_kind);
Index: gcc/fortran/array.c
===================================================================
--- gcc/fortran/array.c	(revision 140462)
+++ gcc/fortran/array.c	(working copy)
@@ -24,13 +24,6 @@ along with GCC; see the file COPYING3.  
 #include "gfortran.h"
 #include "match.h"
 
-/* This parameter is the size of the largest array constructor that we
-   will expand to an array constructor without iterators.
-   Constructors larger than this will remain in the iterator form.  */
-
-#define GFC_MAX_AC_EXPAND 65535
-
-
 /**************** Array reference matching subroutines *****************/
 
 /* Copy an array reference structure.  */
@@ -1463,7 +1456,7 @@ gfc_expand_constructor (gfc_expr *e)
   gfc_expr *f;
   gfc_try rc;
 
-  f = gfc_get_array_element (e, GFC_MAX_AC_EXPAND);
+  f = gfc_get_array_element (e, gfc_option.flag_max_array_constructor);
   if (f != NULL)
     {
       gfc_free_expr (f);
Index: gcc/fortran/gfortran.h
===================================================================
--- gcc/fortran/gfortran.h	(revision 140462)
+++ gcc/fortran/gfortran.h	(working copy)
@@ -1980,6 +1980,7 @@ typedef struct
   int flag_second_underscore;
   int flag_implicit_none;
   int flag_max_stack_var_size;
+  int flag_max_array_constructor;
   int flag_range_check;
   int flag_pack_derived;
   int flag_repack_arrays;
Index: gcc/fortran/lang.opt
===================================================================
--- gcc/fortran/lang.opt	(revision 140462)
+++ gcc/fortran/lang.opt	(working copy)
@@ -276,6 +276,10 @@ finit-real=
 Fortran RejectNegative Joined
 -finit-real=<zero|nan|inf|-inf> Initialize local real variables
 
+fmax-array-constructor=
+Fortran RejectNegative Joined UInteger
+-fmax-array-constructor=<n>        Maximum number of objects in an array constructor
+
 fmax-errors=
 Fortran RejectNegative Joined UInteger
 -fmax-errors=<n>	Maximum number of errors to report
Index: gcc/fortran/expr.c
===================================================================
--- gcc/fortran/expr.c	(revision 140462)
+++ gcc/fortran/expr.c	(working copy)
@@ -2411,7 +2411,8 @@ gfc_match_init_expr (gfc_expr **result)
   if (!gfc_is_constant_expr (expr) && check_inquiry (expr, 1) != MATCH_YES
       && !gfc_in_match_data ())
     {
-      gfc_error ("Initialization expression didn't reduce %C");
+      gfc_error ("Initialization expression didn't reduce %C.  " 
+		 "The -fmax-array-constructor option may be required");
       return MATCH_ERROR;
     }
 
Index: gcc/fortran/invoke.texi
===================================================================
--- gcc/fortran/invoke.texi	(revision 140462)
+++ gcc/fortran/invoke.texi	(working copy)
@@ -147,7 +147,8 @@ and warnings}.
 
 @item Directory Options
 @xref{Directory Options,,Options for directory search}.
-@gccoptlist{-I@var{dir}  -J@var{dir}  -M@var{dir}  -fintrinsic-modules-path @var{dir}}
+@gccoptlist{-I@var{dir}  -J@var{dir}  -M@var{dir}  @gol
+-fintrinsic-modules-path @var{dir}}
 
 @item Link Options
 @xref{Link Options,,Options for influencing the linking step}.
@@ -161,9 +162,10 @@ and warnings}.
 
 @item Code Generation Options
 @xref{Code Gen Options,,Options for code generation conventions}.
-@gccoptlist{-fno-automatic  -ff2c  -fno-underscoring
+@gccoptlist{-fno-automatic  -ff2c  -fno-underscoring @gol
 -fsecond-underscore @gol
--fbounds-check -fcheck-array-temporaries  -fmax-stack-var-size=@var{n} @gol
+-fbounds-check -fcheck-array-temporaries  -fmax-array-constructor =@var{n} @gol
+-fmax-stack-var-size=@var{n} @gol
 -fpack-derived  -frepack-arrays  -fshort-enums  -fexternal-blas @gol
 -fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol
 -finit-integer=@var{n} -finit-real=@var{<zero|inf|-inf|nan>} @gol
@@ -1182,6 +1184,28 @@ sometimes useful in optimization, in ord
 Note: The warning is only printed once per location.
 
 
+@item -fmax-array-constructor=@var{n}
+@opindex @code{fmax-array-constructor}
+This option can be used to increase the upper limit permitted in 
+array constructors.  The code below requires this option to expand
+the array at compile time.
+
+@smallexample
+@code{program test}
+@code{implicit none}
+@code{integer j}
+@code{integer, parameter :: n = 100000}
+@code{integer, parameter :: i(n) = (/ (2*j, j = 1, n) /)}
+@code{print '(10(I0,1X))', i}
+@code{end program test}
+@end smallexample
+
+@emph{Caution:  This option can lead to long compile times and excessively
+large object files.}
+
+The default value for @var{n} is 65535.
+
+
 @item -fmax-stack-var-size=@var{n}
 @opindex @code{fmax-stack-var-size}
 This option specifies the size in bytes of the largest array that will be put
Index: gcc/fortran/options.c
===================================================================
--- gcc/fortran/options.c	(revision 140462)
+++ gcc/fortran/options.c	(working copy)
@@ -62,6 +62,7 @@ gfc_init_options (unsigned int argc, con
   gfc_option.max_continue_free = 255;
   gfc_option.max_identifier_length = GFC_MAX_SYMBOL_LEN;
   gfc_option.max_subrecord_length = 0;
+  gfc_option.flag_max_array_constructor = 65535;
   gfc_option.convert = GFC_CONVERT_NATIVE;
   gfc_option.record_marker = 0;
   gfc_option.dump_parse_tree = 0;
@@ -633,6 +634,10 @@ gfc_handle_option (size_t scode, const c
       gfc_add_intrinsic_modules_path (arg);
       break;
 
+    case OPT_fmax_array_constructor_:
+      gfc_option.flag_max_array_constructor = value > 65535 ? value : 65535;
+      break;
+
     case OPT_fmax_errors_:
       gfc_option.max_errors = value;
       break;

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