Repository: angr/angr

Issue:
Decompiler fails when handling return statements possibly due to issues identifying calling convention
**Describe the bug.**

The decompiler fails to decompile a function when trying to handle return statements. Based on the traceback, it seems to be because the calling convention is somehow not determined/known when handling return statements. Looking at the blame history, it seems to be related to the latest commits implementing support for return statements in decompiler.

Traceback

```python
Traceback (most recent call last):
  File "/home/dnivra/angr-dev/angr-management/angrmanagement/ui/main_window.py", line 496, in decompile_current_function
    self.workspace.decompile_current_function()
  File "/home/dnivra/angr-dev/angr-management/angrmanagement/ui/workspace.py", line 265, in decompile_current_function
    view.decompile_current_function()
  File "/home/dnivra/angr-dev/angr-management/angrmanagement/ui/views/disassembly_view.py", line 382, in decompile_current_function
    self.workspace.decompile_function(self._current_function.am_obj)
  File "/home/dnivra/angr-dev/angr-management/angrmanagement/ui/workspace.py", line 279, in decompile_function
    view.function = func
  File "/home/dnivra/angr-dev/angr-management/angrmanagement/ui/views/code_view.py", line 66, in function
    self.decompile()
  File "/home/dnivra/angr-dev/angr-management/angrmanagement/ui/views/code_view.py", line 43, in decompile
    d = self.workspace.instance.project.analyses.Decompiler(
  File "/home/dnivra/angr-dev/angr/angr/analyses/analysis.py", line 115, in __call__
    oself.__init__(*args, **kwargs)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/decompiler.py", line 24, in __init__
    self._decompile()
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/decompiler.py", line 41, in _decompile
    clinic = self.project.analyses.Clinic(self.func,
  File "/home/dnivra/angr-dev/angr/angr/analyses/analysis.py", line 115, in __call__
    oself.__init__(*args, **kwargs)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/clinic.py", line 70, in __init__
    self._analyze()
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/clinic.py", line 138, in _analyze
    ail_graph = self._make_returns(ail_graph)
  File "/home/dnivra/angr-dev/angr/angr/utils/timing.py", line 28, in timed_func
    return func(*args, **kwargs)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/clinic.py", line 457, in _make_returns
    AILGraphWalker(ail_graph, _handler, replace_nodes=True).walk()
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/ailgraph_walker.py", line 23, in walk
    r = self.handler(node)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/clinic.py", line 453, in _handler
    walker.walk(block)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/ailblock_walker.py", line 37, in walk
    self._handle_stmt(i, stmt, block)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/ailblock_walker.py", line 50, in _handle_stmt
    return handler(stmt_idx, stmt, block)
  File "/home/dnivra/angr-dev/angr/angr/analyses/decompiler/clinic.py", line 434, in _handle_Return
    and self.function.calling_convention.ret_val is not None:
AttributeError: 'NoneType' object has no attribute 'ret_val'
```

**Environment Information.**

I'm running the latest version of all angr repos used when angr-dev is setup. Including the environment info below for completeness. If there is any info missing or any additional info is required that could be useful, please let me know.

angr environment report
=============================
Date: 2020-12-27 16:49:02.552115
Running in virtual environment at /home/dnivra/.virtualenvs/angr-dev
Platform: linux-x86_64
Python version: 3.8.5 (default, Jul 28 2020, 12:59:40) 
[GCC 9.3.0]
######## angr #########
Python found it in /home/dnivra/angr-dev/angr/angr
Pip version angr 9.0.gitrolling
Git info:
        Current commit ae7ff3bc64b3f8ee00ed5528ca8c806e3f44facd from branch master
        Checked out from remote origin: https://github.com/angr/angr
######## ailment #########
Python found it in /home/dnivra/angr-dev/ailment/ailment
Pip version ailment 9.0.gitrolling
Git info:
        Current commit 32226062135e5ed54c88f86228ffd65053655a95 from branch master
        Checked out from remote origin: https://github.com/angr/ailment
