Commit f8552cd4 by Tobias Burnus Committed by Tobias Burnus

interface.c (gfc_procedure_use): Return gfc_try instead of

2012-07-31  Tobias Burnus  <burnus@net-b.de>

        * interface.c (gfc_procedure_use): Return gfc_try instead of
        * void.
        * gfortran.h (gfc_procedure_use): Update prototype.
        * resolve.c (gfc_iso_c_func_interface): Allow noninteroperable
        procedures for c_funloc for TS29113.
        * (gfc_iso_c_sub_interface): Ditto for c_f_procpointer. Add
        diagnostic for c_ptr vs. c_funptr for c_f_(proc)pointer.

2012-07-31  Tobias Burnus  <burnus@net-b.de>

        * gfortran.dg/c_funloc_tests_6.f90: New.
        * gfortran.dg/c_funloc_tests_7.f90: New.
        * gfortran.dg/c_funloc_tests_5.f03: Compile with -std=f2003.

From-SVN: r190003
parent 4adf72f1
2012-07-31 Tobias Burnus <burnus@net-b.de>
* interface.c (gfc_procedure_use): Return gfc_try instead of void.
* gfortran.h (gfc_procedure_use): Update prototype.
* resolve.c (gfc_iso_c_func_interface): Allow noninteroperable
procedures for c_funloc for TS29113.
* (gfc_iso_c_sub_interface): Ditto for c_f_procpointer. Add
diagnostic for c_ptr vs. c_funptr for c_f_(proc)pointer.
2012-07-30 Janus Weil <janus@gcc.gnu.org> 2012-07-30 Janus Weil <janus@gcc.gnu.org>
PR fortran/51081 PR fortran/51081
......
...@@ -2849,7 +2849,7 @@ int gfc_compare_types (gfc_typespec *, gfc_typespec *); ...@@ -2849,7 +2849,7 @@ int gfc_compare_types (gfc_typespec *, gfc_typespec *);
int gfc_compare_interfaces (gfc_symbol*, gfc_symbol*, const char *, int, int, int gfc_compare_interfaces (gfc_symbol*, gfc_symbol*, const char *, int, int,
char *, int, const char *, const char *); char *, int, const char *, const char *);
void gfc_check_interfaces (gfc_namespace *); void gfc_check_interfaces (gfc_namespace *);
void gfc_procedure_use (gfc_symbol *, gfc_actual_arglist **, locus *); gfc_try gfc_procedure_use (gfc_symbol *, gfc_actual_arglist **, locus *);
void gfc_ppc_use (gfc_component *, gfc_actual_arglist **, locus *); void gfc_ppc_use (gfc_component *, gfc_actual_arglist **, locus *);
gfc_symbol *gfc_search_interface (gfc_interface *, int, gfc_symbol *gfc_search_interface (gfc_interface *, int,
gfc_actual_arglist **); gfc_actual_arglist **);
......
...@@ -2927,7 +2927,7 @@ check_intents (gfc_formal_arglist *f, gfc_actual_arglist *a) ...@@ -2927,7 +2927,7 @@ check_intents (gfc_formal_arglist *f, gfc_actual_arglist *a)
well, the actual argument list will also end up being properly well, the actual argument list will also end up being properly
sorted. */ sorted. */
void gfc_try
gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
{ {
/* Warn about calls with an implicit interface. Special case /* Warn about calls with an implicit interface. Special case
...@@ -2954,7 +2954,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) ...@@ -2954,7 +2954,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
gfc_error("The pointer object '%s' at %L must have an explicit " gfc_error("The pointer object '%s' at %L must have an explicit "
"function interface or be declared as array", "function interface or be declared as array",
sym->name, where); sym->name, where);
return; return FAILURE;
} }
if (sym->attr.allocatable && !sym->attr.external) if (sym->attr.allocatable && !sym->attr.external)
...@@ -2962,14 +2962,14 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) ...@@ -2962,14 +2962,14 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
gfc_error("The allocatable object '%s' at %L must have an explicit " gfc_error("The allocatable object '%s' at %L must have an explicit "
"function interface or be declared as array", "function interface or be declared as array",
sym->name, where); sym->name, where);
return; return FAILURE;
} }
if (sym->attr.allocatable) if (sym->attr.allocatable)
{ {
gfc_error("Allocatable function '%s' at %L must have an explicit " gfc_error("Allocatable function '%s' at %L must have an explicit "
"function interface", sym->name, where); "function interface", sym->name, where);
return; return FAILURE;
} }
for (a = *ap; a; a = a->next) for (a = *ap; a; a = a->next)
...@@ -3009,7 +3009,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) ...@@ -3009,7 +3009,7 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
&& a->expr->ts.type == BT_UNKNOWN) && a->expr->ts.type == BT_UNKNOWN)
{ {
gfc_error ("MOLD argument to NULL required at %L", &a->expr->where); gfc_error ("MOLD argument to NULL required at %L", &a->expr->where);
return; return FAILURE;
} }
/* TS 29113, C407b. */ /* TS 29113, C407b. */
...@@ -3018,19 +3018,23 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where) ...@@ -3018,19 +3018,23 @@ gfc_procedure_use (gfc_symbol *sym, gfc_actual_arglist **ap, locus *where)
{ {
gfc_error ("Assumed-rank argument requires an explicit interface " gfc_error ("Assumed-rank argument requires an explicit interface "
"at %L", &a->expr->where); "at %L", &a->expr->where);
return; return FAILURE;
} }
} }
return; return SUCCESS;
} }
if (!compare_actual_formal (ap, sym->formal, 0, sym->attr.elemental, where)) if (!compare_actual_formal (ap, sym->formal, 0, sym->attr.elemental, where))
return; return FAILURE;
if (check_intents (sym->formal, *ap) == FAILURE)
return FAILURE;
check_intents (sym->formal, *ap);
if (gfc_option.warn_aliasing) if (gfc_option.warn_aliasing)
check_some_aliasing (sym->formal, *ap); check_some_aliasing (sym->formal, *ap);
return SUCCESS;
} }
......
...@@ -3011,20 +3011,18 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args, ...@@ -3011,20 +3011,18 @@ gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args,
{ {
/* TODO: Update this error message to allow for procedure /* TODO: Update this error message to allow for procedure
pointers once they are implemented. */ pointers once they are implemented. */
gfc_error_now ("Parameter '%s' to '%s' at %L must be a " gfc_error_now ("Argument '%s' to '%s' at %L must be a "
"procedure", "procedure",
args_sym->name, sym->name, args_sym->name, sym->name,
&(args->expr->where)); &(args->expr->where));
retval = FAILURE; retval = FAILURE;
} }
else if (args_sym->attr.is_bind_c != 1) else if (args_sym->attr.is_bind_c != 1
{ && gfc_notify_std (GFC_STD_F2008_TS, "Noninteroperable "
gfc_error_now ("Parameter '%s' to '%s' at %L must be " "argument '%s' to '%s' at %L",
"BIND(C)", args_sym->name, sym->name,
args_sym->name, sym->name, &(args->expr->where)) == FAILURE)
&(args->expr->where)); retval = FAILURE;
retval = FAILURE;
}
} }
/* for c_loc/c_funloc, the new symbol is the same as the old one */ /* for c_loc/c_funloc, the new symbol is the same as the old one */
...@@ -3479,7 +3477,11 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym) ...@@ -3479,7 +3477,11 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
/* Make sure the actual arguments are in the necessary order (based on the /* Make sure the actual arguments are in the necessary order (based on the
formal args) before resolving. */ formal args) before resolving. */
gfc_procedure_use (sym, &c->ext.actual, &(c->loc)); if (gfc_procedure_use (sym, &c->ext.actual, &(c->loc)) == FAILURE)
{
c->resolved_sym = sym;
return MATCH_ERROR;
}
if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER) || if ((sym->intmod_sym_id == ISOCBINDING_F_POINTER) ||
(sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)) (sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER))
...@@ -3490,6 +3492,15 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym) ...@@ -3490,6 +3492,15 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
{ {
if (c->ext.actual != NULL && c->ext.actual->next != NULL) if (c->ext.actual != NULL && c->ext.actual->next != NULL)
{ {
if (c->ext.actual->expr->ts.type != BT_DERIVED
|| c->ext.actual->expr->ts.u.derived->intmod_sym_id
!= ISOCBINDING_PTR)
{
gfc_error ("Argument at %L to C_F_POINTER shall have the type"
" C_PTR", &c->ext.actual->expr->where);
m = MATCH_ERROR;
}
/* Make sure we got a third arg if the second arg has non-zero /* Make sure we got a third arg if the second arg has non-zero
rank. We must also check that the type and rank are rank. We must also check that the type and rank are
correct since we short-circuit this check in correct since we short-circuit this check in
...@@ -3515,7 +3526,26 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym) ...@@ -3515,7 +3526,26 @@ gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym)
} }
} }
} }
else /* ISOCBINDING_F_PROCPOINTER. */
{
if (c->ext.actual
&& (c->ext.actual->expr->ts.type != BT_DERIVED
|| c->ext.actual->expr->ts.u.derived->intmod_sym_id
!= ISOCBINDING_FUNPTR))
{
gfc_error ("Argument at %L to C_F_FUNPOINTER shall have the type "
"C_FUNPTR", &c->ext.actual->expr->where);
m = MATCH_ERROR;
}
if (c->ext.actual && c->ext.actual->next
&& !gfc_expr_attr (c->ext.actual->next->expr).is_bind_c
&& gfc_notify_std (GFC_STD_F2008_TS, "Noninteroperable "
"procedure-pointer at %L to C_F_FUNPOINTER",
&c->ext.actual->next->expr->where)
== FAILURE)
m = MATCH_ERROR;
}
if (m != MATCH_ERROR) if (m != MATCH_ERROR)
{ {
/* the 1 means to add the optional arg to formal list */ /* the 1 means to add the optional arg to formal list */
......
2012-07-31 Tobias Burnus <burnus@net-b.de>
* gfortran.dg/c_funloc_tests_6.f90: New.
* gfortran.dg/c_funloc_tests_7.f90: New.
* gfortran.dg/c_funloc_tests_5.f03: Compile with -std=f2003.
2012-07-31 Paolo Carlini <paolo.carlini@oracle.com> 2012-07-31 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/53624 PR c++/53624
......
! { dg-do compile } ! { dg-do compile }
! { dg-options "-std=f2003" }
! Test that the arg checking for c_funloc verifies the procedures are ! Test that the arg checking for c_funloc verifies the procedures are
! C interoperable. ! C interoperable.
module c_funloc_tests_5 module c_funloc_tests_5
...@@ -7,9 +8,9 @@ contains ...@@ -7,9 +8,9 @@ contains
subroutine sub0() bind(c) subroutine sub0() bind(c)
type(c_funptr) :: my_c_funptr type(c_funptr) :: my_c_funptr
my_c_funptr = c_funloc(sub1) ! { dg-error "must be BIND.C." } my_c_funptr = c_funloc(sub1) ! { dg-error "TS 29113: Noninteroperable argument" }
my_c_funptr = c_funloc(func0) ! { dg-error "must be BIND.C." } my_c_funptr = c_funloc(func0) ! { dg-error "TS 29113: Noninteroperable argument" }
end subroutine sub0 end subroutine sub0
subroutine sub1() subroutine sub1()
......
! { dg-do compile }
! { dg-options "-std=f2008" }
!
! Check relaxed TS29113 constraints for procedures
! and c_f_*pointer argument checking for c_ptr/c_funptr.
!
use iso_c_binding
implicit none
type(c_ptr) :: cp
type(c_funptr) :: cfp
interface
subroutine sub() bind(C)
end subroutine sub
end interface
integer(c_int), pointer :: int
procedure(sub), pointer :: fsub
integer, external :: noCsub
procedure(integer), pointer :: fint
cp = c_funloc (sub) ! { dg-error "Can't convert TYPE.c_funptr. to TYPE.c_ptr." })
cfp = c_loc (int) ! { dg-error "Can't convert TYPE.c_ptr. to TYPE.c_funptr." }
call c_f_pointer (cfp, int) ! { dg-error "Argument at .1. to C_F_POINTER shall have the type C_PTR" }
call c_f_procpointer (cp, fsub) ! { dg-error "Argument at .1. to C_F_FUNPOINTER shall have the type C_FUNPTR" }
cfp = c_funloc (noCsub) ! { dg-error "TS 29113: Noninteroperable argument 'nocsub' to 'c_funloc'" }
call c_f_procpointer (cfp, fint) ! { dg-error "TS 29113: Noninteroperable procedure-pointer at .1. to C_F_FUNPOINTER" }
end
! { dg-do compile }
! { dg-options "-std=f2008ts -fdump-tree-original" }
!
! Check relaxed TS29113 constraints for procedures
! and c_f_*pointer argument checking for c_ptr/c_funptr.
!
use iso_c_binding
implicit none
type(c_funptr) :: cfp
integer, external :: noCsub
procedure(integer), pointer :: fint
cfp = c_funloc (noCsub)
call c_f_procpointer (cfp, fint)
end
! { dg-final { scan-tree-dump-times "cfp =\[^;\]+ nocsub;" 1 "original" } }
! { dg-final { scan-tree-dump-times "fint =\[^;\]+ cfp;" 1 "original" } }
! { dg-final { cleanup-tree-dump "original" } }
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