Message ID | trinity-f485a27b-2425-4203-8931-df0e244fe304-1636738788711@3c-app-gmx-bap24 |
---|---|
State | New |
Headers | show |
Series | PR fortran/102368 - Failure to compile program using the C_SIZEOF function in ISO_C_BINDING | expand |
On Fri, 12 Nov 2021 18:39:48 +0100 Harald Anlauf via Fortran <fortran@gcc.gnu.org> wrote: Sounds plausible. Nits: > diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 > new file mode 100644 > index 00000000000..3cfa3371f72 > --- /dev/null > +++ b/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 [I'd name this .f08, no?] > @@ -0,0 +1,13 @@ > +! { dg-do compile } > +! { dg-options "-std=f2008 -fdump-tree-original" } [and drop the -std] > +! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 0 "original" } } [ ...-times 0 == scan-tree-dump-not ] > +! PR fortran/102368 > + > +program main > + use, intrinsic :: iso_c_binding > + implicit none > + character(kind=c_char, len=*), parameter :: a = 'abc' > + character(kind=c_char, len=8) :: b character(kind=c_char, len=-42) :: c ! { dg-error "positive integer greater than 0" } character(kind=c_char, len=-0) :: d ! { dg-error "positive integer greater than 0" } character(kind=c_char, len=0) :: e ! { dg-error "positive integer greater than 0" } character(kind=c_char, len=+0) :: f ! { dg-error "positive integer greater than 0" } character(kind=c_char, len=0.0d) :: g ! { dg-error "positive integer greater than 0" } character(kind=c_char, len=3.) :: h ! { dg-error "positive integer greater than 0" } character(kind=c_char, len=.031415e2) :: i ! { dg-error "positive integer greater than 0" } ... are caught elsewhere if one assumes that len should be a positive int > 0 (didn't look) Also did not look if character(kind=c_char, len=SELECTED_REAL_KIND(10)) :: j ! is that constant? Should it be? > + if (c_sizeof (a) /= 3) stop 1 > + if (c_sizeof (b) /= 8) stop 2 indeed. cheers, > +end program main > -- > 2.26.2 >
Hi Bernhard, Am 12.11.21 um 21:18 schrieb Bernhard Reutner-Fischer via Fortran: > On Fri, 12 Nov 2021 18:39:48 +0100 > Harald Anlauf via Fortran <fortran@gcc.gnu.org> wrote: > > Sounds plausible. this is what I thought, too. And nvfortran and flang accept the testcase, as well as crayftn (cce/12.0.2). Intel accepts the first case (a), but rejects the second (b). I asked in the Intel forum. Steve Lionel doubts that the code is valid. There might be some confusion on my side, but having Cray on my side feels good. (Although the PR was entered into bugzilla by a Cray employee). > Nits: > >> diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 >> new file mode 100644 >> index 00000000000..3cfa3371f72 >> --- /dev/null >> +++ b/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 > > [I'd name this .f08, no?] > >> @@ -0,0 +1,13 @@ >> +! { dg-do compile } >> +! { dg-options "-std=f2008 -fdump-tree-original" } > > [and drop the -std] > >> +! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 0 "original" } } > > [ ...-times 0 == scan-tree-dump-not ] Good point. >> +! PR fortran/102368 >> + >> +program main >> + use, intrinsic :: iso_c_binding >> + implicit none >> + character(kind=c_char, len=*), parameter :: a = 'abc' >> + character(kind=c_char, len=8) :: b > > character(kind=c_char, len=-42) :: c ! { dg-error "positive integer greater than 0" } > character(kind=c_char, len=-0) :: d ! { dg-error "positive integer greater than 0" } > character(kind=c_char, len=0) :: e ! { dg-error "positive integer greater than 0" } > character(kind=c_char, len=+0) :: f ! { dg-error "positive integer greater than 0" } > character(kind=c_char, len=0.0d) :: g ! { dg-error "positive integer greater than 0" } > character(kind=c_char, len=3.) :: h ! { dg-error "positive integer greater than 0" } > character(kind=c_char, len=.031415e2) :: i ! { dg-error "positive integer greater than 0" } > ... > are caught elsewhere if one assumes that len should be a positive int > 0 (didn't look) > Also did not look if > character(kind=c_char, len=SELECTED_REAL_KIND(10)) :: j ! is that constant? Should it be? These things should already be handled in general and elsewhere, as they are not about interoperability. >> + if (c_sizeof (a) /= 3) stop 1 >> + if (c_sizeof (b) /= 8) stop 2 > > indeed. > cheers, > >> +end program main >> -- >> 2.26.2 >> > Thanks, Harald
From 1fc44a5bf0b294021490f3c0a1539982a09000f5 Mon Sep 17 00:00:00 2001 From: Harald Anlauf <anlauf@gmx.de> Date: Fri, 12 Nov 2021 18:32:18 +0100 Subject: [PATCH] Fortran: fix interoperability check for character variables for F2008 gcc/fortran/ChangeLog: PR fortran/102368 * check.c (is_c_interoperable): F2008:15.3.5 relaxed the condition on interoperable character variables and allows values different from one. gcc/testsuite/ChangeLog: PR fortran/102368 * gfortran.dg/c_sizeof_7.f90: New test. --- gcc/fortran/check.c | 20 ++++++++++++++------ gcc/testsuite/gfortran.dg/c_sizeof_7.f90 | 13 +++++++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/c_sizeof_7.f90 diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c index ffa07b510cd..69a2e35e81b 100644 --- a/gcc/fortran/check.c +++ b/gcc/fortran/check.c @@ -5272,13 +5272,21 @@ is_c_interoperable (gfc_expr *expr, const char **msg, bool c_loc, bool c_f_ptr) && !gfc_simplify_expr (expr->ts.u.cl->length, 0)) gfc_internal_error ("is_c_interoperable(): gfc_simplify_expr failed"); - if (!c_loc && expr->ts.u.cl - && (!expr->ts.u.cl->length - || expr->ts.u.cl->length->expr_type != EXPR_CONSTANT - || mpz_cmp_si (expr->ts.u.cl->length->value.integer, 1) != 0)) + if (!c_loc && expr->ts.u.cl) { - *msg = "Type shall have a character length of 1"; - return false; + bool len_ok = (expr->ts.u.cl->length + && expr->ts.u.cl->length->expr_type == EXPR_CONSTANT); + + /* F2003:15.2.1 required the length of a character variable to be one. + F2008:15.3.5 relaxed this to constant length. */ + if (len_ok && !(gfc_option.allow_std & GFC_STD_F2008)) + len_ok = mpz_cmp_si (expr->ts.u.cl->length->value.integer, 1) == 0; + + if (!len_ok) + { + *msg = "Type shall have a character length of 1"; + return false; + } } } diff --git a/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 b/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 new file mode 100644 index 00000000000..3cfa3371f72 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/c_sizeof_7.f90 @@ -0,0 +1,13 @@ +! { dg-do compile } +! { dg-options "-std=f2008 -fdump-tree-original" } +! { dg-final { scan-tree-dump-times "_gfortran_stop_numeric" 0 "original" } } +! PR fortran/102368 + +program main + use, intrinsic :: iso_c_binding + implicit none + character(kind=c_char, len=*), parameter :: a = 'abc' + character(kind=c_char, len=8) :: b + if (c_sizeof (a) /= 3) stop 1 + if (c_sizeof (b) /= 8) stop 2 +end program main -- 2.26.2