This commit is contained in:
parent
4ac7da7d51
commit
07e00d57d9
|
@ -25,6 +25,9 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &checks);
|
||||||
|
|
||||||
|
|
||||||
// default : bail out if the condition is has variable handling
|
// default : bail out if the condition is has variable handling
|
||||||
bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *> & checks)
|
bool ExecutionPath::parseCondition(const Token &tok, std::list<ExecutionPath *> & checks)
|
||||||
{
|
{
|
||||||
|
@ -80,6 +83,61 @@ static void printchecks(const std::list<ExecutionPath *> &checks)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Parse If/Switch body recursively.
|
||||||
|
* @param tok First token in body.
|
||||||
|
* @param checks The current checks
|
||||||
|
* @param newchecks new checks
|
||||||
|
* @param countif The countif set - count number of if for each execution path
|
||||||
|
*/
|
||||||
|
static void parseIfSwitchBody(const Token * const tok,
|
||||||
|
const std::list<ExecutionPath *> &checks,
|
||||||
|
std::list<ExecutionPath *> &newchecks,
|
||||||
|
std::set<unsigned int> &countif)
|
||||||
|
{
|
||||||
|
std::set<unsigned int> countif2;
|
||||||
|
std::list<ExecutionPath *> c;
|
||||||
|
if (!checks.empty())
|
||||||
|
{
|
||||||
|
std::list<ExecutionPath *>::const_iterator it;
|
||||||
|
for (it = checks.begin(); it != checks.end(); ++it)
|
||||||
|
{
|
||||||
|
c.push_back((*it)->copy());
|
||||||
|
if ((*it)->varId != 0)
|
||||||
|
countif2.insert((*it)->varId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkExecutionPaths_(tok, c);
|
||||||
|
while (!c.empty())
|
||||||
|
{
|
||||||
|
if (c.back()->varId == 0)
|
||||||
|
{
|
||||||
|
c.pop_back();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool duplicate = false;
|
||||||
|
std::list<ExecutionPath *>::const_iterator it;
|
||||||
|
for (it = checks.begin(); it != checks.end(); ++it)
|
||||||
|
{
|
||||||
|
if (*(*it) == *c.back())
|
||||||
|
{
|
||||||
|
duplicate = true;
|
||||||
|
countif2.erase((*it)->varId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!duplicate)
|
||||||
|
newchecks.push_back(c.back());
|
||||||
|
c.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add countif2 ids to countif.. countif.
|
||||||
|
countif.insert(countif2.begin(), countif2.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &checks)
|
static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &checks)
|
||||||
{
|
{
|
||||||
if (!tok || tok->str() == "}" || checks.empty())
|
if (!tok || tok->str() == "}" || checks.empty())
|
||||||
|
@ -138,62 +196,22 @@ static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &c
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
else if (tok2->str() == "}")
|
else if (tok2->str() == "}")
|
||||||
break;
|
break;
|
||||||
else if (tok2->str() == "case")
|
else if (tok2->str() == "case" &&
|
||||||
|
!Token::Match(tok2, "case %num% : ; case"))
|
||||||
{
|
{
|
||||||
if (Token::Match(tok2, "case %num% : ; case"))
|
parseIfSwitchBody(tok2, checks, newchecks, countif);
|
||||||
continue;
|
|
||||||
|
|
||||||
std::set<unsigned int> countif2;
|
|
||||||
std::list<ExecutionPath *> c;
|
|
||||||
if (!checks.empty())
|
|
||||||
{
|
|
||||||
std::list<ExecutionPath *>::const_iterator it;
|
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
|
||||||
{
|
|
||||||
c.push_back((*it)->copy());
|
|
||||||
if ((*it)->varId != 0)
|
|
||||||
countif2.insert((*it)->varId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkExecutionPaths_(tok2, c);
|
|
||||||
while (!c.empty())
|
|
||||||
{
|
|
||||||
if (c.back()->varId == 0)
|
|
||||||
{
|
|
||||||
c.pop_back();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool duplicate = false;
|
|
||||||
std::list<ExecutionPath *>::const_iterator it;
|
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
|
||||||
{
|
|
||||||
if (*(*it) == *c.back())
|
|
||||||
{
|
|
||||||
duplicate = true;
|
|
||||||
countif2.erase((*it)->varId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!duplicate)
|
|
||||||
newchecks.push_back(c.back());
|
|
||||||
c.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add countif2 ids to countif.. countif.
|
|
||||||
countif.insert(countif2.begin(), countif2.end());
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add newchecks to checks..
|
// Add newchecks to checks..
|
||||||
std::copy(newchecks.begin(), newchecks.end(), std::back_inserter(checks));
|
std::copy(newchecks.begin(), newchecks.end(), std::back_inserter(checks));
|
||||||
|
|
||||||
// Increase numberOfIf
|
// Increase numberOfIf
|
||||||
std::list<ExecutionPath *>::iterator it;
|
std::list<ExecutionPath *>::iterator it;
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
for (it = checks.begin(); it != checks.end(); ++it)
|
||||||
{
|
{
|
||||||
if (countif.find((*it)->varId) != countif.end())
|
if (countif.find((*it)->varId) != countif.end())
|
||||||
(*it)->numberOfIf++;
|
(*it)->numberOfIf++;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,47 +354,7 @@ static void checkExecutionPaths_(const Token *tok, std::list<ExecutionPath *> &c
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively check into the if ..
|
// Recursively check into the if ..
|
||||||
{
|
parseIfSwitchBody(tok->next(), checks, newchecks, countif);
|
||||||
std::set<unsigned int> countif2;
|
|
||||||
std::list<ExecutionPath *> c;
|
|
||||||
if (!checks.empty())
|
|
||||||
{
|
|
||||||
std::list<ExecutionPath *>::const_iterator it;
|
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
|
||||||
{
|
|
||||||
c.push_back((*it)->copy());
|
|
||||||
if ((*it)->varId != 0)
|
|
||||||
countif2.insert((*it)->varId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
checkExecutionPaths_(tok->next(), c);
|
|
||||||
while (!c.empty())
|
|
||||||
{
|
|
||||||
if (c.back()->varId == 0)
|
|
||||||
{
|
|
||||||
c.pop_back();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool duplicate = false;
|
|
||||||
std::list<ExecutionPath *>::const_iterator it;
|
|
||||||
for (it = checks.begin(); it != checks.end(); ++it)
|
|
||||||
{
|
|
||||||
if (*(*it) == *c.back())
|
|
||||||
{
|
|
||||||
duplicate = true;
|
|
||||||
countif2.erase((*it)->varId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!duplicate)
|
|
||||||
newchecks.push_back(c.back());
|
|
||||||
c.pop_back();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add countif2 ids to countif..
|
|
||||||
countif.insert(countif2.begin(), countif2.end());
|
|
||||||
}
|
|
||||||
|
|
||||||
// goto "}"
|
// goto "}"
|
||||||
tok = tok->link();
|
tok = tok->link();
|
||||||
|
|
|
@ -1754,6 +1754,21 @@ private:
|
||||||
" return i;\n"
|
" return i;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// No segmentation fault
|
||||||
|
checkUninitVar("void a() try\n"
|
||||||
|
"{\n"
|
||||||
|
" {\n"
|
||||||
|
" while (1) {\n"
|
||||||
|
" switch (1) {\n"
|
||||||
|
" case 1: {\n"
|
||||||
|
" int i;\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" }\n"
|
||||||
|
" } catch (...) {\n"
|
||||||
|
" }\n"
|
||||||
|
"}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// arrays..
|
// arrays..
|
||||||
|
|
Loading…
Reference in New Issue