summaryrefslogtreecommitdiff
path: root/gcc/testsuite/gfortran.dg
diff options
context:
space:
mode:
authorkargl <kargl@138bc75d-0d04-0410-961f-82ee72b054a4>2007-07-02 02:47:21 +0000
committerkargl <kargl@138bc75d-0d04-0410-961f-82ee72b054a4>2007-07-02 02:47:21 +0000
commitc5d33754e3b885a5a2f323bedaa29371f44748b3 (patch)
treeac4b8eff52a0e3e3d04868300cc36392b6ca3faa /gcc/testsuite/gfortran.dg
parentaf1ff7da323f7dda32e4b0e7bda1d43fa4654252 (diff)
downloadgcc-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')
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_array_params.f0314
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_coms.f9051
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_coms_driver.c42
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_dts.f9041
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_dts_2.f0361
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_dts_2_driver.c37
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_dts_3.f0339
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_dts_4.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_dts_driver.c66
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_procs.f0339
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_2.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_3.f0319
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_5.f038
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_6.f0348
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_usage_7.f0316
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_vars.f9038
-rw-r--r--gcc/testsuite/gfortran.dg/bind_c_vars_driver.c46
-rw-r--r--gcc/testsuite/gfortran.dg/binding_c_table_15_1.f0314
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests.f0377
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_10.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_10_main.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_11.f0314
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_11_main.f0319
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_12.f0324
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_13.f038
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_13_main.f0316
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_14.f0312
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_2.f0335
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_3.f0330
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_4.f0324
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_5.f0312
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_6.f036
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_7.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_8.f039
-rw-r--r--gcc/testsuite/gfortran.dg/binding_label_tests_9.f0323
-rw-r--r--gcc/testsuite/gfortran.dg/c_assoc.f9068
-rw-r--r--gcc/testsuite/gfortran.dg/c_assoc_2.f0336
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_pointer_shape_test.f9019
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_pointer_tests.f9068
-rw-r--r--gcc/testsuite/gfortran.dg/c_f_tests_driver.c66
-rw-r--r--gcc/testsuite/gfortran.dg/c_funloc_tests.f0321
-rw-r--r--gcc/testsuite/gfortran.dg/c_funloc_tests_2.f0316
-rw-r--r--gcc/testsuite/gfortran.dg/c_funloc_tests_3.f0336
-rw-r--r--gcc/testsuite/gfortran.dg/c_funloc_tests_3_funcs.c25
-rw-r--r--gcc/testsuite/gfortran.dg/c_kind_params.f9076
-rw-r--r--gcc/testsuite/gfortran.dg/c_kind_tests_2.f0314
-rw-r--r--gcc/testsuite/gfortran.dg/c_kinds.c54
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_driver.c17
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_test.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_2.f0388
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_2_funcs.c42
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_3.f038
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_4.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_5.f0319
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_6.f0313
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_7.f0311
-rw-r--r--gcc/testsuite/gfortran.dg/c_loc_tests_8.f0313
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests.f0344
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_10.f0318
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_5.f0316
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_7.f0312
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_7_driver.c14
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_8.f0320
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_8_funcs.c26
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_9.f0331
-rw-r--r--gcc/testsuite/gfortran.dg/c_ptr_tests_driver.c34
-rw-r--r--gcc/testsuite/gfortran.dg/c_size_t_driver.c12
-rw-r--r--gcc/testsuite/gfortran.dg/c_size_t_test.f0316
-rw-r--r--gcc/testsuite/gfortran.dg/com_block_driver.f9034
-rw-r--r--gcc/testsuite/gfortran.dg/global_vars_c_init.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/global_vars_c_init_driver.c13
-rw-r--r--gcc/testsuite/gfortran.dg/global_vars_f90_init.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/global_vars_f90_init_driver.c14
-rw-r--r--gcc/testsuite/gfortran.dg/interop_params.f0324
-rw-r--r--gcc/testsuite/gfortran.dg/iso_c_binding_only.f039
-rw-r--r--gcc/testsuite/gfortran.dg/iso_c_binding_rename_1.f0383
-rw-r--r--gcc/testsuite/gfortran.dg/iso_c_binding_rename_1_driver.c19
-rw-r--r--gcc/testsuite/gfortran.dg/iso_c_binding_rename_2.f0340
-rw-r--r--gcc/testsuite/gfortran.dg/iso_c_binding_rename_2_driver.c16
-rw-r--r--gcc/testsuite/gfortran.dg/kind_tests_2.f037
-rw-r--r--gcc/testsuite/gfortran.dg/kind_tests_3.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/module_md5_1.f902
-rw-r--r--gcc/testsuite/gfortran.dg/only_clause_main.c12
-rw-r--r--gcc/testsuite/gfortran.dg/print_c_kinds.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/test_bind_c_parens.f037
-rw-r--r--gcc/testsuite/gfortran.dg/test_c_assoc.c55
-rw-r--r--gcc/testsuite/gfortran.dg/test_com_block.f9032
-rw-r--r--gcc/testsuite/gfortran.dg/test_common_binding_labels.f0342
-rw-r--r--gcc/testsuite/gfortran.dg/test_common_binding_labels_2.f0315
-rw-r--r--gcc/testsuite/gfortran.dg/test_common_binding_labels_2_main.f0325
-rw-r--r--gcc/testsuite/gfortran.dg/test_common_binding_labels_3.f0310
-rw-r--r--gcc/testsuite/gfortran.dg/test_common_binding_labels_3_main.f0314
-rw-r--r--gcc/testsuite/gfortran.dg/test_only_clause.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/use_iso_c_binding.f9049
-rw-r--r--gcc/testsuite/gfortran.dg/value_5.f9068
-rw-r--r--gcc/testsuite/gfortran.dg/value_test.f9023
-rw-r--r--gcc/testsuite/gfortran.dg/value_tests_f03.f9037
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
+