From patchwork Sat Mar 3 14:23:01 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Burnus X-Patchwork-Id: 144425 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id E31A51007D3 for ; Sun, 4 Mar 2012 01:23:30 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1331389415; h=Comment: DomainKey-Signature:Received:Received:Received:Received: Message-ID:Date:From:User-Agent:MIME-Version:To:Subject: Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:Sender:Delivered-To; bh=SK+/YDr HHYiM5T0XFu7xB0SNB5U=; b=YMvm1obQVxtVfdu/ctL3XcSDByhI6+d3YErBS/K yR5L8fYAY5CfzRpI5gEA2damOPwxJNTt7lmvM8eJgl/ALFUsHke2AXCMv1WyD0i/ +fC150ZMjd69bsT5NupYzT7L5VafiSstPCYAkvGtJKXhqWrWfQX5nx8IlWZqUbgU aIMM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Message-ID:Date:From:User-Agent:MIME-Version:To:Subject:Content-Type:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=KcY9wqSbfmWXVoAC6aqHkT/51B8IVEaFQCJaKEToGTOWvfjuLBfw6k5ebtYb+B TpMj4WGhd3HLBG4wzzWPdycRQxLppnt5n2u5YXDb+WImvPbYO7w4BFNxeKYpT5D5 d1Yu2dS02lAqd3s0OAFPgkQBH+Ho1ONOcWK28/8jHU7cs=; Received: (qmail 32152 invoked by alias); 3 Mar 2012 14:23:23 -0000 Received: (qmail 32133 invoked by uid 22791); 3 Mar 2012 14:23:19 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_NONE X-Spam-Check-By: sourceware.org Received: from mx01.qsc.de (HELO mx01.qsc.de) (213.148.129.14) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 03 Mar 2012 14:23:03 +0000 Received: from [192.168.178.22] (port-92-204-104-94.dynamic.qsc.de [92.204.104.94]) by mx01.qsc.de (Postfix) with ESMTP id 616FA3D378; Sat, 3 Mar 2012 15:23:01 +0100 (CET) Message-ID: <4F522945.6010001@net-b.de> Date: Sat, 03 Mar 2012 15:23:01 +0100 From: Tobias Burnus User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.2) Gecko/20120215 Thunderbird/10.0.2 MIME-Version: 1.0 To: gcc patches , gfortran Subject: [Patch, Fortran] Add -Wc-binding-type warning Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org GNU Fortran warns by default for code like the following: interface subroutine sub (n) bind (C) integer :: n end subroutine sub end interface Namely, it prints: Warning: Variable 'n' at (1) is a parameter to the BIND(C) procedure 'sub' but may not be C interoperable That's on one hand correct: There is no defined relation between Fortran default kinds (or any kind number) and the C types. Thus, the proper way is to use the parameters defined in ISO_C_BINDING, such as "c_int". On the other hand, "integer" and "int" is the same on many (but not on all systems) and, thus, many users simply use the default type. Compiling interfaces with hundreds of such definitions clutters the screen with those warnings and makes it difficult to spot other warnings. Thus, this patch adds a warning flag for this purpose - and it also excludes those warnings from the default setting. That's a bit in line with Fortran 2008 and TS 29113, which remove more and more constraints and force the users to ensure themselves that the variables are interoperable. However, keeping it as default warning is also fine with me. Build and regtested on x86-64-linux. OK? Tobias 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 * 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" } }