Commit 1107b970 by Paul Brook

decl.c (gfc_match_implicit_range): Don't use typespec.

	* decl.c (gfc_match_implicit_range): Don't use typespec.
	(gfc_match_implicit): Handle character selectors.
	* gfortran.h (gfc_set_implicit): Remove prototype.
	(gfc_add_new_implicit_range, gfc_merge_new_implicit): Update.
	* parse.c (accept_statement): Don't call gfc_set_implicit.
	* symbol.c (new_ts): Remove.
	(gfc_set_implicit_none): Use same loop bounds as other functions.
	(gfc_set_implicit): Remove.
	(gfc_clear_new_implicit, gfc_add_new_implicit_range): Only set flags.
	(gfc_merge_new_implicit): Combine with gfc_set_implicit.
testsuite/
	* gfortran.fortran-torture/compile/implicit_1.f90: New test.

From-SVN: r84063
parent 614ed70a
2004-07-04 Paul Brook <paul@codesourcery.com>
* decl.c (gfc_match_implicit_range): Don't use typespec.
(gfc_match_implicit): Handle character selectors.
* gfortran.h (gfc_set_implicit): Remove prototype.
(gfc_add_new_implicit_range, gfc_merge_new_implicit): Update.
* parse.c (accept_statement): Don't call gfc_set_implicit.
* symbol.c (new_ts): Remove.
(gfc_set_implicit_none): Use same loop bounds as other functions.
(gfc_set_implicit): Remove.
(gfc_clear_new_implicit, gfc_add_new_implicit_range): Only set flags.
(gfc_merge_new_implicit): Combine with gfc_set_implicit.
2004-06-30 Richard Henderson <rth@redhat.com> 2004-06-30 Richard Henderson <rth@redhat.com>
* match.c (var_element): Remove unused variable. * match.c (var_element): Remove unused variable.
......
...@@ -1001,7 +1001,7 @@ gfc_match_implicit_none (void) ...@@ -1001,7 +1001,7 @@ gfc_match_implicit_none (void)
/* Match the letter range(s) of an IMPLICIT statement. */ /* Match the letter range(s) of an IMPLICIT statement. */
static match static match
match_implicit_range (gfc_typespec * ts) match_implicit_range (void)
{ {
int c, c1, c2, inner; int c, c1, c2, inner;
locus cur_loc; locus cur_loc;
...@@ -1068,7 +1068,7 @@ match_implicit_range (gfc_typespec * ts) ...@@ -1068,7 +1068,7 @@ match_implicit_range (gfc_typespec * ts)
conflicts with whatever earlier IMPLICIT statements may have conflicts with whatever earlier IMPLICIT statements may have
set. This is done when we've successfully finished matching set. This is done when we've successfully finished matching
the current one. */ the current one. */
if (gfc_add_new_implicit_range (c1, c2, ts) != SUCCESS) if (gfc_add_new_implicit_range (c1, c2) != SUCCESS)
goto bad; goto bad;
} }
...@@ -1116,11 +1116,11 @@ gfc_match_implicit (void) ...@@ -1116,11 +1116,11 @@ gfc_match_implicit (void)
return MATCH_ERROR; return MATCH_ERROR;
} }
/* First cleanup. */
gfc_clear_new_implicit ();
do do
{ {
/* First cleanup. */
gfc_clear_new_implicit ();
/* A basic type is mandatory here. */ /* A basic type is mandatory here. */
m = match_type_spec (&ts, 1); m = match_type_spec (&ts, 1);
if (m == MATCH_ERROR) if (m == MATCH_ERROR)
...@@ -1129,39 +1129,56 @@ gfc_match_implicit (void) ...@@ -1129,39 +1129,56 @@ gfc_match_implicit (void)
goto syntax; goto syntax;
cur_loc = gfc_current_locus; cur_loc = gfc_current_locus;
m = match_implicit_range (&ts); m = match_implicit_range ();
if (m != MATCH_YES && ts.type == BT_CHARACTER)
{
/* looks like we are matching CHARACTER (<len>) (<range>) */
m = match_char_spec (&ts);
}
if (m == MATCH_YES) if (m == MATCH_YES)
{ {
/* Looks like we have the <TYPE> (<RANGE>). */ /* We may have <TYPE> (<RANGE>). */
gfc_gobble_whitespace (); gfc_gobble_whitespace ();
c = gfc_next_char (); c = gfc_next_char ();
if ((c == '\n') || (c == ',')) if ((c == '\n') || (c == ','))
continue; {
/* Check for CHARACTER with no length parameter. */
if (ts.type == BT_CHARACTER && !ts.cl)
{
ts.kind = gfc_default_character_kind ();
ts.cl = gfc_get_charlen ();
ts.cl->next = gfc_current_ns->cl_list;
gfc_current_ns->cl_list = ts.cl;
ts.cl->length = gfc_int_expr (1);
}
/* Record the Successful match. */
if (gfc_merge_new_implicit (&ts) != SUCCESS)
return MATCH_ERROR;
continue;
}
gfc_current_locus = cur_loc; gfc_current_locus = cur_loc;
} }
/* Last chance -- check <TYPE> (<KIND>) (<RANGE>). */ /* Discard the (incorrectly) matched range. */
m = gfc_match_kind_spec (&ts); gfc_clear_new_implicit ();
if (m == MATCH_ERROR)
goto error; /* Last chance -- check <TYPE> <SELECTOR> (<RANGE>). */
if (m == MATCH_NO) if (ts.type == BT_CHARACTER)
m = match_char_spec (&ts);
else
{ {
m = gfc_match_old_kind_spec (&ts); m = gfc_match_kind_spec (&ts);
if (m == MATCH_ERROR)
goto error;
if (m == MATCH_NO) if (m == MATCH_NO)
goto syntax; {
m = gfc_match_old_kind_spec (&ts);
if (m == MATCH_ERROR)
goto error;
if (m == MATCH_NO)
goto syntax;
}
} }
if (m == MATCH_ERROR)
goto error;
m = match_implicit_range (&ts); m = match_implicit_range ();
if (m == MATCH_ERROR) if (m == MATCH_ERROR)
goto error; goto error;
if (m == MATCH_NO) if (m == MATCH_NO)
...@@ -1172,14 +1189,12 @@ gfc_match_implicit (void) ...@@ -1172,14 +1189,12 @@ gfc_match_implicit (void)
if ((c != '\n') && (c != ',')) if ((c != '\n') && (c != ','))
goto syntax; goto syntax;
if (gfc_merge_new_implicit (&ts) != SUCCESS)
return MATCH_ERROR;
} }
while (c == ','); while (c == ',');
/* All we need to now is try to merge the new implicit types back return MATCH_YES;
into the existing types. This will fail if another implicit
type is already defined for a letter. */
return (gfc_merge_new_implicit () == SUCCESS) ?
MATCH_YES : MATCH_ERROR;
syntax: syntax:
gfc_syntax_error (ST_IMPLICIT); gfc_syntax_error (ST_IMPLICIT);
......
...@@ -1435,10 +1435,9 @@ extern int gfc_index_integer_kind; ...@@ -1435,10 +1435,9 @@ extern int gfc_index_integer_kind;
/* symbol.c */ /* symbol.c */
void gfc_clear_new_implicit (void); void gfc_clear_new_implicit (void);
try gfc_add_new_implicit_range (int, int, gfc_typespec *); try gfc_add_new_implicit_range (int, int);
try gfc_merge_new_implicit (void); try gfc_merge_new_implicit (gfc_typespec *);
void gfc_set_implicit_none (void); void gfc_set_implicit_none (void);
void gfc_set_implicit (void);
gfc_typespec *gfc_get_default_type (gfc_symbol *, gfc_namespace *); gfc_typespec *gfc_get_default_type (gfc_symbol *, gfc_namespace *);
try gfc_set_default_type (gfc_symbol *, int, gfc_namespace *); try gfc_set_default_type (gfc_symbol *, int, gfc_namespace *);
......
...@@ -1019,7 +1019,6 @@ accept_statement (gfc_statement st) ...@@ -1019,7 +1019,6 @@ accept_statement (gfc_statement st)
break; break;
case ST_IMPLICIT: case ST_IMPLICIT:
gfc_set_implicit ();
break; break;
case ST_FUNCTION: case ST_FUNCTION:
......
...@@ -96,13 +96,9 @@ static gfc_symbol *changed_syms = NULL; ...@@ -96,13 +96,9 @@ static gfc_symbol *changed_syms = NULL;
/*********** IMPLICIT NONE and IMPLICIT statement handlers ***********/ /*********** IMPLICIT NONE and IMPLICIT statement handlers ***********/
/* The following static variables hold the default types set by /* The following static variable indicates whether a particular element has
IMPLICIT statements. We have to store kind information because of been explicitly set or not. */
IMPLICIT DOUBLE PRECISION statements. IMPLICIT NONE stores a
BT_UNKNOWN into all elements. The arrays of flags indicate whether
a particular element has been explicitly set or not. */
static gfc_typespec new_ts[GFC_LETTERS];
static int new_flag[GFC_LETTERS]; static int new_flag[GFC_LETTERS];
...@@ -113,48 +109,30 @@ gfc_set_implicit_none (void) ...@@ -113,48 +109,30 @@ gfc_set_implicit_none (void)
{ {
int i; int i;
for (i = 'a'; i <= 'z'; i++) for (i = 0; i < GFC_LETTERS; i++)
{ {
gfc_clear_ts (&gfc_current_ns->default_type[i - 'a']); gfc_clear_ts (&gfc_current_ns->default_type[i]);
gfc_current_ns->set_flag[i - 'a'] = 1; gfc_current_ns->set_flag[i] = 1;
} }
} }
/* Sets the implicit types parsed by gfc_match_implicit(). */ /* Reset the implicit range flags. */
void void
gfc_set_implicit (void) gfc_clear_new_implicit (void)
{
int i;
for (i = 0; i < GFC_LETTERS; i++)
if (new_flag[i])
{
gfc_current_ns->default_type[i] = new_ts[i];
gfc_current_ns->set_flag[i] = 1;
}
}
/* Wipe anything a previous IMPLICIT statement may have tried to do. */
void gfc_clear_new_implicit (void)
{ {
int i; int i;
for (i = 0; i < GFC_LETTERS; i++) for (i = 0; i < GFC_LETTERS; i++)
{ new_flag[i] = 0;
gfc_clear_ts (&new_ts[i]);
if (new_flag[i])
new_flag[i] = 0;
}
} }
/* Prepare for a new implicit range. Sets flags in new_flag[] and /* Prepare for a new implicit range. Sets flags in new_flag[]. */
copies the typespec to new_ts[]. */
try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts) try
gfc_add_new_implicit_range (int c1, int c2)
{ {
int i; int i;
...@@ -170,7 +148,6 @@ try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts) ...@@ -170,7 +148,6 @@ try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts)
return FAILURE; return FAILURE;
} }
new_ts[i] = *ts;
new_flag[i] = 1; new_flag[i] = 1;
} }
...@@ -178,27 +155,29 @@ try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts) ...@@ -178,27 +155,29 @@ try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts)
} }
/* Add a matched implicit range for gfc_set_implicit(). An implicit /* Add a matched implicit range for gfc_set_implicit(). Check if merging
statement has been fully matched at this point. We now need to the new implicit types back into the existing types will work. */
check if merging the new implicit types back into the existing
types will work. */
try try
gfc_merge_new_implicit (void) gfc_merge_new_implicit (gfc_typespec * ts)
{ {
int i; int i;
for (i = 0; i < GFC_LETTERS; i++) for (i = 0; i < GFC_LETTERS; i++)
if (new_flag[i]) {
{ if (new_flag[i])
if (gfc_current_ns->set_flag[i]) {
{
gfc_error ("Letter %c already has an IMPLICIT type at %C",
i + 'A');
return FAILURE;
}
}
if (gfc_current_ns->set_flag[i])
{
gfc_error ("Letter %c already has an IMPLICIT type at %C",
i + 'A');
return FAILURE;
}
gfc_current_ns->default_type[i] = *ts;
gfc_current_ns->set_flag[i] = 1;
}
}
return SUCCESS; return SUCCESS;
} }
......
2004-07-03 Scott Brumbaugh <scottb.lists@verizon.net> 2004-07-04 Paul Brook <paul@codesourcery.com>
PR c++/3761 * gfortran.fortran-torture/compile/implicit_1.f90: New test.
* g++.dg/lookup/crash4.C: New test.
2004-07-03 Scott Brumbaugh <scottb.lists@verizon.net>
PR c++/3761
* g++.dg/lookup/crash4.C: New test.
2004-07-02 Zack Weinberg <zack@codesourcery.com> 2004-07-02 Zack Weinberg <zack@codesourcery.com>
......
! Test implicit character declarations.
! This requires some coordination between the typespec and variable name range
! matchers to get it right.
module implicit_1
integer, parameter :: x = 10
integer, parameter :: y = 6
integer, parameter :: z = selected_int_kind(4)
end module
subroutine foo(n)
use implicit_1
! Test various combinations with and without character length
! and type kind specifiers
implicit character(len=5) (a)
implicit character(n) (b)
implicit character*6 (c-d)
implicit character (e)
implicit character(x-y) (f)
implicit integer(z) (g)
implicit character (z)
a1 = 'Hello'
b1 = 'world'
c1 = 'wibble'
d1 = 'hmmm'
e1 = 'n'
f1 = 'test'
g1 = 1
x1 = 1.0
y1 = 2.0
z1 = 'A'
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment