diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 401d66dab81..f488afc37bb 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,13 @@ +2012-03-03 Tobias Burnus + + * lang.opt (Wc-binding-type): New flag. + * options.c (gfc_init_options, gfc_handle_option): Handle it. + * invoke.texi (Wc-binding-type): Document it. + * gfortran.h (gfc_option_t): Add warn_c_binding_type. + * decl.c (verify_bind_c_sym): Handle -Wc-binding-type. + * symbol.c (gfc_set_default_type, verify_bind_c_derived_type): + Ditto. + 2012-03-03 Tobias Burnus PR fortran/48820 diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c index bdb8c39acb9..75b8a899c5e 100644 --- a/gcc/fortran/decl.c +++ b/gcc/fortran/decl.c @@ -3930,7 +3930,7 @@ verify_bind_c_sym (gfc_symbol *tmp_sym, gfc_typespec *ts, { tmp_sym = tmp_sym->result; /* Make sure it wasn't an implicitly typed result. */ - if (tmp_sym->attr.implicit_type) + if (tmp_sym->attr.implicit_type && gfc_option.warn_c_binding_type) { gfc_warning ("Implicitly declared BIND(C) function '%s' at " "%L may not be C interoperable", tmp_sym->name, @@ -3951,7 +3951,7 @@ verify_bind_c_sym (gfc_symbol *tmp_sym, gfc_typespec *ts, if (gfc_verify_c_interop (&(tmp_sym->ts)) != SUCCESS) { /* See if we're dealing with a sym in a common block or not. */ - if (is_in_common == 1) + if (is_in_common == 1 && gfc_option.warn_c_binding_type) { gfc_warning ("Variable '%s' in common block '%s' at %L " "may not be a C interoperable " @@ -3965,7 +3965,7 @@ verify_bind_c_sym (gfc_symbol *tmp_sym, gfc_typespec *ts, gfc_error ("Type declaration '%s' at %L is not C " "interoperable but it is BIND(C)", tmp_sym->name, &(tmp_sym->declared_at)); - else + else if (gfc_option.warn_c_binding_type) gfc_warning ("Variable '%s' at %L " "may not be a C interoperable " "kind but it is bind(c)", diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h index a5edd1306ad..a36e1068466 100644 --- a/gcc/fortran/gfortran.h +++ b/gcc/fortran/gfortran.h @@ -2200,6 +2200,7 @@ typedef struct int warn_aliasing; int warn_ampersand; int gfc_warn_conversion; + int warn_c_binding_type; int warn_conversion_extra; int warn_function_elimination; int warn_implicit_interface; diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi index 1f6de84b99f..38ebfe991b2 100644 --- a/gcc/fortran/invoke.texi +++ b/gcc/fortran/invoke.texi @@ -142,7 +142,7 @@ by type. Explanations are in the following sections. @xref{Error and Warning Options,,Options to request or suppress errors and warnings}. @gccoptlist{-Waliasing -Wall -Wampersand -Warray-bounds --Wcharacter-truncation @gol +-Wc-binding-type -Wcharacter-truncation @gol -Wconversion -Wfunction-elimination -Wimplicit-interface @gol -Wimplicit-procedure -Wintrinsic-shadow -Wintrinsics-std @gol -Wline-truncation -Wno-align-commons -Wno-tabs -Wreal-q-constant @gol @@ -773,6 +773,14 @@ Warn about array temporaries generated by the compiler. The information generated by this warning is sometimes useful in optimization, in order to avoid such temporaries. +@item -Wc-binding-type +@opindex @code{Wc-binding-type} +@cindex warning, C binding type +Warn if the a variable might not be C interoperable. In particular, warn if +the variable has been declared using an intrinsic type with default kind +instead of using a kind parameter defined for C interoperability in the +intrinsic @code{ISO_C_Binding} module. + @item -Wcharacter-truncation @opindex @code{Wcharacter-truncation} @cindex warnings, character truncation diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt index 56c589c6bdf..7e160a0c456 100644 --- a/gcc/fortran/lang.opt +++ b/gcc/fortran/lang.opt @@ -210,6 +210,10 @@ Warray-temporaries Fortran Warning Warn about creation of array temporaries +Wc-binding-type +Fortran Warning +Warn if the type of a variable might be not interoperable with C + Wcharacter-truncation Fortran Warning Warn about truncated character expressions diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c index b6929fce1f2..1010a93844c 100644 --- a/gcc/fortran/options.c +++ b/gcc/fortran/options.c @@ -97,6 +97,7 @@ gfc_init_options (unsigned int decoded_options_count, gfc_option.warn_ampersand = 0; gfc_option.warn_character_truncation = 0; gfc_option.warn_array_temp = 0; + gfc_option.warn_c_binding_type = 0; gfc_option.gfc_warn_conversion = 0; gfc_option.warn_conversion_extra = 0; gfc_option.warn_function_elimination = 0; @@ -456,6 +457,7 @@ set_Wall (int setting) { gfc_option.warn_aliasing = setting; gfc_option.warn_ampersand = setting; + gfc_option.warn_c_binding_type = setting; gfc_option.gfc_warn_conversion = setting; gfc_option.warn_line_truncation = setting; gfc_option.warn_surprising = setting; @@ -620,6 +622,10 @@ gfc_handle_option (size_t scode, const char *arg, int value, gfc_option.warn_array_temp = value; break; + case OPT_Wc_binding_type: + gfc_option.warn_c_binding_type = value; + break; + case OPT_Wcharacter_truncation: gfc_option.warn_character_truncation = value; break; diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 0cd7cc8d3e3..46e5f56feee 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -274,7 +274,7 @@ gfc_set_default_type (gfc_symbol *sym, int error_flag, gfc_namespace *ns) if (ts->type == BT_CHARACTER && ts->u.cl) sym->ts.u.cl = gfc_new_charlen (sym->ns, ts->u.cl); - if (sym->attr.is_bind_c == 1) + if (sym->attr.is_bind_c == 1 && gfc_option.warn_c_binding_type) { /* BIND(C) variables should not be implicitly declared. */ gfc_warning_now ("Implicitly declared BIND(C) variable '%s' at %L may " @@ -287,7 +287,8 @@ gfc_set_default_type (gfc_symbol *sym, int error_flag, gfc_namespace *ns) if (sym->ns->proc_name != NULL && (sym->ns->proc_name->attr.subroutine != 0 || sym->ns->proc_name->attr.function != 0) - && sym->ns->proc_name->attr.is_bind_c != 0) + && sym->ns->proc_name->attr.is_bind_c != 0 + && gfc_option.warn_c_binding_type) { /* Dummy args to a BIND(C) routine may not be interoperable if they are implicitly typed. */ @@ -3694,7 +3695,8 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) recompiles with different flags (e.g., -m32 and -m64 on x86_64 and using integer(4) to claim interop with a C_LONG). */ - if (derived_sym->attr.is_bind_c == 1) + if (derived_sym->attr.is_bind_c == 1 + && gfc_option.warn_c_binding_type) /* If the derived type is bind(c), all fields must be interop. */ gfc_warning ("Component '%s' in derived type '%s' at %L " @@ -3702,7 +3704,7 @@ verify_bind_c_derived_type (gfc_symbol *derived_sym) "derived type '%s' is BIND(C)", curr_comp->name, derived_sym->name, &(curr_comp->loc), derived_sym->name); - else + else if (gfc_option.warn_c_binding_type) /* If derived type is param to bind(c) routine, or to one of the iso_c_binding procs, it must be interoperable, so all fields must interop too. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 65e9aaee4df..a4275d9d867 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2012-03-03 Tobias Burnus + + * gfortran.dg/bind_c_dts_4.f03: Add dg-options -Wc-binding-type. + * gfortran.dg/bind_c_implicit_vars.f03: Ditto. + * gfortran.dg/bind_c_usage_8.f03: Ditto. + * gfortran.dg/c_kind_tests_2.f03: Ditto. + * gfortran.dg/class_30.f90: Remove dg-warning line. + * gfortran.dg/bind_c_usage_25.f90: New. + 2012-03-03 Tobias Burnus PR fortran/48820 diff --git a/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 b/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 index b2eb5694f1c..c6fc4024443 100644 --- a/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 +++ b/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-Wc-binding-type" } module test use iso_c_binding, only: c_int type, bind(c) :: foo diff --git a/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 b/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 index d6b4b6d6176..bac7d4d5815 100644 --- a/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 +++ b/gcc/testsuite/gfortran.dg/bind_c_implicit_vars.f03 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-Wc-binding-type" } module bind_c_implicit_vars bind(c) :: j ! { dg-warning "may not be C interoperable" } diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_25.f90 b/gcc/testsuite/gfortran.dg/bind_c_usage_25.f90 new file mode 100644 index 00000000000..087a9e05ac9 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_25.f90 @@ -0,0 +1,63 @@ +! { dg-do compile } +! { dg-options "-Wno-c-binding-type" } +! +! That's a copy of "bind_c_usage_8.f03", "bind_c_dts_4.f03", +! "bind_c_implicit_vars.f03" and "c_kind_tests_2.f03" +! to check that with -Wno-c-binding-type no warning is printed. +! + +MODULE ISO_C_UTILITIES + USE ISO_C_BINDING + implicit none + CHARACTER(C_CHAR), DIMENSION(1), SAVE, TARGET, PRIVATE :: dummy_string="?" +CONTAINS + FUNCTION C_F_STRING(CPTR) RESULT(FPTR) + use, intrinsic :: iso_c_binding + TYPE(C_PTR), INTENT(IN) :: CPTR ! The C address + CHARACTER(KIND=C_CHAR), DIMENSION(:), POINTER :: FPTR + INTERFACE + FUNCTION strlen(string) RESULT(len) BIND(C,NAME="strlen") + USE ISO_C_BINDING + TYPE(C_PTR), VALUE :: string ! A C pointer + END FUNCTION + END INTERFACE + CALL C_F_POINTER(FPTR=FPTR, CPTR=CPTR, SHAPE=[strlen(CPTR)]) + END FUNCTION +END MODULE ISO_C_UTILITIES + +module test +use iso_c_binding, only: c_int + type, bind(c) :: foo + integer :: p + end type + type(foo), bind(c) :: cp +end module test + +module bind_c_implicit_vars + +bind(c) :: j + +contains + subroutine sub0(i) bind(c) + i = 0 + end subroutine sub0 +end module bind_c_implicit_vars + +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-warning "is for type REAL" } + integer(c_double), bind(c) :: myCInt2 ! { dg-warning "is for type REAL" } + + integer, parameter :: myI = c_int + real(myI) :: myReal ! { dg-warning "is for type INTEGER" } + real(myI), bind(c) :: myCFloat2 ! { dg-warning "is for type INTEGER" } + real(4), bind(c) :: myFloat +end module c_kind_tests_2 + +! { dg-final { cleanup-modules "c_kind_tests_2" } } +! { dg-final { cleanup-modules "bind_c_implicit_vars" } } +! { dg-final { cleanup-modules "test" } } +! { dg-final { cleanup-modules "iso_c_utilities" } } diff --git a/gcc/testsuite/gfortran.dg/bind_c_usage_8.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_8.f03 index a94545cc51c..e31af86bffd 100644 --- a/gcc/testsuite/gfortran.dg/bind_c_usage_8.f03 +++ b/gcc/testsuite/gfortran.dg/bind_c_usage_8.f03 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-Wc-binding-type" } ! This should compile, though there is a warning about the type of len ! (return variable of strlen()) for being implicit. ! PR fortran/32797 diff --git a/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 b/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 index a8cdbdff50c..5bc99f55387 100644 --- a/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 +++ b/gcc/testsuite/gfortran.dg/c_kind_tests_2.f03 @@ -1,4 +1,5 @@ ! { dg-do compile } +! { dg-options "-Wc-binding-type" } module c_kind_tests_2 use, intrinsic :: iso_c_binding diff --git a/gcc/testsuite/gfortran.dg/class_30.f90 b/gcc/testsuite/gfortran.dg/class_30.f90 index f2cedcb9763..343c0d6139a 100644 --- a/gcc/testsuite/gfortran.dg/class_30.f90 +++ b/gcc/testsuite/gfortran.dg/class_30.f90 @@ -15,7 +15,6 @@ end type t2 type, bind(C):: t3 class(t), pointer :: y - ! { dg-warning "may not be C interoperable" "" { target *-*-* } 17 } ! { dg-error "Polymorphic component y at .1. in SEQUENCE or BIND" "" { target *-*-* } 17 } end type t3 end