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
returnorthrowstatement, inside dead branches,caseandcatchblocks, 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”.
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
Routine or
Routine_Template
nodes, which are either marked as entry points by
connecting them to the special
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
DeadandAliveviews.Architecture-CombinedDeadCode: Run dead code detection on RFGs of multiple projects and produce
Combined DeadandCombined Aliveviews.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 DeadandCombined Aliveviews.
“Dead Entity” findings reported by the above rules can be viewed in the “Dead Entities”
view in the dashboard denoted by the
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
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 |
|
|---|---|---|---|
✅ |
✅ |
✅ |
|
✅ |
❌ |
❌ |
|
✅ |
❌ |
❌ |
|
✅ |
✅ |
✅ |
|
✅ |
❌ |
✅ |
|
✅ |
✅ |
✅ |
|
✅ |
✅ |
✅ |
|
✅ |
❌ |
❌ |
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:
CQM-DeadImplementation: Unreachable statements.
CQM-DeadFields: A private filed of a class is not used.
Fault Detection:
FaultDetection-DeadCatch: There shall be no dead exception handlers.
FaultDetection-RemovableStatements: There shall be no statements that could be removed because they do not contribute to a function's result.
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:
FaultDetection-DeadBranches: There shall be no dead branches.
FaultDetection-DeadCatch: There shall be no dead exception handlers.
FaultDetection-RemovableStatements: There shall be no statements that could be removed because they do not contribute to a function's result.
FaultDetection-UnusedAssignments: A project shall not contain unused assignments.
4.4.3. Metrics for Dead Code¶
The following metrics
MV are related to dead
code:
CQM-DeadRoutines: Counts the number of dead routines. (C/C++ only)
Metric-IssueCount.DeadEntity: Number of Dead Entities (all languages)