Skip to content

Commit

Permalink
fixed coverage issues
Browse files Browse the repository at this point in the history
  • Loading branch information
SCHREIBER Martin committed Nov 14, 2024
1 parent f282827 commit 1db15dd
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 23 deletions.
50 changes: 28 additions & 22 deletions src/psyclone/psyir/nodes/call.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
from typing import List


class CallMatchingArgumentsNotFound(BaseException):
"""Excepction to signal that matching arguments have not been found
for this routine
"""


class Call(Statement, DataNode):
''' Node representing a Call. This can be found as a standalone statement
or an expression.
Expand Down Expand Up @@ -258,7 +264,8 @@ def replace_named_arg(self, existing_name, arg):
raise ValueError(
f"The value of the existing_name argument ({existing_name}) "
f"in 'replace_named_arg' in the 'Call' node was not found "
f"in the existing arguments.")
f"in the existing arguments."
)
# The n'th argument is placed at the n'th+1 children position
# because the 1st child is the routine reference
self.children[index + 1] = arg
Expand Down Expand Up @@ -594,11 +601,6 @@ def _location_txt(node):
f"{_location_txt(root_node)}. This is normally because the routine"
f" is within a CodeBlock.")

class MatchingArgumentsNotFound(BaseException):
"""Excepction to signal that matching arguments have not been found
for this routine
"""

def get_argument_routine_match(self, routine: Routine):
"""Return a list of integers giving for each argument of the call
the index of the argument in argument_list (typically of a routine)
Expand All @@ -615,12 +617,8 @@ def get_argument_routine_match(self, routine: Routine):
routine_argument_list: List[DataNode] = \
routine.symbol_table.argument_list[:]

# Find matching argument list
# if len(self.arguments) != len(routine_argument_list):
# return None

if len(self.arguments) > len(routine.symbol_table.argument_list):
raise self.MatchingArgumentsNotFound(
raise CallMatchingArgumentsNotFound(
f"More arguments in callee (call '{self.routine.name}')"
f" than caller (routine '{routine.name}')"
)
Expand Down Expand Up @@ -648,7 +646,7 @@ def get_argument_routine_match(self, routine: Routine):
routine_arg.datatype,
UnsupportedFortranType):
if call_arg.datatype != routine_arg.datatype:
raise self.MatchingArgumentsNotFound(
raise CallMatchingArgumentsNotFound(
f"Argument type mismatch of call argument "
f"'{call_arg}' and routine argument "
f"'{routine_arg}'"
Expand Down Expand Up @@ -680,7 +678,7 @@ def get_argument_routine_match(self, routine: Routine):
routine_arg.datatype,
UnsupportedFortranType):
if call_arg.datatype != routine_arg.datatype:
raise self.MatchingArgumentsNotFound(
raise CallMatchingArgumentsNotFound(
f"Argument type mismatch of call argument "
f"'{call_arg}' and routine argument "
f"'{routine_arg}'"
Expand All @@ -692,10 +690,9 @@ def get_argument_routine_match(self, routine: Routine):

if not named_arg_found:
# It doesn't match => Raise exception
raise self.MatchingArgumentsNotFound

if routine_arg_idx is None:
raise IndexError("Internal error")
raise CallMatchingArgumentsNotFound(
f"Named argument '{arg_name}' not found"
)

routine_argument_list[routine_arg_idx] = None

Expand All @@ -713,8 +710,8 @@ def get_argument_routine_match(self, routine: Routine):
if ", OPTIONAL" in str(routine_arg.datatype):
continue

raise self.MatchingArgumentsNotFound(
f"Argument '{routine_arg}' in subroutine"
raise CallMatchingArgumentsNotFound(
f"Argument '{routine_arg.name}' in subroutine"
f" '{routine.name}' not handled"
)

Expand All @@ -740,15 +737,20 @@ def get_callee(

routine_list = self.get_callees()

error: Exception = None

# Search for the routine matching the right arguments
for routine in routine_list:
routine: Routine

try:
arg_match_list = self.get_argument_routine_match(routine)
except self.MatchingArgumentsNotFound:
except CallMatchingArgumentsNotFound as err:
error = err
continue

error = None

if ret_arg_match_list is not None:
ret_arg_match_list[:] = arg_match_list

Expand All @@ -761,5 +763,9 @@ def get_callee(
if not check_matching_arguments:
return routine_list[0]

raise NotImplementedError(f"No matching routine for call "
f"'{self.routine.name}' found")
if error is not None:
raise error
else:
raise NotImplementedError(
f"No matching routine for call " f"'{self.routine.name}' found"
)
91 changes: 90 additions & 1 deletion src/psyclone/tests/psyir/nodes/call_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
from psyclone.psyir.symbols import (
ArrayType, INTEGER_TYPE, DataSymbol, NoType, RoutineSymbol, REAL_TYPE,
SymbolError, UnsupportedFortranType)
from psyclone.psyir.nodes.call import CallMatchingArgumentsNotFound
from psyclone.errors import GenerationError


Expand Down Expand Up @@ -741,7 +742,9 @@ def test_call_get_callee_3_trigger_error(fortran_reader):

try:
call_foo.get_callee(ret_arg_match_list=arg_idx_list)
except Exception:

except CallMatchingArgumentsNotFound as err:
assert "More arguments in callee" in str(err)
print("Success! Exception triggered (as expected)")
return

Expand Down Expand Up @@ -1073,6 +1076,92 @@ def test_call_get_callee_6_interfaces(fortran_reader):
print(" - Passed subtest foo_c[2]")


def test_call_get_callee_7_matching_arguments_not_found(fortran_reader):
"""
Trigger error that matching arguments were not found
"""
code = """
module some_mod
implicit none
contains
subroutine main()
integer :: e, f, g
! Use name 'd' which doesn't exist
call foo(e, f, d=g)
end subroutine
! Matching routine
subroutine foo(a, b, c)
integer :: a, b, c
end subroutine
end module some_mod"""

psyir = fortran_reader.psyir_from_source(code)

routine_main: Routine = psyir.walk(Routine)[0]
assert routine_main.name == "main"

call_foo: Call = routine_main.walk(Call)[0]

try:
call_foo.get_callee()

except CallMatchingArgumentsNotFound as err:
assert "Named argument 'd' not found" in str(err)
print("Success! Exception triggered (as expected)")
return

assert False, (
"This should have triggered an error since there"
"are more arguments in the call than in the routine"
)


def test_call_get_callee_8_arguments_not_handled(fortran_reader):
"""
Trigger error that matching arguments were not found
"""
code = """
module some_mod
implicit none
contains
subroutine main()
integer :: e, f
! Use name 'd' which doesn't exist
call foo(e, f)
end subroutine
! Matching routine
subroutine foo(a, b, c)
integer :: a, b, c
end subroutine
end module some_mod"""

psyir = fortran_reader.psyir_from_source(code)

routine_main: Routine = psyir.walk(Routine)[0]
assert routine_main.name == "main"

call_foo: Call = routine_main.walk(Call)[0]

try:
call_foo.get_callee()

except CallMatchingArgumentsNotFound as err:
assert "Argument 'c' in subroutine 'foo' not handled" in str(err)
print("Success! Exception triggered (as expected)")
return

assert False, (
"This should have triggered an error since there"
"are more arguments in the call than in the routine"
)


@pytest.mark.usefixtures("clear_module_manager_instance")
def test_call_get_callees_unresolved(fortran_reader, tmpdir, monkeypatch):
'''
Expand Down

0 comments on commit 1db15dd

Please sign in to comment.