Skip to content

Commit 99ab3e0

Browse files
committed
#2884 Improve ref2arrayrange handling of structures (still incomplete)
1 parent 3e1c6b8 commit 99ab3e0

File tree

3 files changed

+55
-28
lines changed

3 files changed

+55
-28
lines changed

src/psyclone/psyir/transformations/reference2arrayrange_trans.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@ class Reference2ArrayRangeTrans(Transformation):
9292
end program example
9393
<BLANKLINE>
9494
95-
This transformation does not currently support arrays within
96-
structures, see issue #1858.
95+
TODO #1858: This transformation does not currently support arrays within
96+
structures, which the validation will pass without an error.
9797
9898
'''
9999

@@ -137,11 +137,7 @@ def validate(self, node, options=None, **kwargs):
137137
# nor further validation
138138
return
139139

140-
if type(node) is StructureReference:
141-
# TODO #1858: Add support for expansion of structures
142-
return
143-
144-
if not type(node) is Reference:
140+
if not type(node) in [Reference, StructureReference]:
145141
raise TransformationError(
146142
f"The supplied node should be a Reference but found "
147143
f"'{type(node).__name__}'.")
@@ -154,6 +150,15 @@ def validate(self, node, options=None, **kwargs):
154150
f"The supplied node should be a Reference to a symbol "
155151
f"of known type, but '{node.symbol}' is not.")
156152

153+
if type(node) is StructureReference:
154+
if node.symbol.is_array:
155+
raise TransformationError(
156+
f"{self.name} does not yet support StructureReferences "
157+
f"but found '{node.symbol}'")
158+
# TODO #1858: This should recursively keep testing the structure
159+
# members
160+
return
161+
157162
def apply(self, node, options=None, **kwargs):
158163
'''Apply the Reference2ArrayRangeTrans transformation to the specified
159164
node. The node must be a Reference to an array. The Reference

src/psyclone/tests/psyir/transformations/arrayassignment2loops_trans_test.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,8 @@ def test_apply_to_arrays_with_different_bounds(fortran_reader, fortran_writer):
264264
psyir = fortran_reader.psyir_from_source('''
265265
program test
266266
use other
267+
268+
type(my_type) :: struct
267269
integer, dimension(10,10) :: x2
268270
integer, dimension(10:20,20:30) :: y2
269271

src/psyclone/tests/psyir/transformations/reference2arrayrange_trans_test.py

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -271,26 +271,58 @@ def test_apply_inquiry(fortran_reader, fortran_writer):
271271
" end if\n") in output
272272

273273

274-
def test_validate_structure(fortran_reader):
275-
'''Test that a StructureReference raises an exception. This limitation
276-
will be removed once issue #1858 is addressed.
277-
274+
def test_validate_structure_references(fortran_reader):
275+
''' Test that the transformation can be applied to StructureReferences.
276+
TODO #1858: this still has several limitations.
278277
'''
279278
code = (
280279
"program test\n"
281280
" type :: array_type\n"
282-
" real, dimension(10) :: a\n"
281+
" real :: scalar\n"
282+
" real, dimension(10) :: field\n"
283283
" real, pointer :: ptr\n"
284284
" end type\n"
285285
" type(array_type) :: ref\n"
286+
" type(array_type), dimension(10) :: array_of_ref\n"
286287
" real :: b\n\n"
287-
" ref%a = b\n"
288+
" ! These pass the transformation unmodified\n"
289+
" ref%scalar = 1\n"
290+
" array_of_ref(:)%scalar = 1\n"
291+
" ref%field(:) = 1\n"
292+
" array_of_ref(:)%field(:) = 1\n"
293+
" ! These need range expressions added\n"
294+
" array_of_ref%scalar = 1\n"
295+
" array_of_ref%field = 1\n"
296+
" ref%field = 1\n"
297+
" ! This is not supported\n"
288298
" ref%ptr => b\n"
289-
"end program test\n")
299+
"end program test\n"
300+
)
290301
psyir = fortran_reader.psyir_from_source(code)
291302
trans = Reference2ArrayRangeTrans()
292-
for assign in psyir.walk(Assignment):
293-
trans.validate(assign.lhs)
303+
assign = psyir.walk(Assignment)
304+
305+
# The 4 first statements are fine
306+
trans.apply(assign[0].lhs)
307+
trans.apply(assign[1].lhs)
308+
trans.apply(assign[2].lhs)
309+
trans.apply(assign[3].lhs)
310+
311+
# TODO #1858: Add support for StructureReference
312+
with pytest.raises(TransformationError) as err:
313+
trans.apply(assign[4].lhs)
314+
assert ("Reference2ArrayRangeTrans does not yet support Structure"
315+
"References but found 'array_of_ref: DataSymbol<Array<"
316+
in str(err.value))
317+
with pytest.raises(TransformationError) as err:
318+
trans.apply(assign[5].lhs)
319+
assert ("Reference2ArrayRangeTrans does not yet support Structure"
320+
"References but found 'array_of_ref: DataSymbol<Array<"
321+
in str(err.value))
322+
323+
# TODO #1858: Extend validations to Structure members
324+
trans.apply(assign[6].lhs)
325+
trans.apply(assign[7].lhs)
294326

295327

296328
def test_validate_pointer_assignment(fortran_reader):
@@ -310,15 +342,3 @@ def test_validate_pointer_assignment(fortran_reader):
310342
trans.validate(reference)
311343
assert ("The supplied node should be a Reference to a symbol of known "
312344
"type, but " in str(info.value))
313-
314-
315-
def test_apply_validate():
316-
'''Test that the apply method calls validate by checking that the
317-
exception raised by validate is raised when apply is called.
318-
319-
'''
320-
trans = Reference2ArrayRangeTrans()
321-
with pytest.raises(TransformationError) as info:
322-
trans.apply(None)
323-
assert ("The supplied node should be a Reference but found 'NoneType'."
324-
in str(info.value))

0 commit comments

Comments
 (0)