Semmle 1.20
Skip to end of metadata
Go to start of metadata

Name: Initialization code not run

Description: Not running initialization code may lead to unexpected behavior.

ID: cpp/initialization-not-run

Kind: problem

Severity: warning

Query: InitialisationNotRun.ql
 * @name Initialization code not run
 * @description Not running initialization code may lead to unexpected behavior.
 * @kind problem
 * @id cpp/initialization-not-run
 * @problem.severity warning
 * @tags reliability
 *       security
 *       external/cwe/cwe-456
import cpp
import semmle.code.cpp.pointsto.CallGraph

predicate global(GlobalVariable v)
  not exists(v.getInitializer())
  and not v.getType() instanceof ArrayType
  and not v.getType() instanceof Class
  and v.getAnAccess().isUsedAsLValue()

predicate mainCalled(Function f)
  f.getQualifiedName() = "main"
  exists(Function caller |
    mainCalled(caller) and allCalls(caller, f))

predicate called(Function f)
  exists(FunctionAccess fa | fa.getTarget() = f)

from GlobalVariable v
where global(v)
  and not exists(VariableAccess lval |
        v.getAnAccess() = lval and lval.isUsedAsLValue() and
select v, "Initialization code for '" + v.getName() + "' is never run."

The query finds code that initializes a global variable (that is, uses it as an L-value) but is never called from main. Unless there is another entry point that triggers the initialization, the code should be modified so that the variable is initialized. Uninitialized variables may contain any value, as not all compilers generate code that zero-out memory, especially when optimizations are enabled or the compiler is not compliant with the latest language standards.

This check is an approximation, so some results may not be actual defects in the program. It is not possible in general to compute which function is actually called in a virtual call, or a call through a pointer, without running the program with all possible input data.


Examine the code and ensure that the variable is always initialized before it is used.


In the example below, the code that triggers the initialization of g_storage is not run from main. Unless the variable is initialized by another method, the call on line 10 may dereference a null pointer.

GlobalStorage *g_storage;

void init() { //initializes g_storage, but is never run from main
	g_storage = new GlobalStorage();

int main(int argc, char *argv[]) {
	... //init not called
	strcpy(g_storage->name, argv[1]); // g_storage is used before init() is called