######## cle #########
Python found it in /home/dnivra/angr-dev/cle/cle
Pip version cle 9.0.gitrolling
Git info:
        Current commit 7f3263c74a2c038234f5ec6adf8ebb4bf119e868 from branch master
        Checked out from remote origin: https://github.com/angr/cle
######## pyvex #########
Python found it in /home/dnivra/angr-dev/pyvex/pyvex
Pip version pyvex 9.0.gitrolling
Git info:
        Current commit bbd8aadbaf03ad7b909dcb74e9693a757d70f5e6 from branch master
        Checked out from remote origin: https://github.com/angr/pyvex
######## claripy #########
Python found it in /home/dnivra/angr-dev/claripy/claripy
Pip version claripy 9.0.gitrolling
Git info:
        Current commit aadfc02e1cb01e4ebfaa55055a42bb4afb6a0347 from branch master
        Checked out from remote origin: https://github.com/angr/claripy
######## archinfo #########
Python found it in /home/dnivra/angr-dev/archinfo/archinfo
Pip version archinfo 9.0.gitrolling
Git info:
        Current commit f5712a1fe0fbc315c4e9bbcf96582e139f745b33 from branch master
        Checked out from remote origin: https://github.com/angr/archinfo
######## z3 #########
Python found it in /home/dnivra/.virtualenvs/angr-dev/lib/python3.8/site-packages/z3
Pip version z3-solver 4.8.9.0
Couldn't find git info
######## unicorn #########
Python found it in /home/dnivra/.virtualenvs/angr-dev/lib/python3.8/site-packages/unicorn
Pip version unicorn 1.0.2rc4
Couldn't find git info
######### Native Module Info ##########
angr: <CDLL '/home/dnivra/angr-dev/angr/angr/lib/angr_native.so', handle 2aee170 at 0x7fc1e796cc40>
unicorn: <CDLL '/home/dnivra/.virtualenvs/angr-dev/lib/python3.8/site-packages/unicorn/lib/libunicorn.so', handle 21fc8e0 at 0x7fc1ed5049d0>
pyvex: <cffi.api._make_ffi_library.<locals>.FFILibrary object at 0x7fc1ee296340>
z3: <CDLL '/home/dnivra/.virtualenvs/angr-dev/lib/python3.8/site-packages/z3/lib/libz3.so', handle 24777e0 at 0x7fc1eabc9c70>

**To Reproduce.**

Unfortunately, I do not have a script: I was decompiling using angr-management. I was trying to decompile function `0x80494f0` in the [NRFIN_00036 CGC binary](https://github.com/zardus/cgc-bins/blob/master/all_unpatched/NRFIN_00036). I suppose it's trivial to create a script that does the same thing. Thought I'd add this too: based on some reversing I have done, I believe the function at `0x80494f0` is [`int2str`](https://github.com/lungetech/cgc-challenge-corpus/blob/master/NRFIN_00036/lib/libc.c#L235). I am not 100% sure since I didn't reverse the function but did some context matching with source code and CFG.


Discussion:

Resolving patch:
diff --git a/angr/analyses/decompiler/clinic.py b/angr/analyses/decompiler/clinic.py
--- a/angr/analyses/decompiler/clinic.py
+++ b/angr/analyses/decompiler/clinic.py
@@ -421,11 +421,15 @@ def _handler(block):
         return ail_graph
 
     @timethis
-    def _make_returns(self, ail_graph: networkx.DiGraph):
+    def _make_returns(self, ail_graph: networkx.DiGraph) -> networkx.DiGraph:
         """
         Work on each return statement and fill in its return expressions.
         """
 
+        if self.function.calling_convention is None:
+            # unknown calling convention. cannot do much about return expressions.
+            return ail_graph
+
         # Block walker
 
         def _handle_Return(stmt_idx: int, stmt: ailment.Stmt.Return, block: Optional[ailment.Block]):  # pylint:disable=unused-argument


Test patch: