diff options
author | Tobias Burnus <burnus@gcc.gnu.org> | 2011-02-18 22:35:44 +0100 |
---|---|---|
committer | Tobias Burnus <burnus@gcc.gnu.org> | 2011-02-18 22:35:44 +0100 |
commit | 56ee2f5a356d5e0067cb233c759315b1f6fa51ff (patch) | |
tree | a6d48e0ab40d9ca539dea5cc470f0c583f2f348d /gcc | |
parent | eddabc80ca0e2fcdcf45fc55a9604145a46b857a (diff) | |
download | gcc-56ee2f5a356d5e0067cb233c759315b1f6fa51ff.zip gcc-56ee2f5a356d5e0067cb233c759315b1f6fa51ff.tar.gz gcc-56ee2f5a356d5e0067cb233c759315b1f6fa51ff.tar.bz2 |
2011-02-18 Tobias Burnus
PR fortran/47775
* trans-expr.c (arrayfunc_assign_needs_temporary): Use
esym to check whether the specific procedure returns an
allocatable or pointer.
2011-02-18 Tobias Burnus
PR fortran/47775
* gfortran.dg/func_result_6.f90: New.
From-SVN: r170289
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/fortran/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/fortran/trans-expr.c | 10 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gfortran.dg/func_result_6.f90 | 73 |
4 files changed, 92 insertions, 3 deletions
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index c0b8d5a..2e9fc8c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,10 @@ +2011-02-18 Tobias Burnus + + PR fortran/47775 + * trans-expr.c (arrayfunc_assign_needs_temporary): Use + esym to check whether the specific procedure returns an + allocatable or pointer. + 2011-02-18 Michael Matz <matz@suse.de> PR fortran/45586 diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c index 3cf8df5..d6c1f9f 100644 --- a/gcc/fortran/trans-expr.c +++ b/gcc/fortran/trans-expr.c @@ -5392,9 +5392,13 @@ arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2) if (gfc_ref_needs_temporary_p (expr1->ref)) return true; - /* Functions returning pointers need temporaries. */ - if (expr2->symtree->n.sym->attr.pointer - || expr2->symtree->n.sym->attr.allocatable) + /* Functions returning pointers or allocatables need temporaries. */ + c = expr2->value.function.esym + ? (expr2->value.function.esym->attr.pointer + || expr2->value.function.esym->attr.allocatable) + : (expr2->symtree->n.sym->attr.pointer + || expr2->symtree->n.sym->attr.allocatable); + if (c) return true; /* Character array functions need temporaries unless the diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8bc8cd2..f023a37 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2011-02-18 Tobias Burnus + + PR fortran/47775 + * gfortran.dg/func_result_6.f90: New. + 2011-02-18 Paolo Carlini <paolo.carlini@oracle.com> PR c++/47795 diff --git a/gcc/testsuite/gfortran.dg/func_result_6.f90 b/gcc/testsuite/gfortran.dg/func_result_6.f90 new file mode 100644 index 0000000..e64a2ef --- /dev/null +++ b/gcc/testsuite/gfortran.dg/func_result_6.f90 @@ -0,0 +1,73 @@ +! { dg-do run } +! +! PR fortran/47775 +! +! Contributed by Fran Martinez Fadrique +! +! Before, a temporary was missing for generic procedured (cf. test()) +! as the allocatable attribute was ignored for the check whether a +! temporary is required +! +module m +type t +contains + procedure, NOPASS :: foo => foo + generic :: gen => foo +end type t +contains + function foo(i) + integer, allocatable :: foo(:) + integer :: i + allocate(foo(2)) + foo(1) = i + foo(2) = i + 10 + end function foo +end module m + +use m +type(t) :: x +integer, pointer :: ptr1, ptr2 +integer, target :: bar1(2) +integer, target, allocatable :: bar2(:) + +allocate(bar2(2)) +ptr1 => bar1(2) +ptr2 => bar2(2) + +bar1 = x%gen(1) +if (ptr1 /= 11) call abort() +bar1 = x%foo(2) +if (ptr1 /= 12) call abort() +bar2 = x%gen(3) +if (ptr2 /= 13) call abort() +bar2 = x%foo(4) +if (ptr2 /= 14) call abort() +bar2(:) = x%gen(5) +if (ptr2 /= 15) call abort() +bar2(:) = x%foo(6) +if (ptr2 /= 16) call abort() + +call test() +end + +subroutine test +interface gen + procedure foo +end interface gen + +integer, target :: bar(2) +integer, pointer :: ptr +bar = [1,2] +ptr => bar(2) +if (ptr /= 2) call abort() +bar = gen() +if (ptr /= 77) call abort() +contains + function foo() + integer, allocatable :: foo(:) + allocate(foo(2)) + foo = [33, 77] + end function foo +end subroutine test + +! { dg-final { cleanup-modules "m" } } |