summaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0202-2011-04-30-Paul-Thomas-pault-gcc.gnu.org.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0202-2011-04-30-Paul-Thomas-pault-gcc.gnu.org.patch')
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0202-2011-04-30-Paul-Thomas-pault-gcc.gnu.org.patch198
1 files changed, 198 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0202-2011-04-30-Paul-Thomas-pault-gcc.gnu.org.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0202-2011-04-30-Paul-Thomas-pault-gcc.gnu.org.patch
new file mode 100644
index 0000000000..59380b0492
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0202-2011-04-30-Paul-Thomas-pault-gcc.gnu.org.patch
@@ -0,0 +1,198 @@
1From f90642b60dbe411df162174646348f4a7d5e1a63 Mon Sep 17 00:00:00 2001
2From: pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4>
3Date: Sat, 30 Apr 2011 12:00:50 +0000
4Subject: [PATCH] 2011-04-30 Paul Thomas <pault@gcc.gnu.org>
5
6 PR fortran/48462
7 PR fortran/48746
8 * trans-expr.c ( arrayfunc_assign_needs_temporary): Need a temp
9 if automatic reallocation on assignement is active, the lhs is a
10 target and the rhs an intrinsic function.
11 (realloc_lhs_bounds_for_intrinsic_call): Rename as next.
12 (fcncall_realloc_result): Renamed version of above function.
13 Free the original descriptor data after the function call.Set the bounds and the
14 offset so that the lbounds are one.
15 (gfc_trans_arrayfunc_assign): Call renamed function.
16
172011-04-30 Paul Thomas <pault@gcc.gnu.org>
18
19 PR fortran/48462
20 PR fortran/48746
21 * gfortran.dg/realloc_on_assign_7.f03: New test.
22
23
24
25git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173214 138bc75d-0d04-0410-961f-82ee72b054a4
26
27index da7cfba..1d678e6 100644
28--- a/gcc/fortran/trans-expr.c
29+++ b/gcc/fortran/trans-expr.c
30@@ -5444,9 +5444,12 @@ arrayfunc_assign_needs_temporary (gfc_expr * expr1, gfc_expr * expr2)
31 return true;
32
33 /* If we have reached here with an intrinsic function, we do not
34- need a temporary. */
35+ need a temporary except in the particular case that reallocation
36+ on assignment is active and the lhs is allocatable and a target. */
37 if (expr2->value.function.isym)
38- return false;
39+ return (gfc_option.flag_realloc_lhs
40+ && sym->attr.allocatable
41+ && sym->attr.target);
42
43 /* If the LHS is a dummy, we need a temporary if it is not
44 INTENT(OUT). */
45@@ -5528,23 +5531,38 @@ realloc_lhs_loop_for_fcn_call (gfc_se *se, locus *where, gfc_ss **ss)
46 }
47
48
49+/* For Assignment to a reallocatable lhs from intrinsic functions,
50+ replace the se.expr (ie. the result) with a temporary descriptor.
51+ Null the data field so that the library allocates space for the
52+ result. Free the data of the original descriptor after the function,
53+ in case it appears in an argument expression and transfer the
54+ result to the original descriptor. */
55+
56 static void
57-realloc_lhs_bounds_for_intrinsic_call (gfc_se *se, int rank)
58+fcncall_realloc_result (gfc_se *se, int rank)
59 {
60 tree desc;
61+ tree res_desc;
62 tree tmp;
63 tree offset;
64 int n;
65
66- /* Use the allocation done by the library. */
67+ /* Use the allocation done by the library. Substitute the lhs
68+ descriptor with a copy, whose data field is nulled.*/
69 desc = build_fold_indirect_ref_loc (input_location, se->expr);
70- tmp = gfc_conv_descriptor_data_get (desc);
71- tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
72- gfc_add_expr_to_block (&se->pre, tmp);
73- gfc_conv_descriptor_data_set (&se->pre, desc, null_pointer_node);
74 /* Unallocated, the descriptor does not have a dtype. */
75 tmp = gfc_conv_descriptor_dtype (desc);
76 gfc_add_modify (&se->pre, tmp, gfc_get_dtype (TREE_TYPE (desc)));
77+ res_desc = gfc_evaluate_now (desc, &se->pre);
78+ gfc_conv_descriptor_data_set (&se->pre, res_desc, null_pointer_node);
79+ se->expr = gfc_build_addr_expr (TREE_TYPE (se->expr), res_desc);
80+
81+ /* Free the lhs after the function call and copy the result to
82+ the lhs descriptor. */
83+ tmp = gfc_conv_descriptor_data_get (desc);
84+ tmp = gfc_call_free (fold_convert (pvoid_type_node, tmp));
85+ gfc_add_expr_to_block (&se->post, tmp);
86+ gfc_add_modify (&se->post, desc, res_desc);
87
88 offset = gfc_index_zero_node;
89 tmp = gfc_index_one_node;
90@@ -5580,7 +5598,6 @@ realloc_lhs_bounds_for_intrinsic_call (gfc_se *se, int rank)
91 }
92
93
94-
95 /* Try to translate array(:) = func (...), where func is a transformational
96 array function, without using a temporary. Returns NULL if this isn't the
97 case. */
98@@ -5645,7 +5662,7 @@ gfc_trans_arrayfunc_assign (gfc_expr * expr1, gfc_expr * expr2)
99 ss->is_alloc_lhs = 1;
100 }
101 else
102- realloc_lhs_bounds_for_intrinsic_call (&se, expr1->rank);
103+ fcncall_realloc_result (&se, expr1->rank);
104 }
105
106 gfc_conv_function_expr (&se, expr2);
107new file mode 100644
108index 0000000..f871d27
109--- /dev/null
110+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_7.f03
111@@ -0,0 +1,84 @@
112+! { dg-do run }
113+! Check the fix for PR48462 in which the assignments involving matmul
114+! seg faulted because a was automatically freed before the assignment.
115+! Since it is related, the test for the fix of PR48746 has been added
116+! as a subroutine by that name.
117+!
118+! Contributed by John Nedney <ortp21@gmail.com>
119+!
120+program main
121+ implicit none
122+ integer, parameter :: dp = kind(0.0d0)
123+ real(kind=dp), allocatable :: delta(:,:)
124+ real(kind=dp), allocatable, target :: a(:,:)
125+ real(kind=dp), pointer :: aptr(:,:)
126+
127+ allocate(a(3,3))
128+ aptr => a
129+
130+ call foo
131+ if (.not. associated (aptr, a)) call abort () ! reallocated to same size - remains associated
132+ call bar
133+ if (.not. associated (aptr, a)) call abort () ! reallocated to smaller size - remains associated
134+ call foobar
135+ if (associated (aptr, a)) call abort () ! reallocated to larger size - disassociates
136+
137+ call pr48746
138+contains
139+!
140+! Original reduced version from comment #2
141+ subroutine foo
142+ implicit none
143+ real(kind=dp), allocatable :: b(:,:)
144+
145+ allocate(b(3,3))
146+ allocate(delta(3,3))
147+
148+ a = reshape ([1d0, 2d0, 3d0, 4d0, 5d0, 6d0, 7d0, 8d0, 9d0], [3,3])
149+ b = reshape ([1d0, 0d0, 0d0, 0d0, 1d0, 0d0, 0d0, 0d0, 1d0], [3,3])
150+
151+ a = matmul( matmul( a, b ), b )
152+ delta = (a - reshape ([1d0, 2d0, 3d0, 4d0, 5d0, 6d0, 7d0, 8d0, 9d0], [3,3]))**2
153+ if (any (delta > 1d-12)) call abort
154+ if (any (lbound (a) .ne. [1, 1])) call abort
155+ end subroutine
156+!
157+! Check that all is well when the shape of 'a' changes.
158+ subroutine bar
159+ implicit none
160+ real(kind=dp), allocatable :: a(:,:)
161+ real(kind=dp), allocatable :: b(:,:)
162+
163+ b = reshape ([1d0, 1d0, 1d0], [3,1])
164+ a = reshape ([1d0, 2d0, 3d0, 4d0, 5d0, 6d0, 7d0, 8d0, 9d0], [3,3])
165+
166+ a = matmul( a, matmul( a, b ) )
167+
168+ delta = (a - reshape ([198d0, 243d0, 288d0], [3,1]))**2
169+ if (any (delta > 1d-12)) call abort
170+ if (any (lbound (a) .ne. [1, 1])) call abort
171+ end subroutine
172+ subroutine foobar
173+ integer :: i
174+ a = reshape ([(real(i, dp), i = 1, 100)],[10,10])
175+ end subroutine
176+ subroutine pr48746
177+! This is a further wrinkle on the original problem and came about
178+! because the dtype field of the result argument, passed to matmul,
179+! was not being set. This is needed by matmul for the rank.
180+!
181+! Contributed by Thomas Koenig <tkoenig@gcc.gnu.org>
182+!
183+ implicit none
184+ integer, parameter :: m=10, n=12, count=4
185+ real :: optmatmul(m, n)
186+ real :: a(m, count), b(count, n), c(m, n)
187+ real, dimension(:,:), allocatable :: tmp
188+ call random_number(a)
189+ call random_number(b)
190+ tmp = matmul(a,b)
191+ if (any (lbound (tmp) .ne. [1,1])) call abort
192+ if (any (ubound (tmp) .ne. [10,12])) call abort
193+ end subroutine
194+end program main
195+
196--
1971.7.0.4
198