* [PATCH, fortran] PR20441 -finit-local-zero @ 2007-08-17 20:12 Asher Langton 2007-08-20 16:33 ` Tobias Burnus 2007-08-31 22:14 ` Asher Langton 0 siblings, 2 replies; 20+ messages in thread From: Asher Langton @ 2007-08-17 20:12 UTC (permalink / raw) To: fortran, gcc-patches [-- Attachment #1: Type: text/plain, Size: 1640 bytes --] :ADDPATCH fortran: Hi all, Here's a patch to add -finit-local-zero, as well as some finer-grained options. I have a working version of the runtime-controlled initialization as discussed previously, but it still needs to be cleaned up a bit, so I'll submit it as a separate patch: http://gcc.gnu.org/ml/fortran/2007-06/msg00028.html I've bootstrapped and regression tested this on x86_64-linux. Everything passes in the ordinary regression tests, and with RUNTESTFLAGS="--tool_opts -finit-local-zero" added, the only failures are tests that invoke cc1 ("cc1: warning: command line option "-finit-local-zero" is valid for Fortran but not for C"). -Asher 2007-08-17 Asher Langton <langton2@llnl.gov> PR fortran/20441 * gfortran.h : Add init_local_* enums and init_flag_* flags to gfc_option_t. * lang.opt: Add -finit-local-zero, -finit-real, -finit-integer, and -finit-logical flags. * invoke.texi: Document new options. * resolve.c (build_init_assign): New function. (apply_init_assign): Move part of function into build_init_assign. (build_default_init_expr): Build local initializer (-finit-*). (apple_default_init_local): Apply local initializer (-finit-*). (resolve_fl_variable): Try to add local initializer (-finit-*). * options.c (gfc_init_options, gfc_handle_option): Handle -finit-local-zero, -finit-real, -finit-integer, and -finit-logical flags. 2007-08-17 Asher Langton <langton2@llnl.gov> PR fortran/20441 * gfortran.dg/init_flag_1.f90: New. * gfortran.dg/init_flag_2.f90: New. * gfortran.dg/init_flag_3.f90: New. * gfortran.dg/init_flag_4.f90: New. * gfortran.dg/init_flag_5.f90: New. [-- Attachment #2: gfc070817_123829.diff --] [-- Type: application/octet-stream, Size: 12347 bytes --] Index: gfortran.h =================================================================== --- gfortran.h (revision 127568) +++ gfortran.h (working copy) @@ -564,6 +564,37 @@ typedef enum } ioerror_codes; +typedef enum +{ + GFC_INIT_REAL_OFF = 0, + GFC_INIT_REAL_ZERO, + GFC_INIT_REAL_NAN, + GFC_INIT_REAL_INF, + GFC_INIT_REAL_NEG_INF +} +init_local_real; + +typedef enum +{ + GFC_INIT_LOGICAL_OFF = 0, + GFC_INIT_LOGICAL_FALSE, + GFC_INIT_LOGICAL_TRUE +} +init_local_logical; + +typedef enum +{ + GFC_INIT_CHARACTER_OFF = 0, + GFC_INIT_CHARACTER_ZERO +} +init_local_character; + +typedef enum +{ + GFC_INIT_INTEGER_OFF = 0, + GFC_INIT_INTEGER_ON +} +init_local_integer; /************************* Structures *****************************/ @@ -1867,6 +1898,12 @@ typedef struct int flag_openmp; int flag_sign_zero; int flag_module_private; + int flag_init_local_zero; + int flag_init_integer; + int flag_init_integer_value; + int flag_init_real; + int flag_init_logical; + int flag_init_character; int fpe; Index: lang.opt =================================================================== --- lang.opt (revision 127568) +++ lang.opt (working copy) @@ -196,6 +196,22 @@ fimplicit-none Fortran Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements +finit-integer= +Fortran RejectNegative Joined +-finit-integer=<n> Initialize local integer variables to n + +finit-local-zero +Fortran +Initialize local variables to zero (from g77) + +finit-logical= +Fortran RejectNegative Joined +-finit-logical=<true|false> Initialize local logical variables + +finit-real= +Fortran RejectNegative Joined +-finit-real=<zero|nan|inf|-inf> Initialize local real variables + fmax-errors= Fortran RejectNegative Joined UInteger -fmax-errors=<n> Maximum number of errors to report Index: invoke.texi =================================================================== --- invoke.texi (revision 127568) +++ invoke.texi (working copy) @@ -156,7 +156,8 @@ and warnings}. -fsecond-underscore @gol -fbounds-check -fmax-stack-var-size=@var{n} @gol -fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol --fblas-matmul-limit=@var{n}} +-fblas-matmul-limit=@var{n} -finit-local-zero -finit-integer=@var{n} @gol +-finit-real=@var{<zero|inf|-inf|nan>} -finit-logical=@var{<true|false>} } @end table @menu @@ -919,6 +920,24 @@ geometric mean of the dimensions of the The default value for @var{n} is 30. +@item -finit-local-zero +@item -finit-integer=@var{n} +@item -finit-real=@var{<zero|inf|-inf|nan>} +@item -finit-logical=@var{<true|false>} +@opindex @code{finit-local-zero} +@opindex @code{finit-integer} +@opindex @code{finit-real} +@opindex @code{finit-logical} +The @option{-finit-local-zero} option instructs the compiler to +initialize local @code{INTEGER}, @code{REAL}, and @code{COMPLEX} +variables to zero, @code{LOGICAL} variables to false, and +@code{CHARACTER} variables to a string of null bytes. Finer-grained +initialization options are provided by the +@option{-finit-integer=@var{n}}, +@option{-finit-real=@var{<zero|inf|-inf|nan>}} (which also initializes +the real and imaginary parts of local @code{COMPLEX} variables), and +@option{-finit-logical=@var{<true|false>}} options. + @end table @xref{Code Gen Options,,Options for Code Generation Conventions, Index: resolve.c =================================================================== --- resolve.c (revision 127568) +++ resolve.c (working copy) @@ -6405,26 +6405,15 @@ is_non_constant_shape_array (gfc_symbol return not_constant; } - -/* Assign the default initializer to a derived type variable or result. */ - +/* Given a symbol and an initialization expression, add code to initialize + the symbol to the function entry. */ static void -apply_default_init (gfc_symbol *sym) +build_init_assign (gfc_symbol *sym, gfc_expr *init) { gfc_expr *lval; - gfc_expr *init = NULL; gfc_code *init_st; gfc_namespace *ns = sym->ns; - if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function) - return; - - if (sym->ts.type == BT_DERIVED && sym->ts.derived) - init = gfc_default_initializer (&sym->ts); - - if (init == NULL) - return; - /* Search for the function namespace if this is a contained function without an explicit result. */ if (sym->attr.function && sym == sym->result @@ -6457,6 +6446,197 @@ apply_default_init (gfc_symbol *sym) init_st->expr2 = init; } +/* Assign the default initializer to a derived type variable or result. */ + +static void +apply_default_init (gfc_symbol *sym) +{ + gfc_expr *init = NULL; + + if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function) + return; + + if (sym->ts.type == BT_DERIVED && sym->ts.derived) + init = gfc_default_initializer (&sym->ts); + + if (init == NULL) + return; + + build_init_assign (sym, init); +} + +/* Build an initializer for a local integer, real, complex, logical, or + character variable, based on the command line flags finit-local-zero, + finit-integer=, finit-real=, finit-logical=, and finit-runtime. Returns + null if the symbol should not have a default initialization. */ +static gfc_expr * +build_default_init_expr (gfc_symbol *sym) +{ + int char_len; + gfc_expr *init_expr; + + /* These symbols should never have a default initialization. */ + if ((sym->attr.dimension && !gfc_is_compile_time_shape (sym->as)) + || sym->attr.external + || sym->attr.dummy + || sym->attr.pointer + || sym->attr.in_equivalence + || sym->attr.in_common + || sym->attr.data + || sym->module + || sym->attr.cray_pointee + || sym->attr.cray_pointer) + return NULL; + + /* Now we'll try to build an initializer expression. */ + init_expr = gfc_get_expr (); + init_expr->expr_type = EXPR_CONSTANT; + init_expr->ts.type = sym->ts.type; + init_expr->ts.kind = sym->ts.kind; + init_expr->where = sym->declared_at; + + /* We will only initialize integers, reals, complex, logicals, and + characters, and only if the corresponding command-line flags + were set. Otherwise, we free init_expr and return null. */ + switch (sym->ts.type) + { + case BT_INTEGER: + if (gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF) + mpz_init_set_si (init_expr->value.integer, + gfc_option.flag_init_integer_value); + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + case BT_REAL: + mpfr_init (init_expr->value.real); + switch (gfc_option.flag_init_real) + { + case GFC_INIT_REAL_NAN: + mpfr_set_nan (init_expr->value.real); + break; + + case GFC_INIT_REAL_INF: + mpfr_set_inf (init_expr->value.real, 1); + break; + + case GFC_INIT_REAL_NEG_INF: + mpfr_set_inf (init_expr->value.real, -1); + break; + + case GFC_INIT_REAL_ZERO: + mpfr_set_ui (init_expr->value.real, 0.0, GFC_RND_MODE); + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + break; + } + break; + + case BT_COMPLEX: + mpfr_init (init_expr->value.complex.r); + mpfr_init (init_expr->value.complex.i); + switch (gfc_option.flag_init_real) + { + case GFC_INIT_REAL_NAN: + mpfr_set_nan (init_expr->value.complex.r); + mpfr_set_nan (init_expr->value.complex.i); + break; + + case GFC_INIT_REAL_INF: + mpfr_set_inf (init_expr->value.complex.r, 1); + mpfr_set_inf (init_expr->value.complex.i, 1); + break; + + case GFC_INIT_REAL_NEG_INF: + mpfr_set_inf (init_expr->value.complex.r, -1); + mpfr_set_inf (init_expr->value.complex.i, -1); + break; + + case GFC_INIT_REAL_ZERO: + mpfr_set_ui (init_expr->value.complex.r, 0.0, GFC_RND_MODE); + mpfr_set_ui (init_expr->value.complex.i, 0.0, GFC_RND_MODE); + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + break; + } + break; + + case BT_LOGICAL: + if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_FALSE) + init_expr->value.logical = 0; + else if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_TRUE) + init_expr->value.logical = 1; + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + case BT_CHARACTER: + /* For characters, the length must be constant in order to + create a default initializer. */ + if (gfc_option.flag_init_character == GFC_INIT_CHARACTER_ZERO + && sym->ts.cl->length + && sym->ts.cl->length->expr_type == EXPR_CONSTANT) + { + char_len = mpz_get_si (sym->ts.cl->length->value.integer); + init_expr->value.character.length = char_len; + /* Set initial value to be a string of null characters. */ + init_expr->value.character.string = gfc_getmem (char_len+1); + } + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + } + return init_expr; +} + +/* Add an initialization expression to a local variable. */ +static void +apply_default_init_local (gfc_symbol *sym) +{ + gfc_expr *init = NULL; + + /* The symbol should be a variable or a function return value. */ + if ((sym->attr.flavor != FL_VARIABLE && !sym->attr.function) + || (sym->attr.function && sym->result != sym)) + return; + + /* Try to build the initializer expression. If we can't initialize + this symbol, then init will be NULL. */ + init = build_default_init_expr (sym); + if (init == NULL) + return; + + /* For saved variables, we don't want to add an initializer at + function entry, so we just add a static initializer. */ + if (sym->attr.save || sym->ns->save_all) + { + /* Don't clobber an existing initializer! */ + gcc_assert (sym->value == NULL); + sym->value = init; + return; + } + + build_init_assign (sym, init); +} /* Resolution of common features of flavors variable and procedure. */ @@ -6571,6 +6751,9 @@ resolve_fl_variable (gfc_symbol *sym, in } } + if (sym->value == NULL && sym->attr.referenced) + apply_default_init_local (sym); /* Try to apply a default initialization. */ + /* Can the symbol have an initializer? */ flag = 0; if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy Index: options.c =================================================================== --- options.c (revision 127568) +++ options.c (working copy) @@ -103,6 +103,11 @@ gfc_init_options (unsigned int argc ATTR gfc_option.flag_d_lines = -1; gfc_option.flag_openmp = 0; gfc_option.flag_sign_zero = 1; + gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF; + gfc_option.flag_init_integer_value = 0; + gfc_option.flag_init_real = GFC_INIT_REAL_OFF; + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF; + gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF; gfc_option.fpe = 0; @@ -615,6 +620,43 @@ gfc_handle_option (size_t scode, const c gfc_option.flag_default_double = value; break; + case OPT_finit_local_zero: + gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON; + gfc_option.flag_init_integer_value = 0; + gfc_option.flag_init_real = GFC_INIT_REAL_ZERO; + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE; + gfc_option.flag_init_character = GFC_INIT_CHARACTER_ZERO; + break; + + case OPT_finit_logical_: + if (!strcmp (arg, "false")) + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE; + else if (!strcmp (arg, "true")) + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_TRUE; + else + gfc_fatal_error ("Unrecognized option to -finit-logical: %s", + arg); + break; + + case OPT_finit_real_: + if (!strcmp (arg, "zero")) + gfc_option.flag_init_real = GFC_INIT_REAL_ZERO; + else if (!strcmp (arg, "nan")) + gfc_option.flag_init_real = GFC_INIT_REAL_NAN; + else if (!strcmp (arg, "inf")) + gfc_option.flag_init_real = GFC_INIT_REAL_INF; + else if (!strcmp (arg, "-inf")) + gfc_option.flag_init_real = GFC_INIT_REAL_NEG_INF; + else + gfc_fatal_error ("Unrecognized option to -finit-real: %s", + arg); + break; + + case OPT_finit_integer_: + gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON; + gfc_option.flag_init_integer_value = atoi (arg); + break; + case OPT_I: gfc_add_include_path (arg, true); break; [-- Attachment #3: init_flag_1.f90 --] [-- Type: application/octet-stream, Size: 1321 bytes --] ! { dg-do run } ! { dg-options "-finit-local-zero" } program init_flag_1 call real_test call logical_test call int_test call complex_test call char_test end program init_flag_1 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 /= 0.0) call abort if (r2(2) /= 0.0) call abort if (r3(5,5) /= 0.0) call abort if (r4 /= 0.0) call abort end subroutine real_test subroutine logical_test logical l1 logical l2(2) if (l1 .neqv. .false.) call abort if (l2(2) .neqv. .false.) call abort end subroutine logical_test subroutine int_test integer i1 integer i2(10) dimension i3(10,10) if (i1 /= 0) call abort if (i2(2) /= 0) call abort if (i3(5,5) /= 0) call abort if (i4 /= 0) call abort end subroutine int_test subroutine complex_test complex c1 complex c2(20,20) if (c1 /= (0.0,0.0)) call abort if (c2(1,1) /= (0.0,0.0)) call abort end subroutine complex_test subroutine char_test character*1 c1 character*8 c2, c3(5) character c4(10) if (c1 /= '\0') call abort if (c2 /= '\0\0\0\0\0\0\0\0') call abort if (c3(1) /= '\0\0\0\0\0\0\0\0') call abort if (c3(5) /= '\0\0\0\0\0\0\0\0') call abort if (c4(5) /= '\0') call abort end subroutine char_test [-- Attachment #4: init_flag_2.f90 --] [-- Type: application/octet-stream, Size: 1035 bytes --] ! { dg-do run } ! { dg-options "-finit-integer=1 -finit-logical=true -finit-real=zero" } program init_flag_2 call real_test call logical_test call int_test call complex_test end program init_flag_2 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 /= 0.0) call abort if (r2(2) /= 0.0) call abort if (r3(5,5) /= 0.0) call abort if (r4 /= 0.0) call abort end subroutine real_test subroutine logical_test logical l1 logical l2(2) if (l1 .neqv. .true.) call abort if (l2(2) .neqv. .true.) call abort end subroutine logical_test subroutine int_test integer i1 integer i2(10) dimension i3(10,10) if (i1 /= 1) call abort if (i2(2) /= 1) call abort if (i3(5,5) /= 1) call abort if (i4 /= 1) call abort end subroutine int_test subroutine complex_test complex c1 complex c2(20,20) if (c1 /= (0.0,0.0)) call abort if (c2(1,1) /= (0.0,0.0)) call abort end subroutine complex_test [-- Attachment #5: init_flag_3.f90 --] [-- Type: application/octet-stream, Size: 1049 bytes --] ! { dg-do run } ! { dg-options "-finit-integer=-1 -finit-logical=false -finit-real=nan" } program init_flag_3 call real_test call logical_test call int_test call complex_test end program init_flag_3 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 .eq. r1) call abort if (r2(2) .eq. r2(2)) call abort if (r3(5,5) .eq. r3(5,5)) call abort if (r4 .eq. r4) call abort end subroutine real_test subroutine logical_test logical l1 logical l2(2) if (l1 .neqv. .false.) call abort if (l2(2) .neqv. .false.) call abort end subroutine logical_test subroutine int_test integer i1 integer i2(10) dimension i3(10,10) if (i1 /= -1) call abort if (i2(2) /= -1) call abort if (i3(5,5) /= -1) call abort if (i4 /= -1) call abort end subroutine int_test subroutine complex_test complex c1 complex c2(20,20) if (c1 .eq. c1) call abort if (c2(1,1) .eq. c2(1,1)) call abort end subroutine complex_test [-- Attachment #6: init_flag_4.f90 --] [-- Type: application/octet-stream, Size: 505 bytes --] ! { dg-do run } ! { dg-options "-finit-real=inf" } program init_flag_4 call real_test end program init_flag_4 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 .le. 0 .or. r1 .ne. 2*r1) call abort if (r2(2) .le. 0 .or. r2(2) .ne. 2*r2(2)) call abort if (r3(5,5) .le. 0 .or. r3(5,5) .ne. 2*r3(5,5)) call abort if (r4 .le. 0 .or. r4 .ne. 2*r4) call abort end subroutine real_test [-- Attachment #7: init_flag_5.f90 --] [-- Type: application/octet-stream, Size: 506 bytes --] ! { dg-do run } ! { dg-options "-finit-real=-inf" } program init_flag_5 call real_test end program init_flag_5 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 .ge. 0 .or. r1 .ne. 2*r1) call abort if (r2(2) .ge. 0 .or. r2(2) .ne. 2*r2(2)) call abort if (r3(5,5) .ge. 0 .or. r3(5,5) .ne. 2*r3(5,5)) call abort if (r4 .ge. 0 .or. r4 .ne. 2*r4) call abort end subroutine real_test ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-17 20:12 [PATCH, fortran] PR20441 -finit-local-zero Asher Langton @ 2007-08-20 16:33 ` Tobias Burnus 2007-08-20 17:49 ` Asher Langton 2007-08-29 2:02 ` Asher Langton 2007-08-31 22:14 ` Asher Langton 1 sibling, 2 replies; 20+ messages in thread From: Tobias Burnus @ 2007-08-20 16:33 UTC (permalink / raw) To: Asher Langton; +Cc: 'fortran@gcc.gnu.org', gcc-patches Hi Asher, Asher Langton wrote: > Here's a patch to add -finit-local-zero, Shouldn't also the derived variables be initialized? type bar real :: r complex :: z integer :: i character(len=5) :: c logical :: l end type bar type(bar) :: t print *, t%r; print *, t%z; print *, t%i; print *, t%c; print *, t%l end With ifort and sunf95 they are set to zero; with "openf95 -zerouv" they are zero. NAG f95 gives partially zeros (?) but -nan works. I therefore think that -finit* also should initialize those. Replacing "integer :: i" by "integer :: i = 5" changes the behaviour of gfortran (independent of the -finit* options): Not only "i" is initalized but all other variables are initialized to zero. Using -finit-real=nan I would still expect NAN and not "0.0" ... Tobias PS: I wonder whether it makes sense to have -finit-character=c to initially character variables with, e.g. "XXXXXXXXXXXXXXXXXXXX". ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-20 16:33 ` Tobias Burnus @ 2007-08-20 17:49 ` Asher Langton 2007-08-21 11:41 ` François-Xavier Coudert 2007-08-29 2:02 ` Asher Langton 1 sibling, 1 reply; 20+ messages in thread From: Asher Langton @ 2007-08-20 17:49 UTC (permalink / raw) To: Tobias Burnus; +Cc: fortran, gcc-patches On 8/20/07, Tobias Burnus <burnus@net-b.de> wrote: > Hi Asher, > > Asher Langton wrote: > > Here's a patch to add -finit-local-zero, > Shouldn't also the derived variables be initialized? > > type bar > real :: r > complex :: z > integer :: i > character(len=5) :: c > logical :: l > end type bar > type(bar) :: t > > print *, t%r; print *, t%z; print *, t%i; > print *, t%c; print *, t%l > end > > With ifort and sunf95 they are set to zero; with "openf95 -zerouv" they > are zero. NAG f95 gives partially zeros (?) but -nan works. > > I therefore think that -finit* also should initialize those. Replacing > "integer :: i" by "integer :: i = 5" changes the behaviour of gfortran > (independent of the -finit* options): Not only "i" is initalized but all > other variables are initialized to zero. Using -finit-real=nan I would > still expect NAN and not "0.0" ... Hi Tobias, Thanks for the feedback. I'll take a look at this and see what I can do. > PS: I wonder whether it makes sense to have -finit-character=c to > initially character variables with, e.g. "XXXXXXXXXXXXXXXXXXXX". It makes sense, but I left it out because I didn't know if anyone would find it useful. I can easily add an finit-character option, though. -Asher ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-20 17:49 ` Asher Langton @ 2007-08-21 11:41 ` François-Xavier Coudert 2007-08-21 15:58 ` Tobias Schlüter 0 siblings, 1 reply; 20+ messages in thread From: François-Xavier Coudert @ 2007-08-21 11:41 UTC (permalink / raw) To: Asher Langton; +Cc: Tobias Burnus, fortran, gcc-patches >> PS: I wonder whether it makes sense to have -finit-character=c to >> initially character variables with, e.g. "XXXXXXXXXXXXXXXXXXXX". > > It makes sense, but I left it out because I didn't know if anyone > would find it useful. I can easily add an finit-character option, > though. I'd find it useful. I think -finit-character=32 would fill with spaces, and so on (ie, using a ASCII value as argument). FX ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-21 11:41 ` François-Xavier Coudert @ 2007-08-21 15:58 ` Tobias Schlüter 0 siblings, 0 replies; 20+ messages in thread From: Tobias Schlüter @ 2007-08-21 15:58 UTC (permalink / raw) To: François-Xavier Coudert Cc: Asher Langton, Tobias Burnus, fortran, gcc-patches François-Xavier Coudert wrote: >>> PS: I wonder whether it makes sense to have -finit-character=c to >>> initially character variables with, e.g. "XXXXXXXXXXXXXXXXXXXX". >> It makes sense, but I left it out because I didn't know if anyone >> would find it useful. I can easily add an finit-character option, >> though. > > I'd find it useful. I think -finit-character=32 would fill with > spaces, and so on (ie, using a ASCII value as argument). I'm wondering if all these options are really useful enough to justify their existence. What additional benefit does this fine-grained control have over, say, one option that allows me to give a 32bit value that will be filled into any variable's space? This suggestions allows behavior for -finit-local-zero, and therefore fixes the backwards ocmpatibility issue. For debugging, I don't think there's a realistic case where this is not sufficient. I'm somewhat doubtful that the maintenance overhead is worth the general solution. We have already identified two cases previously not thought of in this thread. Another issue that has remained unadressed so far: what happens if I initialize a INTEGER*1 to 2**20? I'm sure I could think of more issues or potential headaches. Cheers, - Tobi ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-20 16:33 ` Tobias Burnus 2007-08-20 17:49 ` Asher Langton @ 2007-08-29 2:02 ` Asher Langton 1 sibling, 0 replies; 20+ messages in thread From: Asher Langton @ 2007-08-29 2:02 UTC (permalink / raw) To: Tobias Burnus; +Cc: fortran, gcc-patches On 8/20/07, Tobias Burnus <burnus@net-b.de> wrote: > Hi Asher, > > Asher Langton wrote: > > Here's a patch to add -finit-local-zero, > Shouldn't also the derived variables be initialized? > > type bar > real :: r > complex :: z > integer :: i > character(len=5) :: c > logical :: l > end type bar > type(bar) :: t > > print *, t%r; print *, t%z; print *, t%i; > print *, t%c; print *, t%l > end > > With ifort and sunf95 they are set to zero; with "openf95 -zerouv" they > are zero. NAG f95 gives partially zeros (?) but -nan works. > > I therefore think that -finit* also should initialize those. Replacing > "integer :: i" by "integer :: i = 5" changes the behaviour of gfortran > (independent of the -finit* options): Not only "i" is initalized but all > other variables are initialized to zero. Using -finit-real=nan I would > still expect NAN and not "0.0" ... Hi Tobias, I've thought about this quite a bit, and I haven't come up with a good solution. If some of the components have initializers, then I can add initializers to the gfc_constructor for the remaining components (in expr.c::gfc_default_initializer()). However, I couldn't find a straightforward way to avoid initializing derived types variables that appear in equivalence statements, so this fails in gfortran.dg/equiv_7.f90::derived_types(). Handling arbitrary derived types is tougher. For a scalar derived type, it would suffice to run through the components and generate some initialization statements, but initializing arrays of derived types is more difficult. It can probably done by abusing the gfc_constructor initializers and letting trans-expr.c::gfc_trans_assignment() handle the scalarization, but I haven't figured out a clean way to do this. For now, my inclination is to leave derived type initialization as a TODO and document the -finit-* limitations in the manual. If that's acceptable, I'll put together a fresh patch with the added documentation, as well as an -finit-character option. -Asher ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-17 20:12 [PATCH, fortran] PR20441 -finit-local-zero Asher Langton 2007-08-20 16:33 ` Tobias Burnus @ 2007-08-31 22:14 ` Asher Langton 2007-09-01 20:26 ` Thomas Koenig ` (2 more replies) 1 sibling, 3 replies; 20+ messages in thread From: Asher Langton @ 2007-08-31 22:14 UTC (permalink / raw) To: fortran, gcc-patches [-- Attachment #1: Type: text/plain, Size: 3508 bytes --] Hi all, Here's an updated patch. I've added -finit-character=<n>, where 0 <= n <= 127 is an ASCII value. Derived types aren't initialized, but I've documented this in the manual. I've added a test that checks initialization of SAVE'd variables. This has been bootstrapped (+make pdf) and regression tested on x86_64-unknown-linux-gnu. I won't have reliable internet access for the next couple of days, but I'll be back online by Monday evening. -Asher 2007-08-31 Asher Langton <langton2@llnl.gov> PR fortran/20441 * gfortran.h : Add init_local_* enums and init_flag_* flags to gfc_option_t. * lang.opt: Add -finit-local-zero, -finit-real, -finit-integer, -finit-character, and -finit-logical flags. * invoke.texi: Document new options. * resolve.c (build_init_assign): New function. (apply_init_assign): Move part of function into build_init_assign. (build_default_init_expr): Build local initializer (-finit-*). (apply_default_init_local): Apply local initializer (-finit-*). (resolve_fl_variable): Try to add local initializer (-finit-*). * options.c (gfc_init_options, gfc_handle_option, gfc_post_options): Handle -finit-local-zero, -finit-real, -finit-integer, -finit-character, and -finit-logical flags. 2007-08-31 Asher Langton <langton2@llnl.gov> PR fortran/20441 * gfortran.dg/init_flag_1.f90: New. * gfortran.dg/init_flag_2.f90: New. * gfortran.dg/init_flag_3.f90: New. * gfortran.dg/init_flag_4.f90: New. * gfortran.dg/init_flag_5.f90: New. * gfortran.dg/init_flag_6.f90: New. * gfortran.dg/init_flag_7.f90: New. On 8/17/07, Asher Langton <langton2@llnl.gov> wrote: > :ADDPATCH fortran: > > > Hi all, > > Here's a patch to add -finit-local-zero, as well as some finer-grained > options. I have a working version of the runtime-controlled > initialization as discussed previously, but it still needs to be > cleaned up a bit, so I'll submit it as a separate patch: > > http://gcc.gnu.org/ml/fortran/2007-06/msg00028.html > > I've bootstrapped and regression tested this on x86_64-linux. > Everything passes in the ordinary regression tests, and with > RUNTESTFLAGS="--tool_opts -finit-local-zero" added, the only failures > are tests that invoke cc1 ("cc1: warning: command line option > "-finit-local-zero" is valid for Fortran but not for C"). > > -Asher > > > 2007-08-17 Asher Langton <langton2@llnl.gov> > > PR fortran/20441 > * gfortran.h : Add init_local_* enums and init_flag_* flags to > gfc_option_t. > * lang.opt: Add -finit-local-zero, -finit-real, -finit-integer, > and -finit-logical flags. > * invoke.texi: Document new options. > * resolve.c (build_init_assign): New function. > (apply_init_assign): Move part of function into build_init_assign. > (build_default_init_expr): Build local initializer (-finit-*). > (apple_default_init_local): Apply local initializer (-finit-*). > (resolve_fl_variable): Try to add local initializer (-finit-*). > * options.c (gfc_init_options, gfc_handle_option): Handle > -finit-local-zero, -finit-real, -finit-integer, -finit-logical > flags, and -finit-character flags. > > 2007-08-17 Asher Langton <langton2@llnl.gov> > > PR fortran/20441 > * gfortran.dg/init_flag_1.f90: New. > * gfortran.dg/init_flag_2.f90: New. > * gfortran.dg/init_flag_3.f90: New. > * gfortran.dg/init_flag_4.f90: New. > * gfortran.dg/init_flag_5.f90: New. > > [-- Attachment #2: gfc070831_142756.diff --] [-- Type: application/octet-stream, Size: 13504 bytes --] Index: gfortran.h =================================================================== --- gfortran.h (revision 127997) +++ gfortran.h (working copy) @@ -564,6 +564,37 @@ typedef enum } ioerror_codes; +typedef enum +{ + GFC_INIT_REAL_OFF = 0, + GFC_INIT_REAL_ZERO, + GFC_INIT_REAL_NAN, + GFC_INIT_REAL_INF, + GFC_INIT_REAL_NEG_INF +} +init_local_real; + +typedef enum +{ + GFC_INIT_LOGICAL_OFF = 0, + GFC_INIT_LOGICAL_FALSE, + GFC_INIT_LOGICAL_TRUE +} +init_local_logical; + +typedef enum +{ + GFC_INIT_CHARACTER_OFF = 0, + GFC_INIT_CHARACTER_ON +} +init_local_character; + +typedef enum +{ + GFC_INIT_INTEGER_OFF = 0, + GFC_INIT_INTEGER_ON +} +init_local_integer; /************************* Structures *****************************/ @@ -1868,6 +1899,13 @@ typedef struct int flag_sign_zero; int flag_module_private; int flag_recursive; + int flag_init_local_zero; + int flag_init_integer; + int flag_init_integer_value; + int flag_init_real; + int flag_init_logical; + int flag_init_character; + char flag_init_character_value; int fpe; Index: lang.opt =================================================================== --- lang.opt (revision 127997) +++ lang.opt (working copy) @@ -196,6 +196,26 @@ fimplicit-none Fortran Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements +finit-character= +Fortran RejectNegative Joined UInteger +-finit-character=<n> Initialize local character variables to ASCII value n + +finit-integer= +Fortran RejectNegative Joined +-finit-integer=<n> Initialize local integer variables to n + +finit-local-zero +Fortran +Initialize local variables to zero (from g77) + +finit-logical= +Fortran RejectNegative Joined +-finit-logical=<true|false> Initialize local logical variables + +finit-real= +Fortran RejectNegative Joined +-finit-real=<zero|nan|inf|-inf> Initialize local real variables + fmax-errors= Fortran RejectNegative Joined UInteger -fmax-errors=<n> Maximum number of errors to report Index: invoke.texi =================================================================== --- invoke.texi (revision 127997) +++ invoke.texi (working copy) @@ -156,7 +156,9 @@ and warnings}. -fsecond-underscore @gol -fbounds-check -fmax-stack-var-size=@var{n} @gol -fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol --fblas-matmul-limit=@var{n} -frecursive} +-fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol +-finit-integer=@var{n} -finit-real=@var{<zero|inf|-inf|nan>} @gol +-finit-logical=@var{<true|false>} -finit-character=@var{n}} @end table @menu @@ -931,6 +933,28 @@ Allow indirect recursion by forcing all on the stack. This flag cannot be used together with @option{-fmax-stack-var-size=} or @option{-fno-automatic}. +@item -finit-local-zero +@item -finit-integer=@var{n} +@item -finit-real=@var{<zero|inf|-inf|nan>} +@item -finit-logical=@var{<true|false>} +@item -finit-character=@var{n} +@opindex @code{finit-local-zero} +@opindex @code{finit-integer} +@opindex @code{finit-real} +@opindex @code{finit-logical} +@opindex @code{finit-character} +The @option{-finit-local-zero} option instructs the compiler to +initialize local @code{INTEGER}, @code{REAL}, and @code{COMPLEX} +variables to zero, @code{LOGICAL} variables to false, and +@code{CHARACTER} variables to a string of null bytes. Finer-grained +initialization options are provided by the +@option{-finit-integer=@var{n}}, +@option{-finit-real=@var{<zero|inf|-inf|nan>}} (which also initializes +the real and imaginary parts of local @code{COMPLEX} variables), +@option{-finit-logical=@var{<true|false>}}, and +@option{-finit-character=@var{n}} (where @var{n} is an ASCII character +value) options. These options do not initialize components of derived +type variables. (This limitation may be removed in future releases). @end table @xref{Code Gen Options,,Options for Code Generation Conventions, Index: resolve.c =================================================================== --- resolve.c (revision 127997) +++ resolve.c (working copy) @@ -6553,26 +6553,15 @@ is_non_constant_shape_array (gfc_symbol return not_constant; } - -/* Assign the default initializer to a derived type variable or result. */ - +/* Given a symbol and an initialization expression, add code to initialize + the symbol to the function entry. */ static void -apply_default_init (gfc_symbol *sym) +build_init_assign (gfc_symbol *sym, gfc_expr *init) { gfc_expr *lval; - gfc_expr *init = NULL; gfc_code *init_st; gfc_namespace *ns = sym->ns; - if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function) - return; - - if (sym->ts.type == BT_DERIVED && sym->ts.derived) - init = gfc_default_initializer (&sym->ts); - - if (init == NULL) - return; - /* Search for the function namespace if this is a contained function without an explicit result. */ if (sym->attr.function && sym == sym->result @@ -6605,6 +6594,201 @@ apply_default_init (gfc_symbol *sym) init_st->expr2 = init; } +/* Assign the default initializer to a derived type variable or result. */ + +static void +apply_default_init (gfc_symbol *sym) +{ + gfc_expr *init = NULL; + + if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function) + return; + + if (sym->ts.type == BT_DERIVED && sym->ts.derived) + init = gfc_default_initializer (&sym->ts); + + if (init == NULL) + return; + + build_init_assign (sym, init); +} + +/* Build an initializer for a local integer, real, complex, logical, or + character variable, based on the command line flags finit-local-zero, + finit-integer=, finit-real=, finit-logical=, and finit-runtime. Returns + null if the symbol should not have a default initialization. */ +static gfc_expr * +build_default_init_expr (gfc_symbol *sym) +{ + int char_len; + gfc_expr *init_expr; + int i; + char *ch; + + /* These symbols should never have a default initialization. */ + if ((sym->attr.dimension && !gfc_is_compile_time_shape (sym->as)) + || sym->attr.external + || sym->attr.dummy + || sym->attr.pointer + || sym->attr.in_equivalence + || sym->attr.in_common + || sym->attr.data + || sym->module + || sym->attr.cray_pointee + || sym->attr.cray_pointer) + return NULL; + + /* Now we'll try to build an initializer expression. */ + init_expr = gfc_get_expr (); + init_expr->expr_type = EXPR_CONSTANT; + init_expr->ts.type = sym->ts.type; + init_expr->ts.kind = sym->ts.kind; + init_expr->where = sym->declared_at; + + /* We will only initialize integers, reals, complex, logicals, and + characters, and only if the corresponding command-line flags + were set. Otherwise, we free init_expr and return null. */ + switch (sym->ts.type) + { + case BT_INTEGER: + if (gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF) + mpz_init_set_si (init_expr->value.integer, + gfc_option.flag_init_integer_value); + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + case BT_REAL: + mpfr_init (init_expr->value.real); + switch (gfc_option.flag_init_real) + { + case GFC_INIT_REAL_NAN: + mpfr_set_nan (init_expr->value.real); + break; + + case GFC_INIT_REAL_INF: + mpfr_set_inf (init_expr->value.real, 1); + break; + + case GFC_INIT_REAL_NEG_INF: + mpfr_set_inf (init_expr->value.real, -1); + break; + + case GFC_INIT_REAL_ZERO: + mpfr_set_ui (init_expr->value.real, 0.0, GFC_RND_MODE); + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + break; + } + break; + + case BT_COMPLEX: + mpfr_init (init_expr->value.complex.r); + mpfr_init (init_expr->value.complex.i); + switch (gfc_option.flag_init_real) + { + case GFC_INIT_REAL_NAN: + mpfr_set_nan (init_expr->value.complex.r); + mpfr_set_nan (init_expr->value.complex.i); + break; + + case GFC_INIT_REAL_INF: + mpfr_set_inf (init_expr->value.complex.r, 1); + mpfr_set_inf (init_expr->value.complex.i, 1); + break; + + case GFC_INIT_REAL_NEG_INF: + mpfr_set_inf (init_expr->value.complex.r, -1); + mpfr_set_inf (init_expr->value.complex.i, -1); + break; + + case GFC_INIT_REAL_ZERO: + mpfr_set_ui (init_expr->value.complex.r, 0.0, GFC_RND_MODE); + mpfr_set_ui (init_expr->value.complex.i, 0.0, GFC_RND_MODE); + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + break; + } + break; + + case BT_LOGICAL: + if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_FALSE) + init_expr->value.logical = 0; + else if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_TRUE) + init_expr->value.logical = 1; + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + case BT_CHARACTER: + /* For characters, the length must be constant in order to + create a default initializer. */ + if (gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON + && sym->ts.cl->length + && sym->ts.cl->length->expr_type == EXPR_CONSTANT) + { + char_len = mpz_get_si (sym->ts.cl->length->value.integer); + init_expr->value.character.length = char_len; + init_expr->value.character.string = gfc_getmem (char_len+1); + ch = init_expr->value.character.string; + for (i = 0; i < char_len; i++) + *(ch++) = gfc_option.flag_init_character_value; + } + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + } + return init_expr; +} + +/* Add an initialization expression to a local variable. */ +static void +apply_default_init_local (gfc_symbol *sym) +{ + gfc_expr *init = NULL; + + /* The symbol should be a variable or a function return value. */ + if ((sym->attr.flavor != FL_VARIABLE && !sym->attr.function) + || (sym->attr.function && sym->result != sym)) + return; + + /* Try to build the initializer expression. If we can't initialize + this symbol, then init will be NULL. */ + init = build_default_init_expr (sym); + if (init == NULL) + return; + + /* For saved variables, we don't want to add an initializer at + function entry, so we just add a static initializer. */ + if (sym->attr.save || sym->ns->save_all) + { + /* Don't clobber an existing initializer! */ + gcc_assert (sym->value == NULL); + sym->value = init; + return; + } + + build_init_assign (sym, init); +} /* Resolution of common features of flavors variable and procedure. */ @@ -6719,6 +6903,9 @@ resolve_fl_variable (gfc_symbol *sym, in } } + if (sym->value == NULL && sym->attr.referenced) + apply_default_init_local (sym); /* Try to apply a default initialization. */ + /* Can the symbol have an initializer? */ flag = 0; if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy Index: options.c =================================================================== --- options.c (revision 127997) +++ options.c (working copy) @@ -107,7 +107,13 @@ gfc_init_options (unsigned int argc ATTR gfc_option.flag_openmp = 0; gfc_option.flag_sign_zero = 1; gfc_option.flag_recursive = 0; - + gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF; + gfc_option.flag_init_integer_value = 0; + gfc_option.flag_init_real = GFC_INIT_REAL_OFF; + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF; + gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF; + gfc_option.flag_init_character_value = (char)0; + gfc_option.fpe = 0; /* Argument pointers cannot point to anything but their argument. */ @@ -650,6 +656,55 @@ gfc_handle_option (size_t scode, const c gfc_option.flag_default_double = value; break; + case OPT_finit_local_zero: + gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON; + gfc_option.flag_init_integer_value = 0; + gfc_option.flag_init_real = GFC_INIT_REAL_ZERO; + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE; + gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON; + gfc_option.flag_init_character_value = (char)0; + break; + + case OPT_finit_logical_: + if (!strcmp (arg, "false")) + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE; + else if (!strcmp (arg, "true")) + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_TRUE; + else + gfc_fatal_error ("Unrecognized option to -finit-logical: %s", + arg); + break; + + case OPT_finit_real_: + if (!strcmp (arg, "zero")) + gfc_option.flag_init_real = GFC_INIT_REAL_ZERO; + else if (!strcmp (arg, "nan")) + gfc_option.flag_init_real = GFC_INIT_REAL_NAN; + else if (!strcmp (arg, "inf")) + gfc_option.flag_init_real = GFC_INIT_REAL_INF; + else if (!strcmp (arg, "-inf")) + gfc_option.flag_init_real = GFC_INIT_REAL_NEG_INF; + else + gfc_fatal_error ("Unrecognized option to -finit-real: %s", + arg); + break; + + case OPT_finit_integer_: + gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON; + gfc_option.flag_init_integer_value = atoi (arg); + break; + + case OPT_finit_character_: + if (value >= 0 && value <= 127) + { + gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON; + gfc_option.flag_init_character_value = (char)value; + } + else + gfc_fatal_error ("The value of n in -finit-character=n must be " + "between 0 and 127"); + break; + case OPT_I: gfc_add_include_path (arg, true); break; [-- Attachment #3: init_flag_1.f90 --] [-- Type: application/octet-stream, Size: 1321 bytes --] ! { dg-do run } ! { dg-options "-finit-local-zero" } program init_flag_1 call real_test call logical_test call int_test call complex_test call char_test end program init_flag_1 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 /= 0.0) call abort if (r2(2) /= 0.0) call abort if (r3(5,5) /= 0.0) call abort if (r4 /= 0.0) call abort end subroutine real_test subroutine logical_test logical l1 logical l2(2) if (l1 .neqv. .false.) call abort if (l2(2) .neqv. .false.) call abort end subroutine logical_test subroutine int_test integer i1 integer i2(10) dimension i3(10,10) if (i1 /= 0) call abort if (i2(2) /= 0) call abort if (i3(5,5) /= 0) call abort if (i4 /= 0) call abort end subroutine int_test subroutine complex_test complex c1 complex c2(20,20) if (c1 /= (0.0,0.0)) call abort if (c2(1,1) /= (0.0,0.0)) call abort end subroutine complex_test subroutine char_test character*1 c1 character*8 c2, c3(5) character c4(10) if (c1 /= '\0') call abort if (c2 /= '\0\0\0\0\0\0\0\0') call abort if (c3(1) /= '\0\0\0\0\0\0\0\0') call abort if (c3(5) /= '\0\0\0\0\0\0\0\0') call abort if (c4(5) /= '\0') call abort end subroutine char_test [-- Attachment #4: init_flag_2.f90 --] [-- Type: application/octet-stream, Size: 1035 bytes --] ! { dg-do run } ! { dg-options "-finit-integer=1 -finit-logical=true -finit-real=zero" } program init_flag_2 call real_test call logical_test call int_test call complex_test end program init_flag_2 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 /= 0.0) call abort if (r2(2) /= 0.0) call abort if (r3(5,5) /= 0.0) call abort if (r4 /= 0.0) call abort end subroutine real_test subroutine logical_test logical l1 logical l2(2) if (l1 .neqv. .true.) call abort if (l2(2) .neqv. .true.) call abort end subroutine logical_test subroutine int_test integer i1 integer i2(10) dimension i3(10,10) if (i1 /= 1) call abort if (i2(2) /= 1) call abort if (i3(5,5) /= 1) call abort if (i4 /= 1) call abort end subroutine int_test subroutine complex_test complex c1 complex c2(20,20) if (c1 /= (0.0,0.0)) call abort if (c2(1,1) /= (0.0,0.0)) call abort end subroutine complex_test [-- Attachment #5: init_flag_3.f90 --] [-- Type: application/octet-stream, Size: 1049 bytes --] ! { dg-do run } ! { dg-options "-finit-integer=-1 -finit-logical=false -finit-real=nan" } program init_flag_3 call real_test call logical_test call int_test call complex_test end program init_flag_3 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 .eq. r1) call abort if (r2(2) .eq. r2(2)) call abort if (r3(5,5) .eq. r3(5,5)) call abort if (r4 .eq. r4) call abort end subroutine real_test subroutine logical_test logical l1 logical l2(2) if (l1 .neqv. .false.) call abort if (l2(2) .neqv. .false.) call abort end subroutine logical_test subroutine int_test integer i1 integer i2(10) dimension i3(10,10) if (i1 /= -1) call abort if (i2(2) /= -1) call abort if (i3(5,5) /= -1) call abort if (i4 /= -1) call abort end subroutine int_test subroutine complex_test complex c1 complex c2(20,20) if (c1 .eq. c1) call abort if (c2(1,1) .eq. c2(1,1)) call abort end subroutine complex_test [-- Attachment #6: init_flag_4.f90 --] [-- Type: application/octet-stream, Size: 505 bytes --] ! { dg-do run } ! { dg-options "-finit-real=inf" } program init_flag_4 call real_test end program init_flag_4 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 .le. 0 .or. r1 .ne. 2*r1) call abort if (r2(2) .le. 0 .or. r2(2) .ne. 2*r2(2)) call abort if (r3(5,5) .le. 0 .or. r3(5,5) .ne. 2*r3(5,5)) call abort if (r4 .le. 0 .or. r4 .ne. 2*r4) call abort end subroutine real_test [-- Attachment #7: init_flag_5.f90 --] [-- Type: application/octet-stream, Size: 506 bytes --] ! { dg-do run } ! { dg-options "-finit-real=-inf" } program init_flag_5 call real_test end program init_flag_5 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine real_test real r1 real r2(10) dimension r3(10,10) if (r1 .ge. 0 .or. r1 .ne. 2*r1) call abort if (r2(2) .ge. 0 .or. r2(2) .ne. 2*r2(2)) call abort if (r3(5,5) .ge. 0 .or. r3(5,5) .ne. 2*r3(5,5)) call abort if (r4 .ge. 0 .or. r4 .ne. 2*r4) call abort end subroutine real_test [-- Attachment #8: init_flag_6.f90 --] [-- Type: application/octet-stream, Size: 494 bytes --] ! { dg-do run } ! { dg-options "-finit-character=32" } program init_flag_6 call char_test end program init_flag_6 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine char_test character*1 c1 character*8 c2, c3(5) character c4(10) if (c1 /= ' ') call abort if (c2 /= ' ') call abort if (c3(1) /= ' ') call abort if (c3(5) /= ' ') call abort if (c4(5) /= ' ') call abort end subroutine char_test [-- Attachment #9: init_flag_7.f90 --] [-- Type: application/octet-stream, Size: 1021 bytes --] ! { dg-do run } ! { dg-options "-finit-integer=101" } program init_flag_7 call save_test1 (.true.) call save_test1 (.false.) call save_test2 (.true.) call save_test2 (.false.) end program init_flag_7 ! Test some initializations for both implicitly and ! explicitly declared local variables. subroutine save_test1 (first) logical first integer :: i1 = -100 integer i2 integer i3 save i2 if (first) then if (i1 .ne. -100) call abort if (i2 .ne. 101) call abort if (i3 .ne. 101) call abort else if (i1 .ne. 1001) call abort if (i2 .ne. 1002) call abort if (i3 .ne. 101) call abort end if i1 = 1001 i2 = 1002 i3 = 1003 end subroutine save_test1 subroutine save_test2 (first) logical first integer :: i1 = -100 integer i2 save if (first) then if (i1 .ne. -100) call abort if (i2 .ne. 101) call abort else if (i1 .ne. 1001) call abort if (i2 .ne. 1002) call abort end if i1 = 1001 i2 = 1002 end subroutine save_test2 ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-31 22:14 ` Asher Langton @ 2007-09-01 20:26 ` Thomas Koenig 2007-09-14 11:27 ` Tobias Burnus [not found] ` <46E7B808.8070104@net-b.de> 2 siblings, 0 replies; 20+ messages in thread From: Thomas Koenig @ 2007-09-01 20:26 UTC (permalink / raw) To: Asher Langton; +Cc: fortran, gcc-patches Asher Langton wrote: Hi Asher, > Here's an updated patch. I've added -finit-character=<n>, where 0 <= > n <= 127 is an ASCII value. Derived types aren't initialized, but > I've documented this in the manual. I've added a test that checks > initialization of SAVE'd variables. This has been bootstrapped (+make > pdf) and regression tested on x86_64-unknown-linux-gnu. Equivalenced variables are not initialized by your patch: $ cat foo.f program main call foo end subroutine foo equivalence(i,j) print *,j end $ g77 -finit-local-zero foo.f && ./a.out 0 $ gfortran -finit-local-zero foo.f && ./a.out 1 This behavior is different from g77, so I think it should be either documented, or the behavior changed to match g77. Of course, if the user specifies -finit-integer and -finit-real and equivalences the values, he's on his own :-) Thomas ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-08-31 22:14 ` Asher Langton 2007-09-01 20:26 ` Thomas Koenig @ 2007-09-14 11:27 ` Tobias Burnus 2007-09-14 11:34 ` François-Xavier Coudert 2007-09-14 13:15 ` Asher Langton [not found] ` <46E7B808.8070104@net-b.de> 2 siblings, 2 replies; 20+ messages in thread From: Tobias Burnus @ 2007-09-14 11:27 UTC (permalink / raw) To: Asher Langton; +Cc: fortran, gcc-patches Hi all, Asher Langton wrote: > 2007-08-31 Asher Langton <langton2@llnl.gov> > > PR fortran/20441 > * gfortran.h : Add init_local_* enums and init_flag_* flags to > gfc_option_t. > [...] > Thomas König wrote: > Equivalenced variables are not initialized by your patch: > [...] > This behavior is different from g77, so I think it should be either > documented, or the behavior changed to match g77. (Side note: On my system I was not able to get non-zero equivalenced variables with gfortran [NAG f95 had them for the same program]; though I don't know why they were zero.) I am very much in favour of including this patch in GCC 4.3.0 as it is (a) a regression with regards to g77, (b) there are still several applications around which bluntly assume that local variables (esp. integer variables) are initialized by zero [e.g. the quantum-physics/-chemistry program Wien2k], (c) the patch has been submitted before stage 3, which we entered very recently. I therefore suggest to patch the documentation (see patch below) and include it otherwise as is. For improvements (derived types, equivalence, optionally initializing intent(OUT) dummies [etc.?]), we can fill (a) PR(s) and handle them later. To the patch itself: http://gcc.gnu.org/ml/fortran/2007-08/msg00666.html + else if (!strcmp (arg, "nan")) I am wondering whether one should use strcasecmp instead (as people like to write INF, NaN,...), but I do not have a real opinion on this. +@option{-finit-real=@var{<zero|inf|-inf|nan>}} (which also initializes +the real and imaginary parts of local @code{COMPLEX} variables), I wonder whether one should add something like "Note: @var{nan} initializes REAL and COMPLEX variables with a quiet NaN." as some might expect that the NaN are signalling.* From my side this patch (with the patch below) is OK for the trunk - unless someone comes up with reasons why this patch should not be checked in (as is). Tobias --- invoke.texi.old 2007-09-14 10:25:20.000000000 +0200 +++ invoke.texi 2007-09-14 10:27:28.000000000 +0200 @@ -954,7 +954,8 @@ @option{-finit-logical=@var{<true|false>}}, and @option{-finit-character=@var{n}} (where @var{n} is an ASCII character value) options. These options do not initialize components of derived -type variables. (This limitation may be removed in future releases). +type variables nor equivalenced variables. +(These limitations may be removed in future releases). @end table @xref{Code Gen Options,,Options for Code Generation Conventions, ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-14 11:27 ` Tobias Burnus @ 2007-09-14 11:34 ` François-Xavier Coudert 2007-09-14 13:15 ` Asher Langton 1 sibling, 0 replies; 20+ messages in thread From: François-Xavier Coudert @ 2007-09-14 11:34 UTC (permalink / raw) To: Tobias Burnus; +Cc: Asher Langton, fortran, gcc-patches > I am very much in favour of including this patch in GCC 4.3.0 Same opinion here. > the patch has been submitted before stage 3, which we entered very recently. Yep, the rule is about patch submission date, not approval. FX ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-14 11:27 ` Tobias Burnus 2007-09-14 11:34 ` François-Xavier Coudert @ 2007-09-14 13:15 ` Asher Langton 1 sibling, 0 replies; 20+ messages in thread From: Asher Langton @ 2007-09-14 13:15 UTC (permalink / raw) To: Tobias Burnus; +Cc: fortran, gcc-patches On 9/14/07, Tobias Burnus <burnus@net-b.de> wrote: > + else if (!strcmp (arg, "nan")) > > I am wondering whether one should use strcasecmp instead (as people like > to write INF, NaN,...), but I do not have a real opinion on this. That's a good idea, and it certainly won't harm anything. > > +@option{-finit-real=@var{<zero|inf|-inf|nan>}} (which also initializes > +the real and imaginary parts of local @code{COMPLEX} variables), > > I wonder whether one should add something like > "Note: @var{nan} initializes REAL and COMPLEX variables with a quiet NaN." > as some might expect that the NaN are signalling.* I'll add something like this. Eventually, I'd like to add finit-real=<snan,qnan> options, but so far I haven't come up with a nice kludge to deal with sNaNs in mpfr. -Asher ^ permalink raw reply [flat|nested] 20+ messages in thread
[parent not found: <46E7B808.8070104@net-b.de>]
* Re: [PATCH, fortran] PR20441 -finit-local-zero [not found] ` <46E7B808.8070104@net-b.de> @ 2007-09-14 12:55 ` Asher Langton 2007-09-19 21:44 ` Thomas Koenig 0 siblings, 1 reply; 20+ messages in thread From: Asher Langton @ 2007-09-14 12:55 UTC (permalink / raw) To: Tobias Burnus, fortran, gcc-patches Hi all, I somehow missed Thomas's original message entirely. I will take a look at equivalenced variables tonight. -Asher On 9/12/07, Tobias Burnus <burnus@net-b.de> wrote: > Asher Langton wrote: > > Here's an updated patch. > > Thomas König wrote: > > Equivalenced variables are not initialized by your patch: > > [...] > > This behavior is different from g77, so I think it should be either > > documented, or the behavior changed to match g77. > > Could you send an updated patch (e.g. with documentation update only) > rather soonish. I think we can then still include this patch in stage 3 > (starts today) as the initial patch has been submitted before stage 3 > has started. I really would like to see this patch in 4.3.x (I have some > programs which don't initialize local variables). I think we can worry > about finer points (equivalence, derived types) later. Unless you have a > patch ready which initializes also equivalence. > > (I have to admit that on my system Thomas' equivalence example did not > work: the variables were always zero with any options.) > > Tobias > ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-14 12:55 ` Asher Langton @ 2007-09-19 21:44 ` Thomas Koenig 2007-09-20 4:47 ` Asher Langton 0 siblings, 1 reply; 20+ messages in thread From: Thomas Koenig @ 2007-09-19 21:44 UTC (permalink / raw) To: Asher Langton; +Cc: Tobias Burnus, fortran, gcc-patches On Fri, 2007-09-14 at 07:44 -0500, Asher Langton wrote: Hi Asher, > I will take a > look at equivalenced variables tonight. Any progress? If you haven't got a round tuit, I'd be in favor of committing right now, and updating the documentation according to Tobias Burnus' suggestion. Thomas ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-19 21:44 ` Thomas Koenig @ 2007-09-20 4:47 ` Asher Langton 2007-09-20 10:08 ` Asher Langton 0 siblings, 1 reply; 20+ messages in thread From: Asher Langton @ 2007-09-20 4:47 UTC (permalink / raw) To: Thomas Koenig; +Cc: Tobias Burnus, fortran, gcc-patches On 9/19/07, Thomas Koenig <tkoenig@alice-dsl.net> wrote: > On Fri, 2007-09-14 at 07:44 -0500, Asher Langton wrote: > > Hi Asher, > > > I will take a > > look at equivalenced variables tonight. > > Any progress? If you haven't got a round tuit, I'd be in favor of > committing right now, and updating the documentation according to > Tobias Burnus' suggestion. Okay, that sounds good to me. I'd like to look into the equivalence issue some more, but the last few days have been quite hectic. I'll put together an updated patch with the added documentation, and then deal with the equivalence issue when I have a little more time. -Asher ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-20 4:47 ` Asher Langton @ 2007-09-20 10:08 ` Asher Langton 2007-09-20 10:14 ` Tobias Burnus 0 siblings, 1 reply; 20+ messages in thread From: Asher Langton @ 2007-09-20 10:08 UTC (permalink / raw) To: Thomas Koenig; +Cc: Tobias Burnus, fortran, gcc-patches [-- Attachment #1: Type: text/plain, Size: 933 bytes --] On 9/19/07, Asher Langton <langton2@llnl.gov> wrote: > On 9/19/07, Thomas Koenig <tkoenig@alice-dsl.net> wrote: > > On Fri, 2007-09-14 at 07:44 -0500, Asher Langton wrote: > > > > Hi Asher, > > > > > I will take a > > > look at equivalenced variables tonight. > > > > Any progress? If you haven't got a round tuit, I'd be in favor of > > committing right now, and updating the documentation according to > > Tobias Burnus' suggestion. > > Okay, that sounds good to me. I'd like to look into the equivalence > issue some more, but the last few days have been quite hectic. I'll > put together an updated patch with the added documentation, and then > deal with the equivalence issue when I have a little more time. Here's an updated patch. The Changelog and the tests are the same as here: http://gcc.gnu.org/ml/fortran/2007-08/msg00666.html I bootstrapped and regression tested this on x86_64-linux. Okay to commit? -Asher [-- Attachment #2: gfc070919_214008.diff --] [-- Type: application/octet-stream, Size: 13816 bytes --] Index: gfortran.h =================================================================== --- gfortran.h (revision 128613) +++ gfortran.h (working copy) @@ -510,6 +510,38 @@ enum gfc_isym_id typedef enum gfc_isym_id gfc_isym_id; +typedef enum +{ + GFC_INIT_REAL_OFF = 0, + GFC_INIT_REAL_ZERO, + GFC_INIT_REAL_NAN, + GFC_INIT_REAL_INF, + GFC_INIT_REAL_NEG_INF +} +init_local_real; + +typedef enum +{ + GFC_INIT_LOGICAL_OFF = 0, + GFC_INIT_LOGICAL_FALSE, + GFC_INIT_LOGICAL_TRUE +} +init_local_logical; + +typedef enum +{ + GFC_INIT_CHARACTER_OFF = 0, + GFC_INIT_CHARACTER_ON +} +init_local_character; + +typedef enum +{ + GFC_INIT_INTEGER_OFF = 0, + GFC_INIT_INTEGER_ON +} +init_local_integer; + /************************* Structures *****************************/ /* Used for keeping things in balanced binary trees. */ @@ -1822,6 +1854,13 @@ typedef struct int flag_sign_zero; int flag_module_private; int flag_recursive; + int flag_init_local_zero; + int flag_init_integer; + int flag_init_integer_value; + int flag_init_real; + int flag_init_logical; + int flag_init_character; + char flag_init_character_value; int fpe; Index: lang.opt =================================================================== --- lang.opt (revision 128613) +++ lang.opt (working copy) @@ -196,6 +196,26 @@ fimplicit-none Fortran Specify that no implicit typing is allowed, unless overridden by explicit IMPLICIT statements +finit-character= +Fortran RejectNegative Joined UInteger +-finit-character=<n> Initialize local character variables to ASCII value n + +finit-integer= +Fortran RejectNegative Joined +-finit-integer=<n> Initialize local integer variables to n + +finit-local-zero +Fortran +Initialize local variables to zero (from g77) + +finit-logical= +Fortran RejectNegative Joined +-finit-logical=<true|false> Initialize local logical variables + +finit-real= +Fortran RejectNegative Joined +-finit-real=<zero|nan|inf|-inf> Initialize local real variables + fmax-errors= Fortran RejectNegative Joined UInteger -fmax-errors=<n> Maximum number of errors to report Index: invoke.texi =================================================================== --- invoke.texi (revision 128613) +++ invoke.texi (working copy) @@ -156,7 +156,9 @@ and warnings}. -fsecond-underscore @gol -fbounds-check -fmax-stack-var-size=@var{n} @gol -fpack-derived -frepack-arrays -fshort-enums -fexternal-blas @gol --fblas-matmul-limit=@var{n} -frecursive} +-fblas-matmul-limit=@var{n} -frecursive -finit-local-zero @gol +-finit-integer=@var{n} -finit-real=@var{<zero|inf|-inf|nan>} @gol +-finit-logical=@var{<true|false>} -finit-character=@var{n}} @end table @menu @@ -931,6 +933,33 @@ Allow indirect recursion by forcing all on the stack. This flag cannot be used together with @option{-fmax-stack-var-size=} or @option{-fno-automatic}. +@item -finit-local-zero +@item -finit-integer=@var{n} +@item -finit-real=@var{<zero|inf|-inf|nan>} +@item -finit-logical=@var{<true|false>} +@item -finit-character=@var{n} +@opindex @code{finit-local-zero} +@opindex @code{finit-integer} +@opindex @code{finit-real} +@opindex @code{finit-logical} +@opindex @code{finit-character} +The @option{-finit-local-zero} option instructs the compiler to +initialize local @code{INTEGER}, @code{REAL}, and @code{COMPLEX} +variables to zero, @code{LOGICAL} variables to false, and +@code{CHARACTER} variables to a string of null bytes. Finer-grained +initialization options are provided by the +@option{-finit-integer=@var{n}}, +@option{-finit-real=@var{<zero|inf|-inf|nan>}} (which also initializes +the real and imaginary parts of local @code{COMPLEX} variables), +@option{-finit-logical=@var{<true|false>}}, and +@option{-finit-character=@var{n}} (where @var{n} is an ASCII character +value) options. These options do not initialize components of derived +type variables, nor do they initialize variables that appear in an +@code{EQUIVALENCE} statement. (This limitation may be removed in +future releases). + +Note that the @option{-finit-real=nan} option initializes @code{REAL} +and @code{COMPLEX} variables with a quiet NaN. @end table @xref{Code Gen Options,,Options for Code Generation Conventions, Index: resolve.c =================================================================== --- resolve.c (revision 128613) +++ resolve.c (working copy) @@ -6566,26 +6566,15 @@ is_non_constant_shape_array (gfc_symbol return not_constant; } - -/* Assign the default initializer to a derived type variable or result. */ - +/* Given a symbol and an initialization expression, add code to initialize + the symbol to the function entry. */ static void -apply_default_init (gfc_symbol *sym) +build_init_assign (gfc_symbol *sym, gfc_expr *init) { gfc_expr *lval; - gfc_expr *init = NULL; gfc_code *init_st; gfc_namespace *ns = sym->ns; - if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function) - return; - - if (sym->ts.type == BT_DERIVED && sym->ts.derived) - init = gfc_default_initializer (&sym->ts); - - if (init == NULL) - return; - /* Search for the function namespace if this is a contained function without an explicit result. */ if (sym->attr.function && sym == sym->result @@ -6618,6 +6607,201 @@ apply_default_init (gfc_symbol *sym) init_st->expr2 = init; } +/* Assign the default initializer to a derived type variable or result. */ + +static void +apply_default_init (gfc_symbol *sym) +{ + gfc_expr *init = NULL; + + if (sym->attr.flavor != FL_VARIABLE && !sym->attr.function) + return; + + if (sym->ts.type == BT_DERIVED && sym->ts.derived) + init = gfc_default_initializer (&sym->ts); + + if (init == NULL) + return; + + build_init_assign (sym, init); +} + +/* Build an initializer for a local integer, real, complex, logical, or + character variable, based on the command line flags finit-local-zero, + finit-integer=, finit-real=, finit-logical=, and finit-runtime. Returns + null if the symbol should not have a default initialization. */ +static gfc_expr * +build_default_init_expr (gfc_symbol *sym) +{ + int char_len; + gfc_expr *init_expr; + int i; + char *ch; + + /* These symbols should never have a default initialization. */ + if ((sym->attr.dimension && !gfc_is_compile_time_shape (sym->as)) + || sym->attr.external + || sym->attr.dummy + || sym->attr.pointer + || sym->attr.in_equivalence + || sym->attr.in_common + || sym->attr.data + || sym->module + || sym->attr.cray_pointee + || sym->attr.cray_pointer) + return NULL; + + /* Now we'll try to build an initializer expression. */ + init_expr = gfc_get_expr (); + init_expr->expr_type = EXPR_CONSTANT; + init_expr->ts.type = sym->ts.type; + init_expr->ts.kind = sym->ts.kind; + init_expr->where = sym->declared_at; + + /* We will only initialize integers, reals, complex, logicals, and + characters, and only if the corresponding command-line flags + were set. Otherwise, we free init_expr and return null. */ + switch (sym->ts.type) + { + case BT_INTEGER: + if (gfc_option.flag_init_integer != GFC_INIT_INTEGER_OFF) + mpz_init_set_si (init_expr->value.integer, + gfc_option.flag_init_integer_value); + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + case BT_REAL: + mpfr_init (init_expr->value.real); + switch (gfc_option.flag_init_real) + { + case GFC_INIT_REAL_NAN: + mpfr_set_nan (init_expr->value.real); + break; + + case GFC_INIT_REAL_INF: + mpfr_set_inf (init_expr->value.real, 1); + break; + + case GFC_INIT_REAL_NEG_INF: + mpfr_set_inf (init_expr->value.real, -1); + break; + + case GFC_INIT_REAL_ZERO: + mpfr_set_ui (init_expr->value.real, 0.0, GFC_RND_MODE); + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + break; + } + break; + + case BT_COMPLEX: + mpfr_init (init_expr->value.complex.r); + mpfr_init (init_expr->value.complex.i); + switch (gfc_option.flag_init_real) + { + case GFC_INIT_REAL_NAN: + mpfr_set_nan (init_expr->value.complex.r); + mpfr_set_nan (init_expr->value.complex.i); + break; + + case GFC_INIT_REAL_INF: + mpfr_set_inf (init_expr->value.complex.r, 1); + mpfr_set_inf (init_expr->value.complex.i, 1); + break; + + case GFC_INIT_REAL_NEG_INF: + mpfr_set_inf (init_expr->value.complex.r, -1); + mpfr_set_inf (init_expr->value.complex.i, -1); + break; + + case GFC_INIT_REAL_ZERO: + mpfr_set_ui (init_expr->value.complex.r, 0.0, GFC_RND_MODE); + mpfr_set_ui (init_expr->value.complex.i, 0.0, GFC_RND_MODE); + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + break; + } + break; + + case BT_LOGICAL: + if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_FALSE) + init_expr->value.logical = 0; + else if (gfc_option.flag_init_logical == GFC_INIT_LOGICAL_TRUE) + init_expr->value.logical = 1; + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + case BT_CHARACTER: + /* For characters, the length must be constant in order to + create a default initializer. */ + if (gfc_option.flag_init_character == GFC_INIT_CHARACTER_ON + && sym->ts.cl->length + && sym->ts.cl->length->expr_type == EXPR_CONSTANT) + { + char_len = mpz_get_si (sym->ts.cl->length->value.integer); + init_expr->value.character.length = char_len; + init_expr->value.character.string = gfc_getmem (char_len+1); + ch = init_expr->value.character.string; + for (i = 0; i < char_len; i++) + *(ch++) = gfc_option.flag_init_character_value; + } + else + { + gfc_free_expr (init_expr); + init_expr = NULL; + } + break; + + default: + gfc_free_expr (init_expr); + init_expr = NULL; + } + return init_expr; +} + +/* Add an initialization expression to a local variable. */ +static void +apply_default_init_local (gfc_symbol *sym) +{ + gfc_expr *init = NULL; + + /* The symbol should be a variable or a function return value. */ + if ((sym->attr.flavor != FL_VARIABLE && !sym->attr.function) + || (sym->attr.function && sym->result != sym)) + return; + + /* Try to build the initializer expression. If we can't initialize + this symbol, then init will be NULL. */ + init = build_default_init_expr (sym); + if (init == NULL) + return; + + /* For saved variables, we don't want to add an initializer at + function entry, so we just add a static initializer. */ + if (sym->attr.save || sym->ns->save_all) + { + /* Don't clobber an existing initializer! */ + gcc_assert (sym->value == NULL); + sym->value = init; + return; + } + + build_init_assign (sym, init); +} /* Resolution of common features of flavors variable and procedure. */ @@ -6732,6 +6916,9 @@ resolve_fl_variable (gfc_symbol *sym, in } } + if (sym->value == NULL && sym->attr.referenced) + apply_default_init_local (sym); /* Try to apply a default initialization. */ + /* Can the symbol have an initializer? */ flag = 0; if (sym->attr.allocatable || sym->attr.external || sym->attr.dummy Index: options.c =================================================================== --- options.c (revision 128613) +++ options.c (working copy) @@ -107,7 +107,13 @@ gfc_init_options (unsigned int argc ATTR gfc_option.flag_openmp = 0; gfc_option.flag_sign_zero = 1; gfc_option.flag_recursive = 0; - + gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF; + gfc_option.flag_init_integer_value = 0; + gfc_option.flag_init_real = GFC_INIT_REAL_OFF; + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF; + gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF; + gfc_option.flag_init_character_value = (char)0; + gfc_option.fpe = 0; /* Argument pointers cannot point to anything but their argument. */ @@ -650,6 +656,55 @@ gfc_handle_option (size_t scode, const c gfc_option.flag_default_double = value; break; + case OPT_finit_local_zero: + gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON; + gfc_option.flag_init_integer_value = 0; + gfc_option.flag_init_real = GFC_INIT_REAL_ZERO; + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE; + gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON; + gfc_option.flag_init_character_value = (char)0; + break; + + case OPT_finit_logical_: + if (!strcasecmp (arg, "false")) + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE; + else if (!strcasecmp (arg, "true")) + gfc_option.flag_init_logical = GFC_INIT_LOGICAL_TRUE; + else + gfc_fatal_error ("Unrecognized option to -finit-logical: %s", + arg); + break; + + case OPT_finit_real_: + if (!strcasecmp (arg, "zero")) + gfc_option.flag_init_real = GFC_INIT_REAL_ZERO; + else if (!strcasecmp (arg, "nan")) + gfc_option.flag_init_real = GFC_INIT_REAL_NAN; + else if (!strcasecmp (arg, "inf")) + gfc_option.flag_init_real = GFC_INIT_REAL_INF; + else if (!strcasecmp (arg, "-inf")) + gfc_option.flag_init_real = GFC_INIT_REAL_NEG_INF; + else + gfc_fatal_error ("Unrecognized option to -finit-real: %s", + arg); + break; + + case OPT_finit_integer_: + gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON; + gfc_option.flag_init_integer_value = atoi (arg); + break; + + case OPT_finit_character_: + if (value >= 0 && value <= 127) + { + gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON; + gfc_option.flag_init_character_value = (char)value; + } + else + gfc_fatal_error ("The value of n in -finit-character=n must be " + "between 0 and 127"); + break; + case OPT_I: gfc_add_include_path (arg, true); break; ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-20 10:08 ` Asher Langton @ 2007-09-20 10:14 ` Tobias Burnus 2007-09-20 20:20 ` Thomas Koenig 0 siblings, 1 reply; 20+ messages in thread From: Tobias Burnus @ 2007-09-20 10:14 UTC (permalink / raw) To: Asher Langton; +Cc: Thomas Koenig, fortran, gcc-patches Asher Langton wrote: > Here's an updated patch. The Changelog and the tests are the same as here: > > http://gcc.gnu.org/ml/fortran/2007-08/msg00666.html > > I bootstrapped and regression tested this on x86_64-linux. Okay to commit? > Checking the interdiff, it looks good. OK for the trunk and thank you for the patch. (If one looks at a very recent thread at comp.lang.fortran, one sees that people are missing that option.) This fixes PR 20441; follow up PRs are PR33430 (optionally initialize also intent(out) variables) and PR31447 (initialize derived compounds, equivalenced variables and support sNaN). Did I miss something regarding the follow-up PRs? Tobias ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-20 10:14 ` Tobias Burnus @ 2007-09-20 20:20 ` Thomas Koenig 2007-09-20 20:22 ` FX Coudert 0 siblings, 1 reply; 20+ messages in thread From: Thomas Koenig @ 2007-09-20 20:20 UTC (permalink / raw) To: Tobias Burnus; +Cc: Asher Langton, fortran, gcc-patches On Thu, 2007-09-20 at 10:32 +0200, Tobias Burnus wrote: > This fixes PR 20441; follow up PRs are PR33430 (optionally initialize > also intent(out) variables) and PR31447 (initialize derived compounds, > equivalenced variables and support sNaN). Did I miss something regarding > the follow-up PRs? We need either to leave PR 20441 open, with a reminder that equivalenced variables still aren't initialized, or to open a new PR. Thomas ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-20 20:20 ` Thomas Koenig @ 2007-09-20 20:22 ` FX Coudert 2007-09-20 20:54 ` Thomas Koenig 0 siblings, 1 reply; 20+ messages in thread From: FX Coudert @ 2007-09-20 20:22 UTC (permalink / raw) To: Thomas Koenig; +Cc: Tobias Burnus, Asher Langton, fortran, gcc-patches >> PR31447 (initialize derived compounds, >> equivalenced variables and support sNaN) > > We need either to leave PR 20441 open, with a reminder that > equivalenced > variables still aren't initialized This seems to be in PR31447 already. FX ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-20 20:22 ` FX Coudert @ 2007-09-20 20:54 ` Thomas Koenig 2007-09-21 7:36 ` Asher Langton 0 siblings, 1 reply; 20+ messages in thread From: Thomas Koenig @ 2007-09-20 20:54 UTC (permalink / raw) To: FX Coudert; +Cc: Tobias Burnus, Asher Langton, fortran, gcc-patches On Thu, 2007-09-20 at 20:40 +0100, FX Coudert wrote: > >> PR31447 (initialize derived compounds, > >> equivalenced variables and support sNaN) > > > > We need either to leave PR 20441 open, with a reminder that > > equivalenced > > variables still aren't initialized > > This seems to be in PR31447 already. Yes, you're right. It's OK then. Thomas ^ permalink raw reply [flat|nested] 20+ messages in thread
* Re: [PATCH, fortran] PR20441 -finit-local-zero 2007-09-20 20:54 ` Thomas Koenig @ 2007-09-21 7:36 ` Asher Langton 0 siblings, 0 replies; 20+ messages in thread From: Asher Langton @ 2007-09-21 7:36 UTC (permalink / raw) To: Thomas Koenig; +Cc: FX Coudert, Tobias Burnus, fortran, gcc-patches On 9/20/07, Thomas Koenig <tkoenig@alice-dsl.net> wrote: > On Thu, 2007-09-20 at 20:40 +0100, FX Coudert wrote: > > >> PR31447 (initialize derived compounds, > > >> equivalenced variables and support sNaN) > > > > > > We need either to leave PR 20441 open, with a reminder that > > > equivalenced > > > variables still aren't initialized > > > > This seems to be in PR31447 already. > > Yes, you're right. It's OK then. Thanks Thomas, FX, and Tobias for the review. I've committed the patch and closed PR 20441. -Asher ^ permalink raw reply [flat|nested] 20+ messages in thread
end of thread, other threads:[~2007-09-21 2:40 UTC | newest] Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2007-08-17 20:12 [PATCH, fortran] PR20441 -finit-local-zero Asher Langton 2007-08-20 16:33 ` Tobias Burnus 2007-08-20 17:49 ` Asher Langton 2007-08-21 11:41 ` François-Xavier Coudert 2007-08-21 15:58 ` Tobias Schlüter 2007-08-29 2:02 ` Asher Langton 2007-08-31 22:14 ` Asher Langton 2007-09-01 20:26 ` Thomas Koenig 2007-09-14 11:27 ` Tobias Burnus 2007-09-14 11:34 ` François-Xavier Coudert 2007-09-14 13:15 ` Asher Langton [not found] ` <46E7B808.8070104@net-b.de> 2007-09-14 12:55 ` Asher Langton 2007-09-19 21:44 ` Thomas Koenig 2007-09-20 4:47 ` Asher Langton 2007-09-20 10:08 ` Asher Langton 2007-09-20 10:14 ` Tobias Burnus 2007-09-20 20:20 ` Thomas Koenig 2007-09-20 20:22 ` FX Coudert 2007-09-20 20:54 ` Thomas Koenig 2007-09-21 7:36 ` Asher Langton
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).