diff options
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.patch | 198 |
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 @@ | |||
1 | From f90642b60dbe411df162174646348f4a7d5e1a63 Mon Sep 17 00:00:00 2001 | ||
2 | From: pault <pault@138bc75d-0d04-0410-961f-82ee72b054a4> | ||
3 | Date: Sat, 30 Apr 2011 12:00:50 +0000 | ||
4 | Subject: [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 | |||
17 | 2011-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 | |||
25 | git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@173214 138bc75d-0d04-0410-961f-82ee72b054a4 | ||
26 | |||
27 | index 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); | ||
107 | new file mode 100644 | ||
108 | index 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 | -- | ||
197 | 1.7.0.4 | ||
198 | |||