Repository: crytic/slither

Issue:
[Bug]: EVM printer fails for Abstract Contracts
### Describe the issue:

If slither is runned with `slither --print evm contract.sol` where contract.sol is an abstract contract, it will fail with the following error:

```shell
➜ slither --print evm contract.sol


  File "/Users/dm/Projects/slither/slither/__main__.py", line 143, in _process
    printer_results = slither.run_printers()
                      ^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dm/Projects/slither/slither/slither.py", line 300, in run_printers
    return [p.output(self._crytic_compile.target).data for p in self._printers]
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dm/Projects/slither/slither/printers/summary/evm.py", line 78, in output
    evm_info = _extract_evm_info(self.slither)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dm/Projects/slither/slither/printers/summary/evm.py", line 30, in _extract_evm_info
    cfg = CFG(contract_bytecode_runtime)
          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/dm/Projects/slither/env/lib/python3.12/site-packages/evm_cfg_builder/cfg/__init__.py", line 96, in __init__
    self.create_functions()
  File "/Users/dm/Projects/slither/env/lib/python3.12/site-packages/evm_cfg_builder/cfg/__init__.py", line 183, in create_functions
    self.compute_functions(self._basic_blocks[0], True)
                           ~~~~~~~~~~~~~~~~~~^^^


```


### Code example to reproduce the issue:

`abstract contract Ownable {}`

### Version:

0.10.2

### Relevant log output:

_No response_


Discussion:

Resolving patch:
diff --git a/slither/printers/summary/evm.py b/slither/printers/summary/evm.py
--- a/slither/printers/summary/evm.py
+++ b/slither/printers/summary/evm.py
@@ -1,6 +1,8 @@
 """
     Module printing evm mapping of the contract
 """
+import logging
+
 from slither.printers.abstract_printer import AbstractPrinter
 from slither.analyses.evm import (
     generate_source_to_evm_ins_mapping,
@@ -9,6 +11,9 @@
 from slither.utils.colors import blue, green, magenta, red
 
 
+logger: logging.Logger = logging.getLogger("EVMPrinter")
+
+
 def _extract_evm_info(slither):
     """
     Extract evm information for all derived contracts using evm_cfg_builder
@@ -24,6 +29,16 @@ def _extract_evm_info(slither):
         contract_bytecode_runtime = contract.file_scope.bytecode_runtime(
             contract.compilation_unit.crytic_compile_compilation_unit, contract.name
         )
+
+        if not contract_bytecode_runtime:
+            logger.info(
+                "Contract %s (abstract: %r) has no bytecode runtime, skipping. ",
+                contract.name,
+                contract.is_abstract,
+            )
+            evm_info["empty", contract.name] = True
+            continue
+
         contract_srcmap_runtime = contract.file_scope.srcmap_runtime(
             contract.compilation_unit.crytic_compile_compilation_unit, contract.name
         )
@@ -80,6 +95,10 @@ def output(self, _filename):
         for contract in self.slither.contracts_derived:
             txt += blue(f"Contract {contract.name}\n")
 
+            if evm_info.get(("empty", contract.name), False):
+                txt += "\tempty contract\n"
+                continue
+
             contract_file = self.slither.source_code[
                 contract.source_mapping.filename.absolute
             ].encode("utf-8")


Test patch: