#6753 segmentation fault (invalid code) in CheckMemoryLeakStructMember::checkStructVariable. #6754 segmentation fault (invalid code) in CheckUnusedVar::checkFunctionVariableUsage_iterateScopes. Trivial fixes to avoid null pointer access
This commit is contained in:
parent
87bf09c0ae
commit
f2d397882f
|
@ -2520,7 +2520,7 @@ void CheckMemoryLeakStructMember::checkStructVariable(const Variable * const var
|
||||||
|
|
||||||
// Check struct..
|
// Check struct..
|
||||||
unsigned int indentlevel2 = 0;
|
unsigned int indentlevel2 = 0;
|
||||||
for (const Token *tok2 = variable->nameToken(); tok2 != variable->scope()->classEnd; tok2 = tok2->next()) {
|
for (const Token *tok2 = variable->nameToken(); tok2 && tok2 != variable->scope()->classEnd; tok2 = tok2->next()) {
|
||||||
if (tok2->str() == "{")
|
if (tok2->str() == "{")
|
||||||
++indentlevel2;
|
++indentlevel2;
|
||||||
|
|
||||||
|
|
|
@ -440,7 +440,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
|
||||||
if (Token::Match(tok, "(| &| %name%") ||
|
if (Token::Match(tok, "(| &| %name%") ||
|
||||||
Token::Match(tok->next(), "< const| struct|union| %type% *| > ( &| %name%")) {
|
(tok && Token::Match(tok->next(), "< const| struct|union| %type% *| > ( &| %name%"))) {
|
||||||
bool addressOf = false;
|
bool addressOf = false;
|
||||||
|
|
||||||
if (Token::Match(tok, "%var% ."))
|
if (Token::Match(tok, "%var% ."))
|
||||||
|
@ -504,7 +504,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
|
||||||
|
|
||||||
// check if variable is local
|
// check if variable is local
|
||||||
unsigned int varid2 = tok->varId();
|
unsigned int varid2 = tok->varId();
|
||||||
Variables::VariableUsage* var2 = variables.find(varid2);
|
const Variables::VariableUsage* var2 = variables.find(varid2);
|
||||||
|
|
||||||
if (var2) { // local variable (alias or read it)
|
if (var2) { // local variable (alias or read it)
|
||||||
if (var1->_type == Variables::pointer || var1->_type == Variables::pointerArray) {
|
if (var1->_type == Variables::pointer || var1->_type == Variables::pointerArray) {
|
||||||
|
@ -599,9 +599,9 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
|
||||||
// check for alias to struct member
|
// check for alias to struct member
|
||||||
// char c[10]; a.b = c;
|
// char c[10]; a.b = c;
|
||||||
else if (Token::Match(tok->tokAt(-2), "%name% .")) {
|
else if (Token::Match(tok->tokAt(-2), "%name% .")) {
|
||||||
if (tok->tokAt(2)->varId()) {
|
if (tok->tokAt(2) && tok->tokAt(2)->varId()) {
|
||||||
unsigned int varid2 = tok->tokAt(2)->varId();
|
const unsigned int varid2 = tok->tokAt(2)->varId();
|
||||||
Variables::VariableUsage *var2 = variables.find(varid2);
|
const Variables::VariableUsage *var2 = variables.find(varid2);
|
||||||
|
|
||||||
// struct member aliased to local variable
|
// struct member aliased to local variable
|
||||||
if (var2 && (var2->_type == Variables::array ||
|
if (var2 && (var2->_type == Variables::array ||
|
||||||
|
@ -616,7 +616,7 @@ static const Token* doAssignment(Variables &variables, const Token *tok, bool de
|
||||||
// Possible pointer alias
|
// Possible pointer alias
|
||||||
else if (Token::Match(tok, "%name% = %name% ;")) {
|
else if (Token::Match(tok, "%name% = %name% ;")) {
|
||||||
const unsigned int varid2 = tok->tokAt(2)->varId();
|
const unsigned int varid2 = tok->tokAt(2)->varId();
|
||||||
Variables::VariableUsage *var2 = variables.find(varid2);
|
const Variables::VariableUsage *var2 = variables.find(varid2);
|
||||||
if (var2 && (var2->_type == Variables::array ||
|
if (var2 && (var2->_type == Variables::array ||
|
||||||
var2->_type == Variables::pointer)) {
|
var2->_type == Variables::pointer)) {
|
||||||
variables.use(varid2,tok);
|
variables.use(varid2,tok);
|
||||||
|
|
|
@ -113,6 +113,8 @@ private:
|
||||||
TEST_CASE(garbageCode72);
|
TEST_CASE(garbageCode72);
|
||||||
TEST_CASE(garbageCode73);
|
TEST_CASE(garbageCode73);
|
||||||
TEST_CASE(garbageCode74);
|
TEST_CASE(garbageCode74);
|
||||||
|
TEST_CASE(garbageCode75);
|
||||||
|
TEST_CASE(garbageCode76);
|
||||||
|
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
|
@ -630,6 +632,14 @@ private:
|
||||||
checkCode("_lenraw(const char* digits) { } typedef decltype(sizeof(0)) { } operator");
|
checkCode("_lenraw(const char* digits) { } typedef decltype(sizeof(0)) { } operator");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void garbageCode75() { // #6753
|
||||||
|
checkCode("{ { void foo() { struct }; { }; } }; struct S { } f =", "test.c");
|
||||||
|
}
|
||||||
|
|
||||||
|
void garbageCode76() { // #6754
|
||||||
|
checkCode(" ( ) ( ) { ( ) [ ] } TEST ( ) { ( _broadcast_f32x4 ) ( ) ( ) ( ) ( ) if ( ) ( ) ; } E mask = ( ) [ ] ( ) res1.x =");
|
||||||
|
}
|
||||||
|
|
||||||
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