Created attachment 43691 [details] Module exemplifying failure The gfortran compiler mistakenly prohibits calls to `c_f_pointer` where `fptr` is a noninteroperable *scalar* derived type. The standard only prohibits this for *arrays* of the derived type (and this restriction is lifted in TS29113). The compiler correctly allows `c_loc(fptr)` on the same pointer object; and according to the standard the ability to do `c_loc` and `c_f_pointer` should be symmetric. I have attached a minimal test case: ``` $ gfortran-mp-7 -save-temps -std=f2003 -c -Wall -Wextra ftest.f90 ftest.f90:27:38: call c_f_pointer(cptr=p, fptr=handle) 1 Error: TS 29113/TS 18508: Noninteroperable array FPTR at (1) to C_F_POINTER: Expression is a noninteroperable derived type ``` I think the code in `gfc_check_c_f_pointer` in `gcc/fortran/check.c` simply needs to be replaced by similar code in `gfc_check_c_loc`: ``` if (!is_c_interoperable (fptr, &msg, false, true)) ``` should become ``` if (fptr->rank > 0 && !is_c_interoperable (fptr, &msg, false, true)) ```
- Correction in test case: `call dellocate(` should be replaced by `deallocate(` (but this doesn't affect the behavior or test outcome - Also note that the Fortran 2003 standard itself includes a structurally identical example in "C.10.2.4 Example of opaque communication between C and Fortran", if further evidence is needed that this is allowable with `-std=f2003` and `-std=f2008`.
There is no error for -std=f2008ts or -std=2018.
That's correct, because those standards include TS 29113 which allows arrays to be referenced. `-std=f2008ts` also works. The problem is that the usage described is valid Fortran 2003 but is marked otherwise. This is like the "const" qualifier raising an error with `gcc -std=c89` but allowing it with `gcc -std=c99`. It's valid with C99, sure, but the feature is allowed in the C89 standard as well.
Is the following patch OK? return false; } - if (!is_c_interoperable (fptr, &msg, false, true)) + if (fptr->rank > 0 && !is_c_interoperable (fptr, &msg, false, true)) return gfc_notify_std (GFC_STD_F2008_TS, "Noninteroperable array FPTR " "at %L to C_F_POINTER: %s", &fptr->where, msg);
That looks perfect, thank you for looking into this. (In reply to Dominique d'Humieres from comment #4) > Is the following patch OK? > > return false; > } > > - if (!is_c_interoperable (fptr, &msg, false, true)) > + if (fptr->rank > 0 && !is_c_interoperable (fptr, &msg, false, true)) > return gfc_notify_std (GFC_STD_F2008_TS, "Noninteroperable array FPTR " > "at %L to C_F_POINTER: %s", &fptr->where, msg);
> That looks perfect, thank you for looking into this. So taking the PR. I'll do the packaging and submit it.
Author: dominiq Date: Sun Mar 25 11:30:24 2018 New Revision: 258843 URL: https://gcc.gnu.org/viewcvs?rev=258843&root=gcc&view=rev Log: 2018-03-25 Seth Johnson <johnsonsr@ornl.gov> Dominique d'Humieres <dominiq@gcc.gnu.org> PR fortran/84924 * check.c (gfc_check_c_f_pointer): Allow scalar noninteroperable scalar derived type with -std=f2003 and -std=f2008. 2018-03-25 Seth Johnson <johnsonsr@ornl.gov> Dominique d'Humieres <dominiq@gcc.gnu.org> PR fortran/84924 * gfortran.dg/scalar_pointer_1.f90: New test. Added: trunk/gcc/testsuite/gfortran.dg/scalar_pointer_1.f90 Modified: trunk/gcc/fortran/ChangeLog trunk/gcc/fortran/check.c trunk/gcc/testsuite/ChangeLog
Closing as FIXED.
Thanks guys for the fast fix and review!