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();
|
||||
|
||||
// struct initialization (must be used before simplifyVarDecl)
|
||||
simplifyStructInit();
|
||||
|
||||
// Split up variable declarations.
|
||||
simplifyVarDecl();
|
||||
|
||||
|
@ -1264,6 +1267,7 @@ bool Tokenizer::tokenize(std::istream &code, const char FileName[], const std::s
|
|||
simplifyFunctionPointers();
|
||||
//updateClassList();
|
||||
setVarId();
|
||||
|
||||
if (!validate())
|
||||
return false;
|
||||
|
||||
|
@ -6535,6 +6539,59 @@ std::string Tokenizer::simplifyString(const std::string &source)
|
|||
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()
|
||||
{
|
||||
// Use "<" comparison instead of ">"
|
||||
|
|
|
@ -290,6 +290,9 @@ private:
|
|||
*/
|
||||
bool simplifyFunctionReturn();
|
||||
|
||||
/** Struct initialization */
|
||||
void simplifyStructInit();
|
||||
|
||||
/**
|
||||
* Remove redundant paranthesis:
|
||||
* - "((x))" => "(x)"
|
||||
|
|
|
@ -222,6 +222,9 @@ private:
|
|||
|
||||
// while(fclose(f)); => r = fclose(f); while(r){r=fclose(f);}
|
||||
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)
|
||||
|
@ -4102,6 +4105,14 @@ private:
|
|||
"}",
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue