aboutsummaryrefslogtreecommitdiff
path: root/gcc/fortran/decl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r--gcc/fortran/decl.c71
1 files changed, 51 insertions, 20 deletions
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 06a049c..cb449a2 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -5354,27 +5354,56 @@ cleanup:
to return false upon finding an existing global entry. */
static bool
-add_global_entry (const char *name, int sub)
+add_global_entry (const char *name, const char *binding_label, bool sub)
{
gfc_gsymbol *s;
enum gfc_symbol_type type;
- s = gfc_get_gsymbol(name);
type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
- if (s->defined
- || (s->type != GSYM_UNKNOWN
- && s->type != type))
- gfc_global_used(s, NULL);
- else
+ /* Only in Fortran 2003: For procedures with a binding label also the Fortran
+ name is a global identifier. */
+ if (!binding_label || gfc_notification_std (GFC_STD_F2008))
{
- s->type = type;
- s->where = gfc_current_locus;
- s->defined = 1;
- s->ns = gfc_current_ns;
- return true;
+ s = gfc_get_gsymbol (name);
+
+ if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
+ {
+ gfc_global_used(s, NULL);
+ return false;
+ }
+ else
+ {
+ s->type = type;
+ s->where = gfc_current_locus;
+ s->defined = 1;
+ s->ns = gfc_current_ns;
+ }
}
- return false;
+
+ /* Don't add the symbol multiple times. */
+ if (binding_label
+ && (!gfc_notification_std (GFC_STD_F2008)
+ || strcmp (name, binding_label) != 0))
+ {
+ s = gfc_get_gsymbol (binding_label);
+
+ if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
+ {
+ gfc_global_used(s, NULL);
+ return false;
+ }
+ else
+ {
+ s->type = type;
+ s->binding_label = binding_label;
+ s->where = gfc_current_locus;
+ s->defined = 1;
+ s->ns = gfc_current_ns;
+ }
+ }
+
+ return true;
}
@@ -5502,10 +5531,6 @@ gfc_match_entry (void)
if (state == COMP_SUBROUTINE)
{
- /* An entry in a subroutine. */
- if (!gfc_current_ns->parent && !add_global_entry (name, 1))
- return MATCH_ERROR;
-
m = gfc_match_formal_arglist (entry, 0, 1);
if (m != MATCH_YES)
return MATCH_ERROR;
@@ -5527,6 +5552,11 @@ gfc_match_entry (void)
return MATCH_ERROR;
}
+ if (!gfc_current_ns->parent
+ && !add_global_entry (name, entry->binding_label, true))
+ return MATCH_ERROR;
+
+ /* An entry in a subroutine. */
if (!gfc_add_entry (&entry->attr, entry->name, NULL)
|| !gfc_add_subroutine (&entry->attr, entry->name, NULL))
return MATCH_ERROR;
@@ -5542,9 +5572,6 @@ gfc_match_entry (void)
ENTRY f() RESULT (r)
can't be written as
ENTRY f RESULT (r). */
- if (!gfc_current_ns->parent && !add_global_entry (name, 0))
- return MATCH_ERROR;
-
old_loc = gfc_current_locus;
if (gfc_match_eos () == MATCH_YES)
{
@@ -5593,6 +5620,10 @@ gfc_match_entry (void)
entry->result = entry;
}
}
+
+ if (!gfc_current_ns->parent
+ && !add_global_entry (name, entry->binding_label, false))
+ return MATCH_ERROR;
}
if (gfc_match_eos () != MATCH_YES)