* [patch, fortran] Fix pointers not escaping via C_PTR
@ 2019-02-28 20:14 Thomas Koenig
2019-03-02 1:18 ` Steve Kargl
2019-03-09 14:17 ` Jerry DeLisle
0 siblings, 2 replies; 6+ messages in thread
From: Thomas Koenig @ 2019-02-28 20:14 UTC (permalink / raw)
To: fortran, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 800 bytes --]
Hello world,
the attached patch fixes a wrong-code bug for gfortran where pointers
were not marked as escaping. A C_PTR can be stashed away and reused
later (at least as long as the variable it points to remains active).
This is not a regression, but IMHO a bad wrong-code bug. The chances
of this patch introducing regressions are really, really low.
Regression-tested. OK for trunk?
Regards
Thomas
2019-02-29 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/71544
* trans-types.c (gfc_typenode_for_spec) Set ts->is_c_interop of
C_PTR and
C_FUNPTR.
(create_fn_spec): Mark argument as escaping if ts->is_c_interop
is set.
2019-02-29 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/71544
* gfortran.dg/c_ptr_tests_19.f90: New test.
[-- Attachment #2: p1.diff --]
[-- Type: text/x-patch, Size: 1021 bytes --]
Index: trans-types.c
===================================================================
--- trans-types.c (Revision 269260)
+++ trans-types.c (Arbeitskopie)
@@ -1176,7 +1176,8 @@ gfc_typenode_for_spec (gfc_typespec * spec, int co
{
spec->type = BT_INTEGER;
spec->kind = gfc_index_integer_kind;
- spec->f90_type = BT_VOID;
+ spec->f90_type = BT_VOID;
+ spec->is_c_interop = 1; /* Mark as escaping later. */
}
break;
case BT_VOID:
@@ -2957,7 +2958,8 @@ create_fn_spec (gfc_symbol *sym, tree fntype)
|| f->sym->ts.u.derived->attr.pointer_comp))
|| (f->sym->ts.type == BT_CLASS
&& (CLASS_DATA (f->sym)->ts.u.derived->attr.proc_pointer_comp
- || CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp)))
+ || CLASS_DATA (f->sym)->ts.u.derived->attr.pointer_comp))
+ || (f->sym->ts.type == BT_INTEGER && f->sym->ts.is_c_interop))
spec[spec_len++] = '.';
else if (f->sym->attr.intent == INTENT_IN)
spec[spec_len++] = 'r';
[-- Attachment #3: c_ptr_tests_19.f90 --]
[-- Type: text/x-fortran, Size: 820 bytes --]
! { dg-do run }
! PR 71544 - this failed with some optimization options due to a
! pointer not being marked as escaping.
module store_cptr
use, intrinsic :: iso_c_binding
implicit none
public
type(c_ptr), save :: cptr
end module store_cptr
subroutine init()
use, intrinsic :: iso_c_binding
implicit none
integer(c_int), pointer :: a
allocate(a)
call save_cptr(c_loc(a))
a = 100
end subroutine init
subroutine save_cptr(cptr_in)
use store_cptr
implicit none
type(c_ptr), intent(in) :: cptr_in
cptr = cptr_in
end subroutine save_cptr
program init_fails
use store_cptr
implicit none
integer(c_int), pointer :: val
call init()
call c_f_pointer(cptr,val)
print *,'The following line should print 100'
print *,val
end program init_fails
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch, fortran] Fix pointers not escaping via C_PTR
2019-02-28 20:14 [patch, fortran] Fix pointers not escaping via C_PTR Thomas Koenig
@ 2019-03-02 1:18 ` Steve Kargl
2019-03-02 11:23 ` Thomas Koenig
2019-03-09 14:17 ` Jerry DeLisle
1 sibling, 1 reply; 6+ messages in thread
From: Steve Kargl @ 2019-03-02 1:18 UTC (permalink / raw)
To: Thomas Koenig; +Cc: fortran, gcc-patches
On Thu, Feb 28, 2019 at 09:14:48PM +0100, Thomas Koenig wrote:
>
> the attached patch fixes a wrong-code bug for gfortran where pointers
> were not marked as escaping. A C_PTR can be stashed away and reused
> later (at least as long as the variable it points to remains active).
>
> This is not a regression, but IMHO a bad wrong-code bug. The chances
> of this patch introducing regressions are really, really low.
>
> Regression-tested. OK for trunk?
>
Is this a wrong code bug or a clever user wandering off into
undefined behavior?
> subroutine init()
> use, intrinsic :: iso_c_binding
> implicit none
> integer(c_int), pointer :: a
> allocate(a)
> call save_cptr(c_loc(a))
> a = 100
> end subroutine init
Of particular note, 'a' is an unsaved local variable. When init()
returns, 'a' goes out-of-scope. Fortran normally deallocates
an unsaved allocatable entity, but 'a' is an unsaved local variable
with the pointer attribute. For lack of a better term, 'allocate(a)'
allocates an anonymous target and associates the anonymous target
with the pointer 'a'. save_ptr() caches the address of the anonymous
target. When init() returns does the anonymous target get deallocated
or does the program leak memory? In addition, when init() returns,
what happens to the pointer association of 'a'? I think it becomes
undefined, which means the anonymous memory is inaccessible at least
by Fortran means as there are no pointers associated with the
anonymous target. The Fortran standard does not what happens to
leaked memory. In particular, the Fortran standard does not
guarantee that leaked memory is not reaped by some garbage collection
or that it must retain value 100.
--
Steve
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch, fortran] Fix pointers not escaping via C_PTR
2019-03-02 1:18 ` Steve Kargl
@ 2019-03-02 11:23 ` Thomas Koenig
2019-03-03 10:16 ` Thomas Koenig
0 siblings, 1 reply; 6+ messages in thread
From: Thomas Koenig @ 2019-03-02 11:23 UTC (permalink / raw)
To: sgk; +Cc: fortran, gcc-patches
Hi Steve,
> On Thu, Feb 28, 2019 at 09:14:48PM +0100, Thomas Koenig wrote:
>>
>> the attached patch fixes a wrong-code bug for gfortran where pointers
>> were not marked as escaping. A C_PTR can be stashed away and reused
>> later (at least as long as the variable it points to remains active).
>>
>> This is not a regression, but IMHO a bad wrong-code bug. The chances
>> of this patch introducing regressions are really, really low.
>>
>> Regression-tested. OK for trunk?
>>
>
> Is this a wrong code bug or a clever user wandering off into
> undefined behavior?
>
>> subroutine init()
>> use, intrinsic :: iso_c_binding
>> implicit none
>> integer(c_int), pointer :: a
>> allocate(a)
>> call save_cptr(c_loc(a))
>> a = 100
>> end subroutine init
>
> Of particular note, 'a' is an unsaved local variable. When init()
> returns, 'a' goes out-of-scope. Fortran normally deallocates
> an unsaved allocatable entity, but 'a' is an unsaved local variable
> with the pointer attribute. For lack of a better term, 'allocate(a)'
> allocates an anonymous target and associates the anonymous target
> with the pointer 'a'. save_ptr() caches the address of the anonymous
> target. When init() returns does the anonymous target get deallocated
> or does the program leak memory?
Neither. If there were no C_PTR pointing to the memory, it would
leak memory.
> In addition, when init() returns,
> what happens to the pointer association of 'a'?
'a' becomes undefined, hence it is no longer associated with the
memory.
> I think it becomes
> undefined, which means the anonymous memory is inaccessible at least
> by Fortran means as there are no pointers associated with the
> anonymous target.
That is not correct. Looking at F2018, 18.2.3.3, by using C_F_POINTER,
you can
" Associate a data pointer with the target of a C pointer and specify
its shape. "
First, this talks about a C pointer having a target. Second, you can
re-estabilsh the association to a different pointer to the Fortran
program.
Regards
Thomas
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch, fortran] Fix pointers not escaping via C_PTR
2019-03-02 11:23 ` Thomas Koenig
@ 2019-03-03 10:16 ` Thomas Koenig
0 siblings, 0 replies; 6+ messages in thread
From: Thomas Koenig @ 2019-03-03 10:16 UTC (permalink / raw)
To: sgk; +Cc: fortran, gcc-patches
I wrote:
> First, this talks about a C pointer having a target. Second, you can
> re-estabilsh the association to a different pointer to the Fortran
> program.
There is another point to consider: This is interoperability with C
we are dealing with, so we also have to follow C semantics.
And, love it or hate it, C pointers escape.
So, OK for trunk?
Regards
Thomas
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch, fortran] Fix pointers not escaping via C_PTR
2019-02-28 20:14 [patch, fortran] Fix pointers not escaping via C_PTR Thomas Koenig
2019-03-02 1:18 ` Steve Kargl
@ 2019-03-09 14:17 ` Jerry DeLisle
2019-03-09 19:23 ` Thomas Koenig
1 sibling, 1 reply; 6+ messages in thread
From: Jerry DeLisle @ 2019-03-09 14:17 UTC (permalink / raw)
To: Thomas Koenig, fortran, gcc-patches
On 2/28/19 12:14 PM, Thomas Koenig wrote:
> Hello world,
>
> the attached patch fixes a wrong-code bug for gfortran where pointers
> were not marked as escaping. A C_PTR can be stashed away and reused
> later (at least as long as the variable it points to remains active).
>
> This is not a regression, but IMHO a bad wrong-code bug. The chances
> of this patch introducing regressions are really, really low.
>
> Regression-tested. OK for trunk?
>
This is Ok except the test case. You are using dg-run but are not testing for
any condition. I think you want to to IF .... STOP instead of printing some test
values or dou you just want dg-conpile?
Fix test case and OK for trunk.
Jerry
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [patch, fortran] Fix pointers not escaping via C_PTR
2019-03-09 14:17 ` Jerry DeLisle
@ 2019-03-09 19:23 ` Thomas Koenig
0 siblings, 0 replies; 6+ messages in thread
From: Thomas Koenig @ 2019-03-09 19:23 UTC (permalink / raw)
To: Jerry DeLisle, fortran, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 279 bytes --]
Hi Jerry,
> I think you want to to IF .... STOP instead of printing some test values
> or dou you just want dg-conpile?
You're correct, I wanted a dg-do run.
Here is the version of the test case that I committed.
Thanks for the review (and the other one).
Regards
Thomas
[-- Attachment #2: c_ptr_tests_19.f90 --]
[-- Type: text/x-fortran, Size: 781 bytes --]
! { dg-do run }
! PR 71544 - this failed with some optimization options due to a
! pointer not being marked as escaping.
module store_cptr
use, intrinsic :: iso_c_binding
implicit none
public
type(c_ptr), save :: cptr
end module store_cptr
subroutine init()
use, intrinsic :: iso_c_binding
implicit none
integer(c_int), pointer :: a
allocate(a)
call save_cptr(c_loc(a))
a = 100
end subroutine init
subroutine save_cptr(cptr_in)
use store_cptr
implicit none
type(c_ptr), intent(in) :: cptr_in
cptr = cptr_in
end subroutine save_cptr
program init_fails
use store_cptr
implicit none
integer(c_int), pointer :: val
call init()
call c_f_pointer(cptr,val)
if (val /= 100) stop 1
end program init_fails
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2019-03-09 19:23 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-28 20:14 [patch, fortran] Fix pointers not escaping via C_PTR Thomas Koenig
2019-03-02 1:18 ` Steve Kargl
2019-03-02 11:23 ` Thomas Koenig
2019-03-03 10:16 ` Thomas Koenig
2019-03-09 14:17 ` Jerry DeLisle
2019-03-09 19:23 ` Thomas Koenig
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).