diff options
author | kargl <kargl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-07-02 02:47:21 +0000 |
---|---|---|
committer | kargl <kargl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-07-02 02:47:21 +0000 |
commit | c5d33754e3b885a5a2f323bedaa29371f44748b3 (patch) | |
tree | ac4b8eff52a0e3e3d04868300cc36392b6ca3faa /gcc/testsuite/gfortran.dg | |
parent | af1ff7da323f7dda32e4b0e7bda1d43fa4654252 (diff) | |
download | gcc-c5d33754e3b885a5a2f323bedaa29371f44748b3.tar.gz |
2007-07-01 Christopher D. Rickett <crickett@lanl.gov>
* interface.c (gfc_compare_derived_types): Special case for comparing
derived types across namespaces.
(gfc_compare_types): Deal with BT_VOID.
(compare_parameter): Use BT_VOID to accept ISO C Binding pointers.
* trans-expr.c (gfc_conv_function_call): Remove setting parm_kind
to SCALAR
(gfc_conv_initializer): Deal with ISO C Binding NULL_PTR and
NULL_FUNPTR.
(gfc_conv_expr): Convert expressions for ISO C Binding derived types.
* symbol.c (gfc_set_default_type): BIND(C) variables should not be
implicitly declared.
(check_conflict): Add BIND(C) and check for conflicts.
(gfc_add_explicit_interface): Whitespace.
(gfc_add_is_bind_c): New function.
(gfc_copy_attr): Use it.
(gfc_new_symbol): Initialize ISO C Binding objects.
(get_iso_c_binding_dt): New function.
(verify_bind_c_derived_type): Ditto.
(gen_special_c_interop_ptr): Ditto.
(add_formal_arg): Ditto.
(gen_cptr_param): Ditto.
(gen_fptr_param): Ditto.
(gen_shape_param): Ditto.
(add_proc_interface): Ditto.
(build_formal_args): Ditto.
(generate_isocbinding_symbol): Ditto.
(get_iso_c_sym): Ditto.
* decl.c (num_idents_on_line, has_name_equals): New variables.
(verify_c_interop_param): New function.
(build_sym): Finish binding labels and deal with COMMON blocks.
(add_init_expr_to_sym): Check if the initialized expression is
an iso_c_binding named constants
(variable_decl): Set ISO C Binding type_spec components.
(gfc_match_kind_spec): Check match for C interoperable kind.
(match_char_spec): Fix comment. Chnage gfc_match_small_int
to gfc_match_small_int_expr. Check for C interoperable kind.
(match_type_spec): Clear the current binding label.
(match_attr_spec): Add DECL_IS_BIND_C. If BIND(C) is found, use it
to set attributes.
(set_binding_label): New function.
(set_com_block_bind_c): Ditto.
(verify_c_interop): Ditto.
(verify_com_block_vars_c_interop): Ditto.
(verify_bind_c_sym): Ditto.
(set_verify_bind_c_sym): Ditto.
(set_verify_bind_c_com_block): Ditto.
(get_bind_c_idents): Ditto.
(gfc_match_bind_c_stmt): Ditto.
(gfc_match_data_decl): Use num_idents_on_line.
(match_result): Deal with right paren in BIND(C).
(gfc_match_suffix): New function.
(gfc_match_function_decl): Use it. Code is re-arranged to deal with
ISO C Binding result clauses.
(gfc_match_subroutine): Deal with BIND(C).
(gfc_match_bind_c): New function.
(gfc_get_type_attr_spec): New function. Code is re-arranged in and
taken from gfc_match_derived_decl.
(gfc_match_derived_decl): Add check for BIND(C).
* trans-common.c: Forward declare gfc_get_common.
(gfc_sym_mangled_common_id): Change arg from 'const char *name' to
'gfc_common_head *com'. Check for ISO C Binding of the common block.
(build_common_decl): 'com->name' to 'com in SET_DECL_ASSEMBLER_NAME.
* gfortran.h: Add GFC_MAX_BINDING_LABEL_LEN
(bt): Add BT_VOID
(sym_flavor): Add FL_VOID.
(iso_fortran_env_symbol, iso_c_binding_symbol, intmod_id): New enum
(CInteropKind_t): New struct.
(c_interop_kinds_table): Use it. Declare an array of structs.
(symbol_attribute): Add is_bind_c, is_c_interop, and is_iso_c
bitfields.
(gfc_typespec): Add is_c_interop; is_iso_c, and f90_type members.
(gfc_symbol): Add from_intmod, intmod_sym_id, binding_label, and
common_block members.
(gfc_common_head): Add binding_label and is_bind_c members.
(gfc_gsymbol): Add sym_name, mod_name, and binding_label members.
Add prototypes for get_c_kind, gfc_validate_c_kind,
gfc_check_any_c_kind, gfc_add_is_bind_c, gfc_add_value,
verify_c_interop, verify_c_interop_param, verify_bind_c_sym,
verify_bind_c_derived_type, verify_com_block_vars_c_interop,
generate_isocbinding_symbol, get_iso_c_sym, gfc_iso_c_sub_interface
* iso-c-binding.def: New file. This file contains the definitions
of the types provided by the Fortran 2003 ISO_C_BINDING intrinsic
module.
* trans-const.c (gfc_conv_constant_to_tree): Deal with C_NULL_PTR
or C_NULL_FUNPTR expressions.
* expr.c (gfc_copy_expr): Add BT_VOID case. For BT_CHARACTER, the
ISO C Binding requires a minimum string length of 1 for '\0'.
* module.c (intmod_sym): New struct.
(pointer_info): Add binding_label member.
(write_atom): Set len to 0 for NULL pointers. Check for NULL p and *p.
(ab_attribute): Add AB_IS_BIND_C, AB_IS_C_INTEROP and AB_IS_ISO_C.
(attr_bits): Add "IS_BIND_C", "IS_C_INTEROP", and "IS_ISO_C".
(mio_symbol_attribute): Deal with ISO C Binding attributes.
(bt_types): Add "VOID".
(mio_typespec): Deal with ISO C Binding components.
(mio_namespace_ref): Add intmod variable.
(mio_symbol): Check for symbols from an intrinsic module.
(load_commons): Check for BIND(C) common block.
(read_module): Read binding_label and use it.
(write_common): Add label. Write BIND(C) info.
(write_blank_common): Blank commons are not BIND(C). Explicitly
set is_bind_c=0.
(write_symbol): Deal with binding_label.
(sort_iso_c_rename_list): New function.
(import_iso_c_binding_module): Ditto.
(create_int_parameter): Add to args.
(use_iso_fortran_env_module): Adjust to deal with iso_c_binding
intrinsic module.
* trans-types.c (c_interop_kinds_table): new array of structs.
(gfc_validate_c_kind): New function.
(gfc_check_any_c_kind): Ditto.
(get_real_kind_from_node): Ditto.
(get_int_kind_from_node): Ditto.
(get_int_kind_from_width): Ditto.
(get_int_kind_from_minimal_width): Ditto.
(init_c_interop_kinds): Ditto.
(gfc_init_kinds): call init_c_interop_kinds.
(gfc_typenode_for_spec): Adjust for BT_VOID and ISO C Binding pointers.
Adjust handling of BT_DERIVED.
(gfc_sym_type): Whitespace.
(gfc_get_derived_type): Account for iso_c_binding derived types
* resolve.c (is_scalar_expr_ptr): New function.
(gfc_iso_c_func_interface): Ditto.
(resolve_function): Use gfc_iso_c_func_interface.
(set_name_and_label): New function.
(gfc_iso_c_sub_interface): Ditto.
(resolve_specific_s0): Use gfc_iso_c_sub_interface.
(resolve_bind_c_comms): New function.
(resolve_bind_c_derived_types): Ditto.
(gfc_verify_binding_labels): Ditto.
(resolve_fl_procedure): Check for ISO C interoperability.
(resolve_symbol): Check C interoperability.
(resolve_types): Walk the namespace. Check COMMON blocks.
* trans-decl.c (gfc_sym_mangled_identifier): Prevent the mangling
of identifiers that have an assigned binding label.
(gfc_sym_mangled_function_id): Use the binding label rather than
the mangled name.
(gfc_finish_var_decl): Put variables that are BIND(C) into a common
segment of the object file, because this is what C would do.
(gfc_create_module_variable): Conver to proper types
(set_tree_decl_type_code): New function.
(generate_local_decl): Check dummy variables and derived types for
ISO C Binding attributes.
* match.c (gfc_match_small_int_expr): New function.
(gfc_match_name_C): Ditto.
(match_common_name): Deal with ISO C Binding in COMMON blocks
* trans-io.c (transfer_expr): Deal with C_NULL_PTR or C_NULL_FUNPTR
expressions
* match.h: Add prototypes for gfc_match_small_int_expr,
gfc_match_name_C, match_common_name, set_com_block_bind_c,
set_binding_label, set_verify_bind_c_sym,
set_verify_bind_c_com_block, get_bind_c_idents,
gfc_match_bind_c_stmt, gfc_match_suffix, gfc_match_bind_c,
gfc_get_type_attr_spec
* parse.c (decode_statement): Use gfc_match_bind_c_stmt
(parse_derived): Init *derived_sym = NULL, and gfc_current_block
later for valiadation.
* primary.c (got_delim): Set ISO C Binding components of ts.
(match_logical_constant): Ditto.
(match_complex_constant): Ditto.
(match_complex_constant): Ditto.
(gfc_match_rvalue): Check for existence of at least one arg for
C_LOC, C_FUNLOC, and C_ASSOCIATED.
* misc.c (gfc_clear_ts): Clear ISO C Bindoing components in ts.
(get_c_kind): New function.
2007-07-01 Christopher D. Rickett <crickett@lanl.gov>
* Makefile.in: Add support for iso_c_generated_procs.c and
iso_c_binding.c.
* Makefile.am: Ditto.
* intrinsics/iso_c_generated_procs.c: New file containing helper
functions.
* intrinsics/iso_c_binding.c: Ditto.
* intrinsics/iso_c_binding.h: New file
* gfortran.map: Include the __iso_c_binding_c_* functions.
* libgfortran.h: define GFC_NUM_RANK_BITS.
2007-06-23 Christopher D. Rickett <crickett@lanl.gov>
* bind_c_array_params.f03: New files for Fortran 2003 ISO C Binding.
* bind_c_coms.f90: Ditto.
* bind_c_coms_driver.c: Ditto.
* bind_c_dts.f90: Ditto.
* bind_c_dts_2.f03: Ditto.
* bind_c_dts_2_driver.c: Ditto.
* bind_c_dts_3.f03: Ditto.
* bind_c_dts_4.f03: Ditto.
* bind_c_dts_driver.c: Ditto.
* bind_c_implicit_vars.f03: Ditto.
* bind_c_procs.f03: Ditto.
* bind_c_usage_2.f03: Ditto.
* bind_c_usage_3.f03: Ditto.
* bind_c_usage_5.f03: Ditto.
* bind_c_usage_6.f03: Ditto.
* bind_c_usage_7.f03: Ditto.
* bind_c_vars.f90: Ditto.
* bind_c_vars_driver.c: Ditto.
* binding_c_table_15_1.f03: Ditto.
* binding_label_tests.f03: Ditto.
* binding_label_tests_10.f03: Ditto.
* binding_label_tests_10_main.f03: Ditto.
* binding_label_tests_11.f03: Ditto.
* binding_label_tests_11_main.f03: Ditto.
* binding_label_tests_12.f03: Ditto.
* binding_label_tests_13.f03: Ditto.
* binding_label_tests_13_main.f03: Ditto.
* binding_label_tests_14.f03: Ditto.
* binding_label_tests_2.f03: Ditto.
* binding_label_tests_3.f03: Ditto.
* binding_label_tests_4.f03: Ditto.
* binding_label_tests_5.f03: Ditto.
* binding_label_tests_6.f03: Ditto.
* binding_label_tests_7.f03: Ditto.
* binding_label_tests_8.f03: Ditto.
* binding_label_tests_9.f03: Ditto.
* c_assoc.f90: Ditto.
* c_assoc_2.f03: Ditto.
* c_f_pointer_shape_test.f90: Ditto.
* c_f_pointer_tests.f90: Ditto.
* c_f_tests_driver.c: Ditto.
* c_funloc_tests.f03: Ditto.
* c_funloc_tests_2.f03: Ditto.
* c_funloc_tests_3.f03: Ditto.
* c_funloc_tests_3_funcs.c: Ditto.
* c_kind_params.f90: Ditto.
* c_kind_tests_2.f03: Ditto.
* c_kinds.c: Ditto.
* c_loc_driver.c: Ditto.
* c_loc_test.f90: Ditto.
* c_loc_tests_2.f03: Ditto.
* c_loc_tests_2_funcs.c: Ditto.
* c_loc_tests_3.f03: Ditto.
* c_loc_tests_4.f03: Ditto.
* c_loc_tests_5.f03: Ditto.
* c_loc_tests_6.f03: Ditto.
* c_loc_tests_7.f03: Ditto.
* c_loc_tests_8.f03: Ditto.
* c_ptr_tests.f03: Ditto.
* c_ptr_tests_10.f03: Ditto.
* c_ptr_tests_5.f03: Ditto.
* c_ptr_tests_7.f03: Ditto.
* c_ptr_tests_7_driver.c: Ditto.
* c_ptr_tests_8.f03: Ditto.
* c_ptr_tests_8_funcs.c: Ditto.
* c_ptr_tests_9.f03: Ditto.
* c_ptr_tests_driver.c: Ditto.
* c_size_t_driver.c: Ditto.
* c_size_t_test.f03: Ditto.
* com_block_driver.f90: Ditto.
* global_vars_c_init.f90: Ditto.
* global_vars_c_init_driver.c: Ditto.
* global_vars_f90_init.f90: Ditto.
* global_vars_f90_init_driver.c: Ditto.
* interop_params.f03: Ditto.
* iso_c_binding_only.f03: Ditto.
* iso_c_binding_rename_1.f03: Ditto.
* iso_c_binding_rename_1_driver.c: Ditto.
* iso_c_binding_rename_2.f03: Ditto.
* iso_c_binding_rename_2_driver.c: Ditto.
* kind_tests_2.f03: Ditto.
* kind_tests_3.f03: Ditto.
* module_md5_1.f90: Ditto.
* only_clause_main.c: Ditto.
* print_c_kinds.f90: Ditto.
* test_bind_c_parens.f03: Ditto.
* test_c_assoc.c: Ditto.
* test_com_block.f90: Ditto.
* test_common_binding_labels.f03: Ditto.
* test_common_binding_labels_2.f03: Ditto.
* test_common_binding_labels_2_main.f03: Ditto.
* test_common_binding_labels_3.f03: Ditto.
* test_common_binding_labels_3_main.f03: Ditto.
* test_only_clause.f90: Ditto.
* use_iso_c_binding.f90: Ditto.
* value_5.f90: Ditto.
* value_test.f90: Ditto.
* value_tests_f03.f90: Ditto.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@126185 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/testsuite/gfortran.dg')
98 files changed, 2705 insertions, 1 deletions
diff --git a/gcc/testsuite/gfortran.dg/bind_c_array_params.f03 b/gcc/testsuite/gfortran.dg/bind_c_array_params.f03 new file mode 100644 index 00000000000..6590db1d1d6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_array_params.f03 @@ -0,0 +1,14 @@ +! { dg-do compile } +module bind_c_array_params +use, intrinsic :: iso_c_binding +implicit none + +contains + subroutine sub0(assumed_array) bind(c) ! { dg-error "cannot be an argument" } + integer(c_int), dimension(:) :: assumed_array + end subroutine sub0 + + subroutine sub1(deferred_array) bind(c) ! { dg-error "cannot" } + integer(c_int), pointer :: deferred_array(:) + end subroutine sub1 +end module bind_c_array_params diff --git a/gcc/testsuite/gfortran.dg/bind_c_coms.f90 b/gcc/testsuite/gfortran.dg/bind_c_coms.f90 new file mode 100644 index 00000000000..e88d56d182c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_coms.f90 @@ -0,0 +1,51 @@ +! { dg-do run } +! { dg-additional-sources bind_c_coms_driver.c } +! { dg-options "-w" } +! the -w option is to prevent the warning about long long ints +module bind_c_coms + use, intrinsic :: iso_c_binding + implicit none + + common /COM/ R, S + real(c_double) :: r + real(c_double) :: t + real(c_double) :: s + bind(c) :: /COM/, /SINGLE/, /MYCOM/ + common /SINGLE/ T + common /MYCOM/ LONG_INTS + integer(c_long) :: LONG_INTS + common /MYCOM2/ LONG_LONG_INTS + integer(c_long_long) :: long_long_ints + bind(c) :: /mycom2/ + + common /com2/ i, j + integer(c_int) :: i, j + bind(c, name="f03_com2") /com2/ + + common /com3/ m, n + integer(c_int) :: m, n + bind(c, name="") /com3/ + +contains + subroutine test_coms() bind(c) + r = r + .1d0; + s = s + .1d0; + t = t + .1d0; + long_ints = long_ints + 1 + long_long_ints = long_long_ints + 1 + i = i + 1 + j = j + 1 + + m = 1 + n = 1 + end subroutine test_coms +end module bind_c_coms + +module bind_c_coms_2 + use, intrinsic :: iso_c_binding, only: c_int + common /com3/ m, n + integer(c_int) :: m, n + bind(c, name="") /com3/ +end module bind_c_coms_2 + +! { dg-final { cleanup-modules "bind_c_coms bind_c_coms_2" } } diff --git a/gcc/testsuite/gfortran.dg/bind_c_coms_driver.c b/gcc/testsuite/gfortran.dg/bind_c_coms_driver.c new file mode 100644 index 00000000000..c83f22d836f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_coms_driver.c @@ -0,0 +1,42 @@ +double fabs(double); + +void test_coms(void); + +extern void abort(void); + +struct {double r, s; } com; /* refers to the common block "com" */ +double single; /* refers to the common block "single" */ +long int mycom; /* refers to the common block "MYCOM" */ +long long int mycom2; /* refers to the common block "MYCOM2" */ +struct {int i, j; } f03_com2; /* refers to the common block "com2" */ + +int main(int argc, char **argv) +{ + com.r = 1.0; + com.s = 2.0; + single = 1.0; + mycom = 1; + mycom2 = 2; + f03_com2.i = 1; + f03_com2.j = 2; + + /* change the common block variables in F90 */ + test_coms(); + + if(fabs(com.r - 1.1) > 0.00000000) + abort(); + if(fabs(com.s - 2.1) > 0.00000000) + abort(); + if(fabs(single - 1.1) > 0.00000000) + abort(); + if(mycom != 2) + abort(); + if(mycom2 != 3) + abort(); + if(f03_com2.i != 2) + abort(); + if(f03_com2.j != 3) + abort(); + + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts.f90 b/gcc/testsuite/gfortran.dg/bind_c_dts.f90 new file mode 100644 index 00000000000..f78630ba560 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts.f90 @@ -0,0 +1,41 @@ +! { dg-do run } +! { dg-additional-sources bind_c_dts_driver.c } +module bind_c_dts + use, intrinsic :: iso_c_binding + implicit none + + type, bind(c) :: MYFTYPE_1 + integer(c_int) :: i, j + real(c_float) :: s + end type MYFTYPE_1 + + TYPE, BIND(C) :: particle + REAL(C_DOUBLE) :: x,vx + REAL(C_DOUBLE) :: y,vy + REAL(C_DOUBLE) :: z,vz + REAL(C_DOUBLE) :: m + END TYPE particle + + type(myftype_1), bind(c, name="myDerived") :: myDerived + +contains + subroutine types_test(my_particles, num_particles) bind(c) + integer(c_int), value :: num_particles + type(particle), dimension(num_particles) :: my_particles + integer :: i + + ! going to set the particle in the middle of the list + i = num_particles / 2; + my_particles(i)%x = my_particles(i)%x + .2d0 + my_particles(i)%vx = my_particles(i)%vx + .2d0 + my_particles(i)%y = my_particles(i)%y + .2d0 + my_particles(i)%vy = my_particles(i)%vy + .2d0 + my_particles(i)%z = my_particles(i)%z + .2d0 + my_particles(i)%vz = my_particles(i)%vz + .2d0 + my_particles(i)%m = my_particles(i)%m + .2d0 + + myDerived%i = myDerived%i + 1 + myDerived%j = myDerived%j + 1 + myDerived%s = myDerived%s + 1.0; + end subroutine types_test +end module bind_c_dts diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_2.f03 b/gcc/testsuite/gfortran.dg/bind_c_dts_2.f03 new file mode 100644 index 00000000000..4e5e61b4ee8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_2.f03 @@ -0,0 +1,61 @@ +! { dg-do run } +! { dg-additional-sources bind_c_dts_2_driver.c } +module bind_c_dts_2 +use, intrinsic :: iso_c_binding +implicit none + +type, bind(c) :: my_c_type_0 + integer(c_int) :: i + type(c_ptr) :: nested_c_address + integer(c_int) :: array(3) +end type my_c_type_0 + +type, bind(c) :: my_c_type_1 + type(my_c_type_0) :: my_nested_type + type(c_ptr) :: c_address + integer(c_int) :: j +end type my_c_type_1 + +contains + subroutine sub0(my_type, expected_i, expected_nested_c_address, & + expected_array_1, expected_array_2, expected_array_3, & + expected_c_address, expected_j) bind(c) + type(my_c_type_1) :: my_type + integer(c_int), value :: expected_i + type(c_ptr), value :: expected_nested_c_address + integer(c_int), value :: expected_array_1 + integer(c_int), value :: expected_array_2 + integer(c_int), value :: expected_array_3 + type(c_ptr), value :: expected_c_address + integer(c_int), value :: expected_j + + if (my_type%my_nested_type%i .ne. expected_i) then + call abort () + end if + + if (.not. c_associated(my_type%my_nested_type%nested_c_address, & + expected_nested_c_address)) then + call abort () + end if + + if (my_type%my_nested_type%array(1) .ne. expected_array_1) then + call abort () + end if + + if (my_type%my_nested_type%array(2) .ne. expected_array_2) then + call abort () + end if + + if (my_type%my_nested_type%array(3) .ne. expected_array_3) then + call abort () + end if + + if (.not. c_associated(my_type%c_address, expected_c_address)) then + call abort () + end if + + if (my_type%j .ne. expected_j) then + call abort () + end if + end subroutine sub0 +end module bind_c_dts_2 diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_2_driver.c b/gcc/testsuite/gfortran.dg/bind_c_dts_2_driver.c new file mode 100644 index 00000000000..53d26794e3f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_2_driver.c @@ -0,0 +1,37 @@ +typedef struct c_type_0 +{ + int i; + int *ptr; + int array[3]; +}c_type_0_t; + +typedef struct c_type_1 +{ + c_type_0_t nested_type; + int *ptr; + int j; +}c_type_1_t; + +void sub0(c_type_1_t *c_type, int expected_i, int *expected_nested_ptr, + int array_0, int array_1, int array_2, + int *expected_ptr, int expected_j); + +int main(int argc, char **argv) +{ + c_type_1_t c_type; + + c_type.nested_type.i = 10; + c_type.nested_type.ptr = &(c_type.nested_type.i); + c_type.nested_type.array[0] = 1; + c_type.nested_type.array[1] = 2; + c_type.nested_type.array[2] = 3; + c_type.ptr = &(c_type.j); + c_type.j = 11; + + sub0(&c_type, c_type.nested_type.i, c_type.nested_type.ptr, + c_type.nested_type.array[0], + c_type.nested_type.array[1], c_type.nested_type.array[2], + c_type.ptr, c_type.j); + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_3.f03 b/gcc/testsuite/gfortran.dg/bind_c_dts_3.f03 new file mode 100644 index 00000000000..6c6da9f5785 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_3.f03 @@ -0,0 +1,39 @@ +! { dg-do compile } +module bind_c_dts_3 +use, intrinsic :: iso_c_binding +implicit none + +TYPE, bind(c) :: t + integer(c_int) :: i +end type t + +type :: my_c_type_0 ! { dg-error "must have the BIND attribute" } + integer(c_int) :: i +end type my_c_type_0 + +type, bind(c) :: my_c_type_1 ! { dg-error "BIND.C. derived type" } + type(my_c_type_0) :: my_nested_type + type(c_ptr) :: c_address + integer(c_int), pointer :: j ! { dg-error "cannot have the POINTER" } +end type my_c_type_1 + +type, bind(c) :: t2 ! { dg-error "BIND.C. derived type" } + type (t2), pointer :: next ! { dg-error "cannot have the POINTER" } +end type t2 + +type, bind(c):: t3 ! { dg-error "BIND.C. derived type" } + type(t), allocatable :: c(:) ! { dg-error "cannot have the ALLOCATABLE" } +end type t3 + +contains + subroutine sub0(my_type, expected_value) bind(c) ! { dg-error "is not C interoperable" } + type(my_c_type_1) :: my_type + integer(c_int), value :: expected_value + + if (my_type%my_nested_type%i .ne. expected_value) then + call abort () + end if + end subroutine sub0 +end module bind_c_dts_3 + +! { dg-final { cleanup-modules "bind_c_dts_3" } } diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 b/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 new file mode 100644 index 00000000000..b2eb5694f1c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 @@ -0,0 +1,10 @@ +! { dg-do compile } +module test +use iso_c_binding, only: c_int + type, bind(c) :: foo + integer :: p ! { dg-warning "may not be C interoperable" } + end type + type(foo), bind(c) :: cp +end module test + +! { dg-final { cleanup-modules "test" } } diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_driver.c b/gcc/testsuite/gfortran.dg/bind_c_dts_driver.c new file mode 100644 index 00000000000..bf076ce4a40 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_driver.c @@ -0,0 +1,66 @@ +double fabs (double); + +/* interops with myftype_1 */ +typedef struct { + int m, n; + float r; +} myctype_t; + +/* interops with particle in f90 */ +typedef struct particle +{ + double x; /* x position */ + double vx; /* velocity in x direction */ + double y; /* y position */ + double vy; /* velocity in y direction */ + double z; /* z position */ + double vz; /* velocity in z direction */ + double m; /* mass */ +}particle_t; + +extern void abort(void); +void types_test(particle_t *my_particles, int num_particles); +/* declared in the fortran module bind_c_dts */ +extern myctype_t myDerived; + +int main(int argc, char **argv) +{ + particle_t my_particles[100]; + + /* the fortran code will modify the middle particle */ + my_particles[49].x = 1.0; + my_particles[49].vx = 1.0; + my_particles[49].y = 1.0; + my_particles[49].vy = 1.0; + my_particles[49].z = 1.0; + my_particles[49].vz = 1.0; + my_particles[49].m = 1.0; + + myDerived.m = 1; + myDerived.n = 2; + myDerived.r = 3.0; + + types_test(&(my_particles[0]), 100); + + if(fabs(my_particles[49].x - 1.2) > 0.00000000) + abort(); + if(fabs(my_particles[49].vx - 1.2) > 0.00000000) + abort(); + if(fabs(my_particles[49].y - 1.2) > 0.00000000) + abort(); + if(fabs(my_particles[49].vy - 1.2) > 0.00000000) + abort(); + if(fabs(my_particles[49].z - 1.2) > 0.00000000) + abort(); + if(fabs(my_particles[49].vz - 1.2) > 0.00000000) + abort(); + if(fabs(my_particles[49].m - 1.2) > 0.00000000) + abort(); + if(myDerived.m != 2) + abort(); + if(myDerived.n != 3) + abort(); + if(fabs(myDerived.r - 4.0) > 0.00000000) + abort(); + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 b/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 new file mode 100644 index 00000000000..ff284ce3346 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 @@ -0,0 +1,10 @@ +! { dg-do compile } +module bind_c_implicit_vars + +bind(c) :: j ! { dg-warning "may not be C interoperable" } + +contains + subroutine sub0(i) bind(c) ! { dg-warning "may not be C interoperable" } + i = 0 + end subroutine sub0 +end module bind_c_implicit_vars diff --git a/gcc/testsuite/gfortran.dg/bind_c_procs.f03 b/gcc/testsuite/gfortran.dg/bind_c_procs.f03 new file mode 100644 index 00000000000..718042bafcb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_procs.f03 @@ -0,0 +1,39 @@ +! { dg-do compile } +module bind_c_procs + use, intrinsic :: iso_c_binding, only: c_int + + interface + ! warning for my_param possibly not being C interoperable + subroutine my_c_sub(my_param) bind(c) ! { dg-warning "may not be C interoperable" } + integer, value :: my_param + end subroutine my_c_sub + + ! warning for my_c_func possibly not being a C interoperable kind + ! warning for my_param possibly not being C interoperable + ! error message truncated to provide an expression that both warnings + ! should match. + function my_c_func(my_param) bind(c) ! { dg-warning "may not be" } + integer, value :: my_param + integer :: my_c_func + end function my_c_func + end interface + +contains + ! warning for my_param possibly not being C interoperable + subroutine my_f03_sub(my_param) bind(c) ! { dg-warning "may not be" } + integer, value :: my_param + end subroutine my_f03_sub + + ! warning for my_f03_func possibly not being a C interoperable kind + ! warning for my_param possibly not being C interoperable + ! error message truncated to provide an expression that both warnings + ! should match. + function my_f03_func(my_param) bind(c) ! { dg-warning "may not be" } + integer, value :: my_param + integer :: my_f03_func + my_f03_func = 1 + end function my_f03_func + +end module bind_c_procs + +! { dg-final { cleanup-modules "bind_c_procs" } } diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_2.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_2.f03 new file mode 100644 index 00000000000..e76215e7f2b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_2.f03 @@ -0,0 +1,15 @@ +! { dg-do compile } +use, intrinsic :: iso_c_binding +type, bind(c) :: mytype + integer(c_int) :: j +end type mytype + +type(mytype), bind(c) :: mytype_var ! { dg-error "cannot be BIND.C." } + +integer(c_int), bind(c) :: i ! { dg-error "cannot be declared with BIND.C." } +integer(c_int), bind(c), dimension(10) :: my_array ! { dg-error "cannot be BIND.C." } + +common /COM/ i +bind(c) :: /com/ + +end diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_3.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_3.f03 new file mode 100644 index 00000000000..47f9d9a9218 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_3.f03 @@ -0,0 +1,19 @@ +! { dg-do compile } +module test + use, intrinsic :: iso_c_binding + + type, bind(c) :: my_c_type ! { dg-error "BIND.C. derived type" } + integer(c_int), pointer :: ptr ! { dg-error "cannot have the POINTER attribute" } + end type my_c_type + + type, bind(c) :: my_type ! { dg-error "BIND.C. derived type" } + integer(c_int), allocatable :: ptr(:) ! { dg-error "cannot have the ALLOCATABLE attribute" } + end type my_type + + type foo ! { dg-error "must have the BIND attribute" } + integer(c_int) :: p + end type foo + + type(foo), bind(c) :: cp ! { dg-error "is not C interoperable" } + real(c_double), pointer,bind(c) :: p ! { dg-error "cannot have both the POINTER and BIND.C." } +end module test diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_5.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_5.f03 new file mode 100644 index 00000000000..95afa010fb1 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_5.f03 @@ -0,0 +1,8 @@ +! { dg-do compile } +module bind_c_usage_5 +use, intrinsic :: iso_c_binding + +bind(c) c3, c4 +integer(c_int), bind(c) :: c3 ! { dg-error "Duplicate BIND attribute" } +integer(c_int) :: c4 +end module bind_c_usage_5 diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_6.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_6.f03 new file mode 100644 index 00000000000..924dd40bc69 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_6.f03 @@ -0,0 +1,48 @@ +! { dg-do compile } +module x + use iso_c_binding + bind(c) :: test, sub1 ! { dg-error "only be used for variables or common blocks" } + bind(c) :: sub2 ! { dg-error "only be used for variables or common blocks" } +contains + function foo() bind(c,name="xx") + integer(c_int),bind(c,name="xy") :: foo ! { dg-error "only be used for variables or common blocks" } + ! NAG f95: "BIND(C) for non-variable FOO" + ! g95: "Duplicate BIND attribute specified" + ! gfortran: Accepted + foo = 5_c_int + end function foo + + function test() + integer(c_int) :: test + bind(c,name="kk") :: test ! { dg-error "only be used for variables or common blocks" } + ! NAG f95: "BIND(C) for non-variable TEST" + ! gfortran, g95: Accepted + test = 5_c_int + end function test + + function bar() bind(c) + integer(c_int) :: bar + bind(c,name="zx") :: bar ! { dg-error "only be used for variables or common blocks" } + bar = 5_c_int + end function bar + + subroutine sub0() bind(c) + bind(c) :: sub0 ! { dg-error "only be used for variables or common blocks" } + end subroutine sub0 + + subroutine sub1(i) bind(c) + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int), value :: i + end subroutine sub1 + + subroutine sub2(i) + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int), value :: i + end subroutine sub2 + + subroutine sub3(i) + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int), value :: i + bind(c) :: sub3 ! { dg-error "only be used for variables or common blocks" } + end subroutine sub3 +end module x diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_7.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_7.f03 new file mode 100644 index 00000000000..845aab95322 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_7.f03 @@ -0,0 +1,16 @@ +! { dg-do compile } +module x + use iso_c_binding + implicit none +contains + function bar() bind(c) ! { dg-error "cannot be an array" } + integer(c_int) :: bar(5) + end function bar + + function my_string_func() bind(c) ! { dg-error "cannot be a character string" } + character(kind=c_char, len=10) :: my_string_func + my_string_func = 'my_string' // C_NULL_CHAR + end function my_string_func +end module x + +! { dg-final { cleanup-modules "x" } } diff --git a/gcc/testsuite/gfortran.dg/bind_c_vars.f90 b/gcc/testsuite/gfortran.dg/bind_c_vars.f90 new file mode 100644 index 00000000000..4f4a0cfd795 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_vars.f90 @@ -0,0 +1,38 @@ +! { dg-do run } +! { dg-additional-sources bind_c_vars_driver.c } +module bind_c_vars + use, intrinsic :: iso_c_binding + implicit none + + integer(c_int), bind(c) :: myF90Int + real(c_float), bind(c, name="myF90Real") :: f90_real + integer(c_int) :: c2 + integer(c_int) :: c3 + integer(c_int) :: c4 + bind(c, name="myVariable") :: c2 + bind(c) c3, c4 + + integer(c_int), bind(c, name="myF90Array3D") :: A(18, 3:7, 10) + integer(c_int), bind(c, name="myF90Array2D") :: B(3, 2) + +contains + + subroutine changeF90Globals() bind(c, name='changeF90Globals') + implicit none + ! should make it 2 + myF90Int = myF90Int + 1 + ! should make it 3.0 + f90_real = f90_real * 3.0; + ! should make it 4 + c2 = c2 * 2; + ! should make it 6 + c3 = c3 + 3; + ! should make it 2 + c4 = c4 / 2; + ! should make it 2 + A(5, 6, 3) = A(5, 6, 3) + 1 + ! should make it 3 + B(3, 2) = B(3, 2) + 1 + end subroutine changeF90Globals + +end module bind_c_vars diff --git a/gcc/testsuite/gfortran.dg/bind_c_vars_driver.c b/gcc/testsuite/gfortran.dg/bind_c_vars_driver.c new file mode 100644 index 00000000000..2af800a15c2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_vars_driver.c @@ -0,0 +1,46 @@ +double fabs (double); + +/* defined in fortran module bind_c_vars */ +void changeF90Globals(void); + +extern void abort(void); + +/* module level scope in bind_c_vars */ +extern int myf90int; /* myf90int in bind_c_vars */ +float myF90Real; /* f90_real in bind_c_vars */ +int myF90Array3D[10][5][18]; /* A in bind_c_vars */ +int myF90Array2D[2][3]; /* B in bind_c_vars */ +int myVariable; /* c2 in bind_c_vars */ +int c3; /* c3 in bind_c_vars */ +int c4; /* c4 in bind_c_vars */ + +int main(int argc, char **argv) +{ + myf90int = 1; + myF90Real = 1.0; + myVariable = 2; + c3 = 3; + c4 = 4; + myF90Array3D[2][3][4] = 1; + myF90Array2D[1][2] = 2; + + /* will change the global vars initialized above */ + changeF90Globals(); + + if(myf90int != 2) + abort(); + if(fabs(myF90Real-3.0) > 0.00000000) + abort(); + if(myVariable != 4) + abort(); + if(c3 != 6) + abort(); + if(c4 != 2) + abort(); + if(myF90Array3D[2][3][4] != 2) + abort(); + if(myF90Array2D[1][2] != 3) + abort(); + + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/binding_c_table_15_1.f03 b/gcc/testsuite/gfortran.dg/binding_c_table_15_1.f03 new file mode 100644 index 00000000000..a5573092d85 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_c_table_15_1.f03 @@ -0,0 +1,14 @@ +! { dg-do run } +! Test the named constants in Table 15.1. +program a + use, intrinsic :: iso_c_binding + implicit none + if (C_NULL_CHAR /= CHAR(0) ) call abort + if (C_ALERT /= ACHAR(7) ) call abort + if (C_BACKSPACE /= ACHAR(8) ) call abort + if (C_FORM_FEED /= ACHAR(12)) call abort + if (C_NEW_LINE /= ACHAR(10)) call abort + if (C_CARRIAGE_RETURN /= ACHAR(13)) call abort + if (C_HORIZONTAL_TAB /= ACHAR(9) ) call abort + if (C_VERTICAL_TAB /= ACHAR(11)) call abort +end program a diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests.f03 new file mode 100644 index 00000000000..34986501e29 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests.f03 @@ -0,0 +1,77 @@ +! { dg-do compile } +module binding_label_tests + use, intrinsic :: iso_c_binding + implicit none + + contains + + subroutine c_sub() BIND(c, name = "C_Sub") + print *, 'hello from c_sub' + end subroutine c_sub + + integer(c_int) function c_func() bind(C, name="__C_funC") + print *, 'hello from c_func' + c_func = 1 + end function c_func + + real(c_float) function f90_func() + print *, 'hello from f90_func' + f90_func = 1.0 + end function f90_func + + real(c_float) function c_real_func() bind(c) + print *, 'hello from c_real_func' + c_real_func = 1.5 + end function c_real_func + + integer function f90_func_0() result ( f90_func_0_result ) + print *, 'hello from f90_func_0' + f90_func_0_result = 0 + end function f90_func_0 + + integer(c_int) function f90_func_1() result ( f90_func_1_result ) bind(c, name="__F90_Func_1__") + print *, 'hello from f90_func_1' + f90_func_1_result = 1 + end function f90_func_1 + + integer(c_int) function f90_func_3() result ( f90_func_3_result ) bind(c) + print *, 'hello from f90_func_3' + f90_func_3_result = 3 + end function f90_func_3 + + integer(c_int) function F90_func_2() bind(c) result ( f90_func_2_result ) + print *, 'hello from f90_func_2' + f90_func_2_result = 2 + end function f90_func_2 + + integer(c_int) function F90_func_4() bind(c, name="F90_func_4") result ( f90_func_4_result ) + print *, 'hello from f90_func_4' + f90_func_4_result = 4 + end function f90_func_4 + + integer(c_int) function F90_func_5() bind(c, name="F90_func_5") result ( f90_func_5_result ) + print *, 'hello from f90_func_5' + f90_func_5_result = 5 + end function f90_func_5 + + subroutine c_sub_2() bind(c, name='c_sub_2') + print *, 'hello from c_sub_2' + end subroutine c_sub_2 + + subroutine c_sub_3() BIND(c, name = " C_Sub_3 ") + print *, 'hello from c_sub_3' + end subroutine c_sub_3 + + subroutine c_sub_5() BIND(c, name = "C_Sub_5 ") + print *, 'hello from c_sub_5' + end subroutine c_sub_5 + + ! nothing between the quotes except spaces, so name="". + ! the name will get set to the regularly mangled version of the name. + ! perhaps it should be marked with some characters that are invalid for + ! C names so C can not call it? + subroutine sub4() BIND(c, name = " ") + end subroutine sub4 +end module binding_label_tests + +! { dg-final { cleanup-modules "binding_label_tests" } } diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_10.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_10.f03 new file mode 100644 index 00000000000..99c9c527624 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_10.f03 @@ -0,0 +1,10 @@ +! { dg-do compile } +! This file must be compiled BEFORE binding_label_tests_10_main.f03, which it +! should be because dejagnu will sort the files. +module binding_label_tests_10 + use iso_c_binding + implicit none + integer(c_int), bind(c,name="c_one") :: one +end module binding_label_tests_10 + +! Do not use dg-final to cleanup-modules diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03 new file mode 100644 index 00000000000..aa24a6ac1d6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f03 @@ -0,0 +1,15 @@ +! { dg-do compile } +! This file must be compiled AFTER binding_label_tests_10.f03, which it +! should be because dejagnu will sort the files. +module binding_label_tests_10_main + use iso_c_binding + implicit none + integer(c_int), bind(c,name="c_one") :: one ! { dg-error "collides" } +end module binding_label_tests_10_main + +program main + use binding_label_tests_10 ! { dg-error "collides" } + use binding_label_tests_10_main +end program main + +! { dg-final { cleanup-modules "binding_label_tests_10_main binding_label_tests_10" } } diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_11.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_11.f03 new file mode 100644 index 00000000000..5e889a7886e --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_11.f03 @@ -0,0 +1,14 @@ +! { dg-do compile } +! This file must be compiled BEFORE binding_label_tests_11_main.f03, which it +! should be because dejagnu will sort the files. +module binding_label_tests_11 + use iso_c_binding, only: c_int + implicit none +contains + function one() bind(c, name="c_one") + integer(c_int) one + one = 1 + end function one +end module binding_label_tests_11 + +! Do not use dg-final to cleanup-modules diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_11_main.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_11_main.f03 new file mode 100644 index 00000000000..53eac7cf546 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_11_main.f03 @@ -0,0 +1,19 @@ +! { dg-do compile } +! This file must be compiled AFTER binding_label_tests_11.f03, which it +! should be because dejagnu will sort the files. +module binding_label_tests_11_main + use iso_c_binding, only: c_int + implicit none +contains + function one() bind(c, name="c_one") ! { dg-error "collides" } + integer(c_int) one + one = 1 + end function one +end module binding_label_tests_11_main + +program main + use binding_label_tests_11 ! { dg-error "collides" } + use binding_label_tests_11_main +end program main + +! { dg-final { cleanup-modules "binding_label_tests_11_main binding_label_tests_11" } } diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_12.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_12.f03 new file mode 100644 index 00000000000..0a000668115 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_12.f03 @@ -0,0 +1,24 @@ +! { dg-do run } +! This verifies that the compiler will correctly accpet the name="", write out +! an empty string for the binding label to the module file, and then read it +! back in. Also, during gfc_verify_binding_labels, the name="" will prevent +! any verification (since there is no label to verify). +module one +contains + subroutine foo() bind(c) + end subroutine foo +end module one + +module two +contains + ! This procedure is only used accessed in C + ! as procedural pointer + subroutine foo() bind(c, name="") + end subroutine foo +end module two + +use one, only: foo_one => foo +use two, only: foo_two => foo +end + +! { dg-final { cleanup-modules "one two" } } diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_13.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_13.f03 new file mode 100644 index 00000000000..786945d3af7 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_13.f03 @@ -0,0 +1,8 @@ +! { dg-do compile } +! This file must be compiled BEFORE binding_label_tests_13_main.f03, which it +! should be because dejagnu will sort the files. +module binding_label_tests_13 + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int) :: c3 + bind(c) c3 +end module binding_label_tests_13 diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_13_main.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_13_main.f03 new file mode 100644 index 00000000000..1addc9c495c --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_13_main.f03 @@ -0,0 +1,16 @@ +! { dg-do compile } +! This file must be compiled AFTER binding_label_tests_13.f03, which it +! should be because dejagnu will sort the files. The module file +! binding_label_tests_13.mod can not be removed until after this test is done. +module binding_label_tests_13_main + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int) :: c3 ! { dg-error "collides" } + bind(c) c3 + +contains + subroutine c_sub() BIND(c, name = "C_Sub") + use binding_label_tests_13 ! { dg-error "collides" } + end subroutine c_sub +end module binding_label_tests_13_main +! { dg-final { cleanup-modules "binding_label_tests_13 binding_label_tests_13_main" } } + diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_14.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_14.f03 new file mode 100644 index 00000000000..041237bbee5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_14.f03 @@ -0,0 +1,12 @@ +! { dg-do run } +subroutine display() bind(c) + implicit none +end subroutine display + +program main + implicit none + interface + subroutine display() bind(c) + end subroutine display + end interface +end program main diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_2.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_2.f03 new file mode 100644 index 00000000000..bf9da112ab4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_2.f03 @@ -0,0 +1,35 @@ +! { dg-do compile } +module binding_label_tests_2 + +contains + ! this is just here so at least one of the subroutines will be accepted so + ! gfortran doesn't give an Extension warning when using -pedantic-errors + subroutine ok() + end subroutine ok + + subroutine sub0() bind(c, name=" 1") ! { dg-error "Invalid C name" } + end subroutine sub0 ! { dg-error "Expecting END MODULE" } + + subroutine sub1() bind(c, name="$") ! { dg-error "Invalid C name" } + end subroutine sub1 ! { dg-error "Expecting END MODULE" } + + subroutine sub2() bind(c, name="abc$") ! { dg-error "Invalid C name" } + end subroutine sub2 ! { dg-error "Expecting END MODULE" } + + subroutine sub3() bind(c, name="abc d") ! { dg-error "Embedded space" } + end subroutine sub3 ! { dg-error "Expecting END MODULE" } + + subroutine sub5() BIND(C, name=" myvar 2 ") ! { dg-error "Embedded space" } + end subroutine sub5 ! { dg-error "Expecting END MODULE" } + + subroutine sub6() bind(c, name=" ) ! { dg-error "Invalid C name" } + end subroutine sub6 ! { dg-error "Expecting END MODULE" } + + subroutine sub7() bind(c, name=) ! { dg-error "Syntax error" } + end subroutine sub7 ! { dg-error "Expecting END MODULE" } + + subroutine sub8() bind(c, name) ! { dg-error "Syntax error" } + end subroutine sub8 ! { dg-error "Expecting END MODULE" } +end module binding_label_tests_2 + +! { dg-final { cleanup-modules "binding_label_tests_2" } } diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_3.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_3.f03 new file mode 100644 index 00000000000..6e124470251 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_3.f03 @@ -0,0 +1,30 @@ +! { dg-do compile } +program main +use iso_c_binding + interface + subroutine p1(f, a1, a2, a3, a4) bind(c, name='printf') ! { dg-error "collides" } + import :: c_ptr, c_int, c_double + type(c_ptr), value :: f + integer(c_int), value :: a1, a3 + real(c_double), value :: a2, a4 + end subroutine p1 + + subroutine p2(f, a1, a2, a3, a4) bind(c, name='printf') ! { dg-error "collides" } + import :: c_ptr, c_int, c_double + type(c_ptr), value :: f + real(c_double), value :: a1, a3 + integer(c_int), value :: a2, a4 + end subroutine p2 + end interface + + type(c_ptr) :: f_ptr + character(len=20), target :: format + + f_ptr = c_loc(format(1:1)) + + format = 'Hello %d %f %d %f\n' // char(0) + call p1(f_ptr, 10, 1.23d0, 20, 2.46d0) + + format = 'World %f %d %f %d\n' // char(0) + call p2(f_ptr, 1.23d0, 10, 2.46d0, 20) +end program main diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_4.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_4.f03 new file mode 100644 index 00000000000..5a0767d8785 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_4.f03 @@ -0,0 +1,24 @@ +! { dg-do compile } +module A + use, intrinsic :: iso_c_binding +contains + subroutine pA() bind(c, name='printf') ! { dg-error "collides" } + print *, 'hello from pA' + end subroutine pA +end module A + +module B + use, intrinsic :: iso_c_binding + +contains + subroutine pB() bind(c, name='printf') ! { dg-error "collides" } + print *, 'hello from pB' + end subroutine pB +end module B + +module C +use A +use B ! { dg-error "Can't open module file" } +end module C + + diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_5.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_5.f03 new file mode 100644 index 00000000000..c8aa4e86218 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_5.f03 @@ -0,0 +1,12 @@ +! { dg-do compile } +module binding_label_tests_5 + use, intrinsic :: iso_c_binding + + interface + subroutine sub0() bind(c, name='c_sub') ! { dg-error "collides" } + end subroutine sub0 + + subroutine sub1() bind(c, name='c_sub') ! { dg-error "collides" } + end subroutine sub1 + end interface +end module binding_label_tests_5 diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_6.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_6.f03 new file mode 100644 index 00000000000..0784de12e29 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_6.f03 @@ -0,0 +1,6 @@ +! { dg-do compile } +module binding_label_tests_6 + use, intrinsic :: iso_c_binding + integer(c_int), bind(c, name='my_int') :: my_f90_int_1 ! { dg-error "collides" } + integer(c_int), bind(c, name='my_int') :: my_f90_int_2 ! { dg-error "collides" } +end module binding_label_tests_6 diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_7.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_7.f03 new file mode 100644 index 00000000000..1234bb53538 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_7.f03 @@ -0,0 +1,15 @@ +! { dg-do compile } +module A + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int), bind(c, name='my_c_print') :: my_int ! { dg-error "collides" } +end module A + +program main +use A +interface + subroutine my_c_print() bind(c) ! { dg-error "collides" } + end subroutine my_c_print +end interface + +call my_c_print() +end program main diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_8.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_8.f03 new file mode 100644 index 00000000000..c49ee625458 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_8.f03 @@ -0,0 +1,9 @@ +! { dg-do compile } +module binding_label_tests_8 + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int), bind(c, name='my_f90_sub') :: my_c_int ! { dg-error "collides" } + +contains + subroutine my_f90_sub() bind(c) ! { dg-error "collides" } + end subroutine my_f90_sub +end module binding_label_tests_8 diff --git a/gcc/testsuite/gfortran.dg/binding_label_tests_9.f03 b/gcc/testsuite/gfortran.dg/binding_label_tests_9.f03 new file mode 100644 index 00000000000..0f50a08b7e0 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/binding_label_tests_9.f03 @@ -0,0 +1,23 @@ +! { dg-do compile } +module x + use iso_c_binding + implicit none + private :: bar ! { dg-warning "PRIVATE but has been given the binding label" } + private :: my_private_sub + private :: my_private_sub_2 ! { dg-warning "PRIVATE but has been given the binding label" } + public :: my_public_sub +contains + subroutine bar() bind(c,name="foo") + end subroutine bar + + subroutine my_private_sub() bind(c, name="") + end subroutine my_private_sub + + subroutine my_private_sub_2() bind(c) + end subroutine my_private_sub_2 + + subroutine my_public_sub() bind(c, name="my_sub") + end subroutine my_public_sub +end module x + +! { dg-final { cleanup-modules "x" } } diff --git a/gcc/testsuite/gfortran.dg/c_assoc.f90 b/gcc/testsuite/gfortran.dg/c_assoc.f90 new file mode 100644 index 00000000000..9b2af24f984 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_assoc.f90 @@ -0,0 +1,68 @@ +! { dg-do run } +! { dg-additional-sources test_c_assoc.c } +module c_assoc + use, intrinsic :: iso_c_binding + implicit none + +contains + + function test_c_assoc_0(my_c_ptr) bind(c) + use, intrinsic :: iso_c_binding, only: c_ptr, c_int, c_associated + integer(c_int) :: test_c_assoc_0 + type(c_ptr), value :: my_c_ptr + + if(c_associated(my_c_ptr)) then + test_c_assoc_0 = 1 + else + test_c_assoc_0 = 0 + endif + end function test_c_assoc_0 + + function test_c_assoc_1(my_c_ptr_1, my_c_ptr_2) bind(c) + use, intrinsic :: iso_c_binding, only: c_ptr, c_int, c_associated + integer(c_int) :: test_c_assoc_1 + type(c_ptr), value :: my_c_ptr_1 + type(c_ptr), value :: my_c_ptr_2 + + if(c_associated(my_c_ptr_1, my_c_ptr_2)) then + test_c_assoc_1 = 1 + else + test_c_assoc_1 = 0 + endif + end function test_c_assoc_1 + + function test_c_assoc_2(my_c_ptr_1, my_c_ptr_2, num_ptrs) bind(c) + integer(c_int) :: test_c_assoc_2 + type(c_ptr), value :: my_c_ptr_1 + type(c_ptr), value :: my_c_ptr_2 + integer(c_int), value :: num_ptrs + + if(num_ptrs .eq. 1) then + if(c_associated(my_c_ptr_1)) then + test_c_assoc_2 = 1 + else + test_c_assoc_2 = 0 + endif + else + if(c_associated(my_c_ptr_1, my_c_ptr_2)) then + test_c_assoc_2 = 1 + else + test_c_assoc_2 = 0 + endif + endif + end function test_c_assoc_2 + + subroutine verify_assoc(my_c_ptr_1, my_c_ptr_2) bind(c) + type(c_ptr), value :: my_c_ptr_1 + type(c_ptr), value :: my_c_ptr_2 + + if(.not. c_associated(my_c_ptr_1)) then + call abort() + else if(.not. c_associated(my_c_ptr_2)) then + call abort() + else if(.not. c_associated(my_c_ptr_1, my_c_ptr_2)) then + call abort() + endif + end subroutine verify_assoc + +end module c_assoc diff --git a/gcc/testsuite/gfortran.dg/c_assoc_2.f03 b/gcc/testsuite/gfortran.dg/c_assoc_2.f03 new file mode 100644 index 00000000000..9bb2f1b6abc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_assoc_2.f03 @@ -0,0 +1,36 @@ +! { dg-do compile } +module c_assoc_2 + use, intrinsic :: iso_c_binding, only: c_ptr, c_associated + +contains + subroutine sub0(my_c_ptr) bind(c) + type(c_ptr), value :: my_c_ptr + type(c_ptr), pointer :: my_c_ptr_2 + integer :: my_integer + + if(.not. c_associated(my_c_ptr)) then + call abort() + end if + + if(.not. c_associated(my_c_ptr, my_c_ptr)) then + call abort() + end if + + if(.not. c_associated(my_c_ptr, my_c_ptr, my_c_ptr)) then ! { dg-error "More actual than formal arguments" } + call abort() + end if + + if(.not. c_associated()) then ! { dg-error "Missing argument" } + call abort() + end if ! { dg-error "Expecting END SUBROUTINE" } + + if(.not. c_associated(my_c_ptr_2)) then + call abort() + end if + + if(.not. c_associated(my_integer)) then ! { dg-error "Type/rank mismatch" } + call abort() + end if + end subroutine sub0 + +end module c_assoc_2 diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_shape_test.f90 b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_test.f90 new file mode 100644 index 00000000000..c6204bdac7f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_f_pointer_shape_test.f90 @@ -0,0 +1,19 @@ +! { dg-do compile } +! verify that the compiler catches the error in the call to c_f_pointer +! because it is missing the required SHAPE parameter. the SHAPE parameter +! is optional, in general, but must exist if given a fortran pointer +! to a non-zero rank object. --Rickett, 09.26.06 +module c_f_pointer_shape_test +contains + subroutine test_0(myAssumedArray, cPtr) + use, intrinsic :: iso_c_binding + integer, dimension(*) :: myAssumedArray + integer, dimension(:), pointer :: myArrayPtr + integer, dimension(1:2), target :: myArray + type(c_ptr), value :: cPtr + + myArrayPtr => myArray + call c_f_pointer(cPtr, myArrayPtr) ! { dg-error "Missing SHAPE parameter" } + end subroutine test_0 +end module c_f_pointer_shape_test + diff --git a/gcc/testsuite/gfortran.dg/c_f_pointer_tests.f90 b/gcc/testsuite/gfortran.dg/c_f_pointer_tests.f90 new file mode 100644 index 00000000000..1e4dbc0201f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_f_pointer_tests.f90 @@ -0,0 +1,68 @@ +! { dg-do run } +! { dg-additional-sources c_f_tests_driver.c } +module c_f_pointer_tests + use, intrinsic :: iso_c_binding + + type myF90Derived + integer(c_int) :: cInt + real(c_double) :: cDouble + real(c_float) :: cFloat + integer(c_short) :: cShort + type(c_funptr) :: myFunPtr + end type myF90Derived + + type dummyDerived + integer(c_int) :: myInt + end type dummyDerived + + contains + + subroutine testDerivedPtrs(myCDerived, derivedArray, arrayLen, & + derived2DArray, dim1, dim2) & + bind(c, name="testDerivedPtrs") + implicit none + type(c_ptr), value :: myCDerived + type(c_ptr), value :: derivedArray + integer(c_int), value :: arrayLen + type(c_ptr), value :: derived2DArray + integer(c_int), value :: dim1 + integer(c_int), value :: dim2 + type(myF90Derived), pointer :: myF90Type + type(myF90Derived), dimension(:), pointer :: myF90DerivedArray + type(myF90Derived), dimension(:,:), pointer :: derivedArray2D + ! one dimensional array coming in (derivedArray) + integer(c_int), dimension(1:1) :: shapeArray + integer(c_int), dimension(1:2) :: shapeArray2 + type(myF90Derived), dimension(1:10), target :: tmpArray + + call c_f_pointer(myCDerived, myF90Type) + ! make sure numbers are ok. initialized in c_f_tests_driver.c + if(myF90Type%cInt .ne. 1) then + call abort() + endif + if(myF90Type%cDouble .ne. 2.0d0) then + call abort() + endif + if(myF90Type%cFloat .ne. 3.0) then + call abort() + endif + if(myF90Type%cShort .ne. 4) then + call abort() + endif + + shapeArray(1) = arrayLen + call c_f_pointer(derivedArray, myF90DerivedArray, shapeArray) + + ! upper bound of each dim is arrayLen2 + shapeArray2(1) = dim1 + shapeArray2(2) = dim2 + call c_f_pointer(derived2DArray, derivedArray2D, shapeArray2) + ! make sure the last element is ok + if((derivedArray2D(dim1, dim2)%cInt .ne. 4) .or. & + (derivedArray2D(dim1, dim2)%cDouble .ne. 4.0d0) .or. & + (derivedArray2D(dim1, dim2)%cFloat .ne. 4.0) .or. & + (derivedArray2D(dim1, dim2)%cShort .ne. 4)) then + call abort() + endif + end subroutine testDerivedPtrs +end module c_f_pointer_tests diff --git a/gcc/testsuite/gfortran.dg/c_f_tests_driver.c b/gcc/testsuite/gfortran.dg/c_f_tests_driver.c new file mode 100644 index 00000000000..5079cf79900 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_f_tests_driver.c @@ -0,0 +1,66 @@ +extern void abort(void); + +typedef struct myCDerived +{ + int cInt; + double cDouble; + float cFloat; + short cShort; + void *ptr; +}myCDerived_t; + +#define DERIVED_ARRAY_LEN 10 +#define ARRAY_LEN_2 3 +#define DIM1 2 +#define DIM2 3 + +void testDerivedPtrs(myCDerived_t *cDerivedPtr, + myCDerived_t *derivedArray, int arrayLen, + myCDerived_t *derived2d, int dim1, int dim2); + +int main(int argc, char **argv) +{ + myCDerived_t cDerived; + myCDerived_t derivedArray[DERIVED_ARRAY_LEN]; + myCDerived_t derived2DArray[DIM1][DIM2]; + int i = 0; + int j = 0; + + cDerived.cInt = 1; + cDerived.cDouble = 2.0; + cDerived.cFloat = 3.0; + cDerived.cShort = 4; +/* cDerived.ptr = NULL; */ + /* nullify the ptr */ + cDerived.ptr = 0; + + for(i = 0; i < DERIVED_ARRAY_LEN; i++) + { + derivedArray[i].cInt = (i+1) * 1; + derivedArray[i].cDouble = (i+1) * 1.0; /* 2.0; */ + derivedArray[i].cFloat = (i+1) * 1.0; /* 3.0; */ + derivedArray[i].cShort = (i+1) * 1; /* 4; */ +/* derivedArray[i].ptr = NULL; */ + derivedArray[i].ptr = 0; + } + + for(i = 0; i < DIM1; i++) + { + for(j = 0; j < DIM2; j++) + { + derived2DArray[i][j].cInt = ((i*DIM1) * 1) + j; + derived2DArray[i][j].cDouble = ((i*DIM1) * 1.0) + j; + derived2DArray[i][j].cFloat = ((i*DIM1) * 1.0) + j; + derived2DArray[i][j].cShort = ((i*DIM1) * 1) + j; +/* derived2DArray[i][j].ptr = NULL; */ + derived2DArray[i][j].ptr = 0; + } + } + + /* send in the transpose size (dim2 is dim1, dim1 is dim2) */ + testDerivedPtrs(&cDerived, derivedArray, DERIVED_ARRAY_LEN, + derived2DArray[0], DIM2, DIM1); + + return 0; +}/* end main() */ + diff --git a/gcc/testsuite/gfortran.dg/c_funloc_tests.f03 b/gcc/testsuite/gfortran.dg/c_funloc_tests.f03 new file mode 100644 index 00000000000..c34ef2b6f49 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_funloc_tests.f03 @@ -0,0 +1,21 @@ +! { dg-do run } +! This test case simply checks that c_funloc exists, accepts arguments of +! flavor FL_PROCEDURE, and returns the type c_funptr +module c_funloc_tests + use, intrinsic :: iso_c_binding, only: c_funptr, c_funloc + +contains + subroutine sub0() bind(c) + type(c_funptr) :: my_c_funptr + + my_c_funptr = c_funloc(sub0) + end subroutine sub0 +end module c_funloc_tests + +program driver + use c_funloc_tests + + call sub0() +end program driver + +! { dg-final { cleanup-modules "c_funloc_tests" } } diff --git a/gcc/testsuite/gfortran.dg/c_funloc_tests_2.f03 b/gcc/testsuite/gfortran.dg/c_funloc_tests_2.f03 new file mode 100644 index 00000000000..afaf29fc896 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_funloc_tests_2.f03 @@ -0,0 +1,16 @@ +! { dg-do compile } +module c_funloc_tests_2 + use, intrinsic :: iso_c_binding, only: c_funptr, c_funloc + implicit none + +contains + subroutine sub0() bind(c) + type(c_funptr) :: my_c_funptr + integer :: my_local_variable + + my_c_funptr = c_funloc() ! { dg-error "Missing argument" } + my_c_funptr = c_funloc(sub0) + my_c_funptr = c_funloc(sub0, sub0) ! { dg-error "More actual than formal" } + my_c_funptr = c_funloc(my_local_variable) ! { dg-error "must be a procedure" } + end subroutine sub0 +end module c_funloc_tests_2 diff --git a/gcc/testsuite/gfortran.dg/c_funloc_tests_3.f03 b/gcc/testsuite/gfortran.dg/c_funloc_tests_3.f03 new file mode 100644 index 00000000000..2d23efb243a --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_funloc_tests_3.f03 @@ -0,0 +1,36 @@ +! { dg-do run } +! { dg-additional-sources c_funloc_tests_3_funcs.c } +! This testcase tests c_funloc and c_funptr from iso_c_binding. It uses +! functions defined in c_funloc_tests_3_funcs.c. +module c_funloc_tests_3 + implicit none +contains + function ffunc(j) bind(c) + use iso_c_binding, only: c_funptr, c_int + integer(c_int) :: ffunc + integer(c_int), value :: j + ffunc = -17*j + end function ffunc +end module c_funloc_tests_3 +program main + use iso_c_binding, only: c_funptr, c_funloc + use c_funloc_tests_3, only: ffunc + implicit none + interface + function returnFunc() bind(c,name="returnFunc") + use iso_c_binding, only: c_funptr + type(c_funptr) :: returnFunc + end function returnFunc + subroutine callFunc(func,pass,compare) bind(c,name="callFunc") + use iso_c_binding, only: c_funptr, c_int + type(c_funptr), value :: func + integer(c_int), value :: pass,compare + end subroutine callFunc + end interface + type(c_funptr) :: p + p = returnFunc() + call callFunc(p, 13,3*13) + p = c_funloc(ffunc) + call callFunc(p, 21,-17*21) +end program main +! { dg-final { cleanup-modules "c_funloc_tests_3" } } diff --git a/gcc/testsuite/gfortran.dg/c_funloc_tests_3_funcs.c b/gcc/testsuite/gfortran.dg/c_funloc_tests_3_funcs.c new file mode 100644 index 00000000000..994da0a505d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_funloc_tests_3_funcs.c @@ -0,0 +1,25 @@ +/* These functions support the test case c_funloc_tests_3. */ +#include <stdlib.h> +#include <stdio.h> + +int printIntC(int i) +{ + return 3*i; +} + +int (*returnFunc(void))(int) +{ + return &printIntC; +} + +void callFunc(int(*func)(int), int pass, int compare) +{ + int result = (*func)(pass); + if(result != compare) + { + printf("FAILED: Got %d, expected %d\n", result, compare); + abort(); + } + else + printf("SUCCESS: Got %d, expected %d\n", result, compare); +} diff --git a/gcc/testsuite/gfortran.dg/c_kind_params.f90 b/gcc/testsuite/gfortran.dg/c_kind_params.f90 new file mode 100644 index 00000000000..a7e577a9e17 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_kind_params.f90 @@ -0,0 +1,76 @@ +! { dg-do run } +! { dg-additional-sources c_kinds.c } +! { dg-options "-w -std=c99" } +! the -w option is needed to make f951 not report a warning for +! the -std=c99 option that the C file needs. +! +! Note: int_fast*_t currently not supported, cf. PR 448. +module c_kind_params + use, intrinsic :: iso_c_binding + implicit none + +contains + subroutine param_test(my_short, my_int, my_long, my_long_long, & + my_int8_t, my_int_least8_t, my_int16_t, & + my_int_least16_t, my_int32_t, my_int_least32_t, & + my_int64_t, my_int_least64_t, & + my_intmax_t, my_intptr_t, my_float, my_double, my_long_double, & + my_char, my_bool) bind(c) + integer(c_short), value :: my_short + integer(c_int), value :: my_int + integer(c_long), value :: my_long + integer(c_long_long), value :: my_long_long + integer(c_int8_t), value :: my_int8_t + integer(c_int_least8_t), value :: my_int_least8_t +! integer(c_int_fast8_t), value :: my_int_fast8_t + integer(c_int16_t), value :: my_int16_t + integer(c_int_least16_t), value :: my_int_least16_t +! integer(c_int_fast16_t), value :: my_int_fast16_t + integer(c_int32_t), value :: my_int32_t + integer(c_int_least32_t), value :: my_int_least32_t +! integer(c_int_fast32_t), value :: my_int_fast32_t + integer(c_int64_t), value :: my_int64_t + integer(c_int_least64_t), value :: my_int_least64_t +! integer(c_int_fast64_t), value :: my_int_fast64_t + integer(c_intmax_t), value :: my_intmax_t + integer(c_intptr_t), value :: my_intptr_t + real(c_float), value :: my_float + real(c_double), value :: my_double + real(c_long_double), value :: my_long_double + character(c_char), value :: my_char + logical(c_bool), value :: my_bool + + if(my_short /= 1_c_short) call abort() + if(my_int /= 2_c_int) call abort() + if(my_long /= 3_c_long) call abort() + if(my_long_long /= 4_c_long_long) call abort() + + if(my_int8_t /= 1_c_int8_t) call abort() + if(my_int_least8_t /= 2_c_int_least8_t ) call abort() + print *, 'c_int_fast8_t is: ', c_int_fast8_t + + if(my_int16_t /= 1_c_int16_t) call abort() + if(my_int_least16_t /= 2_c_int_least16_t) call abort() + print *, 'c_int_fast16_t is: ', c_int_fast16_t + + if(my_int32_t /= 1_c_int32_t) call abort() + if(my_int_least32_t /= 2_c_int_least32_t) call abort() + print *, 'c_int_fast32_t is: ', c_int_fast32_t + + if(my_int64_t /= 1_c_int64_t) call abort() + if(my_int_least64_t /= 2_c_int_least64_t) call abort() + print *, 'c_int_fast64_t is: ', c_int_fast64_t + + if(my_intmax_t /= 1_c_intmax_t) call abort() + if(my_intptr_t /= 0_c_intptr_t) call abort() + + if(my_float /= 1.0_c_float) call abort() + if(my_double /= 2.0_c_double) call abort() + if(my_long_double /= 3.0_c_long_double) call abort() + + if(my_char /= c_char_'y') call abort() + if(my_bool .neqv. .true._c_bool) call abort() + end subroutine param_test + +end module c_kind_params +! { dg-final { cleanup-modules "c_kind_params" } } diff --git a/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 b/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 new file mode 100644 index 00000000000..dcac65dec43 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 @@ -0,0 +1,14 @@ +! { dg-do compile } +module c_kind_tests_2 + use, intrinsic :: iso_c_binding + + integer, parameter :: myF = c_float + real(myF), bind(c) :: myCFloat + integer(myF), bind(c) :: myCInt ! { dg-error "is for type REAL" } + integer(c_double), bind(c) :: myCInt2 ! { dg-error "is for type REAL" } + + integer, parameter :: myI = c_int + real(myI) :: myReal + real(myI), bind(c) :: myCFloat2 ! { dg-error "is for type INTEGER" } + real(4), bind(c) :: myFloat ! { dg-warning "may not be a C interoperable" } +end module c_kind_tests_2 diff --git a/gcc/testsuite/gfortran.dg/c_kinds.c b/gcc/testsuite/gfortran.dg/c_kinds.c new file mode 100644 index 00000000000..f79a70f7532 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_kinds.c @@ -0,0 +1,54 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c99" } */ + +#include <stdint.h> + +/* Note: int_fast*_t is currently not supported, cf. PR 448 */ +void param_test(short int my_short, int my_int, long int my_long, + long long int my_long_long, int8_t my_int8_t, + int_least8_t my_int_least8_t, /*int_fast8_t my_int_fast8_t,*/ + int16_t my_int16_t, int_least16_t my_int_least16_t, + /*int_fast16_t my_int_fast16_t,*/ int32_t my_int32_t, + int_least32_t my_int_least32_t, /*int_fast32_t my_int_fast32_t,*/ + int64_t my_int64_t, int_least64_t my_int_least64_t, + /*int_fast64_t my_int_fast64_t,*/ intmax_t my_intmax_t, + intptr_t my_intptr_t, float my_float, double my_double, + long double my_long_double, char my_char, _Bool my_bool); + + +int main(int argc, char **argv) +{ + short int my_short = 1; + int my_int = 2; + long int my_long = 3; + long long int my_long_long = 4; + int8_t my_int8_t = 1; + int_least8_t my_int_least8_t = 2; + int_fast8_t my_int_fast8_t = 3; + int16_t my_int16_t = 1; + int_least16_t my_int_least16_t = 2; + int_fast16_t my_int_fast16_t = 3; + int32_t my_int32_t = 1; + int_least32_t my_int_least32_t = 2; + int_fast32_t my_int_fast32_t = 3; + int64_t my_int64_t = 1; + int_least64_t my_int_least64_t = 2; + int_fast64_t my_int_fast64_t = 3; + intmax_t my_intmax_t = 1; + intptr_t my_intptr_t = 0; + float my_float = 1.0; + double my_double = 2.0; + long double my_long_double = 3.0; + char my_char = 'y'; + _Bool my_bool = 1; + + param_test(my_short, my_int, my_long, my_long_long, my_int8_t, + my_int_least8_t, /*my_int_fast8_t, */ my_int16_t, + my_int_least16_t,/* my_int_fast16_t,*/ my_int32_t, + my_int_least32_t,/* my_int_fast32_t,*/ my_int64_t, + my_int_least64_t,/* my_int_fast64_t,*/ my_intmax_t, + my_intptr_t, my_float, my_double, my_long_double, my_char, + my_bool); + + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/c_loc_driver.c b/gcc/testsuite/gfortran.dg/c_loc_driver.c new file mode 100644 index 00000000000..9e010439600 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_driver.c @@ -0,0 +1,17 @@ +/* in fortran module */ +void test0(void); + +extern void abort(void); + +int main(int argc, char **argv) +{ + test0(); + return 0; +}/* end main() */ + +void test_address(void *c_ptr, int expected_value) +{ + if((*(int *)(c_ptr)) != expected_value) + abort(); + return; +}/* end test_address() */ diff --git a/gcc/testsuite/gfortran.dg/c_loc_test.f90 b/gcc/testsuite/gfortran.dg/c_loc_test.f90 new file mode 100644 index 00000000000..178a5164cef --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_test.f90 @@ -0,0 +1,24 @@ +! { dg-do run } +! { dg-additional-sources c_loc_driver.c } +module c_loc_test +implicit none + +contains + subroutine test0() bind(c) + use, intrinsic :: iso_c_binding + implicit none + integer, target :: x + type(c_ptr) :: my_c_ptr + interface + subroutine test_address(x, expected_value) bind(c) + use, intrinsic :: iso_c_binding + type(c_ptr), value :: x + integer(c_int), value :: expected_value + end subroutine test_address + end interface + x = 100 + my_c_ptr = c_loc(x) + call test_address(my_c_ptr, 100) + end subroutine test0 +end module c_loc_test +! { dg-final { cleanup-modules "c_loc_test.mod" } } diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_2.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_2.f03 new file mode 100644 index 00000000000..ae4449574fe --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_2.f03 @@ -0,0 +1,88 @@ +! { dg-do run } +! { dg-additional-sources c_loc_tests_2_funcs.c } +module c_loc_tests_2 +use, intrinsic :: iso_c_binding +implicit none + +interface + function test_scalar_address(cptr) bind(c) + use, intrinsic :: iso_c_binding, only: c_ptr, c_int + type(c_ptr), value :: cptr + integer(c_int) :: test_scalar_address + end function test_scalar_address + + function test_array_address(cptr, num_elements) bind(c) + use, intrinsic :: iso_c_binding, only: c_ptr, c_int + type(c_ptr), value :: cptr + integer(c_int), value :: num_elements + integer(c_int) :: test_array_address + end function test_array_address + + function test_type_address(cptr) bind(c) + use, intrinsic :: iso_c_binding, only: c_ptr, c_int + type(c_ptr), value :: cptr + integer(c_int) :: test_type_address + end function test_type_address +end interface + +contains + subroutine test0() bind(c) + integer, target :: xtar + integer, pointer :: xptr + type(c_ptr) :: my_c_ptr_1 = c_null_ptr + type(c_ptr) :: my_c_ptr_2 = c_null_ptr + xtar = 100 + xptr => xtar + my_c_ptr_1 = c_loc(xtar) + my_c_ptr_2 = c_loc(xptr) + if(test_scalar_address(my_c_ptr_1) .ne. 1) then + call abort() + end if + if(test_scalar_address(my_c_ptr_2) .ne. 1) then + call abort() + end if + end subroutine test0 + + subroutine test1() bind(c) + integer, target, dimension(100) :: int_array_tar + type(c_ptr) :: my_c_ptr_1 = c_null_ptr + type(c_ptr) :: my_c_ptr_2 = c_null_ptr + + int_array_tar = 100 + my_c_ptr_1 = c_loc(int_array_tar) + if(test_array_address(my_c_ptr_1, 100) .ne. 1) then + call abort() + end if + end subroutine test1 + + subroutine test2() bind(c) + type, bind(c) f90type + integer(c_int) :: i + real(c_double) :: x + end type f90type + type(f90type), target :: type_tar + type(f90type), pointer :: type_ptr + type(c_ptr) :: my_c_ptr_1 = c_null_ptr + type(c_ptr) :: my_c_ptr_2 = c_null_ptr + + type_ptr => type_tar + type_tar%i = 100 + type_tar%x = 1.0d0 + my_c_ptr_1 = c_loc(type_tar) + my_c_ptr_2 = c_loc(type_ptr) + if(test_type_address(my_c_ptr_1) .ne. 1) then + call abort() + end if + if(test_type_address(my_c_ptr_2) .ne. 1) then + call abort() + end if + end subroutine test2 +end module c_loc_tests_2 + +program driver + use c_loc_tests_2 + call test0() + call test1() + call test2() +end program driver +! { dg-final { cleanup-modules "c_loc_tests_2" } } diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_2_funcs.c b/gcc/testsuite/gfortran.dg/c_loc_tests_2_funcs.c new file mode 100644 index 00000000000..d47ac81aeaa --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_2_funcs.c @@ -0,0 +1,42 @@ +double fabs (double); + +typedef struct ctype +{ + int i; + double x; +}ctype_t; + +int test_scalar_address(int *ptr) +{ + /* The value in Fortran should be initialized to 100. */ + if(*ptr != 100) + return 0; + else + return 1; +} + +int test_array_address(int *int_array, int num_elements) +{ + int i = 0; + + for(i = 0; i < num_elements; i++) + /* Fortran will init all of the elements to 100; verify that here. */ + if(int_array[i] != 100) + return 0; + + /* all elements were equal to 100 */ + return 1; +} + +int test_type_address(ctype_t *type_ptr) +{ + /* i was set to 100 by Fortran */ + if(type_ptr->i != 100) + return 0; + + /* x was set to 1.0d0 by Fortran */ + if(fabs(type_ptr->x - 1.0) > 0.00000000) + return 0; + + return 1; +} diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_3.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_3.f03 new file mode 100644 index 00000000000..95eac4af380 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_3.f03 @@ -0,0 +1,8 @@ +! { dg-do compile } +use iso_c_binding +implicit none +character(kind=c_char,len=256),target :: arg +type(c_ptr),pointer :: c +c = c_loc(arg) ! { dg-error "must have a length of 1" } + +end diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_4.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_4.f03 new file mode 100644 index 00000000000..8453ec77272 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_4.f03 @@ -0,0 +1,15 @@ +! { dg-do compile } +module c_loc_tests_4 + use, intrinsic :: iso_c_binding + implicit none + +contains + subroutine sub0() bind(c) + integer(c_int), target, dimension(10) :: my_array + integer(c_int), pointer, dimension(:) :: my_array_ptr + type(c_ptr) :: my_c_ptr + + my_array_ptr => my_array + my_c_ptr = c_loc(my_array_ptr) ! { dg-error "must be an associated scalar POINTER" } + end subroutine sub0 +end module c_loc_tests_4 diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_5.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_5.f03 new file mode 100644 index 00000000000..a389437ce10 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_5.f03 @@ -0,0 +1,19 @@ +! { dg-do compile } +module c_loc_tests_5 + use, intrinsic :: iso_c_binding, only: c_char, c_ptr, c_loc, c_int + +contains + subroutine sub0() bind(c) + type(c_ptr) :: f_ptr, my_c_ptr + character(kind=c_char, len=20), target :: format + integer(c_int), dimension(:), pointer :: int_ptr + integer(c_int), dimension(10), target :: int_array + + f_ptr = c_loc(format(1:1)) + + int_ptr => int_array + my_c_ptr = c_loc(int_ptr(0)) + + end subroutine sub0 +end module c_loc_tests_5 +! { dg-final { cleanup-modules "c_loc_tests_5" } } diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_6.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_6.f03 new file mode 100644 index 00000000000..c82a2adbf78 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_6.f03 @@ -0,0 +1,13 @@ +! { dg-do compile } +! Verifies that the c_loc scalar pointer tests recognize the string of length +! one as being allowable for the parameter to c_loc. +module x +use iso_c_binding +contains +SUBROUTINE glutInit_f03() + TYPE(C_PTR), DIMENSION(1), TARGET :: argv=C_NULL_PTR + CHARACTER(C_CHAR), DIMENSION(10), TARGET :: empty_string=C_NULL_CHAR + argv(1)=C_LOC(empty_string) +END SUBROUTINE +end module x +! { dg-final { cleanup-modules "x" } } diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_7.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_7.f03 new file mode 100644 index 00000000000..78f5276bdef --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_7.f03 @@ -0,0 +1,11 @@ +! { dg-do compile } +module c_loc_tests_7 +use iso_c_binding +contains +SUBROUTINE glutInit_f03() + TYPE(C_PTR), DIMENSION(1), TARGET :: argv=C_NULL_PTR + CHARACTER(C_CHAR), DIMENSION(1), TARGET :: empty_string=C_NULL_CHAR + argv(1)=C_LOC(empty_string) +END SUBROUTINE +end module c_loc_tests_7 +! { dg-final { cleanup-modules "c_loc_tests_7" } } diff --git a/gcc/testsuite/gfortran.dg/c_loc_tests_8.f03 b/gcc/testsuite/gfortran.dg/c_loc_tests_8.f03 new file mode 100644 index 00000000000..a094d690bdd --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_loc_tests_8.f03 @@ -0,0 +1,13 @@ +! { dg-do compile } +! Verifies that the c_loc scalar pointer tests recognize the string of length +! greater than one as not being allowable for the parameter to c_loc. +module x +use iso_c_binding +contains +SUBROUTINE glutInit_f03() + TYPE(C_PTR), DIMENSION(1), TARGET :: argv=C_NULL_PTR + character(kind=c_char, len=5), target :: string="hello" + argv(1)=C_LOC(string) ! { dg-error "must have a length of 1" } +END SUBROUTINE +end module x + diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests.f03 b/gcc/testsuite/gfortran.dg/c_ptr_tests.f03 new file mode 100644 index 00000000000..0b7c98be714 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests.f03 @@ -0,0 +1,44 @@ +! { dg-do run } +! { dg-additional-sources c_ptr_tests_driver.c } +module c_ptr_tests + use, intrinsic :: iso_c_binding + + ! TODO:: + ! in order to be associated with a C address, + ! the derived type needs to be C interoperable, + ! which requires bind(c) and all fields interoperable. + type, bind(c) :: myType + type(c_ptr) :: myServices + type(c_funptr) :: mySetServices + type(c_ptr) :: myPort + end type myType + + type, bind(c) :: f90Services + integer(c_int) :: compId + type(c_ptr) :: globalServices = c_null_ptr + end type f90Services + + contains + + subroutine sub0(c_self, services) bind(c) + use, intrinsic :: iso_c_binding + implicit none + type(c_ptr), value :: c_self, services + type(myType), pointer :: self + type(f90Services), pointer :: localServices +! type(c_ptr) :: my_cptr + type(c_ptr), save :: my_cptr = c_null_ptr + + call c_f_pointer(c_self, self) + if(.not. associated(self)) then + print *, 'self is not associated' + end if + self%myServices = services + + ! c_null_ptr is defined in iso_c_binding + my_cptr = c_null_ptr + + ! get access to the local services obj from C + call c_f_pointer(self%myServices, localServices) + end subroutine sub0 +end module c_ptr_tests diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_10.f03 b/gcc/testsuite/gfortran.dg/c_ptr_tests_10.f03 new file mode 100644 index 00000000000..d04786c7c74 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_10.f03 @@ -0,0 +1,18 @@ +! { dg-run } +! This test case exists because gfortran had an error in converting the +! expressions for the derived types from iso_c_binding in some cases. +module c_ptr_tests_10 + use, intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr + +contains + subroutine sub0() bind(c) + print *, 'c_null_ptr is: ', c_null_ptr + end subroutine sub0 +end module c_ptr_tests_10 + +program main + use c_ptr_tests_10 + call sub0() +end program main + +! { dg-final { cleanup-modules "c_ptr_tests_10" } } diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_5.f03 b/gcc/testsuite/gfortran.dg/c_ptr_tests_5.f03 new file mode 100644 index 00000000000..437e3469127 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_5.f03 @@ -0,0 +1,16 @@ +! { dg-do compile } +module c_ptr_tests_5 +use, intrinsic :: iso_c_binding + +type, bind(c) :: my_f90_type + integer(c_int) :: i +end type my_f90_type + +contains + subroutine sub0(c_struct) bind(c) + type(c_ptr), value :: c_struct + type(my_f90_type) :: f90_type + + call c_f_pointer(c_struct, f90_type) ! { dg-error "must have the POINTER" } + end subroutine sub0 +end module c_ptr_tests_5 diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_7.f03 b/gcc/testsuite/gfortran.dg/c_ptr_tests_7.f03 new file mode 100644 index 00000000000..04cb8b22ab8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_7.f03 @@ -0,0 +1,12 @@ +! { dg-do run } +! { dg-additional-sources c_ptr_tests_7_driver.c } +module c_ptr_tests_7 + use, intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr + +contains + function func0() bind(c) + type(c_ptr) :: func0 + func0 = c_null_ptr + end function func0 +end module c_ptr_tests_7 +! { dg-final { cleanup-modules "c_ptr_tests_7" } } diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_7_driver.c b/gcc/testsuite/gfortran.dg/c_ptr_tests_7_driver.c new file mode 100644 index 00000000000..7d8b1e328c8 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_7_driver.c @@ -0,0 +1,14 @@ +/* This is the driver for c_ptr_test_7. */ +extern void abort(void); + +void *func0(); + +int main(int argc, char **argv) +{ + /* The Fortran module c_ptr_tests_7 contains function func0, which has + return type of c_ptr, and should set the return value to c_null_ptr. */ + if (func0() != 0) + abort(); + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_8.f03 b/gcc/testsuite/gfortran.dg/c_ptr_tests_8.f03 new file mode 100644 index 00000000000..3b99ee8bb0f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_8.f03 @@ -0,0 +1,20 @@ +! { dg-do run } +! { dg-additional-sources c_ptr_tests_8_funcs.c } +program main +use iso_c_binding, only: c_ptr +implicit none +interface + function create() bind(c) + use iso_c_binding, only: c_ptr + type(c_ptr) :: create + end function create + subroutine show(a) bind(c) + import :: c_ptr + type(c_ptr), VALUE :: a + end subroutine show +end interface + +type(c_ptr) :: ptr +ptr = create() +call show(ptr) +end program main diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_8_funcs.c b/gcc/testsuite/gfortran.dg/c_ptr_tests_8_funcs.c new file mode 100644 index 00000000000..2ad01211658 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_8_funcs.c @@ -0,0 +1,26 @@ +/* This file provides auxilliary functions for c_ptr_tests_8. */ + +#include <stdio.h> +#include <stdlib.h> + +extern void abort (void); + +void *create (void) +{ + int *a; + a = malloc (sizeof (a)); + *a = 444; + return a; + +} + +void show (int *a) +{ + if (*a == 444) + printf ("SUCCESS (%d)\n", *a); + else + { + printf ("FAILED: Expected 444, received %d\n", *a); + abort (); + } +} diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_9.f03 b/gcc/testsuite/gfortran.dg/c_ptr_tests_9.f03 new file mode 100644 index 00000000000..db598590825 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_9.f03 @@ -0,0 +1,31 @@ +! { dg-do run } +! This test is pretty simple but is here just to make sure that the changes +! done to c_ptr and c_funptr (translating them to void *) works in the case +! where a component of a type is of type c_ptr or c_funptr. +module c_ptr_tests_9 + use, intrinsic :: iso_c_binding, only: c_ptr, c_null_ptr + + type myF90Derived + type(c_ptr) :: my_c_ptr + end type myF90Derived + +contains + subroutine sub0() bind(c) + type(myF90Derived), target :: my_f90_type + type(myF90Derived), pointer :: my_f90_type_ptr + + my_f90_type%my_c_ptr = c_null_ptr + print *, 'my_f90_type is: ', my_f90_type + my_f90_type_ptr => my_f90_type + print *, 'my_f90_type_ptr is: ', my_f90_type_ptr + end subroutine sub0 +end module c_ptr_tests_9 + + +program main + use c_ptr_tests_9 + + call sub0() +end program main + +! { dg-final { cleanup-modules "c_ptr_tests_9" } } diff --git a/gcc/testsuite/gfortran.dg/c_ptr_tests_driver.c b/gcc/testsuite/gfortran.dg/c_ptr_tests_driver.c new file mode 100644 index 00000000000..cd81c7bccec --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_ptr_tests_driver.c @@ -0,0 +1,34 @@ +/* this is the driver for c_ptr_test.f03 */ + +typedef struct services +{ + int compId; + void *globalServices; +}services_t; + +typedef struct comp +{ + void *myServices; + void (*setServices)(struct comp *self, services_t *myServices); + void *myPort; +}comp_t; + +/* prototypes for f90 functions */ +void sub0(comp_t *self, services_t *myServices); + +int main(int argc, char **argv) +{ + services_t servicesObj; + comp_t myComp; + + servicesObj.compId = 17; + servicesObj.globalServices = 0; /* NULL; */ + myComp.myServices = &servicesObj; + myComp.setServices = 0; /* NULL; */ + myComp.myPort = 0; /* NULL; */ + + sub0(&myComp, &servicesObj); + + return 0; +}/* end main() */ + diff --git a/gcc/testsuite/gfortran.dg/c_size_t_driver.c b/gcc/testsuite/gfortran.dg/c_size_t_driver.c new file mode 100644 index 00000000000..b2d49917142 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_size_t_driver.c @@ -0,0 +1,12 @@ +#include <stdlib.h> +void sub0(int my_c_size); + +int main(int argc, char **argv) +{ + int my_c_size; + + my_c_size = (int)sizeof(size_t); + sub0(my_c_size); + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/c_size_t_test.f03 b/gcc/testsuite/gfortran.dg/c_size_t_test.f03 new file mode 100644 index 00000000000..91d7aa57b05 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_size_t_test.f03 @@ -0,0 +1,16 @@ +! { dg-do run } +! { dg-additional-sources c_size_t_driver.c } +module c_size_t_test + use, intrinsic :: iso_c_binding + +contains + subroutine sub0(my_c_size) bind(c) + integer(c_int), value :: my_c_size ! value of C's sizeof(size_t) + + ! if the value of c_size_t isn't equal to the value of C's sizeof(size_t) + ! we call abort. + if(c_size_t .ne. my_c_size) then + call abort () + end if + end subroutine sub0 +end module c_size_t_test diff --git a/gcc/testsuite/gfortran.dg/com_block_driver.f90 b/gcc/testsuite/gfortran.dg/com_block_driver.f90 new file mode 100644 index 00000000000..0445635c881 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/com_block_driver.f90 @@ -0,0 +1,34 @@ +! { dg-do run } +module myComModule + use, intrinsic :: iso_c_binding + + common /COM2/ R2, S2 + real(c_double) :: r2 + real(c_double) :: s2 + bind(c) :: /COM2/ + +end module myComModule + +module comBlockTests + use, intrinsic :: iso_c_binding + use myComModule + + implicit none + + common /COM/ R, S + real(c_double) :: r + real(c_double) :: s + bind(c) :: /COM/ + + contains + + subroutine testTypes() + implicit none + end subroutine testTypes +end module comBlockTests + +program comBlockDriver + use comBlockTests + + call testTypes() +end program comBlockDriver diff --git a/gcc/testsuite/gfortran.dg/global_vars_c_init.f90 b/gcc/testsuite/gfortran.dg/global_vars_c_init.f90 new file mode 100644 index 00000000000..abcdccd3fb2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/global_vars_c_init.f90 @@ -0,0 +1,18 @@ +! { dg-do run } +! { dg-additional-sources global_vars_c_init_driver.c } +module global_vars_c_init + use, intrinsic :: iso_c_binding, only: c_int + implicit none + + integer(c_int), bind(c, name='i') :: I + +contains + subroutine test_globals() bind(c) + ! the value of I is initialized above + if(I .ne. 2) then + call abort() + endif + end subroutine test_globals +end module global_vars_c_init + + diff --git a/gcc/testsuite/gfortran.dg/global_vars_c_init_driver.c b/gcc/testsuite/gfortran.dg/global_vars_c_init_driver.c new file mode 100644 index 00000000000..b58c2c96661 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/global_vars_c_init_driver.c @@ -0,0 +1,13 @@ +int i = 2; +void test_globals(void); + +extern void abort(void); + +int main(int argc, char **argv) +{ + /* verify that i has been initialized by f90 */ + if(i != 2) + abort(); + test_globals(); + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/global_vars_f90_init.f90 b/gcc/testsuite/gfortran.dg/global_vars_f90_init.f90 new file mode 100644 index 00000000000..2ff3c52fb17 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/global_vars_f90_init.f90 @@ -0,0 +1,18 @@ +! { dg-do run } +! { dg-additional-sources global_vars_f90_init_driver.c } +module global_vars_f90_init + use, intrinsic :: iso_c_binding, only: c_int + implicit none + + integer(c_int), bind(c, name='i') :: I = 2 + +contains + subroutine test_globals() bind(c) + ! the value of I is initialized above + if(I .ne. 2) then + call abort() + endif + end subroutine test_globals +end module global_vars_f90_init + + diff --git a/gcc/testsuite/gfortran.dg/global_vars_f90_init_driver.c b/gcc/testsuite/gfortran.dg/global_vars_f90_init_driver.c new file mode 100644 index 00000000000..7869c83f712 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/global_vars_f90_init_driver.c @@ -0,0 +1,14 @@ +/* initialized by fortran */ +int i; +void test_globals(void); + +extern void abort(void); + +int main(int argc, char **argv) +{ + /* verify that i has been initialized by f90 */ + if(i != 2) + abort(); + test_globals(); + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/interop_params.f03 b/gcc/testsuite/gfortran.dg/interop_params.f03 new file mode 100644 index 00000000000..8163b4a5040 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/interop_params.f03 @@ -0,0 +1,24 @@ +! { dg-do compile } +module interop_params +use, intrinsic :: iso_c_binding + +type my_f90_type + integer :: i + real :: x +end type my_f90_type + +contains + subroutine test_0(my_f90_int) bind(c) ! { dg-warning "may not be C interoperable" } + use, intrinsic :: iso_c_binding + integer, value :: my_f90_int + end subroutine test_0 + + subroutine test_1(my_f90_real) bind(c) ! { dg-error "is for type INTEGER" } + real(c_int), value :: my_f90_real + end subroutine test_1 + + subroutine test_2(my_type) bind(c) ! { dg-error "is not C interoperable" } + use, intrinsic :: iso_c_binding + type(my_f90_type) :: my_type + end subroutine test_2 +end module interop_params diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_only.f03 b/gcc/testsuite/gfortran.dg/iso_c_binding_only.f03 new file mode 100644 index 00000000000..40c45a46726 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_only.f03 @@ -0,0 +1,9 @@ +! { dg-do compile } +module iso_c_binding_only + use, intrinsic :: iso_c_binding, only: c_null_ptr + ! This should be allowed since the C_PTR that the C_NULL_PTR needs will use + ! a mangled name to prevent collisions. + integer :: c_ptr +end module iso_c_binding_only +! { dg-final { cleanup-modules "iso_c_binding_only" } } + diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_rename_1.f03 b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_1.f03 new file mode 100644 index 00000000000..215e487ada4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_1.f03 @@ -0,0 +1,83 @@ +! { dg-do run } +! { dg-additional-sources iso_c_binding_rename_1_driver.c } +module iso_c_binding_rename_0 + use, intrinsic :: iso_c_binding, only: my_c_ptr_0 => c_ptr, & + c_associated +end module iso_c_binding_rename_0 + + +module iso_c_binding_rename_1 + ! rename a couple of the symbols from iso_c_binding. the compiler + ! needs to be able to recognize the derived types with names different + ! from the one in iso_c_binding because it will look up the derived types + ! to define the args and return values of some of the procedures in + ! iso_c_binding. this should verify that this functionality works. + use, intrinsic :: iso_c_binding, my_c_int => c_int, my_c_ptr => c_ptr, & + my_c_associated => c_associated, my_c_f_pointer => c_f_pointer + +contains + subroutine sub0(my_int) bind(c) + integer(my_c_int), value :: my_int + if(my_int .ne. 1) then + call abort() + end if + end subroutine sub0 + + subroutine sub1(my_ptr) bind(c) + type(my_c_ptr), value :: my_ptr + + if(.not. my_c_associated(my_ptr)) then + call abort() + end if + end subroutine sub1 + + subroutine sub2(my_int, my_long) bind(c) + use, intrinsic :: iso_c_binding, my_c_int_2 => c_int, & + my_c_long_2 => c_long + integer(my_c_int_2), value :: my_int + integer(my_c_long_2), value :: my_long + + if(my_int .ne. 1) then + call abort() + end if + if(my_long .ne. 1) then + call abort() + end if + end subroutine sub2 + + subroutine sub3(cptr1, cptr2) bind(c) + type(my_c_ptr), value :: cptr1 + type(my_c_ptr), value :: cptr2 + integer(my_c_int), pointer :: my_f90_c_ptr + + if(.not. my_c_associated(cptr1)) then + call abort() + end if + + if(.not. my_c_associated(cptr1, cptr2)) then + call abort() + end if + + call my_c_f_pointer(cptr1, my_f90_c_ptr) + end subroutine sub3 + + subroutine sub4(cptr1, cptr2) bind(c) + ! rename the my_c_ptr_0 from iso_c_binding_rename_0 just to further test + ! both are actually aliases to c_ptr + use iso_c_binding_rename_0, my_c_ptr_local => my_c_ptr_0, & + my_c_associated_2 => c_associated + + implicit none + type(my_c_ptr_local), value :: cptr1 + type(my_c_ptr_local), value :: cptr2 + + if(.not. my_c_associated_2(cptr1)) then + call abort() + end if + + if(.not. my_c_associated_2(cptr2)) then + call abort() + end if + end subroutine sub4 +end module iso_c_binding_rename_1 + diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_rename_1_driver.c b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_1_driver.c new file mode 100644 index 00000000000..26c21d912e5 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_1_driver.c @@ -0,0 +1,19 @@ +void sub0(int); +void sub1(int *); +void sub2(int, long); +void sub3(int *, int *); +void sub4(int *, int *); + +int main(int argc, char **argv) +{ + int i = 1; + long j = 1; + + sub0(i); + sub1(&i); + sub2(i, j); + sub3(&i, &i); + sub4(&i, &i); + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_rename_2.f03 b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_2.f03 new file mode 100644 index 00000000000..75797e78f73 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_2.f03 @@ -0,0 +1,40 @@ +! { dg-do run } +! { dg-additional-sources iso_c_binding_rename_2_driver.c } +module mod0 + use, intrinsic :: iso_c_binding, only: c_ptr, c_associated +end module mod0 + +module mod1 + use mod0, my_c_ptr => c_ptr, my_c_associated => c_associated +end module mod1 + +module mod2 +contains + subroutine sub2(my_ptr1) bind(c) + use mod1, my_c_ptr_2 => my_c_ptr, my_c_associated_2 => my_c_associated + implicit none + type(my_c_ptr_2) :: my_ptr1 + if( .not. my_c_associated_2(my_ptr1)) then + call abort() + end if + end subroutine sub2 + + subroutine sub3(my_ptr1) bind(c) + use mod1, my_c_ptr_2 => my_c_ptr + implicit none + type(my_c_ptr_2) :: my_ptr1 + if( .not. my_c_associated(my_ptr1)) then + call abort() + end if + end subroutine sub3 + + subroutine sub4(my_ptr1) bind(c) + use mod1, my_c_associated_3 => my_c_associated + implicit none + type(my_c_ptr) :: my_ptr1 + if( .not. my_c_associated_3(my_ptr1)) then + call abort() + end if + end subroutine sub4 + +end module mod2 diff --git a/gcc/testsuite/gfortran.dg/iso_c_binding_rename_2_driver.c b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_2_driver.c new file mode 100644 index 00000000000..8be704c341b --- /dev/null +++ b/gcc/testsuite/gfortran.dg/iso_c_binding_rename_2_driver.c @@ -0,0 +1,16 @@ +void sub2(int **); +void sub3(int **); +void sub4(int **); + +int main(int argc, char **argv) +{ + int i = 1; + int *ptr; + + ptr = &i; + sub2(&ptr); + sub3(&ptr); + sub4(&ptr); + + return 0; +} diff --git a/gcc/testsuite/gfortran.dg/kind_tests_2.f03 b/gcc/testsuite/gfortran.dg/kind_tests_2.f03 new file mode 100644 index 00000000000..d740657a262 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/kind_tests_2.f03 @@ -0,0 +1,7 @@ +! { dg-do compile } +module kind_tests_2 + use, intrinsic :: iso_c_binding + + integer, parameter :: myFKind = c_float + real(myFKind), bind(c) :: myF +end module kind_tests_2 diff --git a/gcc/testsuite/gfortran.dg/kind_tests_3.f03 b/gcc/testsuite/gfortran.dg/kind_tests_3.f03 new file mode 100644 index 00000000000..83cb91e95d6 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/kind_tests_3.f03 @@ -0,0 +1,10 @@ +! { dg-do compile } +module my_kinds + use, intrinsic :: iso_c_binding + integer, parameter :: myFKind = c_float +end module my_kinds + +module my_module + use my_kinds + real(myFKind), bind(c) :: myF +end module my_module diff --git a/gcc/testsuite/gfortran.dg/module_md5_1.f90 b/gcc/testsuite/gfortran.dg/module_md5_1.f90 index 7081804c494..45792bda389 100644 --- a/gcc/testsuite/gfortran.dg/module_md5_1.f90 +++ b/gcc/testsuite/gfortran.dg/module_md5_1.f90 @@ -10,5 +10,5 @@ program test use foo print *, pi end program test -! { dg-final { scan-module "foo" "MD5:18a257e13c90e3872b7b9400c2fc6e4b" } } +! { dg-final { scan-module "foo" "MD5:10e58dd12566bfc60412da6f8f8f7a07" } } ! { dg-final { cleanup-modules "foo" } } diff --git a/gcc/testsuite/gfortran.dg/only_clause_main.c b/gcc/testsuite/gfortran.dg/only_clause_main.c new file mode 100644 index 00000000000..2cc6c8dd317 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/only_clause_main.c @@ -0,0 +1,12 @@ +/* this is an f90 function */ +void testOnly(int *cIntPtr); + +int main(int argc, char **argv) +{ + int myCInt; + + myCInt = -11; + testOnly(&myCInt); + + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/print_c_kinds.f90 b/gcc/testsuite/gfortran.dg/print_c_kinds.f90 new file mode 100644 index 00000000000..a66323316b2 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/print_c_kinds.f90 @@ -0,0 +1,35 @@ +! { dg-do run } +program print_c_kinds + use, intrinsic :: iso_c_binding + implicit none + + print *, 'c_short is: ', c_short + print *, 'c_int is: ', c_int + print *, 'c_long is: ', c_long + print *, 'c_long_long is: ', c_long_long + print * + print *, 'c_int8_t is: ', c_int8_t + print *, 'c_int_least8_t is: ', c_int_least8_t + print *, 'c_int_fast8_t is: ', c_int_fast8_t + print * + print *, 'c_int16_t is: ', c_int16_t + print *, 'c_int_least16_t is: ', c_int_least16_t + print *, 'c_int_fast16_t is: ', c_int_fast16_t + print * + print *, 'c_int32_t is: ', c_int32_t + print *, 'c_int_least32_t is: ', c_int_least32_t + print *, 'c_int_fast32_t is: ', c_int_fast32_t + print * + print *, 'c_int64_t is: ', c_int64_t + print *, 'c_int_least64_t is: ', c_int_least64_t + print *, 'c_int_fast64_t is: ', c_int_fast64_t + print * + print *, 'c_intmax_t is: ', c_intmax_t + print *, 'c_intptr_t is: ', c_intptr_t + print * + print *, 'c_float is: ', c_float + print *, 'c_double is: ', c_double + print *, 'c_long_double is: ', c_long_double + print * + print *, 'c_char is: ', c_char +end program print_c_kinds diff --git a/gcc/testsuite/gfortran.dg/test_bind_c_parens.f03 b/gcc/testsuite/gfortran.dg/test_bind_c_parens.f03 new file mode 100644 index 00000000000..ee7b6a8ac63 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_bind_c_parens.f03 @@ -0,0 +1,7 @@ +! { dg-do compile } +module test_bind_c_parens + interface + subroutine sub bind(c) ! { dg-error "Missing required parentheses" } + end subroutine sub ! { dg-error "Expecting END INTERFACE" } + end interface +end module test_bind_c_parens diff --git a/gcc/testsuite/gfortran.dg/test_c_assoc.c b/gcc/testsuite/gfortran.dg/test_c_assoc.c new file mode 100644 index 00000000000..aa6571874ae --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_c_assoc.c @@ -0,0 +1,55 @@ +/* use 0 for NULL so no need for system header */ + +int test_c_assoc_0(void *my_c_ptr); +int test_c_assoc_1(void *my_c_ptr_1, void *my_c_ptr_2); +int test_c_assoc_2(void *my_c_ptr_1, void *my_c_ptr_2, int num_ptrs); +void verify_assoc(void *my_c_ptr_1, void *my_c_ptr_2); + +extern void abort(void); + +int main(int argc, char **argv) +{ + int i; + int j; + + if(test_c_assoc_0(0) != 0) + abort(); + + if(test_c_assoc_0(&i) != 1) + abort(); + + if(test_c_assoc_1(0, 0) != 0) + abort(); + + if(test_c_assoc_1(0, &i) != 0) + abort(); + + if(test_c_assoc_1(&i, &i) != 1) + abort(); + + if(test_c_assoc_1(&i, 0) != 0) + abort(); + + if(test_c_assoc_1(&i, &j) != 0) + abort(); + + /* this should be associated, cause only testing 1 ptr (i) */ + if(test_c_assoc_2(&i, 0, 1) != 1) + abort(); + + /* this should be associated */ + if(test_c_assoc_2(&i, &i, 2) != 1) + abort(); + + /* this should not be associated (i) */ + if(test_c_assoc_2(&i, &j, 2) != 0) + abort(); + + /* this should be associated, cause only testing 1 ptr (i) */ + if(test_c_assoc_2(&i, &j, 1) != 1) + abort(); + + verify_assoc(&i, &i); + + return 0; +}/* end main() */ diff --git a/gcc/testsuite/gfortran.dg/test_com_block.f90 b/gcc/testsuite/gfortran.dg/test_com_block.f90 new file mode 100644 index 00000000000..df3f643e72d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_com_block.f90 @@ -0,0 +1,32 @@ +! { dg-do run } +module nonF03ComBlock + common /NONF03COM/ r, s + real :: r + real :: s + + contains + + subroutine hello(myArray) + integer, dimension(:) :: myArray + + r = 1.0 + s = 2.0 + end subroutine hello +end module nonF03ComBlock + +program testComBlock + use nonF03ComBlock + integer, dimension(1:10) :: myArray + + call hello(myArray) + + ! these are set in the call to hello() above + ! r and s are reals (default size) in com block, set to + ! 1.0 and 2.0, respectively, in hello() + if(r .ne. 1.0) then + call abort() + endif + if(s .ne. 2.0) then + call abort() + endif +end program testComBlock diff --git a/gcc/testsuite/gfortran.dg/test_common_binding_labels.f03 b/gcc/testsuite/gfortran.dg/test_common_binding_labels.f03 new file mode 100644 index 00000000000..ea9a59a35e4 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_common_binding_labels.f03 @@ -0,0 +1,42 @@ +! { dg-do compile } +module x + use, intrinsic :: iso_c_binding, only: c_double + implicit none + + common /mycom/ r, s ! { dg-error "does not match" } + real(c_double) :: r + real(c_double) :: s + bind(c, name="my_common_block") :: /mycom/ +end module x + +module y + use, intrinsic :: iso_c_binding, only: c_double, c_int + implicit none + + common /mycom/ r, s + real(c_double) :: r + real(c_double) :: s + bind(c, name="my_common_block") :: /mycom/ + + common /com2/ i ! { dg-error "does not match" } + integer(c_int) :: i + bind(c, name="") /com2/ +end module y + +module z + use, intrinsic :: iso_c_binding, only: c_double, c_int + implicit none + + common /mycom/ r, s ! { dg-error "does not match" } + real(c_double) :: r + real(c_double) :: s + ! this next line is an error; if a common block is bind(c), the binding label + ! for it must match across all scoping units that declare it. + bind(c, name="my_common_block_2") :: /mycom/ + + common /com2/ i ! { dg-error "does not match" } + integer(c_int) :: i + bind(c, name="mycom2") /com2/ +end module z + +! { dg-final { cleanup-modules "x y" } } diff --git a/gcc/testsuite/gfortran.dg/test_common_binding_labels_2.f03 b/gcc/testsuite/gfortran.dg/test_common_binding_labels_2.f03 new file mode 100644 index 00000000000..d14c9b1168f --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_common_binding_labels_2.f03 @@ -0,0 +1,15 @@ +! { dg-do compile } +module test_common_binding_labels_2 + use, intrinsic :: iso_c_binding, only: c_double, c_int + implicit none + + common /mycom/ r, s + real(c_double) :: r + real(c_double) :: s + bind(c, name="my_common_block") :: /mycom/ + + common /com2/ i + integer(c_int) :: i + bind(c, name="") /com2/ +end module test_common_binding_labels_2 + diff --git a/gcc/testsuite/gfortran.dg/test_common_binding_labels_2_main.f03 b/gcc/testsuite/gfortran.dg/test_common_binding_labels_2_main.f03 new file mode 100644 index 00000000000..1b4103ef4cc --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_common_binding_labels_2_main.f03 @@ -0,0 +1,25 @@ +! { dg-do compile } +! This file depends on the module test_common_binding_labels_2. That module +! must be compiled first and not be removed until after this test. +module test_common_binding_labels_2_main + use, intrinsic :: iso_c_binding, only: c_double, c_int + implicit none + + common /mycom/ r, s ! { dg-error "does not match" } + real(c_double) :: r + real(c_double) :: s + ! this next line is an error; if a common block is bind(c), the binding label + ! for it must match across all scoping units that declare it. + bind(c, name="my_common_block_2") :: /mycom/ + + common /com2/ i ! { dg-error "does not match" } + integer(c_int) :: i + bind(c, name="mycom2") /com2/ +end module test_common_binding_labels_2_main + +program main + use test_common_binding_labels_2 ! { dg-error "does not match" } + use test_common_binding_labels_2_main +end program main + +! { dg-final { cleanup-modules "test_common_binding_labels_2_main test_common_binding_labels_2" } } diff --git a/gcc/testsuite/gfortran.dg/test_common_binding_labels_3.f03 b/gcc/testsuite/gfortran.dg/test_common_binding_labels_3.f03 new file mode 100644 index 00000000000..87d6c6b78f9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_common_binding_labels_3.f03 @@ -0,0 +1,10 @@ +! { dg-do compile } +module test_common_binding_labels_3 + use, intrinsic :: iso_c_binding, only: c_double + implicit none + + common /mycom/ r, s + real(c_double) :: r + real(c_double) :: s + bind(c, name="my_common_block") :: /mycom/ +end module test_common_binding_labels_3 diff --git a/gcc/testsuite/gfortran.dg/test_common_binding_labels_3_main.f03 b/gcc/testsuite/gfortran.dg/test_common_binding_labels_3_main.f03 new file mode 100644 index 00000000000..d2c67f65170 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_common_binding_labels_3_main.f03 @@ -0,0 +1,14 @@ +! { dg-do compile } +! This file depends on the module test_common_binding_labels_3. That module +! must be compiled first and not be removed until after this test. +module test_common_binding_labels_3_main + use, intrinsic :: iso_c_binding, only: c_int + integer(c_int), bind(c, name="my_common_block") :: my_int ! { dg-error "collides" } +end module test_common_binding_labels_3_main + +program main + use test_common_binding_labels_3_main + use test_common_binding_labels_3 ! { dg-error "collides" } +end program main + +! { dg-final { cleanup-modules "test_common_binding_labels_3_main test_common_binding_labels_3" } } diff --git a/gcc/testsuite/gfortran.dg/test_only_clause.f90 b/gcc/testsuite/gfortran.dg/test_only_clause.f90 new file mode 100644 index 00000000000..7c63e2be167 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/test_only_clause.f90 @@ -0,0 +1,20 @@ +! { dg-do run } +! { dg-additional-sources only_clause_main.c } +module testOnlyClause + + contains + subroutine testOnly(cIntPtr) bind(c, name="testOnly") + use, intrinsic :: iso_c_binding, only: c_ptr, c_int, c_f_pointer + implicit none + type(c_ptr), value :: cIntPtr + integer(c_int), pointer :: f90IntPtr + + call c_f_pointer(cIntPtr, f90IntPtr) + + ! f90IntPtr coming in has value of -11; this will make it -12 + f90IntPtr = f90IntPtr - 1 + if(f90IntPtr .ne. -12) then + call abort() + endif + end subroutine testOnly +end module testOnlyClause diff --git a/gcc/testsuite/gfortran.dg/use_iso_c_binding.f90 b/gcc/testsuite/gfortran.dg/use_iso_c_binding.f90 new file mode 100644 index 00000000000..6e6a023bcfb --- /dev/null +++ b/gcc/testsuite/gfortran.dg/use_iso_c_binding.f90 @@ -0,0 +1,49 @@ +! { dg-do compile } +! this is to simply test that the various ways the use statement can +! appear are handled by the compiler, since i did a special treatment +! of the intrinsic iso_c_binding module. note: if the user doesn't +! provide the 'intrinsic' keyword, the compiler will check for a user +! provided module by the name of iso_c_binding before using the +! intrinsic one. --Rickett, 09.26.06 +module use_stmt_0 + ! this is an error because c_ptr_2 does not exist + use, intrinsic :: iso_c_binding, only: c_ptr_2 ! { dg-error "Symbol 'c_ptr_2' referenced at \\(1\\) does not exist" } +end module use_stmt_0 + +module use_stmt_1 + ! this is an error because c_ptr_2 does not exist + use iso_c_binding, only: c_ptr_2 ! { dg-error "Symbol 'c_ptr_2' referenced at \\(1\\) does not exist" } +end module use_stmt_1 + +module use_stmt_2 + ! works fine + use, intrinsic :: iso_c_binding, only: c_ptr +end module use_stmt_2 + +module use_stmt_3 + ! works fine + use iso_c_binding, only: c_ptr +end module use_stmt_3 + +module use_stmt_4 + ! works fine + use, intrinsic :: iso_c_binding +end module use_stmt_4 + +module use_stmt_5 + ! works fine + use iso_c_binding +end module use_stmt_5 + +module use_stmt_6 + ! hmm, is this an error? if so, it's not being caught... + ! --Rickett, 09.13.06 + use, intrinsic :: iso_c_binding, only: c_int, c_int +end module use_stmt_6 + +module use_stmt_7 + ! hmm, is this an error? if so, it's not being caught... + ! --Rickett, 09.13.06 + use iso_c_binding, only: c_int, c_int +end module use_stmt_7 + diff --git a/gcc/testsuite/gfortran.dg/value_5.f90 b/gcc/testsuite/gfortran.dg/value_5.f90 new file mode 100644 index 00000000000..4b0dcefb340 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/value_5.f90 @@ -0,0 +1,68 @@ +! { dg-do compile } +! Length of character dummy variable with VALUE attribute: +! - must be initialization expression or omitted +! - C interoperable: must be initialization expression of length one +! or omitted +! +! Contributed by Tobias Burnus +program x + implicit none + character(10) :: c1,c10 + c1 = 'H' + c10 = 'Main' + call foo1(c1) + call foo2(c1) + call foo3(c10) + call foo4(c10) + call bar1(c1) + call bar2(c1) + call bar3(c10) + call bar4(c10) + +contains + + subroutine foo1(a) + character :: a + value :: a + end subroutine foo1 + + subroutine foo2(a) + character(1) :: a + value :: a + end subroutine foo2 + + subroutine foo3(a) + character(10) :: a + value :: a + end subroutine foo3 + + subroutine foo4(a) ! { dg-error "VALUE attribute must have constant length" } + character(*) :: a + value :: a + end subroutine foo4 + + subroutine bar1(a) + use iso_c_binding, only: c_char + character(kind=c_char) :: a + value :: a + end subroutine bar1 + + subroutine bar2(a) + use iso_c_binding, only: c_char + !character(kind=c_char,len=1) :: a + character(1,kind=c_char) :: a + value :: a + end subroutine bar2 + + subroutine bar3(a) ! { dg-error "VALUE attribute must have length one" } + use iso_c_binding, only: c_char + character(kind=c_char,len=10) :: a + value :: a + end subroutine bar3 + + subroutine bar4(a) ! { dg-error "VALUE attribute must have constant length" } + use iso_c_binding, only: c_char + character(kind=c_char,len=*) :: a + value :: a + end subroutine bar4 +end program x diff --git a/gcc/testsuite/gfortran.dg/value_test.f90 b/gcc/testsuite/gfortran.dg/value_test.f90 new file mode 100644 index 00000000000..12313324c4d --- /dev/null +++ b/gcc/testsuite/gfortran.dg/value_test.f90 @@ -0,0 +1,23 @@ +! { dg-do run } +program valueTests + integer :: myInt + interface + subroutine mySub(myInt) + integer, value :: myInt + end subroutine mySub + end interface + + myInt = 10 + + call mySub(myInt) + ! myInt should be unchanged since pass-by-value + if(myInt .ne. 10) then + call abort () + endif +end program valueTests + +subroutine mySub(myInt) + integer, value :: myInt + myInt = 11 +end subroutine mySub + diff --git a/gcc/testsuite/gfortran.dg/value_tests_f03.f90 b/gcc/testsuite/gfortran.dg/value_tests_f03.f90 new file mode 100644 index 00000000000..65251736122 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/value_tests_f03.f90 @@ -0,0 +1,37 @@ +! { dg-do run } +program value_tests_f03 + use, intrinsic :: iso_c_binding + real(c_double) :: myDouble + interface + subroutine value_test(myDouble) bind(c) + use, intrinsic :: iso_c_binding + real(c_double), value :: myDouble + end subroutine value_test + end interface + + myDouble = 9.0d0 + call value_test(myDouble) +end program value_tests_f03 + +subroutine value_test(myDouble) bind(c) + use, intrinsic :: iso_c_binding + real(c_double), value :: myDouble + interface + subroutine mySub(myDouble) + use, intrinsic :: iso_c_binding + real(c_double), value :: myDouble + end subroutine mySub + end interface + + myDouble = 10.0d0 + + call mySub(myDouble) +end subroutine value_test + +subroutine mySub(myDouble) + use, intrinsic :: iso_c_binding + real(c_double), value :: myDouble + + myDouble = 11.0d0 +end subroutine mySub + |