Repository: pyccel/pyccel (python)

Issue:
Can't call return in for loop
### Describe the bug
When calling `return` in a for loop, the function is found in an enclosing scope not the current scope. This leads to a traceback error when checking pointers and targets.

### To Reproduce
Provide code to reproduce the behavior:
```python
def f(n : int):
    for i in range(1000):
        if i > n:
            return 1
    return 0
```

### Error details
Provide the generated code, or the error message:
```
Traceback (most recent call last):
  File "/home/emily/.local/bin/pyccel", line 8, in <module>
    sys.exit(pyccel())
  File "/home/emily/Code/pyccel/pyccel/commands/console.py", line 266, in pyccel
    execute_pyccel(filename,
  File "/home/emily/Code/pyccel/pyccel/codegen/pipeline.py", line 234, in execute_pyccel
    parser.annotate(verbose = verbose)
  File "/home/emily/Code/pyccel/pyccel/parser/parser.py", line 160, in annotate
    parser = SemanticParser(self._syntax_parser,
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 245, in __init__
    self.annotate()
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 318, in annotate
    ast = self._visit(ast)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1947, in _visit_Module
    body = self._visit(expr.program).body
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2214, in _visit_CodeBlock
    line = self._visit(b)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3808, in _visit_FunctionDef
    body = self._visit(expr.body)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2214, in _visit_CodeBlock
    line = self._visit(b)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3335, in _visit_For
    body = self._visit(expr.body)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2214, in _visit_CodeBlock
    line = self._visit(b)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3602, in _visit_If
    args = [self._visit(i) for i in expr.blocks]
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3602, in <listcomp>
    args = [self._visit(i) for i in expr.blocks]
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3591, in _visit_IfSection
    body = self._visit(expr.body)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 2214, in _visit_CodeBlock
    line = self._visit(b)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 1935, in _visit
    obj = getattr(self, annotation_method)(expr)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 3695, in _visit_Return
    self._check_pointer_targets(results)
  File "/home/emily/Code/pyccel/pyccel/parser/semantic.py", line 654, in _check_pointer_targets
    current_func = self.scope.functions[func_name]
KeyError: 'f'
```

### Expected behavior
The scope should be searched using `scope.find`

### Language
All languages

### Additional context
Breaks the Bellman Ford benchmark


Pull request description:
Fix returns in for loops
As described in #1723 the scope is searched incorrectly when handling pointers and targets. This PR fixes #1723

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 49adb84d..1150f709 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,13 @@
 # Change Log
 All notable changes to this project will be documented in this file.
 
-## \[UNRELEASED\]
+## \[1.11.1\] - 2024-02-13
+
+### Fixed
+
+-   #1724 : Fix returns in for loops
+
+## \[1.11.0\] - 2024-02-12
 
 ### Added
 
diff --git a/pyccel/parser/semantic.py b/pyccel/parser/semantic.py
index 9a56932e..e67467c9 100644
--- a/pyccel/parser/semantic.py
+++ b/pyccel/parser/semantic.py
@@ -651,7 +651,7 @@ class SemanticParser(BasicParser):
 
         if self._current_function:
             func_name = self._current_function.name[-1] if isinstance(self._current_function, DottedName) else self._current_function
-            current_func = self.scope.functions[func_name]
+            current_func = self.scope.find(func_name, 'functions')
             arg_vars = {a.var:a for a in current_func.arguments}
 
             for p, t_list in self._pointer_targets[-1].items():
diff --git a/pyccel/version.py b/pyccel/version.py
index 90ccfc11..8a2175f4 100644
--- a/pyccel/version.py
+++ b/pyccel/version.py
@@ -1,4 +1,4 @@
 """
 Module specifying the current version string for pyccel
 """
-__version__ = "1.11.0"
+__version__ = "1.11.1"


Test patch:
diff --git a/tests/epyccel/modules/loops.py b/tests/epyccel/modules/loops.py
index 6f6fec11..6ee2394f 100644
--- a/tests/epyccel/modules/loops.py
+++ b/tests/epyccel/modules/loops.py
@@ -248,3 +248,10 @@ def temp_array_in_loop(a : 'int[:]', b : 'int[:]'):
         d2[:] = np.abs(b - a)
     return d1, d2
 
+def less_than_100(n : int):
+    for i in range(100):
+        if i > n:
+            return True
+    return False
+
+
diff --git a/tests/epyccel/test_loops.py b/tests/epyccel/test_loops.py
index 4517fbc9..882592c8 100644
--- a/tests/epyccel/test_loops.py
+++ b/tests/epyccel/test_loops.py
@@ -229,6 +229,12 @@ def test_temp_array_in_loop(language):
     assert np.array_equal(c_py, c_ep)
     assert np.array_equal(d_py, d_ep)
 
+def test_less_than_100(language):
+    f1 = loops.less_than_100
+    f2 = epyccel( f1, language = language )
+
+    assert f1(10) == f2(10)
+    assert f1(101) == f2(101)
 
 ##==============================================================================
 ## CLEAN UP GENERATED FILES AFTER RUNNING TESTS