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] |
Hi all, Regarding blank commons in BLOCK DATA: I believe the following program is valid Fortran 95 and Fortran 2003, but gfortran currently gives "Warning: BLOCK DATA unit cannot contain blank COMMON at (1)" for: block data bd integer :: i common //i end block data bd I agree that the program is invalid as soon as "i" is initialized (e.g. "data i/5/"). NAG f95 gives a similar warning ("Warning: Blank common appears in BLOCK DATA BD"), but both do not check whether "i" is initialized. By comparison, g95 gives an error if "i" is initialized, but not if a not-initialized variable is used in a blank common. Fortran 95 ("11.4 Block data program units"): "Only an object in a named common block may be initially defined in a block data program unit." Fortran 2003 ("11.3 Block data program units"): "Only an object in a named common block may be initially defined in a block data program unit." (Note: "defined" != "specified"; "defined (2.5.5): For a data object, the property of having or being given a valid value.") On the other hand, one can argue that having COMMON blocks without initialization defeeds the purpose of block data: "A block data program unit is used to provide initial values for data objects in named common blocks." Nonetheless, I believe such programs are valid. Therefore, I think the warning can be completely removed, which I did. One could also downgrade the warning to -Wsurprising, if someone thinks that is a better solution. See also PR 29537 which introduced this warning. Comments? * * * The resolve.c part of the patch should be uncontroversial. It does: - Check also constrains for blank commons - Reject (with -std=f2003) initialized variables outside BLOCK DATA and in BLOCK DATA initialized variables in blank commons. Currently, only with -std=f95 the program is rejected, one could also follow g95 and NAG f95 and emit always an error. ifort (without -stand f95) allows such programs, however. Build and regtested on x86-64-linux; I get an ICE for common_6.f90 now also for -m32, but this is already tracked as PR33375. OK for the trunk? Tobias
2007-01-06 Tobias Burnus <burnus@net-b.de> PR fortran/34658 * match.c (gfc_match_common): Remove blank common in DATA BLOCK warning. * resolve.c (resolve_common_vars): New function. (resolve_common_blocks): Move checks to resolve_common_vars and invoke that function. (resolve_types): Call resolve_common_vars for blank commons. 2007-01-06 Tobias Burnus <burnus@net-b.de> PR fortran/34658 * gfortran.dg/common_11.f90: New. * gfortran.dg/blockdata_1.f90: Update test case. Index: gcc/fortran/match.c =================================================================== --- gcc/fortran/match.c (revision 131350) +++ gcc/fortran/match.c (working copy) @@ -2784,11 +2784,6 @@ gfc_match_common (void) if (name[0] == '\0') { - if (gfc_current_ns->is_block_data) - { - gfc_warning ("BLOCK DATA unit cannot contain blank COMMON " - "at %C"); - } t = &gfc_current_ns->blank_common; if (t->head == NULL) t->where = gfc_current_locus; Index: gcc/fortran/resolve.c =================================================================== --- gcc/fortran/resolve.c (revision 131350) +++ gcc/fortran/resolve.c (working copy) @@ -646,23 +647,27 @@ has_default_initializer (gfc_symbol *der return c != NULL; } - -/* Resolve common blocks. */ +/* Resolve common variables. */ static void -resolve_common_blocks (gfc_symtree *common_root) +resolve_common_vars (gfc_symbol *sym, bool named_common) { - gfc_symbol *sym, *csym; - - if (common_root == NULL) - return; + gfc_symbol *csym = sym; - if (common_root->left) - resolve_common_blocks (common_root->left); - if (common_root->right) - resolve_common_blocks (common_root->right); - - for (csym = common_root->n.common->head; csym; csym = csym->common_next) + for (; csym; csym = csym->common_next) { + if (csym->value || csym->attr.data) + { + if (!csym->ns->is_block_data) + gfc_notify_std (GFC_STD_GNU, "Variable '%s' at %L is in COMMON " + "but only in BLOCK DATA initialization is " + "allowed", csym->name, &csym->declared_at); + else if (!named_common) + gfc_notify_std (GFC_STD_GNU, "Initialized variable '%s' at %L is " + "in a blank COMMON but initialization is only " + "allowed in named common blocks", csym->name, + &csym->declared_at); + } + if (csym->ts.type != BT_DERIVED) continue; @@ -680,6 +685,23 @@ resolve_common_blocks (gfc_symtree *comm "may not have default initializer", csym->name, &csym->declared_at); } +} + +/* Resolve common blocks. */ +static void +resolve_common_blocks (gfc_symtree *common_root) +{ + gfc_symbol *sym; + + if (common_root == NULL) + return; + + if (common_root->left) + resolve_common_blocks (common_root->left); + if (common_root->right) + resolve_common_blocks (common_root->right); + + resolve_common_vars (common_root->n.common->head, true); gfc_find_symbol (common_root->name, gfc_current_ns, 0, &sym); if (sym == NULL) @@ -8931,6 +8957,7 @@ resolve_types (gfc_namespace *ns) resolve_entries (ns); + resolve_common_vars (ns->blank_common.head, false); resolve_common_blocks (ns->common_root); resolve_contained_functions (ns); Index: gcc/testsuite/gfortran.dg/common_11.f90 =================================================================== --- gcc/testsuite/gfortran.dg/common_11.f90 (revision 0) +++ gcc/testsuite/gfortran.dg/common_11.f90 (revision 0) @@ -0,0 +1,30 @@ +! { dg-do compile } +! +! PR fortran/34658 +! +! Check for more COMMON constrains +! +block data + implicit none + integer :: x, a ! { dg-warning "Initialized variable 'a' at .1. is in a blank COMMON" } + integer :: y = 5, b = 5 ! { dg-warning "Initialized variable 'b' at .1. is in a blank COMMON" } + data x/5/, a/5/ + common // a, b + common /a/ x, y +end block data + +subroutine foo() + implicit none + type t + sequence + integer :: i = 5 + end type t + type(t) x ! { dg-error "may not have default initializer" } + common // x +end subroutine foo + +program test + implicit none + common /a/ I ! { dg-warning "in COMMON but only in BLOCK DATA initialization" } + integer :: I = 43 +end program test Index: gcc/testsuite/gfortran.dg/blockdata_1.f90 =================================================================== --- gcc/testsuite/gfortran.dg/blockdata_1.f90 (revision 131350) +++ gcc/testsuite/gfortran.dg/blockdata_1.f90 (working copy) @@ -14,7 +14,7 @@ end blockdata d1 block data d2 common /b/ u - common j ! { dg-warning "cannot contain blank COMMON" } + common j ! { dg-warning "blank COMMON but initialization is only allowed in named common" } data j /1/ end block data d2 !
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |