Skip to content
Merged
9 changes: 9 additions & 0 deletions cpp/ql/src/Critical/InitialisationNotRun.ql
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,18 @@ predicate called(Function f) {
exists(FunctionAccess fa | fa.getTarget() = f)
}

predicate staticWithoutDereference(GlobalVariable v) {
v.isStatic() and
not exists(VariableAccess va |
va = v.getAnAccess() and
dereferenced(va)
)
}

from GlobalVariable v
where
global(v) and
not staticWithoutDereference(v) and
not exists(VariableAccess lval |
v.getAnAccess() = lval and
lval.isUsedAsLValue() and
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The "GlobalVariable not initialized" query (`cpp/not-initialised`) no longer reports an alert on static global variables that has no dereference.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Critical/InitialisationNotRun.ql
32 changes: 32 additions & 0 deletions cpp/ql/test/query-tests/Critical/InitialisationNotRun/test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <string.h>

class GlobalStorage {
public:
char name[1000];
};

GlobalStorage *g1; // BAD
static GlobalStorage g2; // GOOD
static GlobalStorage *g3; // BAD
// static variables are initialized by compilers
static int a; // GOOD
static int b = 0; // GOOD

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

void init2(int b) {
for (int i = 0; i < b; ++i)
a *= -1;
}

int main(int argc, char *argv[]) {
//init not called
strcpy(g1->name, argv[1]); // g1 is used before init() is called
strcpy(g2.name, argv[1]); // g2 is initialised by compiler
strcpy(g3->name, argv[1]);
b++;
return 0;
}