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
This commit is contained in:
parent
614ed70a59
commit
1107b970c6
@ -1,3 +1,16 @@
|
|||||||
|
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)
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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 ();
|
||||||
|
|
||||||
|
/* Last chance -- check <TYPE> <SELECTOR> (<RANGE>). */
|
||||||
|
if (ts.type == BT_CHARACTER)
|
||||||
|
m = match_char_spec (&ts);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m = gfc_match_kind_spec (&ts);
|
||||||
|
if (m == MATCH_NO)
|
||||||
|
{
|
||||||
|
m = gfc_match_old_kind_spec (&ts);
|
||||||
|
if (m == MATCH_ERROR)
|
||||||
|
goto error;
|
||||||
|
if (m == MATCH_NO)
|
||||||
|
goto syntax;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (m == MATCH_ERROR)
|
if (m == MATCH_ERROR)
|
||||||
goto error;
|
goto error;
|
||||||
if (m == MATCH_NO)
|
|
||||||
{
|
|
||||||
m = gfc_match_old_kind_spec (&ts);
|
|
||||||
if (m == MATCH_ERROR)
|
|
||||||
goto error;
|
|
||||||
if (m == MATCH_NO)
|
|
||||||
goto syntax;
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|||||||
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;
|
|||||||
|
|
||||||
/* 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)
|
|||||||
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;
|
|||||||
|
|
||||||
/*********** 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)
|
|||||||
{
|
{
|
||||||
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;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < GFC_LETTERS; i++)
|
for (i = 0; i < GFC_LETTERS; i++)
|
||||||
if (new_flag[i])
|
new_flag[i] = 0;
|
||||||
{
|
|
||||||
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. */
|
/* Prepare for a new implicit range. Sets flags in new_flag[]. */
|
||||||
void gfc_clear_new_implicit (void)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < GFC_LETTERS; i++)
|
try
|
||||||
{
|
gfc_add_new_implicit_range (int c1, int c2)
|
||||||
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
|
|
||||||
copies the typespec to new_ts[]. */
|
|
||||||
|
|
||||||
try gfc_add_new_implicit_range (int c1, int c2, gfc_typespec * ts)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
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>
|
||||||
|
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
! 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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user