[PATCH,fortran]: proposed fix for PR 32732
Christopher D. Rickett
crickett@lanl.gov
Wed Jul 18 18:22:00 GMT 2007
hi all,
attached is a proposed fix for PR 32732. it modifies the expected
expression for by-value character arguments to BIND(C) procedures, and the
type of the backend_decl for the dummy to not expect an address.
bootstrapped and regtested on x86 and x86_64 linux with no new failures.
Chris
:ADDPATCH fortran:
2007-07-18 Christopher D. Rickett <crickett@lanl.gov>
PR fortran/32732
* trans-decl.c (generate_local_decl): Convert the TREE_TYPE for by
value character dummy args of BIND(C) procedures.
* trans-expr.c (gfc_conv_variable): Do not build address
expression for BT_CHARACTER dummy arg of a BIND(C) procedure.
2007-07-18 Christopher D. Rickett <crickett@lanl.gov>
PR fortran/32732
* gfortran.dg/c_char_tests.f03: New test case.
* gfortran.dg/c_char_driver.c: Driver for c_char_tests.f03.
* gfortran.dg/c_char_tests_2.f03: New test case.
* gfortran.dg/pr32732.f03: New test case.
-------------- next part --------------
Index: gcc/testsuite/gfortran.dg/c_char_tests.f03
===================================================================
--- gcc/testsuite/gfortran.dg/c_char_tests.f03 (revision 0)
+++ gcc/testsuite/gfortran.dg/c_char_tests.f03 (revision 0)
@@ -0,0 +1,28 @@
+! { dg-do run }
+! { dg-additional-sources c_char_driver.c }
+! Verify that character dummy arguments for bind(c) procedures can work both
+! by-value and by-reference when called by either C or Fortran.
+module c_char_tests
+ use, intrinsic :: iso_c_binding, only: c_char
+ implicit none
+contains
+ subroutine param_test(my_char, my_char_2) bind(c)
+ character(c_char), value :: my_char
+ character(c_char), value :: my_char_2
+ if(my_char /= c_char_'y') call abort()
+ if(my_char_2 /= c_char_'z') call abort()
+
+ call sub1(my_char)
+ end subroutine param_test
+
+ subroutine sub0() bind(c)
+ call param_test('y', 'z')
+ end subroutine sub0
+
+ subroutine sub1(my_char_ref) bind(c)
+ character(c_char) :: my_char_ref
+ if(my_char_ref /= c_char_'y') call abort()
+ end subroutine sub1
+end module c_char_tests
+
+! { dg-final { cleanup-modules "c_char_tests" } }
Index: gcc/testsuite/gfortran.dg/c_char_tests_2.f03
===================================================================
--- gcc/testsuite/gfortran.dg/c_char_tests_2.f03 (revision 0)
+++ gcc/testsuite/gfortran.dg/c_char_tests_2.f03 (revision 0)
@@ -0,0 +1,32 @@
+! { dg-do run }
+! Verify that the changes made to character dummy arguments for bind(c)
+! procedures doesn't break non-bind(c) routines.
+subroutine bar(a)
+ use, intrinsic :: iso_c_binding, only: c_char
+ character(c_char), value :: a
+ if(a /= c_char_'a') call abort()
+end subroutine bar
+
+subroutine bar2(a)
+ use, intrinsic :: iso_c_binding, only: c_char
+ character(c_char) :: a
+ if(a /= c_char_'a') call abort()
+end subroutine bar2
+
+use iso_c_binding
+implicit none
+interface
+ subroutine bar(a)
+ import
+ character(c_char),value :: a
+ end subroutine bar
+ subroutine bar2(a)
+ import
+ character(c_char) :: a
+ end subroutine bar2
+end interface
+ character(c_char) :: z
+ z = 'a'
+ call bar(z)
+ call bar2(z)
+end
Index: gcc/testsuite/gfortran.dg/pr32732.f03
===================================================================
--- gcc/testsuite/gfortran.dg/pr32732.f03 (revision 0)
+++ gcc/testsuite/gfortran.dg/pr32732.f03 (revision 0)
@@ -0,0 +1,24 @@
+! { dg-do run }
+! Verify by-value passing of character arguments w/in Fortran to a bind(c)
+! procedure.
+module pr32732
+ use, intrinsic :: iso_c_binding, only: c_char
+ implicit none
+contains
+ subroutine test(a) bind(c)
+ character(kind=c_char), value :: a
+ call test2(a)
+ end subroutine test
+ subroutine test2(a) bind(c)
+ character(kind=c_char), value :: a
+ if(a /= c_char_'a') call abort ()
+ print *, 'a=',a
+ end subroutine test2
+end module pr32732
+
+program main
+ use pr32732
+ implicit none
+ call test('a')
+end program main
+! { dg-final { cleanup-modules "pr32732" } }
Index: gcc/testsuite/gfortran.dg/c_char_driver.c
===================================================================
--- gcc/testsuite/gfortran.dg/c_char_driver.c (revision 0)
+++ gcc/testsuite/gfortran.dg/c_char_driver.c (revision 0)
@@ -0,0 +1,14 @@
+void param_test(char my_char, char my_char_2);
+void sub0(void);
+void sub1(char *my_char);
+
+int main(int argc, char **argv)
+{
+ char my_char = 'y';
+
+ param_test('y', 'z');
+ sub0();
+ sub1(&my_char);
+
+ return 0;
+}
Index: gcc/fortran/trans-expr.c
===================================================================
--- gcc/fortran/trans-expr.c (revision 126704)
+++ gcc/fortran/trans-expr.c (working copy)
@@ -473,8 +473,9 @@ gfc_conv_variable (gfc_se * se, gfc_expr
se->expr = build_fold_indirect_ref (se->expr);
/* A character with VALUE attribute needs an address
- expression. */
- if (sym->attr.value)
+ expression if it's a dummy arg of a bind(c) routine. */
+ if (sym->attr.value
+ && (sym->ns == NULL || !sym->ns->proc_name->attr.is_bind_c))
se->expr = build_fold_addr_expr (se->expr);
}
Index: gcc/fortran/trans-decl.c
===================================================================
--- gcc/fortran/trans-decl.c (revision 126704)
+++ gcc/fortran/trans-decl.c (working copy)
@@ -3018,6 +3018,19 @@ generate_local_decl (gfc_symbol * sym)
&sym->declared_at);
}
+ if (sym->attr.dummy == 1)
+ {
+ /* Modify the tree type for scalar character dummy arguments of bind(c)
+ procedures if they are passed by value. The tree type for them will
+ be promoted to INTEGER_TYPE for the middle end, which appears to be
+ what C would do with characters passed by-value. The value attribute
+ implies the dummy is a scalar. */
+ if (sym->attr.value == 1 && sym->backend_decl != NULL
+ && sym->ts.type == BT_CHARACTER && sym->ts.is_c_interop
+ && sym->ns->proc_name != NULL && sym->ns->proc_name->attr.is_bind_c)
+ TREE_TYPE (sym->backend_decl) = unsigned_char_type_node;
+ }
+
/* Make sure we convert the types of the derived types from iso_c_binding
into (void *). */
if (sym->attr.flavor != FL_PROCEDURE && sym->attr.is_iso_c
More information about the Gcc-patches
mailing list