Files
codeql/cpp/ql/test/query-tests/Likely Bugs/Memory Management/AllocaInLoop/AllocaInLoop1.cpp
Geoffrey White cf194219b9 CPP: Fix FPs.
2019-07-15 14:58:35 +01:00

128 lines
2.5 KiB
C++

// semmle-extractor-options: --clang
struct vtype {
int i1, i2;
};
extern int w1, w2;
#ifdef _MSC_VER
#define restrict __restrict
#else
#define restrict __restrict__
#endif
void *__builtin_alloca(unsigned long sz);
#define alloca __builtin_alloca
typedef unsigned long long size_t;
int printf(const char *restrict format, ...);
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
// case 1: alloca directly contained in an unbounded loop
void foo(const struct vtype* vec, int count) {
for (int i = 0; i < count; i++) {
const vtype* v = vec + i;
char *b1 = 0;
if (b1 == nullptr) {
if (w1 > w2) {
// Allocate the buffer on heap
b1 = new char[w1];
} else {
// Allocate the buffer on stack
b1 = (char*) alloca(w1); // BAD
}
}
memcpy(b1, v, w1);
printf("%s\n", b1);
if (w1 > w2) {
delete b1;
}
}
}
// case 2: alloca contained in a do-while(0) that is in turn contained
// in an unbounded loop
void bar(const struct vtype* vec, int count) {
for (int i = 0; i < count; i++) {
const vtype* v = vec + i;
char *b1 = 0;
do {
if (b1 == nullptr) {
if (w1 > w2) {
// Allocate the buffer on heap
b1 = new char[w1];
} else {
// Allocate the buffer on stack
b1 = (char*) alloca(w1); // BAD
}
}
} while (0);
memcpy(b1, v, w1);
printf("%s\n", b1);
if (w1 > w2) {
delete b1;
}
}
}
// case 3: alloca contained in an unbounded loop that is in turn contained
// in a do-while(0)
void baz(const struct vtype* vec, int count) {
do {
for (int i = 0; i < count; i++) {
const vtype* v = vec + i;
char *b1 = 0;
if (b1 == nullptr) {
if (w1 > w2) {
// Allocate the buffer on heap
b1 = new char[w1];
} else {
// Allocate the buffer on stack
b1 = (char*) alloca(w1); // BAD
}
}
memcpy(b1, v, w1);
printf("%s\n", b1);
if (w1 > w2) {
delete b1;
}
}
} while (0);
}
// case 4: alloca contained in an unbounded loop, followed by break.
void case4() {
char *buffer;
do {
buffer = (char*)alloca(1024); // GOOD
break;
} while (1);
delete [] buffer;
}
// case 5: alloca contained in an unbounded loop, followed by continue.
void case5() {
char *buffer;
do {
buffer = (char*)alloca(1024); // BAD
continue;
} while (1);
delete [] buffer;
}
// case 6: alloca contained in an unbounded loop, followed by return.
char *case6() {
char *buffer;
do {
buffer = (char*)alloca(1024); // GOOD
return buffer;
} while (1);
}