4.4. Dead Code

4.4.1. Introduction

Dead code is generally understood as code that is executable, but never executed during a program’s runtime. Within the context of the Axivion Suite, dead code can be put into four categories:

  • Type 1: Directly uncalled routines - Routines that are neither statically nor dynamically called.

  • Type 2: Transitively uncalled routines - Routines that may be called by other routines, but the initial entry point of the call chain is never called.

  • Type 3: Unreachable code - Code statements that are never executed, as they are made unreachable by control-flow constructs, e.g., after a return or throw statement, inside dead branches, case and catch blocks, etc. Routines that are only called from type 2 or type 3 are also considered type 3 dead.

  • Type 4: Removable code - Code statements that, while possibly reachable, do not affect the program’s observable behavior and can be safely removed without changing functionality.

Note that the terms “statically called” and “dynamically called” refer to the time at which the target of a call is resolved: Static calls are known at compile-time, such as calls to static methods or functions, but also non-virtual calls. Dynamically called methods or functions resolve the invocation target at runtime, for example, if abstract classes or interfaces are involved, or if function pointers are used.

Note that Type 4 is derived from the MISRA C definition of “dead code”.

Types of dead code

The above diagram shows the relationship between the four types of dead code. For example, all transitively uncalled routines (type 2) are also unreachable code (type 3), but not the other way around. Note that entries to a program, such as the main routine, are not considered dead code, but rather help define which of the other routines are reachable.

The static part of types 1 and 2 can be detected on a language-agnostic level supported by all programming language frontends of the Axivion Suite, type 3 requires more information and is therefore only available for C and C++. Depending on whether you have enabled StaticSemanticAnalysis or not, you might receive more type 3 findings. Type 4 requires detailed semantic information about the program which is only available for C and C++ and requires StaticSemanticAnalysis to be enabled.

In the following sections, we describe the setup of the Axivion Suite for the purpose of erosion protection in regard to dead code.

4.4.2. Dead Code Detection

4.4.2.1. Types 1 and 2

The basis for dead code detection of types 1 and 2 is an abstraction of the program’s structure represented by a view in the RFG, the “base view”. This view is extracted from the source code by the language analysis front ends. The specifics of this extraction depend on the programming language and are described in Language Schema. This abstraction is available for all languages supported by the Axivion Suite.

The analysis then identifies code entities that are not reachable from any of the entry points of the program. The list of entry points consists of node-routine Routine or node-routine-template Routine_Template nodes, which are either marked as entry points by connecting them to the special node-routine Routine .entry node, or which are added to the Entries view during the analysis.

Available rules (all languages):

  • DeadCodeDetection: Run dead code detection and report findings for unreachable code entities.

  • Architecture-DeadCodeView: Run dead code detection and include the results in the RFG as Dead and Alive views.

  • Architecture-CombinedDeadCode: Run dead code detection on RFGs of multiple projects and produce Combined Dead and Combined Alive views.

  • Architecture-VariantDeadCode: Run dead code detection on the RFG of the current project and also merge already existing RFGs of other projects and produce Combined Dead and Combined Alive views.

“Dead Entity” findings reported by the above rules can be viewed in the “Dead Entities” view in the dashboard denoted by the dashboard2-uiicon-deadcode symbol and the prefix DE.

Configuration of Entry Points

Entry points are configurable via the EntryPoints configuration rules. These rules allow you to specify patterns to add node-routine Routine nodes to the Entries view. These entry points are also used by other analyses, such as StaticSemanticAnalysis.

The following table lists the availability of entry point rules for each language:

C/C++

C#

Rust

EntryPoints-EntriesByAttribute

EntryPoints-EntriesByDLLExport

EntryPoints-EntriesByKeyword

EntryPoints-EntriesByLinkname

EntryPoints-EntriesByMacro

EntryPoints-EntriesByName

EntryPoints-EntriesByPath

EntryPoints-EntriesByVirtualExternal

4.4.2.2. Type 3

Detection of type 3 dead code operates on statements and the program’s control flow graph (CFG) encoded in the Axivion IR, which is only available for C and C++.

Available rules (C/C++ only):

Note

The rules listed below will detect dead code of type 3 as well as type 4, if StaticSemanticAnalysis is enabled.

CQM:

Fault Detection:

4.4.2.3. Type 4

Detection of type 4 dead code operates on statements and the program’s control flow graph (CFG) encoded in the Axivion IR, which is only available for C and C++. Additionally, StaticSemanticAnalysis needs to be enabled.

Available rules (C/C++ only):

Cert:

  • CertC-MSC12: Detect and remove code that has no effect or is never executed.

CWE:

  • CWE-561: Dead Code. [Bad-Coding-Practices, Improper-Adherence-To-Coding-Standards]

FaultDetection:

4.4.3. Metrics for Dead Code

The following metrics dashboard2-uiicon-metricviolation MV are related to dead code: