diff options
author | Tobias Burnus <burnus@net-b.de> | 2013-03-25 16:40:26 +0100 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2013-03-25 16:40:26 +0100 |
commit | cadddfdda2c4a16e7fdd5f0d8d02b465caad2ad5 (patch) | |
tree | 8a59184d212dad5695956782c588f54b5ed68b53 /gcc/fortran/resolve.c | |
parent | a5a4c20a5c922f2faa66b9326b336b5d7eb5065e (diff) | |
download | gcc-cadddfdda2c4a16e7fdd5f0d8d02b465caad2ad5.zip gcc-cadddfdda2c4a16e7fdd5f0d8d02b465caad2ad5.tar.gz gcc-cadddfdda2c4a16e7fdd5f0d8d02b465caad2ad5.tar.bz2 |
re PR fortran/38536 (ICE with C_LOC in resolve.c due to not properly going through expr->ref)
2013-03-25 Tobias Burnus <burnus@net-b.de>
PR fortran/38536
PR fortran/38813
PR fortran/38894
PR fortran/39288
PR fortran/40963
PR fortran/45824
PR fortran/47023
PR fortran/47034
PR fortran/49023
PR fortran/50269
PR fortran/50612
PR fortran/52426
PR fortran/54263
PR fortran/55343
PR fortran/55444
PR fortran/55574
PR fortran/56079
PR fortran/56378
* check.c (gfc_var_strlen): Properly handle 0-sized string.
(gfc_check_c_sizeof): Use is_c_interoperable, add checks.
(is_c_interoperable, gfc_check_c_associated, gfc_check_c_f_pointer,
gfc_check_c_f_procpointer, gfc_check_c_funloc, gfc_check_c_loc): New
functions.
* expr.c (check_inquiry): Add c_sizeof, compiler_version and
compiler_options.
(gfc_check_pointer_assign): Refine function result check.
gfortran.h (gfc_isym_id): Add GFC_ISYM_C_ASSOCIATED,
GFC_ISYM_C_F_POINTER, GFC_ISYM_C_F_PROCPOINTER, GFC_ISYM_C_FUNLOC,
GFC_ISYM_C_LOC.
(iso_fortran_env_symbol, iso_c_binding_symbol): Handle
NAMED_SUBROUTINE.
(generate_isocbinding_symbol): Update prototype.
(get_iso_c_sym): Remove.
(gfc_isym_id_by_intmod, gfc_isym_id_by_intmod_sym): New prototypes.
* intrinsic.c (gfc_intrinsic_subroutine_by_id): New function.
(gfc_intrinsic_sub_interface): Use it.
(add_functions, add_subroutines): Add missing C-binding intrinsics.
(gfc_intrinsic_func_interface): Add special case for c_loc.
gfc_isym_id_by_intmod, gfc_isym_id_by_intmod_sym): New functions.
(gfc_intrinsic_func_interface, gfc_intrinsic_sub_interface): Use them.
* intrinsic.h (gfc_check_c_associated, gfc_check_c_f_pointer,
gfc_check_c_f_procpointer, gfc_check_c_funloc, gfc_check_c_loc,
gfc_resolve_c_loc, gfc_resolve_c_funloc): New prototypes.
* iresolve.c (gfc_resolve_c_loc, gfc_resolve_c_funloc): New
functions.
* iso-c-binding.def: Split PROCEDURE into NAMED_SUBROUTINE and
NAMED_FUNCTION.
* iso-fortran-env.def: Add NAMED_SUBROUTINE for completeness.
* module.c (create_intrinsic_function): Support subroutines and
derived-type results.
(use_iso_fortran_env_module): Update calls.
(import_iso_c_binding_module): Ditto; update calls to
generate_isocbinding_symbol.
* resolve.c (find_arglists): Skip for intrinsic symbols.
(gfc_resolve_intrinsic): Find intrinsic subs via id.
(is_scalar_expr_ptr, gfc_iso_c_func_interface,
set_name_and_label, gfc_iso_c_sub_interface): Remove.
(resolve_function, resolve_specific_s0): Remove calls to those.
(resolve_structure_cons): Fix handling.
* symbol.c (gen_special_c_interop_ptr): Update c_ptr/c_funptr
generation.
(gen_cptr_param, gen_fptr_param, gen_shape_param,
build_formal_args, get_iso_c_sym): Remove.
(std_for_isocbinding_symbol): Handle NAMED_SUBROUTINE.
(generate_isocbinding_symbol): Support hidden symbols and
using c_ptr/c_funptr symtrees for nullptr defs.
* target-memory.c (gfc_target_encode_expr): Fix handling
of c_ptr/c_funptr.
* trans-expr.c (conv_isocbinding_procedure): Remove.
(gfc_conv_procedure_call): Remove call to it.
(gfc_trans_subcomponent_assign, gfc_conv_expr): Update handling
of c_ptr/c_funptr.
* trans-intrinsic.c (conv_isocbinding_function,
conv_isocbinding_subroutine): New.
(gfc_conv_intrinsic_function, gfc_conv_intrinsic_subroutine):
Call them.
* trans-io.c (transfer_expr): Fix handling of c_ptr/c_funptr.
* trans-types.c (gfc_typenode_for_spec,
gfc_get_derived_type): Ditto.
(gfc_init_c_interop_kinds): Handle NAMED_SUBROUTINE.
2013-03-25 Tobias Burnus <burnus@net-b.de>
PR fortran/38536
PR fortran/38813
PR fortran/38894
PR fortran/39288
PR fortran/40963
PR fortran/45824
PR fortran/47023
PR fortran/47034
PR fortran/49023
PR fortran/50269
PR fortran/50612
PR fortran/52426
PR fortran/54263
PR fortran/55343
PR fortran/55444
PR fortran/55574
PR fortran/56079
PR fortran/56378
* gfortran.dg/c_assoc_2.f03: Update dg-error wording.
* gfortran.dg/c_f_pointer_shape_test.f90: Ditto.
* gfortran.dg/c_f_pointer_shape_tests_3.f03: Ditto.
* gfortran.dg/c_f_pointer_tests_5.f90: Ditto.
* gfortran.dg/c_funloc_tests_2.f03: Ditto.
* gfortran.dg/c_funloc_tests_5.f03: Ditto.
* gfortran.dg/c_funloc_tests_6.f90: Ditto.
* gfortran.dg/c_loc_tests_10.f03: Add -std=f2008.
* gfortran.dg/c_loc_tests_11.f03: Ditto, update dg-error.
* gfortran.dg/c_loc_tests_16.f90: Ditto.
* gfortran.dg/c_loc_tests_4.f03: Ditto.
* gfortran.dg/c_loc_tests_15.f90: Update dg-error wording.
* gfortran.dg/c_loc_tests_3.f03: Valid since F2003 TC5.
* gfortran.dg/c_loc_tests_8.f03: Ditto.
* gfortran.dg/c_ptr_tests_14.f90: Update scan-tree-dump-times.
* gfortran.dg/c_ptr_tests_15.f90: Ditto.
* gfortran.dg/c_sizeof_1.f90: Fix invalid code.
* gfortran.dg/iso_c_binding_init_expr.f03: Update dg-error wording.
* gfortran.dg/pr32601_1.f03: Ditto.
* gfortran.dg/storage_size_2.f08: Remove dg-error.
* gfortran.dg/blockdata_7.f90: New.
* gfortran.dg/c_assoc_4.f90: New.
* gfortran.dg/c_f_pointer_tests_6.f90: New.
* gfortran.dg/c_f_pointer_tests_7.f90: New.
* gfortran.dg/c_funloc_tests_8.f90: New.
* gfortran.dg/c_loc_test_17.f90: New.
* gfortran.dg/c_loc_test_18.f90: New.
* gfortran.dg/c_loc_test_19.f90: New.
* gfortran.dg/c_loc_test_20.f90: New.
* gfortran.dg/c_sizeof_5.f90: New.
* gfortran.dg/iso_c_binding_rename_3.f90: New.
* gfortran.dg/transfer_resolve_2.f90: New.
* gfortran.dg/transfer_resolve_3.f90: New.
* gfortran.dg/transfer_resolve_4.f90: New.
* gfortran.dg/pr32601.f03: Update dg-error.
* gfortran.dg/c_ptr_tests_13.f03: Update dg-error.
* gfortran.dg/c_ptr_tests_9.f03: Fix test case.
From-SVN: r197053
Diffstat (limited to 'gcc/fortran/resolve.c')
-rw-r--r-- | gcc/fortran/resolve.c | 612 |
1 files changed, 25 insertions, 587 deletions
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c index e9b6fb9..835b57f 100644 --- a/gcc/fortran/resolve.c +++ b/gcc/fortran/resolve.c @@ -520,7 +520,7 @@ static void find_arglists (gfc_symbol *sym) { if (sym->attr.if_source == IFSRC_UNKNOWN || sym->ns != gfc_current_ns - || sym->attr.flavor == FL_DERIVED) + || sym->attr.flavor == FL_DERIVED || sym->attr.intrinsic) return; resolve_formal_arglist (sym); @@ -1038,23 +1038,6 @@ resolve_structure_cons (gfc_expr *expr, int init) cons = gfc_constructor_first (expr->value.constructor); - /* See if the user is trying to invoke a structure constructor for one of - the iso_c_binding derived types. */ - if (expr->ts.type == BT_DERIVED && expr->ts.u.derived - && expr->ts.u.derived->ts.is_iso_c && cons - && (cons->expr == NULL || cons->expr->expr_type != EXPR_NULL)) - { - gfc_error ("Components of structure constructor '%s' at %L are PRIVATE", - expr->ts.u.derived->name, &(expr->where)); - return FAILURE; - } - - /* Return if structure constructor is c_null_(fun)prt. */ - if (expr->ts.type == BT_DERIVED && expr->ts.u.derived - && expr->ts.u.derived->ts.is_iso_c && cons - && cons->expr && cons->expr->expr_type == EXPR_NULL) - return SUCCESS; - /* A constructor may have references if it is the result of substituting a parameter variable. In this case we just pull out the component we want. */ @@ -1180,7 +1163,7 @@ resolve_structure_cons (gfc_expr *expr, int init) if (cons->expr->expr_type == EXPR_NULL && !(comp->attr.pointer || comp->attr.allocatable - || comp->attr.proc_pointer + || comp->attr.proc_pointer || comp->ts.f90_type == BT_VOID || (comp->ts.type == BT_CLASS && (CLASS_DATA (comp)->attr.class_pointer || CLASS_DATA (comp)->attr.allocatable)))) @@ -1562,12 +1545,20 @@ gfc_resolve_intrinsic (gfc_symbol *sym, locus *loc) gfc_find_subroutine directly to check whether it is a function or subroutine. */ - if (sym->intmod_sym_id) - isym = gfc_intrinsic_function_by_id ((gfc_isym_id) sym->intmod_sym_id); + if (sym->intmod_sym_id && sym->attr.subroutine) + { + gfc_isym_id id = gfc_isym_id_by_intmod_sym (sym); + isym = gfc_intrinsic_subroutine_by_id (id); + } + else if (sym->intmod_sym_id) + { + gfc_isym_id id = gfc_isym_id_by_intmod_sym (sym); + isym = gfc_intrinsic_function_by_id (id); + } else if (!sym->attr.subroutine) isym = gfc_find_function (sym->name); - if (isym) + if (isym && !sym->attr.subroutine) { if (sym->ts.type != BT_UNKNOWN && gfc_option.warn_surprising && !sym->attr.implicit_type) @@ -1580,7 +1571,7 @@ gfc_resolve_intrinsic (gfc_symbol *sym, locus *loc) sym->ts = isym->ts; } - else if ((isym = gfc_find_subroutine (sym->name))) + else if (isym || (isym = gfc_find_subroutine (sym->name))) { if (sym->ts.type != BT_UNKNOWN && !sym->attr.implicit_type) { @@ -2719,366 +2710,6 @@ pure_stmt_function (gfc_expr *e, gfc_symbol *sym) } -static gfc_try -is_scalar_expr_ptr (gfc_expr *expr) -{ - gfc_try retval = SUCCESS; - gfc_ref *ref; - int start; - int end; - - /* See if we have a gfc_ref, which means we have a substring, array - reference, or a component. */ - if (expr->ref != NULL) - { - ref = expr->ref; - while (ref->next != NULL) - ref = ref->next; - - switch (ref->type) - { - case REF_SUBSTRING: - if (ref->u.ss.start == NULL || ref->u.ss.end == NULL - || gfc_dep_compare_expr (ref->u.ss.start, ref->u.ss.end) != 0) - retval = FAILURE; - break; - - case REF_ARRAY: - if (ref->u.ar.type == AR_ELEMENT) - retval = SUCCESS; - else if (ref->u.ar.type == AR_FULL) - { - /* The user can give a full array if the array is of size 1. */ - if (ref->u.ar.as != NULL - && ref->u.ar.as->rank == 1 - && ref->u.ar.as->type == AS_EXPLICIT - && ref->u.ar.as->lower[0] != NULL - && ref->u.ar.as->lower[0]->expr_type == EXPR_CONSTANT - && ref->u.ar.as->upper[0] != NULL - && ref->u.ar.as->upper[0]->expr_type == EXPR_CONSTANT) - { - /* If we have a character string, we need to check if - its length is one. */ - if (expr->ts.type == BT_CHARACTER) - { - if (expr->ts.u.cl == NULL - || expr->ts.u.cl->length == NULL - || mpz_cmp_si (expr->ts.u.cl->length->value.integer, 1) - != 0) - retval = FAILURE; - } - else - { - /* We have constant lower and upper bounds. If the - difference between is 1, it can be considered a - scalar. - FIXME: Use gfc_dep_compare_expr instead. */ - start = (int) mpz_get_si - (ref->u.ar.as->lower[0]->value.integer); - end = (int) mpz_get_si - (ref->u.ar.as->upper[0]->value.integer); - if (end - start + 1 != 1) - retval = FAILURE; - } - } - else - retval = FAILURE; - } - else - retval = FAILURE; - break; - default: - retval = SUCCESS; - break; - } - } - else if (expr->ts.type == BT_CHARACTER && expr->rank == 0) - { - /* Character string. Make sure it's of length 1. */ - if (expr->ts.u.cl == NULL - || expr->ts.u.cl->length == NULL - || mpz_cmp_si (expr->ts.u.cl->length->value.integer, 1) != 0) - retval = FAILURE; - } - else if (expr->rank != 0) - retval = FAILURE; - - return retval; -} - - -/* Match one of the iso_c_binding functions (c_associated or c_loc) - and, in the case of c_associated, set the binding label based on - the arguments. */ - -static gfc_try -gfc_iso_c_func_interface (gfc_symbol *sym, gfc_actual_arglist *args, - gfc_symbol **new_sym) -{ - char name[GFC_MAX_SYMBOL_LEN + 1]; - int optional_arg = 0; - gfc_try retval = SUCCESS; - gfc_symbol *args_sym; - gfc_typespec *arg_ts; - symbol_attribute arg_attr; - - if (args->expr->expr_type == EXPR_CONSTANT - || args->expr->expr_type == EXPR_OP - || args->expr->expr_type == EXPR_NULL) - { - gfc_error ("Argument to '%s' at %L is not a variable", - sym->name, &(args->expr->where)); - return FAILURE; - } - - args_sym = args->expr->symtree->n.sym; - - /* The typespec for the actual arg should be that stored in the expr - and not necessarily that of the expr symbol (args_sym), because - the actual expression could be a part-ref of the expr symbol. */ - arg_ts = &(args->expr->ts); - arg_attr = gfc_expr_attr (args->expr); - - if (sym->intmod_sym_id == ISOCBINDING_ASSOCIATED) - { - /* If the user gave two args then they are providing something for - the optional arg (the second cptr). Therefore, set the name and - binding label to the c_associated for two cptrs. Otherwise, - set c_associated to expect one cptr. */ - if (args->next) - { - /* two args. */ - sprintf (name, "%s_2", sym->name); - optional_arg = 1; - } - else - { - /* one arg. */ - sprintf (name, "%s_1", sym->name); - optional_arg = 0; - } - - /* Get a new symbol for the version of c_associated that - will get called. */ - *new_sym = get_iso_c_sym (sym, name, NULL, optional_arg); - } - else if (sym->intmod_sym_id == ISOCBINDING_LOC - || sym->intmod_sym_id == ISOCBINDING_FUNLOC) - { - sprintf (name, "%s", sym->name); - - /* Error check the call. */ - if (args->next != NULL) - { - gfc_error_now ("More actual than formal arguments in '%s' " - "call at %L", name, &(args->expr->where)); - retval = FAILURE; - } - else if (sym->intmod_sym_id == ISOCBINDING_LOC) - { - gfc_ref *ref; - bool seen_section; - - /* Make sure we have either the target or pointer attribute. */ - if (!arg_attr.target && !arg_attr.pointer) - { - gfc_error_now ("Parameter '%s' to '%s' at %L must be either " - "a TARGET or an associated pointer", - args_sym->name, - sym->name, &(args->expr->where)); - retval = FAILURE; - } - - if (gfc_is_coindexed (args->expr)) - { - gfc_error_now ("Coindexed argument not permitted" - " in '%s' call at %L", name, - &(args->expr->where)); - retval = FAILURE; - } - - /* Follow references to make sure there are no array - sections. */ - seen_section = false; - - for (ref=args->expr->ref; ref; ref = ref->next) - { - if (ref->type == REF_ARRAY) - { - if (ref->u.ar.type == AR_SECTION) - seen_section = true; - - if (ref->u.ar.type != AR_ELEMENT) - { - gfc_ref *r; - for (r = ref->next; r; r=r->next) - if (r->type == REF_COMPONENT) - { - gfc_error_now ("Array section not permitted" - " in '%s' call at %L", name, - &(args->expr->where)); - retval = FAILURE; - break; - } - } - } - } - - if (seen_section && retval == SUCCESS) - gfc_warning ("Array section in '%s' call at %L", name, - &(args->expr->where)); - - /* See if we have interoperable type and type param. */ - if (gfc_verify_c_interop (arg_ts) == SUCCESS - || gfc_check_any_c_kind (arg_ts) == SUCCESS) - { - if (args_sym->attr.target == 1) - { - /* Case 1a, section 15.1.2.5, J3/04-007: variable that - has the target attribute and is interoperable. */ - /* Case 1b, section 15.1.2.5, J3/04-007: allocated - allocatable variable that has the TARGET attribute and - is not an array of zero size. */ - if (args_sym->attr.allocatable == 1) - { - if (args_sym->attr.dimension != 0 - && (args_sym->as && args_sym->as->rank == 0)) - { - gfc_error_now ("Allocatable variable '%s' used as a " - "parameter to '%s' at %L must not be " - "an array of zero size", - args_sym->name, sym->name, - &(args->expr->where)); - retval = FAILURE; - } - } - else - { - /* A non-allocatable target variable with C - interoperable type and type parameters must be - interoperable. */ - if (args_sym && args_sym->attr.dimension) - { - if (args_sym->as->type == AS_ASSUMED_SHAPE) - { - gfc_error ("Assumed-shape array '%s' at %L " - "cannot be an argument to the " - "procedure '%s' because " - "it is not C interoperable", - args_sym->name, - &(args->expr->where), sym->name); - retval = FAILURE; - } - else if (args_sym->as->type == AS_DEFERRED) - { - gfc_error ("Deferred-shape array '%s' at %L " - "cannot be an argument to the " - "procedure '%s' because " - "it is not C interoperable", - args_sym->name, - &(args->expr->where), sym->name); - retval = FAILURE; - } - } - - /* Make sure it's not a character string. Arrays of - any type should be ok if the variable is of a C - interoperable type. */ - if (arg_ts->type == BT_CHARACTER) - if (arg_ts->u.cl != NULL - && (arg_ts->u.cl->length == NULL - || arg_ts->u.cl->length->expr_type - != EXPR_CONSTANT - || mpz_cmp_si - (arg_ts->u.cl->length->value.integer, 1) - != 0) - && is_scalar_expr_ptr (args->expr) != SUCCESS) - { - gfc_error_now ("CHARACTER argument '%s' to '%s' " - "at %L must have a length of 1", - args_sym->name, sym->name, - &(args->expr->where)); - retval = FAILURE; - } - } - } - else if (arg_attr.pointer - && is_scalar_expr_ptr (args->expr) != SUCCESS) - { - /* Case 1c, section 15.1.2.5, J3/04-007: an associated - scalar pointer. */ - gfc_error_now ("Argument '%s' to '%s' at %L must be an " - "associated scalar POINTER", args_sym->name, - sym->name, &(args->expr->where)); - retval = FAILURE; - } - } - else - { - /* The parameter is not required to be C interoperable. If it - is not C interoperable, it must be a nonpolymorphic scalar - with no length type parameters. It still must have either - the pointer or target attribute, and it can be - allocatable (but must be allocated when c_loc is called). */ - if (args->expr->rank != 0 - && is_scalar_expr_ptr (args->expr) != SUCCESS) - { - gfc_error_now ("Parameter '%s' to '%s' at %L must be a " - "scalar", args_sym->name, sym->name, - &(args->expr->where)); - retval = FAILURE; - } - else if (arg_ts->type == BT_CHARACTER - && is_scalar_expr_ptr (args->expr) != SUCCESS) - { - gfc_error_now ("CHARACTER argument '%s' to '%s' at " - "%L must have a length of 1", - args_sym->name, sym->name, - &(args->expr->where)); - retval = FAILURE; - } - else if (arg_ts->type == BT_CLASS) - { - gfc_error_now ("Parameter '%s' to '%s' at %L must not be " - "polymorphic", args_sym->name, sym->name, - &(args->expr->where)); - retval = FAILURE; - } - } - } - else if (sym->intmod_sym_id == ISOCBINDING_FUNLOC) - { - if (args_sym->attr.flavor != FL_PROCEDURE) - { - /* TODO: Update this error message to allow for procedure - pointers once they are implemented. */ - gfc_error_now ("Argument '%s' to '%s' at %L must be a " - "procedure", - args_sym->name, sym->name, - &(args->expr->where)); - retval = FAILURE; - } - else if (args_sym->attr.is_bind_c != 1 - && gfc_notify_std (GFC_STD_F2008_TS, "Noninteroperable " - "argument '%s' to '%s' at %L", - args_sym->name, sym->name, - &(args->expr->where)) == FAILURE) - retval = FAILURE; - } - - /* for c_loc/c_funloc, the new symbol is the same as the old one */ - *new_sym = sym; - } - else - { - gfc_internal_error ("gfc_iso_c_func_interface(): Unhandled " - "iso_c_binding function: '%s'!\n", sym->name); - } - - return retval; -} - - /* Resolve a function call, which means resolving the arguments, then figuring out which entity the name refers to. */ @@ -3141,19 +2772,6 @@ resolve_function (gfc_expr *expr) inquiry_argument = false; - /* Need to setup the call to the correct c_associated, depending on - the number of cptrs to user gives to compare. */ - if (sym && sym->attr.is_iso_c == 1) - { - if (gfc_iso_c_func_interface (sym, expr->value.function.actual, &sym) - == FAILURE) - return FAILURE; - - /* Get the symtree for the new symbol (resolved func). - the old one will be freed later, when it's no longer used. */ - gfc_find_sym_tree (sym->name, sym->ns, 1, &(expr->symtree)); - } - /* Resume assumed_size checking. */ need_full_assumed_size--; @@ -3236,6 +2854,7 @@ resolve_function (gfc_expr *expr) && GENERIC_ID != GFC_ISYM_LBOUND && GENERIC_ID != GFC_ISYM_LEN && GENERIC_ID != GFC_ISYM_LOC + && GENERIC_ID != GFC_ISYM_C_LOC && GENERIC_ID != GFC_ISYM_PRESENT) { /* Array intrinsics must also have the last upper bound of an @@ -3438,190 +3057,6 @@ generic: } -/* Set the name and binding label of the subroutine symbol in the call - expression represented by 'c' to include the type and kind of the - second parameter. This function is for resolving the appropriate - version of c_f_pointer() and c_f_procpointer(). For example, a - call to c_f_pointer() for a default integer pointer could have a - name of c_f_pointer_i4. If no second arg exists, which is an error - for these two functions, it defaults to the generic symbol's name - and binding label. */ - -static void -set_name_and_label (gfc_code *c, gfc_symbol *sym, - char *name, const char **binding_label) -{ - gfc_expr *arg = NULL; - char type; - int kind; - - /* The second arg of c_f_pointer and c_f_procpointer determines - the type and kind for the procedure name. */ - arg = c->ext.actual->next->expr; - - if (arg != NULL) - { - /* Set up the name to have the given symbol's name, - plus the type and kind. */ - /* a derived type is marked with the type letter 'u' */ - if (arg->ts.type == BT_DERIVED) - { - type = 'd'; - kind = 0; /* set the kind as 0 for now */ - } - else - { - type = gfc_type_letter (arg->ts.type); - kind = arg->ts.kind; - } - - if (arg->ts.type == BT_CHARACTER) - /* Kind info for character strings not needed. */ - kind = 0; - - sprintf (name, "%s_%c%d", sym->name, type, kind); - /* Set up the binding label as the given symbol's label plus - the type and kind. */ - *binding_label = gfc_get_string ("%s_%c%d", sym->binding_label, type, - kind); - } - else - { - /* If the second arg is missing, set the name and label as - was, cause it should at least be found, and the missing - arg error will be caught by compare_parameters(). */ - sprintf (name, "%s", sym->name); - *binding_label = sym->binding_label; - } - - return; -} - - -/* Resolve a generic version of the iso_c_binding procedure given - (sym) to the specific one based on the type and kind of the - argument(s). Currently, this function resolves c_f_pointer() and - c_f_procpointer based on the type and kind of the second argument - (FPTR). Other iso_c_binding procedures aren't specially handled. - Upon successfully exiting, c->resolved_sym will hold the resolved - symbol. Returns MATCH_ERROR if an error occurred; MATCH_YES - otherwise. */ - -match -gfc_iso_c_sub_interface (gfc_code *c, gfc_symbol *sym) -{ - gfc_symbol *new_sym; - /* this is fine, since we know the names won't use the max */ - char name[GFC_MAX_SYMBOL_LEN + 1]; - const char* binding_label; - /* default to success; will override if find error */ - match m = MATCH_YES; - - /* Make sure the actual arguments are in the necessary order (based on the - formal args) before resolving. */ - 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) || - (sym->intmod_sym_id == ISOCBINDING_F_PROCPOINTER)) - { - set_name_and_label (c, sym, name, &binding_label); - - if (sym->intmod_sym_id == ISOCBINDING_F_POINTER) - { - if (c->ext.actual != NULL && c->ext.actual->next != NULL) - { - gfc_actual_arglist *arg1 = c->ext.actual; - gfc_actual_arglist *arg2 = c->ext.actual->next; - gfc_actual_arglist *arg3 = c->ext.actual->next->next; - - /* Check first argument (CPTR). */ - if (arg1->expr->ts.type != BT_DERIVED - || arg1->expr->ts.u.derived->intmod_sym_id != ISOCBINDING_PTR) - { - gfc_error ("Argument CPTR to C_F_POINTER at %L shall have " - "the type C_PTR", &arg1->expr->where); - m = MATCH_ERROR; - } - - /* Check second argument (FPTR). */ - if (arg2->expr->ts.type == BT_CLASS) - { - gfc_error ("Argument FPTR to C_F_POINTER at %L must not be " - "polymorphic", &arg2->expr->where); - m = MATCH_ERROR; - } - - /* Make sure we got a third arg (SHAPE) if the second arg has - non-zero rank. We must also check that the type and rank are - correct since we short-circuit this check in - gfc_procedure_use() (called above to sort actual args). */ - if (arg2->expr->rank != 0) - { - if (arg3 == NULL || arg3->expr == NULL) - { - m = MATCH_ERROR; - gfc_error ("Missing SHAPE argument for call to %s at %L", - sym->name, &c->loc); - } - else if (arg3->expr->ts.type != BT_INTEGER - || arg3->expr->rank != 1) - { - m = MATCH_ERROR; - gfc_error ("SHAPE argument for call to %s at %L must be " - "a rank 1 INTEGER array", sym->name, &c->loc); - } - } - } - } - 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) - { - /* the 1 means to add the optional arg to formal list */ - new_sym = get_iso_c_sym (sym, name, binding_label, 1); - - /* for error reporting, say it's declared where the original was */ - new_sym->declared_at = sym->declared_at; - } - } - else - { - /* no differences for c_loc or c_funloc */ - new_sym = sym; - } - - /* set the resolved symbol */ - if (m != MATCH_ERROR) - c->resolved_sym = new_sym; - else - c->resolved_sym = sym; - - return m; -} - - /* Resolve a subroutine call known to be specific. */ static match @@ -3629,12 +3064,6 @@ resolve_specific_s0 (gfc_code *c, gfc_symbol *sym) { match m; - if(sym->attr.is_iso_c) - { - m = gfc_iso_c_sub_interface (c,sym); - return m; - } - if (sym->attr.external || sym->attr.if_source == IFSRC_IFBODY) { if (sym->attr.dummy) @@ -8767,7 +8196,16 @@ resolve_transfer (gfc_code *code) return; } - if (derived_inaccessible (ts->u.derived)) + /* C_PTR and C_FUNPTR have private components which means they can not + be printed. However, if -std=gnu and not -pedantic, allow + the component to be printed to help debugging. */ + if (ts->u.derived->ts.f90_type == BT_VOID) + { + if (gfc_notify_std (GFC_STD_GNU, "Data transfer element at %L cannot " + "have PRIVATE components", &code->loc) == FAILURE) + return; + } + else if (derived_inaccessible (ts->u.derived)) { gfc_error ("Data transfer element at %L cannot have " "PRIVATE components",&code->loc); |