Files
codeql/cpp/ql/test/query-tests/Likely Bugs/RedundantNullCheckSimple/RedundantNullCheckSimple.cpp
2020-02-06 09:26:33 +01:00

113 lines
2.0 KiB
C++

void test_simple_bad(int *p) {
int x;
x = *p;
if (p == nullptr) { // BAD
return;
}
}
void test_not_same_basic_block(int *p) {
int x = *p;
if (x > 100)
return;
if (!p) // BAD
return;
}
void test_indirect(int **p) {
int x;
x = **p;
if (*p == nullptr) { // BAD
return;
}
}
struct ContainsIntPtr {
int **intPtr;
};
bool check_curslist(ContainsIntPtr *cip) {
// both the deref and the null check come from the same instruction, but it's
// an AliasedDefinition instruction.
return *cip->intPtr != nullptr; // GOOD
}
void test_no_single_dominator(int *p, bool b) {
int x;
if (b) {
x = *p;
} else {
x = *p;
}
if (p == nullptr) { // BAD [NOT DETECTED]
return;
}
}
int test_postdominator_same_bb(int *p) {
int b = (p == nullptr); // BAD
// This dereference is a postdominator of the null check, meaning that all
// paths from the check to the function exit will pass through it.
return *p + b;
}
int test_postdominator(int *p) {
int b = (p == nullptr); // BAD [NOT DETECTED]
if (b) b++; // This line breaks up the basic block
// This dereference is a postdominator of the null check, meaning that all
// paths from the check to the function exit will pass through it.
return *p + b;
}
int test_inverted_logic(int *p) {
if (p == nullptr) { // BAD [NOT DETECTED]
// The check above should probably have been `!=` instead of `==`.
return *p;
} else {
return 0;
}
}
void test_indirect_local() {
int a = 0;
int *p = &a;
int **pp = &p;
int x;
x = **pp;
if (*pp == nullptr) { // BAD
return;
}
}
void test_field_local(bool boolvar) {
int a = 0;
struct {
int *p;
} s = { &a };
auto sp = &s;
if (boolvar) {
int x = *sp->p;
if (sp->p == nullptr) { // BAD
return;
}
} else {
int *x = sp->p;
if (sp == nullptr) { // BAD [NOT DETECTED]
return;
}
}
}
struct S {
long **pplong;
void test_phi() {
while (*pplong != nullptr) { // GOOD
pplong++;
}
}
};