This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
[Patch, fortran] PR17737 - ICE when variable appears in two datastatements
- From: Paul Thomas <paulthomas2 at wanadoo dot fr>
- To: "'fortran at gcc dot gnu dot org'" <fortran at gcc dot gnu dot org>,patch <gcc-patches at gcc dot gnu dot org>
- Date: Mon, 31 Oct 2005 16:11:12 +0100
- Subject: [Patch, fortran] PR17737 - ICE when variable appears in two datastatements
:ADDPATCH fortran:
This is the fourth contribution to the reduction of the g77 meta-bug.
This PR concerned the ICE that occurred when a variable appeared in two
DATA statements. Removing the gcc_assert allows compilation to
succeed. Many compilers only warn of this constraint. The most
economical fix replaces the gcc_assert that causes the ICE with a
standard dependent error. Notice that treatment of all double
initializations has been unified. However, the order of arrival of the
expressions differs according to whether they come from data statements
or f95-style declarations. This has been dealt with by choosing the
last initialization, either for an error or to be used for sym->result.
Whilst doing this, I noticed that the standard constraints had only
partially been applied to the DATA statement. I have therefore done
this as part of the patch. Two of the three testscases test the
constraints; one for those that are applied unconditionally and the
other for extensions, when -std=f95 is not in force.
Bootstrapped and regtested on FC3/Athlon. OK for mainline and 4.0?
Paul T
2005-10-31 Paul Thomas <pault@gcc.gnu.org>
PR fortran/17737
* data.c (gfc_assign_data_value): Remove gcc_assert that caused the ICE
and replace by a standard dependent warning/error if overwriting an
existing initialization.
* decl.c (gfc_data_variable): Remove old error for already initialized
variable and the unused error check for common block variables. Add
error for hots associated variable and standard dependent error for
common block variables, outside of blockdata.
* symbol.c (check_conflict): Add constraints for DATA statement.
2005-10-31 Paul Thomas <pault@gcc.gnu.org>
PR fortran/17737
gfortran.dg/data_initialized.f90: New test.
gfortran.dg/data_constraints_1.f90: New test.
gfortran.dg/data_constraints_2.f90: New test.
Index: gcc/gcc/fortran/data.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/data.c,v
retrieving revision 1.14
diff -c -p -r1.14 data.c
*** gcc/gcc/fortran/data.c 25 Jul 2005 07:51:06 -0000 1.14
--- gcc/gcc/fortran/data.c 31 Oct 2005 09:10:44 -0000
*************** gfc_assign_data_value (gfc_expr * lvalue
*** 315,322 ****
expr = create_character_intializer (init, last_ts, ref, rvalue);
else
{
! /* We should never be overwriting an existing initializer. */
! gcc_assert (!init);
expr = gfc_copy_expr (rvalue);
if (!gfc_compare_types (&lvalue->ts, &expr->ts))
--- 315,333 ----
expr = create_character_intializer (init, last_ts, ref, rvalue);
else
{
! /* Overwriting an existing initializer is non-standard but usually only
! provokes a warning from other compilers. */
! if (init != NULL)
! {
! /* Order in which the expressions arrive here depends on whether they
! are from data statements or F95 style declarations. Therefore,
! check which is the most recent. */
! expr = (init->where.lb->linenum > rvalue->where.lb->linenum) ?
! init : rvalue;
! gfc_notify_std (GFC_STD_GNU, "Extension: re-initialization "
! "of '%s' at %L", symbol->name, &expr->where);
! return;
! }
expr = gfc_copy_expr (rvalue);
if (!gfc_compare_types (&lvalue->ts, &expr->ts))
Index: gcc/gcc/fortran/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/decl.c,v
retrieving revision 1.50
diff -c -p -r1.50 decl.c
*** gcc/gcc/fortran/decl.c 26 Oct 2005 05:20:16 -0000 1.50
--- gcc/gcc/fortran/decl.c 31 Oct 2005 09:10:49 -0000
*************** var_element (gfc_data_variable * new)
*** 179,202 ****
sym = new->expr->symtree->n.sym;
! if(sym->value != NULL)
{
! gfc_error ("Variable '%s' at %C already has an initialization",
! sym->name);
return MATCH_ERROR;
}
! #if 0 /* TODO: Find out where to move this message */
! if (sym->attr.in_common)
! /* See if sym is in the blank common block. */
! for (t = &sym->ns->blank_common; t; t = t->common_next)
! if (sym == t->head)
! {
! gfc_error ("DATA statement at %C may not initialize variable "
! "'%s' from blank COMMON", sym->name);
! return MATCH_ERROR;
! }
! #endif
if (gfc_add_data (&sym->attr, sym->name, &new->expr->where) == FAILURE)
return MATCH_ERROR;
--- 179,197 ----
sym = new->expr->symtree->n.sym;
! if (gfc_current_ns->parent && gfc_current_ns->parent == sym->ns)
{
! gfc_error ("Host associated variable '%s' may not be in the DATA "
! "statement at %C.", sym->name);
return MATCH_ERROR;
}
! if (gfc_current_state () != COMP_BLOCK_DATA
! && sym->attr.in_common
! && gfc_notify_std (GFC_STD_GNU, "Extension: initialization of "
! "common block variable '%s' in DATA statement at %C",
! sym->name) == FAILURE)
! return MATCH_ERROR;
if (gfc_add_data (&sym->attr, sym->name, &new->expr->where) == FAILURE)
return MATCH_ERROR;
Index: gcc/gcc/fortran/symbol.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fortran/symbol.c,v
retrieving revision 1.40
diff -c -p -r1.40 symbol.c
*** gcc/gcc/fortran/symbol.c 25 Oct 2005 18:43:21 -0000 1.40
--- gcc/gcc/fortran/symbol.c 31 Oct 2005 09:10:52 -0000
*************** check_conflict (symbol_attribute * attr,
*** 264,270 ****
*function = "FUNCTION", *subroutine = "SUBROUTINE",
*dimension = "DIMENSION", *in_equivalence = "EQUIVALENCE",
*use_assoc = "USE ASSOCIATED", *cray_pointer = "CRAY POINTER",
! *cray_pointee = "CRAY POINTEE";
const char *a1, *a2;
--- 264,270 ----
*function = "FUNCTION", *subroutine = "SUBROUTINE",
*dimension = "DIMENSION", *in_equivalence = "EQUIVALENCE",
*use_assoc = "USE ASSOCIATED", *cray_pointer = "CRAY POINTER",
! *cray_pointee = "CRAY POINTEE", *data = "DATA";
const char *a1, *a2;
*************** check_conflict (symbol_attribute * attr,
*** 371,376 ****
--- 373,384 ----
conf (cray_pointee, in_common);
conf (cray_pointee, in_equivalence);
+ conf (data, dummy);
+ conf (data, function);
+ conf (data, result);
+ conf (data, allocatable);
+ conf (data, use_assoc);
+
a1 = gfc_code2string (flavors, attr->flavor);
if (attr->in_namelist
=========================data_initialized.f90=====================
! { dg-do compile }
! Tests fix for PR17737 - already initialized variable cannot appear
! in data statement
integer :: i, j = 1
data i/0/
data i/0/ ! { dg-error "already has an initialization" }
data j/2/ ! { dg-error "already has an initialization" }
end
=========================data_constraints_1.f90===================
! { dg-do compile }
! Tests standard indepedendent constraints for variables in a data statement
!
! Contributed by Paul Thomas <pault@gcc.gnu.org>
!
module global
integer n
end module global
use global
integer q
data n /0/ ! { dg-error "Cannot change attributes" }
n = 1
n = foo (n)
contains
function foo (m) result (bar)
integer p (m), bar
integer, allocatable :: l(:)
allocate (l(1))
data l /42/ ! { dg-error "conflicts with ALLOCATABLE" }
data p(1) /1/ ! { dg-error "non-constant array in DATA" }
data q /1/ ! { dg-error "Host associated variable" }
data m /1/ ! { dg-error "conflicts with DUMMY attribute" }
data bar /99/ ! { dg-error "conflicts with RESULT" }
end function foo
function foobar ()
integer foobar
data foobar /0/ ! { dg-error "conflicts with FUNCTION" }
end function foobar
end
=========================data_constraints_2.f90===================
! { dg-do compile }
! { dg-options "-std=f95" }
! Tests constraints for variables in a data statement that are commonly
! relaxed.
!
! Contributed by Paul Thomas <pault@gcc.gnu.org>
!
common // a
common /b/ c
integer d
data a /1/ ! { dg-error "common block variable" }
data c /2/ ! { dg-error "common block variable" }
data d /3/
data d /4/ ! { dg-error " re-initialization" }
end