diff options
Diffstat (limited to 'gcc/fortran/decl.c')
-rw-r--r-- | gcc/fortran/decl.c | 71 |
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) |