mirror of
https://github.com/github/codeql.git
synced 2025-12-17 09:13:20 +01:00
189 lines
3.3 KiB
C++
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;
|
|
}
|