diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/fortran/ChangeLog | 17 | ||||
| -rw-r--r-- | gcc/fortran/gfortran.h | 5 | ||||
| -rw-r--r-- | gcc/fortran/invoke.texi | 18 | ||||
| -rw-r--r-- | gcc/fortran/lang.opt | 4 | ||||
| -rw-r--r-- | gcc/fortran/options.c | 9 | ||||
| -rw-r--r-- | gcc/fortran/trans-decl.c | 17 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 9 | ||||
| -rw-r--r-- | gcc/testsuite/gfortran.dg/convert_implied_open.f90 | 8 | ||||
| -rw-r--r-- | gcc/testsuite/gfortran.dg/unf_short_record_1.f90 | 2 | ||||
| -rw-r--r-- | gcc/testsuite/gfortran.dg/unformatted_subrecord_1.f90 | 45 |
10 files changed, 121 insertions, 13 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 9442f68..be3e91e 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,20 @@ +2006-12-01 Thomas Koenig <Thomas.Koenig@online.de> + + PR libfortran/29568 + * gfortran.h (gfc_option_t): Add max_subrecord_length. + (top level): Define MAX_SUBRECORD_LENGTH. + * lang.opt: Add option -fmax-subrecord-length=. + * trans-decl.c: Add new function set_max_subrecord_length. + (gfc_generate_function_code): If we are within the main + program and max_subrecord_length has been set, call + set_max_subrecord_length. + * options.c (gfc_init_options): Add defaults for + max_subrecord_lenght, convert and record_marker. + (gfc_handle_option): Add handling for + -fmax_subrecord_length. + * invoke.texi: Document the new default for + -frecord-marker=<n>. + 2006-11-28 Paul Thomas <pault@gcc.gnu.org> PR fortran/29976 diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index 277cc78..9a18e7851 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -59,6 +59,9 @@ char *alloca (); #define GFC_MAX_DIMENSIONS 7 /* Maximum dimensions in an array. */ #define GFC_LETTERS 26 /* Number of letters in the alphabet. */ +#define MAX_SUBRECORD_LENGTH 2147483639 /* 2**31-9 */ + + #define free(x) Use_gfc_free_instead_of_free() #define gfc_is_whitespace(c) ((c==' ') || (c=='\t')) @@ -1661,12 +1664,12 @@ typedef struct int fshort_enums; int convert; int record_marker; + int max_subrecord_length; } gfc_option_t; extern gfc_option_t gfc_option; - /* Constructor nodes for array and structure constructors. */ typedef struct gfc_constructor { diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index c27218c..c4ee5d3 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -650,13 +650,17 @@ variable override the default specified by -fconvert.} @cindex -frecord-marker=@var{length} @item -frecord-marker=@var{length} Specify the length of record markers for unformatted files. -Valid values for @var{length} are 4 and 8. Default is whatever -@code{off_t} is specified to be on that particular system. -Note that specifying @var{length} as 4 limits the record -length of unformatted files to 2 GB. This option does not -extend the maximum possible record length on systems where -@code{off_t} is a four_byte quantity. - +Valid values for @var{length} are 4 and 8. Default is 4. +@emph{This is different from previous versions of gfortran}, +which specified a default record marker length of 8 on most +systems. If you want to read or write files compatible +with earlier versions of gfortran, use @samp{-frecord-marker=8}. + +@cindex -fmax-subrecord-length=@var{length} +@item -fmax-subrecord-length=@var{length} +Specify the maximum length for a subrecord. The maximum permitted +value for length is 2147483639, which is also the default. Only +really useful for use by the gfortran testsuite. @end table @node Code Gen Options diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 053f63b..ebd6b8d 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -189,6 +189,10 @@ fmax-identifier-length= Fortran RejectNegative Joined UInteger -fmax-identifier-length=<n> Maximum identifier length +fmax-subrecord-length= +Fortran RejectNegative Joined UInteger +-fmax-subrecord-length=<n> Maximum length for subrecords + fmax-stack-var-size= Fortran RejectNegative Joined UInteger -fmax-stack-var-size=<n> Size in bytes of the largest array that will be put on the stack diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index f03319b..6ec8467 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -51,6 +51,9 @@ gfc_init_options (unsigned int argc ATTRIBUTE_UNUSED, gfc_option.max_continue_fixed = 19; gfc_option.max_continue_free = 39; gfc_option.max_identifier_length = GFC_MAX_SYMBOL_LEN; + gfc_option.max_subrecord_length = 0; + gfc_option.convert = CONVERT_NATIVE; + gfc_option.record_marker = 0; gfc_option.verbose = 0; gfc_option.warn_aliasing = 0; @@ -636,6 +639,12 @@ gfc_handle_option (size_t scode, const char *arg, int value) case OPT_frecord_marker_8: gfc_option.record_marker = 8; break; + + case OPT_fmax_subrecord_length_: + if (value > MAX_SUBRECORD_LENGTH) + gfc_fatal_error ("Maximum subrecord length cannot exceed %d", MAX_SUBRECORD_LENGTH); + + gfc_option.max_subrecord_length = value; } return result; diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c index 1f3ab7d..270083f 100644 --- a/gcc/fortran/trans-decl.c +++ b/gcc/fortran/trans-decl.c @@ -94,6 +94,7 @@ tree gfor_fndecl_set_fpe; tree gfor_fndecl_set_std; tree gfor_fndecl_set_convert; tree gfor_fndecl_set_record_marker; +tree gfor_fndecl_set_max_subrecord_length; tree gfor_fndecl_ctime; tree gfor_fndecl_fdate; tree gfor_fndecl_ttynam; @@ -2379,6 +2380,10 @@ gfc_build_builtin_function_decls (void) gfc_build_library_function_decl (get_identifier (PREFIX("set_record_marker")), void_type_node, 1, gfc_c_int_type_node); + gfor_fndecl_set_max_subrecord_length = + gfc_build_library_function_decl (get_identifier (PREFIX("set_max_subrecord_length")), + void_type_node, 1, gfc_c_int_type_node); + gfor_fndecl_in_pack = gfc_build_library_function_decl ( get_identifier (PREFIX("internal_pack")), pvoid_type_node, 1, pvoid_type_node); @@ -3187,6 +3192,18 @@ gfc_generate_function_code (gfc_namespace * ns) } + if (sym->attr.is_main_program && gfc_option.max_subrecord_length != 0) + { + tree arglist, gfc_c_int_type_node; + + gfc_c_int_type_node = gfc_get_int_type (gfc_c_int_kind); + arglist = gfc_chainon_list (NULL_TREE, + build_int_cst (gfc_c_int_type_node, + gfc_option.max_subrecord_length)); + tmp = build_function_call_expr (gfor_fndecl_set_max_subrecord_length, arglist); + gfc_add_expr_to_block (&body, tmp); + } + if (TREE_TYPE (DECL_RESULT (fndecl)) != void_type_node && sym->attr.subroutine) { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 08b4e04..fe29e86 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2006-12-01 Thomas Koenig <Thomas.Koenig@online.de> + + PR libfortran/29568 + * gfortran.dg/convert_implied_open.f90: Change to + new default record length. + * gfortran.dg/unf_short_record_1.f90: Adapt to + new error message. + * gfortran.dg/unformatted_subrecords_1.f90: New test. + 2006-12-01 Andrew MacLeod <amacleod@redhat.com> * gcc.dg/max-1.c: Remove reference to -fno-tree-lrs option. diff --git a/gcc/testsuite/gfortran.dg/convert_implied_open.f90 b/gcc/testsuite/gfortran.dg/convert_implied_open.f90 index 4066f61..9c25b5d 100644 --- a/gcc/testsuite/gfortran.dg/convert_implied_open.f90 +++ b/gcc/testsuite/gfortran.dg/convert_implied_open.f90 @@ -3,13 +3,13 @@ ! PR 26735 - implied open didn't use to honor -fconvert program main implicit none - integer (kind=8) :: i1, i2, i3 - write (10) 1_8 + integer (kind=4) :: i1, i2, i3 + write (10) 1_4 close (10) - open (10, form="unformatted", access="direct", recl=8) + open (10, form="unformatted", access="direct", recl=4) read (10,rec=1) i1 read (10,rec=2) i2 read (10,rec=3) i3 - if (i1 /= 8 .or. i2 /= 1 .or. i3 /= 8) call abort + if (i1 /= 4 .or. i2 /= 1 .or. i3 /= 4) call abort close (10,status="delete") end program main diff --git a/gcc/testsuite/gfortran.dg/unf_short_record_1.f90 b/gcc/testsuite/gfortran.dg/unf_short_record_1.f90 index 1bb6273..45c94c2 100644 --- a/gcc/testsuite/gfortran.dg/unf_short_record_1.f90 +++ b/gcc/testsuite/gfortran.dg/unf_short_record_1.f90 @@ -11,7 +11,7 @@ program main read (10, err=20, iomsg=msg) a call abort 20 continue - if (msg .ne. "Short record on unformatted read") call abort + if (msg .ne. "I/O past end of record on unformatted file") call abort if (a(1) .ne. 'a' .or. a(2) .ne. 'b' .or. a(3) .ne. 'b') call abort close (10, status="delete") end program main diff --git a/gcc/testsuite/gfortran.dg/unformatted_subrecord_1.f90 b/gcc/testsuite/gfortran.dg/unformatted_subrecord_1.f90 new file mode 100644 index 0000000..5812a8e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/unformatted_subrecord_1.f90 @@ -0,0 +1,45 @@ +! { dg-do run } +! { dg-options "-fmax-subrecord-length=16" } +! Test Intel record markers with 16-byte subrecord sizes. +program main + implicit none + integer, dimension(20) :: n + integer, dimension(30) :: m + integer :: i + real :: r + integer :: k + ! Maximum subrecord length is 16 here, or the test will fail. + open (10, file="f10.dat", & + form="unformatted", access="sequential") + n = (/ (i**2, i=1, 20) /) + write (10) n + close (10) + ! Read back the file, including record markers. + open (10, file="f10.dat", form="unformatted", access="stream") + read (10) m + if (any(m .ne. (/ -16, 1, 4, 9, 16, 16, -16, 25, 36, 49, 64, & + -16, -16, 81, 100, 121, 144, -16, -16, 169, 196, 225, & + 256, -16, 16, 289, 324, 361, 400, -16 /))) call abort + close (10) + open (10, file="f10.dat", form="unformatted", & + access="sequential") + m = 42 + read (10) m(1:5) + if (any(m(1:5) .ne. (/ 1, 4, 9, 16, 25 /))) call abort + if (any(m(6:30) .ne. 42)) call abort + backspace 10 + n = 0 + read (10) n(1:5) + if (any(n(1:5) .ne. (/ 1, 4, 9, 16, 25 /))) call abort + if (any(n(6:20) .ne. 0)) call abort + ! Append to the end of the file + write (10) 3.14 + ! Test multiple backspace statements + backspace 10 + backspace 10 + read (10) k + if (k .ne. 1) call abort + read (10) r + if (abs(r-3.14) .gt. 1e-7) call abort + close (10, status="delete") +end program main |
