Commit f11de7c5 by Tobias Burnus Committed by Tobias Burnus

re PR fortran/48858 (Incorrect error for same binding label on two generic interface specifics)

2013-05-20  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48858
        * decl.c (add_global_entry): Use nonbinding name
        only for F2003 or if no binding label exists.
        (gfc_match_entry): Update calls.
        * parse.c (gfc_global_used): Improve error message.
        (add_global_procedure): Use nonbinding name
        only for F2003 or if no binding label exists.
        (gfc_parse_file): Update call.
        * resolve.c (resolve_global_procedure): Use binding
        name when available.
        * trans-decl.c (gfc_get_extern_function_decl): Ditto.

2013-05-20  Tobias Burnus  <burnus@net-b.de>

        PR fortran/48858
        * gfortran.dg/binding_label_tests_17.f90: New.
        * gfortran.dg/binding_label_tests_18.f90: New.
        * gfortran.dg/binding_label_tests_19.f90: New.
        * gfortran.dg/binding_label_tests_20.f90: New.
        * gfortran.dg/binding_label_tests_21.f90: New.
        * gfortran.dg/binding_label_tests_22.f90: New.
        * gfortran.dg/binding_label_tests_23.f90: New.

From-SVN: r199119
parent 878cdb7b
2013-05-20 Tobias Burnus <burnus@net-b.de> 2013-05-20 Tobias Burnus <burnus@net-b.de>
PR fortran/48858 PR fortran/48858
* decl.c (add_global_entry): Use nonbinding name
only for F2003 or if no binding label exists.
(gfc_match_entry): Update calls.
* parse.c (gfc_global_used): Improve error message.
(add_global_procedure): Use nonbinding name
only for F2003 or if no binding label exists.
(gfc_parse_file): Update call.
* resolve.c (resolve_global_procedure): Use binding
name when available.
* trans-decl.c (gfc_get_extern_function_decl): Ditto.
2013-05-20 Tobias Burnus <burnus@net-b.de>
PR fortran/48858
* decl.c (gfc_match_bind_c_stmt): Add gfc_notify_std. * decl.c (gfc_match_bind_c_stmt): Add gfc_notify_std.
* match.c (gfc_match_common): Don't add commons to gsym. * match.c (gfc_match_common): Don't add commons to gsym.
* resolve.c (resolve_common_blocks): Add to gsym and * resolve.c (resolve_common_blocks): Add to gsym and
......
...@@ -5354,27 +5354,56 @@ cleanup: ...@@ -5354,27 +5354,56 @@ cleanup:
to return false upon finding an existing global entry. */ to return false upon finding an existing global entry. */
static bool 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; gfc_gsymbol *s;
enum gfc_symbol_type type; enum gfc_symbol_type type;
s = gfc_get_gsymbol(name);
type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION; type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
if (s->defined /* Only in Fortran 2003: For procedures with a binding label also the Fortran
|| (s->type != GSYM_UNKNOWN name is a global identifier. */
&& s->type != type)) if (!binding_label || gfc_notification_std (GFC_STD_F2008))
gfc_global_used(s, NULL);
else
{ {
s->type = type; s = gfc_get_gsymbol (name);
s->where = gfc_current_locus;
s->defined = 1; if (s->defined || (s->type != GSYM_UNKNOWN && s->type != type))
s->ns = gfc_current_ns; {
return true; 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) ...@@ -5502,10 +5531,6 @@ gfc_match_entry (void)
if (state == COMP_SUBROUTINE) 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); m = gfc_match_formal_arglist (entry, 0, 1);
if (m != MATCH_YES) if (m != MATCH_YES)
return MATCH_ERROR; return MATCH_ERROR;
...@@ -5527,6 +5552,11 @@ gfc_match_entry (void) ...@@ -5527,6 +5552,11 @@ gfc_match_entry (void)
return MATCH_ERROR; 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) if (!gfc_add_entry (&entry->attr, entry->name, NULL)
|| !gfc_add_subroutine (&entry->attr, entry->name, NULL)) || !gfc_add_subroutine (&entry->attr, entry->name, NULL))
return MATCH_ERROR; return MATCH_ERROR;
...@@ -5542,9 +5572,6 @@ gfc_match_entry (void) ...@@ -5542,9 +5572,6 @@ gfc_match_entry (void)
ENTRY f() RESULT (r) ENTRY f() RESULT (r)
can't be written as can't be written as
ENTRY f RESULT (r). */ ENTRY f RESULT (r). */
if (!gfc_current_ns->parent && !add_global_entry (name, 0))
return MATCH_ERROR;
old_loc = gfc_current_locus; old_loc = gfc_current_locus;
if (gfc_match_eos () == MATCH_YES) if (gfc_match_eos () == MATCH_YES)
{ {
...@@ -5593,6 +5620,10 @@ gfc_match_entry (void) ...@@ -5593,6 +5620,10 @@ gfc_match_entry (void)
entry->result = entry; 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) if (gfc_match_eos () != MATCH_YES)
......
...@@ -4232,8 +4232,12 @@ gfc_global_used (gfc_gsymbol *sym, locus *where) ...@@ -4232,8 +4232,12 @@ gfc_global_used (gfc_gsymbol *sym, locus *where)
name = NULL; name = NULL;
} }
gfc_error("Global name '%s' at %L is already being used as a %s at %L", if (sym->binding_label)
sym->name, where, name, &sym->where); gfc_error ("Global binding name '%s' at %L is already being used as a %s "
"at %L", sym->binding_label, where, name, &sym->where);
else
gfc_error ("Global name '%s' at %L is already being used as a %s at %L",
sym->name, where, name, &sym->where);
} }
...@@ -4342,22 +4346,48 @@ loop: ...@@ -4342,22 +4346,48 @@ loop:
/* Add a procedure name to the global symbol table. */ /* Add a procedure name to the global symbol table. */
static void static void
add_global_procedure (int sub) add_global_procedure (bool sub)
{ {
gfc_gsymbol *s; gfc_gsymbol *s;
s = gfc_get_gsymbol(gfc_new_block->name); /* Only in Fortran 2003: For procedures with a binding label also the Fortran
name is a global identifier. */
if (!gfc_new_block->binding_label || gfc_notification_std (GFC_STD_F2008))
{
s = gfc_get_gsymbol (gfc_new_block->name);
if (s->defined if (s->defined
|| (s->type != GSYM_UNKNOWN || (s->type != GSYM_UNKNOWN
&& s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION))) && s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION)))
gfc_global_used(s, NULL); gfc_global_used(s, NULL);
else else
{
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
s->where = gfc_current_locus;
s->defined = 1;
s->ns = gfc_current_ns;
}
}
/* Don't add the symbol multiple times. */
if (gfc_new_block->binding_label
&& (!gfc_notification_std (GFC_STD_F2008)
|| strcmp (gfc_new_block->name, gfc_new_block->binding_label) != 0))
{ {
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION; s = gfc_get_gsymbol (gfc_new_block->binding_label);
s->where = gfc_current_locus;
s->defined = 1; if (s->defined
s->ns = gfc_current_ns; || (s->type != GSYM_UNKNOWN
&& s->type != (sub ? GSYM_SUBROUTINE : GSYM_FUNCTION)))
gfc_global_used(s, NULL);
else
{
s->type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
s->binding_label = gfc_new_block->binding_label;
s->where = gfc_current_locus;
s->defined = 1;
s->ns = gfc_current_ns;
}
} }
} }
...@@ -4556,7 +4586,7 @@ loop: ...@@ -4556,7 +4586,7 @@ loop:
break; break;
case ST_SUBROUTINE: case ST_SUBROUTINE:
add_global_procedure (1); add_global_procedure (true);
push_state (&s, COMP_SUBROUTINE, gfc_new_block); push_state (&s, COMP_SUBROUTINE, gfc_new_block);
accept_statement (st); accept_statement (st);
parse_progunit (ST_NONE); parse_progunit (ST_NONE);
...@@ -4564,7 +4594,7 @@ loop: ...@@ -4564,7 +4594,7 @@ loop:
break; break;
case ST_FUNCTION: case ST_FUNCTION:
add_global_procedure (0); add_global_procedure (false);
push_state (&s, COMP_FUNCTION, gfc_new_block); push_state (&s, COMP_FUNCTION, gfc_new_block);
accept_statement (st); accept_statement (st);
parse_progunit (ST_NONE); parse_progunit (ST_NONE);
......
...@@ -2333,7 +2333,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where, ...@@ -2333,7 +2333,7 @@ resolve_global_procedure (gfc_symbol *sym, locus *where,
type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION; type = sub ? GSYM_SUBROUTINE : GSYM_FUNCTION;
gsym = gfc_get_gsymbol (sym->name); gsym = gfc_get_gsymbol (sym->binding_label ? sym->binding_label : sym->name);
if ((gsym->type != GSYM_UNKNOWN && gsym->type != type)) if ((gsym->type != GSYM_UNKNOWN && gsym->type != type))
gfc_global_used (gsym, where); gfc_global_used (gsym, where);
......
...@@ -1643,7 +1643,8 @@ gfc_get_extern_function_decl (gfc_symbol * sym) ...@@ -1643,7 +1643,8 @@ gfc_get_extern_function_decl (gfc_symbol * sym)
/* See if this is an external procedure from the same file. If so, /* See if this is an external procedure from the same file. If so,
return the backend_decl. */ return the backend_decl. */
gsym = gfc_find_gsymbol (gfc_gsym_root, sym->name); gsym = gfc_find_gsymbol (gfc_gsym_root, sym->binding_label
? sym->binding_label : sym->name);
if ((!sym->attr.use_assoc || sym->attr.if_source != IFSRC_DECL) if ((!sym->attr.use_assoc || sym->attr.if_source != IFSRC_DECL)
&& !sym->backend_decl && !sym->backend_decl
......
2013-05-20 Tobias Burnus <burnus@net-b.de> 2013-05-20 Tobias Burnus <burnus@net-b.de>
PR fortran/48858 PR fortran/48858
* gfortran.dg/binding_label_tests_17.f90: New.
* gfortran.dg/binding_label_tests_18.f90: New.
* gfortran.dg/binding_label_tests_19.f90: New.
* gfortran.dg/binding_label_tests_20.f90: New.
* gfortran.dg/binding_label_tests_21.f90: New.
* gfortran.dg/binding_label_tests_22.f90: New.
* gfortran.dg/binding_label_tests_23.f90: New.
2013-05-20 Tobias Burnus <burnus@net-b.de>
PR fortran/48858
* gfortran.dg/test_common_binding_labels.f03: Update dg-error. * gfortran.dg/test_common_binding_labels.f03: Update dg-error.
* gfortran.dg/test_common_binding_labels_2_main.f03: Ditto. * gfortran.dg/test_common_binding_labels_2_main.f03: Ditto.
* gfortran.dg/test_common_binding_labels_3_main.f03: Ditto. * gfortran.dg/test_common_binding_labels_3_main.f03: Ditto.
......
! { dg-do compile }
!
! PR fortran/48858
!
subroutine foo() bind(C, name="bar") ! { dg-error "Global binding name 'bar' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
subroutine sub() bind(C, name="bar") ! { dg-error "Global binding name 'bar' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine sub
! { dg-do compile }
!
! PR fortran/48858
!
subroutine foo() ! { dg-error "Global name 'foo' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
subroutine foo() ! { dg-error "Global name 'foo' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
! { dg-do compile }
!
! PR fortran/48858
!
subroutine foo() bind(C,name="bar")
end subroutine foo
subroutine foo() bind(C,name="sub")
end subroutine foo
! { dg-do compile }
! { dg-options "-std=f2003" }
!
! PR fortran/48858
!
subroutine foo() bind(C,name="bar") ! { dg-error "Global name 'foo' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
subroutine foo() bind(C,name="sub") ! { dg-error "Global name 'foo' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
! { dg-do compile }
!
! PR fortran/48858
!
subroutine foo() bind(C, name="bar") ! { dg-error "Global binding name 'bar' at .1. is already being used as a SUBROUTINE at .2." }
entry sub() bind(C, name="bar") ! { dg-error "Global binding name 'bar' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
! { dg-do compile }
!
! PR fortran/48858
!
subroutine foo() ! { dg-error "Global name 'foo' at .1. is already being used as a SUBROUTINE at .2." }
entry foo() ! { dg-error "Global name 'foo' at .1. is already being used as a SUBROUTINE at .2." }
end subroutine foo
! { dg-do run }
!
! PR fortran/48858
!
integer function foo(x)
integer :: x
call abort()
foo = 99
end function foo
integer function other() bind(C, name="bar")
other = 42
end function other
program test
interface
integer function foo() bind(C, name="bar")
end function foo
end interface
if (foo() /= 42) call abort() ! Ensure that the binding name is all what counts
end program test
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