Fixed #1477 (false positive: Uninitialized variable when pointer given to struct)
This commit is contained in:
parent
846a3a0186
commit
772aa95c8a
|
@ -1242,6 +1242,9 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
|
||||||
|
|
||||||
simplifyConst();
|
simplifyConst();
|
||||||
|
|
||||||
|
// struct initialization (must be used before simplifyVarDecl)
|
||||||
|
simplifyStructInit();
|
||||||
|
|
||||||
// Split up variable declarations.
|
// Split up variable declarations.
|
||||||
simplifyVarDecl();
|
simplifyVarDecl();
|
||||||
|
|
||||||
|
@ -1264,6 +1267,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
|
||||||
simplifyFunctionPointers();
|
simplifyFunctionPointers();
|
||||||
//updateClassList();
|
//updateClassList();
|
||||||
setVarId();
|
setVarId();
|
||||||
|
|
||||||
if (!validate())
|
if (!validate())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -6535,6 +6539,59 @@ std::string Tokenizer::simplifyString(const std::string &source)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Tokenizer::simplifyStructInit()
|
||||||
|
{
|
||||||
|
for (Token *tok = _tokens; tok; tok = tok->next())
|
||||||
|
{
|
||||||
|
if (Token::Match(tok, "[;{}] struct| %type% %var% = { . %type% ="))
|
||||||
|
{
|
||||||
|
// Goto "." and check if the initializations have an expected format
|
||||||
|
const Token *tok2 = tok;
|
||||||
|
while (tok2->str() != ".")
|
||||||
|
tok2 = tok2->next();
|
||||||
|
while (tok2 && tok2->str() == ".")
|
||||||
|
{
|
||||||
|
if (Token::Match(tok2, ". %type% = %num% [,}]"))
|
||||||
|
tok2 = tok2->tokAt(4);
|
||||||
|
else if (Token::Match(tok2, ". %type% = %var% [,}]"))
|
||||||
|
tok2 = tok2->tokAt(4);
|
||||||
|
else if (Token::Match(tok2, ". %type% = & %var% [,}]"))
|
||||||
|
tok2 = tok2->tokAt(5);
|
||||||
|
|
||||||
|
if (Token::simpleMatch(tok2, ", ."))
|
||||||
|
tok2 = tok2->next();
|
||||||
|
}
|
||||||
|
if (!Token::Match(tok2, "} ;"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Known expression format => Perform simplification
|
||||||
|
Token *vartok = tok->tokAt(3);
|
||||||
|
if (vartok->str() == "=")
|
||||||
|
vartok = vartok->previous();
|
||||||
|
vartok->next()->str(";");
|
||||||
|
|
||||||
|
Token *tok3 = vartok->tokAt(2);
|
||||||
|
tok3->link(0);
|
||||||
|
while (Token::Match(tok3, "[{,] . %type% ="))
|
||||||
|
{
|
||||||
|
tok3->str(vartok->str());
|
||||||
|
tok3->varId(vartok->varId());
|
||||||
|
tok3 = tok3->tokAt(5);
|
||||||
|
while (!Token::Match(tok3, "[,}]"))
|
||||||
|
tok3 = tok3->next();
|
||||||
|
if (tok3->str() == "}")
|
||||||
|
{
|
||||||
|
tok3->deleteThis();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tok3->previous()->insertToken(";");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Tokenizer::simplifyComparisonOrder()
|
void Tokenizer::simplifyComparisonOrder()
|
||||||
{
|
{
|
||||||
// Use "<" comparison instead of ">"
|
// Use "<" comparison instead of ">"
|
||||||
|
|
|
@ -290,6 +290,9 @@ private:
|
||||||
*/
|
*/
|
||||||
bool simplifyFunctionReturn();
|
bool simplifyFunctionReturn();
|
||||||
|
|
||||||
|
/** Struct initialization */
|
||||||
|
void simplifyStructInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove redundant paranthesis:
|
* Remove redundant paranthesis:
|
||||||
* - "((x))" => "(x)"
|
* - "((x))" => "(x)"
|
||||||
|
|
|
@ -222,6 +222,9 @@ private:
|
||||||
|
|
||||||
// while(fclose(f)); => r = fclose(f); while(r){r=fclose(f);}
|
// while(fclose(f)); => r = fclose(f); while(r){r=fclose(f);}
|
||||||
TEST_CASE(simplifyFuncInWhile);
|
TEST_CASE(simplifyFuncInWhile);
|
||||||
|
|
||||||
|
// struct ABC abc = { .a = 3 }; => struct ABC abc; abc.a = 3;
|
||||||
|
TEST_CASE(initstruct);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string tok(const char code[], bool simplify = true)
|
std::string tok(const char code[], bool simplify = true)
|
||||||
|
@ -4102,6 +4105,14 @@ private:
|
||||||
"}",
|
"}",
|
||||||
tok("while(fclose(f)); while(fclose(g));"));
|
tok("while(fclose(f)); while(fclose(g));"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void initstruct()
|
||||||
|
{
|
||||||
|
ASSERT_EQUALS("; struct A a ; a . buf = 3 ;", tok("; struct A a = { .buf = 3 };"));
|
||||||
|
ASSERT_EQUALS("; struct A a ; a . buf = x ;", tok("; struct A a = { .buf = x };"));
|
||||||
|
ASSERT_EQUALS("; struct A a ; a . buf = & key ;", tok("; struct A a = { .buf = &key };"));
|
||||||
|
ASSERT_EQUALS("; struct ABC abc ; abc . a = 3 ; abc . b = x ; abc . c = & key ;", tok("; struct ABC abc = { .a = 3, .b = x, .c = &key };"));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_TEST(TestSimplifyTokens)
|
REGISTER_TEST(TestSimplifyTokens)
|
||||||
|
|
Loading…
Reference in New Issue