Skip to content

DUC unsupported type checks - #3492

Open
LonelyCat124 wants to merge 17 commits into
masterfrom
duc_unsupported_type_checks
Open

DUC unsupported type checks#3492
LonelyCat124 wants to merge 17 commits into
masterfrom
duc_unsupported_type_checks

Conversation

@LonelyCat124

Copy link
Copy Markdown
Collaborator

No description provided.

@LonelyCat124
LonelyCat124 requested review from arporter and sergisiso and removed request for sergisiso July 10, 2026 12:52
@codecov

codecov Bot commented Jul 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (cd6df42) to head (157812f).

Additional details and impacted files
@@            Coverage Diff             @@
##            master     #3492    +/-   ##
==========================================
  Coverage   100.00%   100.00%            
==========================================
  Files          397       397            
  Lines        55587     55687   +100     
==========================================
+ Hits         55587     55687   +100     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@LonelyCat124

Copy link
Copy Markdown
Collaborator Author

@sergisiso @arporter This is ready for a first look - it handles edge cases in the DUC where we need to force any UnsupportedType reference to match to any UnsupportedType reference as we can't guarantee there is no aliasing between them (due to TARGET and POINTER).

@arporter arporter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks Aidan. I have to confess that I don't really understand the implementation (although I'm getting there) so I've mainly focused on whether it looks sensible. I do think it could do with being broken up a bit as the methods are huge - see inline.
Thanks for all the new tests - I've requested quite a few changes to those to help me to understand them. I'll do the ITs next time.

Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_backward_dependence_test.py Outdated
assert reaches[3] is routine.walk(Assignment)[4].rhs.children[0]


def test_definition_use_chains_forward_accesses_unsupported_type(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've not yet looked at these tests but if you could update them in similar ways to the 'backward' tests then I'll look next time.

@LonelyCat124

Copy link
Copy Markdown
Collaborator Author

@arporter Should be ready for another look now - some of the comments you had were repeats so I just put done on a single comment instead of each.

@arporter arporter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking much better now, thanks Aidan. I think I'm getting my head around it. My main concern now is that the new methods update state both via an argument and via internal object state. I think it would be better if they did exclusively one or the other but am open to be persuaded. A little bit of renaming might help make this clearer too.
Apart from that, it's just tidying. There's a merge conflict so I won't run any tests this time.

Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/psyir/tools/definition_use_chains.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py Outdated
Comment thread src/psyclone/tests/psyir/tools/definition_use_chains_forward_dependence_test.py Outdated
@LonelyCat124

Copy link
Copy Markdown
Collaborator Author

@arporter Ready for another look - I didn't comment on repeats necessarily inline but I should have hit them all.

@arporter arporter left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks very much @LonelyCat124, this is proving very educational for me :-)
There are a couple of places where you only look at the first node in the parse tree of a CodeBlock and I'm not convinced that that's safe. Apart from that, it's mostly a bit more clarification and tidying.

# CodeBlocks only find symbols, so we can only do as good
# as checking the symbol - this means we can get false
# positives for structure accesses inside CodeBlocks.
if isinstance(reference.parse_tree_nodes[0], Goto_Stmt):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is only looking at the first parse-tree node sufficient?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not, good spot, I forgot we would combine codeblocks so if we had e.g. print then goto the current test fails.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

# If we find an Exit or Cycle statement, we can't
# reach further in this code region so we can return.
if isinstance(
reference.parse_tree_nodes[0], (Exit_Stmt, Cycle_Stmt)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, is only looking at the first parse-tree node sufficient?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, fixed.


:param reference: The CodeBlock being analysed.

:returns: whether the calling function should terminate.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pls document the raises.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

self._defsout[sig] = []
self._defsout[sig].append(reference)
else:
# Reference outside an Assignment - read only. This could be

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about loop variables (now that they're part of the tree)?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sergi added #3486 about this - loop variables are handled otherwise, so we should hit the loop itself still at the moment.

assign = reference.ancestor(Assignment)
if assign is not None:
if assign.lhs is reference:
for i, sig in enumerate(self._reference_signatures):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha! I think I had worked that out by the end of my last review, thanks to the tests. Please could you add a comment. Perhaps "every signature" at L697/8 is "every signature of a reference to an UnsupportedType"?

end subroutine test"""
psyir = fortran_reader.psyir_from_source(code)
assign = psyir.walk(Assignment)[-1]
sig = assign.rhs.get_signature_and_indices()[0]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"sig_a" for clarity pls.

psyir = fortran_reader.psyir_from_source(code)
assigns = psyir.walk(Assignment)
assign = assigns[-1]
sig = assign.lhs.get_signature_and_indices()[0]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"a_sig"


def test_backward_accesses_unsupported_type_lhs_ends_chain(fortran_reader):
"""Test that if the lhs of a found assignment is an UnsupportedType
then we skip any UnsupportedTypes on the rhs"""

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make sure I understand: we're going backwards so the lhs comes first and if it's an UnsupportedType, then it ends(?) the chain for the assigned-to signature?

routine = psyir.walk(Routine)[1]
assigns = routine.walk(Assignment)
assign = assigns[-1]
sig = assign.lhs.get_signature_and_indices()[0]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"c_sig"

assign = psyir.walk(Assignment)[-1]
a_sig = assign.lhs.get_signature_and_indices()[0]
c_sig = assign.rhs.get_signature_and_indices()[0]
chains = DefinitionUseChain([assign.lhs, assign.rhs])

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a silly question but could you do DefinitionUseChain(assign) instead?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants