diff options
author | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-18 21:35:44 +0000 |
---|---|---|
committer | burnus <burnus@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-02-18 21:35:44 +0000 |
commit | cf028aa992fd55ef59a5287a67f72dc3e858a9af (patch) | |
tree | a6d48e0ab40d9ca539dea5cc470f0c583f2f348d /gcc | |
parent | 22c4d4208b1c35aa897d2ff6947892992a804f5e (diff) | |
download | ppe42-gcc-cf028aa992fd55ef59a5287a67f72dc3e858a9af.tar.gz ppe42-gcc-cf028aa992fd55ef59a5287a67f72dc3e858a9af.zip |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@170289 138bc75d-0d04-0410-961f-82ee72b054a4
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 c0b8d5afd14..2e9fc8c4948 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 3cf8df56e4a..d6c1f9f5a17 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 8bc8cd2a621..f023a37e5b0 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 00000000000..e64a2ef7abc --- /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" } } |