diff --git a/lib/token.cpp b/lib/token.cpp index 55441aa59..e24dcd6ff 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -1436,6 +1436,8 @@ const Token *Token::getValueTokenDeadPointer() const const Variable * const var = vartok->variable(); if (var->isStatic() || var->isReference()) continue; + if (!var->scope()) + return nullptr; // #6804 if (var->scope()->type == Scope::eUnion && var->scope()->nestedIn == this->scope()) continue; // variable must be in same function (not in subfunction) diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index 43cbd9b13..b514a5eec 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -134,6 +134,7 @@ private: TEST_CASE(garbageCode92); TEST_CASE(garbageCode93); TEST_CASE(garbageCode94); + TEST_CASE(garbageCode95); TEST_CASE(garbageValueFlow); TEST_CASE(garbageSymbolDatabase); @@ -141,7 +142,20 @@ private: 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(""); Settings settings; @@ -156,7 +170,7 @@ private: // tokenize.. Tokenizer tokenizer(&settings, this); std::istringstream istr(code); - tokenizer.tokenize(istr, filename); + tokenizer.tokenize(istr, filename.c_str()); // call all "runChecks" in all registered Check classes for (std::list::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); } + 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() { // #6089 const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"