Files
codeql/cpp/ql/test/library-tests/defuse/indirect_use.cpp
2018-08-02 17:53:23 +01:00

189 lines
3.3 KiB
C++

extern int externInt; // used as a source of non-determinism
void receiveInt(int);
void receiveIntPtr(int *p);
void receiveConstIntPtr(const int *p);
// Pointers and references to functions
void (*functionPointer)(int *p);
extern void (&functionReference)(int *p);
void (&referenceToreceiveIntPtr)(int *p) = receiveIntPtr;
struct IntPointer {
int *p;
};
IntPointer globalIntPtr;
IntPointer *globalIntPtrPtr = &globalIntPtr;
static void readPointer1(int *ip) {
int *p = ip;
receiveInt(*p);
}
static void readPointer2(int *ip) {
int *p = ip + 1;
p--;
receiveInt(*p);
}
static void readPPP(int ***ppp) {
receiveInt(***ppp);
}
static void readPointer3(int *ip) {
int *p = ip;
int **pp = &p;
readPPP(&pp);
}
void readPointer4(int *ip) {
readPointer3(ip);
}
void readPointer5(int *ip) {
receiveInt(ip[0]);
}
void readVarArgsByCount(int argCount, ...) {
__builtin_va_list ap;
__builtin_va_start(ap, argCount);
for (int i = 0; i < argCount; i++) {
int *p = __builtin_va_arg(ap, int*);
receiveIntPtr(p);
}
__builtin_va_end(ap);
}
static void readRef1(int &i) {
int *p = &i + 1;
p--;
receiveInt(*p);
}
static void readRef2(int &i) {
if (externInt) {
i = 0;
}
receiveInt(i);
}
static void readRef3(int &i) {
readRef2(i);
}
static void leakPointer1(int *ip) {
globalIntPtrPtr->p = ip;
}
static void readPointerConditional(int *ip) {
if (externInt) {
receiveInt(*ip);
}
}
static void ignorePointer1(int *ip) {
}
// recursive
static void ignorePointer2(int *ip) {
if (externInt > 0) {
externInt--;
ignorePointer1(ip);
ignorePointer2(ip);
}
}
static void writePointer1(int *ip) {
*ip = 1;
}
static void writePointer2(int *ip) {
ip[0] = 1;
}
static void writePointer3(int *ip) {
*ip = 1;
receiveInt(*ip);
}
static void writeRef3(int &i) {
i = 1;
receiveInt(i);
}
static void writePointer4(int *ip) {
ip[0] = 1;
ip++;
ip--;
receiveInt(*ip);
}
struct C {
virtual void f(int &i) {
// This function does not access i, but overrides might.
}
};
struct NestedStruct {
struct {
struct {
double d;
int i;
} level2;
} level1;
};
void readNS1(NestedStruct *ns) {
readPointer1(&ns->level1.level2.i);
}
void readNS2(NestedStruct *ns) {
receiveInt(ns->level1.level2.i);
}
void writeNS1(NestedStruct *ns) {
ns->level1.level2.i = 0;
}
void writeNS2(NestedStruct &ns) {
ns.level1.level2.i = 0;
}
void caller(C *object) {
int i;
readPointer1(&i);
readPointer2(&i);
readPointer3(&i);
readPointer4(&i);
readPointer5(&i);
readVarArgsByCount(0, &i); // does not actually read
readVarArgsByCount(1, &i);
readRef1(i);
readRef2(i);
readRef3(i);
leakPointer1(&i);
readPointerConditional(&i);
ignorePointer1(&i);
ignorePointer2(&i);
writePointer1(&i);
writePointer2(&i);
writePointer3(&i);
writePointer4(&i);
writeRef3(i);
object->f(i);
functionPointer(&i);
functionReference(&i);
referenceToreceiveIntPtr(&i);
NestedStruct ns;
readNS1(&ns);
readNS2(&ns);
writeNS1(&ns);
writeNS2(ns);
receiveInt(*globalIntPtrPtr->p);
functionPointer = receiveIntPtr;
}