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

	* 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  <burnus@net-b.de>

	* 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.

diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index bdb8c39..75b8a89 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 a5edd13..1c242b4 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2200,6 +2201,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 1f6de84..38ebfe9 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 56c589c..7e160a0 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 b6929fc..1010a93 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 0cd7cc8..46e5f56 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/gfortran.dg/bind_c_dts_4.f03 b/gcc/testsuite/gfortran.dg/bind_c_dts_4.f03
index b2eb569..c6fc402 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 d6b4b6d..bac7d4d 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_8.f03 b/gcc/testsuite/gfortran.dg/bind_c_usage_8.f03
index a94545c..e31af86 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 a8cdbdf..5bc99f5 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 f2cedcb..343c0d6 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
--- /dev/null	2012-03-03 08:42:31.311826379 +0100
+++ gcc/gcc/testsuite/gfortran.dg/bind_c_usage_25.f90	2012-03-03 14:20:38.000000000 +0100
@@ -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" } }
