#6804 segmentation fault (invalid code) in Token::getValueTokenDeadPointer. Fix null pointer access
TestGarbage: Increase coverage by running all code snippets as C as well as C++ code. (inspired by #6800)
This commit is contained in:
parent
c0b91662ba
commit
99dfd55d0c
|
@ -1436,6 +1436,8 @@ const Token *Token::getValueTokenDeadPointer() const
|
||||||
const Variable * const var = vartok->variable();
|
const Variable * const var = vartok->variable();
|
||||||
if (var->isStatic() || var->isReference())
|
if (var->isStatic() || var->isReference())
|
||||||
continue;
|
continue;
|
||||||
|
if (!var->scope())
|
||||||
|
return nullptr; // #6804
|
||||||
if (var->scope()->type == Scope::eUnion && var->scope()->nestedIn == this->scope())
|
if (var->scope()->type == Scope::eUnion && var->scope()->nestedIn == this->scope())
|
||||||
continue;
|
continue;
|
||||||
// variable must be in same function (not in subfunction)
|
// variable must be in same function (not in subfunction)
|
||||||
|
|
|
@ -134,6 +134,7 @@ private:
|
||||||
TEST_CASE(garbageCode92);
|
TEST_CASE(garbageCode92);
|
||||||
TEST_CASE(garbageCode93);
|
TEST_CASE(garbageCode93);
|
||||||
TEST_CASE(garbageCode94);
|
TEST_CASE(garbageCode94);
|
||||||
|
TEST_CASE(garbageCode95);
|
||||||
|
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
|
@ -141,7 +142,20 @@ private:
|
||||||
TEST_CASE(templateSimplifierCrashes);
|
TEST_CASE(templateSimplifierCrashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string checkCode(const char code[], const char filename[] = "test.cpp") {
|
std::string checkCode(const char code[], const std::string filename = "test.cpp") {
|
||||||
|
// double the tests - run each example as C as well as C++
|
||||||
|
const std::string alternatefilename = (filename=="test.c") ? "test.cpp" : "test.c";
|
||||||
|
// run alternate check first. It should only ensure stability
|
||||||
|
try {
|
||||||
|
checkCodeInternal(code, alternatefilename);
|
||||||
|
}
|
||||||
|
catch(InternalError& ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return checkCodeInternal(code, filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string checkCodeInternal(const char code[], const std::string& filename) {
|
||||||
errout.str("");
|
errout.str("");
|
||||||
|
|
||||||
Settings settings;
|
Settings settings;
|
||||||
|
@ -156,7 +170,7 @@ private:
|
||||||
// tokenize..
|
// tokenize..
|
||||||
Tokenizer tokenizer(&settings, this);
|
Tokenizer tokenizer(&settings, this);
|
||||||
std::istringstream istr(code);
|
std::istringstream istr(code);
|
||||||
tokenizer.tokenize(istr, filename);
|
tokenizer.tokenize(istr, filename.c_str());
|
||||||
|
|
||||||
// call all "runChecks" in all registered Check classes
|
// call all "runChecks" in all registered Check classes
|
||||||
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
|
for (std::list<Check *>::const_iterator it = Check::instances().begin(); it != Check::instances().end(); ++it) {
|
||||||
|
@ -734,6 +748,10 @@ private:
|
||||||
ASSERT_THROW(checkCode("typedef long __m256i __attribute__ ( ( ( ) ) )[ ; ( ) { } typedef __m256i __attribute__ ( ( ( ) ) ) < ] ( ) { ; }"), InternalError);
|
ASSERT_THROW(checkCode("typedef long __m256i __attribute__ ( ( ( ) ) )[ ; ( ) { } typedef __m256i __attribute__ ( ( ( ) ) ) < ] ( ) { ; }"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void garbageCode95() { // #6804
|
||||||
|
checkCode("{ } x x ; { } h h [ ] ( ) ( ) { struct x ( x ) ; int __attribute__ ( ) f ( ) { h - > first = & x ; struct x * n = h - > first ; ( ) n > } }"); // do not crash
|
||||||
|
}
|
||||||
|
|
||||||
void garbageValueFlow() {
|
void garbageValueFlow() {
|
||||||
// #6089
|
// #6089
|
||||||
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
||||||
|
|
Loading…
Reference in New Issue