parent
0f8f207719
commit
987c8a854e
|
@ -22,8 +22,7 @@ struct ForwardTraversal {
|
||||||
bool analyzeTerminate;
|
bool analyzeTerminate;
|
||||||
Terminate terminate = Terminate::None;
|
Terminate terminate = Terminate::None;
|
||||||
|
|
||||||
Progress Break(Terminate t = Terminate::None)
|
Progress Break(Terminate t = Terminate::None) {
|
||||||
{
|
|
||||||
if ((!analyzeOnly || analyzeTerminate) && t != Terminate::None)
|
if ((!analyzeOnly || analyzeTerminate) && t != Terminate::None)
|
||||||
terminate = t;
|
terminate = t;
|
||||||
return Progress::Break;
|
return Progress::Break;
|
||||||
|
@ -237,8 +236,7 @@ struct ForwardTraversal {
|
||||||
return ft;
|
return ft;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<ForwardTraversal> tryForkScope(Token* endBlock, bool isModified = false)
|
std::vector<ForwardTraversal> tryForkScope(Token* endBlock, bool isModified = false) {
|
||||||
{
|
|
||||||
if (analyzer->updateScope(endBlock, isModified)) {
|
if (analyzer->updateScope(endBlock, isModified)) {
|
||||||
ForwardTraversal ft = forkScope(endBlock);
|
ForwardTraversal ft = forkScope(endBlock);
|
||||||
return {ft};
|
return {ft};
|
||||||
|
@ -251,7 +249,7 @@ struct ForwardTraversal {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool hasInnerReturnScope(const Token* start, const Token* end) const {
|
bool hasInnerReturnScope(const Token* start, const Token* end) const {
|
||||||
for(const Token* tok=start;tok != end;tok = tok->previous()) {
|
for (const Token* tok=start; tok != end; tok = tok->previous()) {
|
||||||
if (Token::simpleMatch(tok, "}")) {
|
if (Token::simpleMatch(tok, "}")) {
|
||||||
const Token* ftok = nullptr;
|
const Token* ftok = nullptr;
|
||||||
bool r = isReturnScope(tok, &settings->library, &ftok);
|
bool r = isReturnScope(tok, &settings->library, &ftok);
|
||||||
|
|
|
@ -116,8 +116,7 @@ struct ReverseTraversal {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void traverse(Token* start, const Token* end = nullptr)
|
void traverse(Token* start, const Token* end = nullptr) {
|
||||||
{
|
|
||||||
if (start == end)
|
if (start == end)
|
||||||
return;
|
return;
|
||||||
for (Token* tok = start->previous(); tok != end; tok = tok->previous()) {
|
for (Token* tok = start->previous(); tok != end; tok = tok->previous()) {
|
||||||
|
|
|
@ -3736,7 +3736,7 @@ static ValueFlow::Value makeConditionValue(long long val, const Token* condTok,
|
||||||
v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is false");
|
v.errorPath.emplace_back(condTok, "Assuming condition '" + condTok->expressionString() + "' is false");
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase* symboldatabase, ErrorLogger *errorLogger, const Settings *settings)
|
||||||
{
|
{
|
||||||
for (const Scope * scope : symboldatabase->functionScopes) {
|
for (const Scope * scope : symboldatabase->functionScopes) {
|
||||||
|
@ -3770,7 +3770,7 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
|
||||||
std::vector<const Token*> args = astFlatten(condTok, "&&");
|
std::vector<const Token*> args = astFlatten(condTok, "&&");
|
||||||
conds.insert(conds.end(), args.begin(), args.end());
|
conds.insert(conds.end(), args.begin(), args.end());
|
||||||
}
|
}
|
||||||
for(const Token* condTok2:conds) {
|
for (const Token* condTok2:conds) {
|
||||||
ExpressionAnalyzer a1(condTok2, makeConditionValue(1, condTok2, true), tokenlist);
|
ExpressionAnalyzer a1(condTok2, makeConditionValue(1, condTok2, true), tokenlist);
|
||||||
valueFlowGenericForward(startTok, startTok->link(), a1, settings);
|
valueFlowGenericForward(startTok, startTok->link(), a1, settings);
|
||||||
|
|
||||||
|
@ -3788,7 +3788,7 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
|
||||||
// Check else block
|
// Check else block
|
||||||
if (Token::simpleMatch(startTok->link(), "} else {")) {
|
if (Token::simpleMatch(startTok->link(), "} else {")) {
|
||||||
startTok = startTok->link()->tokAt(2);
|
startTok = startTok->link()->tokAt(2);
|
||||||
for(const Token* condTok2:conds) {
|
for (const Token* condTok2:conds) {
|
||||||
ExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist);
|
ExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist);
|
||||||
valueFlowGenericForward(startTok, startTok->link(), a1, settings);
|
valueFlowGenericForward(startTok, startTok->link(), a1, settings);
|
||||||
|
|
||||||
|
@ -3799,7 +3799,7 @@ static void valueFlowConditionExpressions(TokenList *tokenlist, SymbolDatabase*
|
||||||
|
|
||||||
// Check if the block terminates early
|
// Check if the block terminates early
|
||||||
if (isEscapeScope(blockTok, tokenlist)) {
|
if (isEscapeScope(blockTok, tokenlist)) {
|
||||||
for(const Token* condTok2:conds) {
|
for (const Token* condTok2:conds) {
|
||||||
ExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist);
|
ExpressionAnalyzer a1(condTok2, makeConditionValue(0, condTok2, false), tokenlist);
|
||||||
valueFlowGenericForward(startTok->link()->next(), scope->bodyEnd, a1, settings);
|
valueFlowGenericForward(startTok->link()->next(), scope->bodyEnd, a1, settings);
|
||||||
|
|
||||||
|
@ -3827,8 +3827,10 @@ static void valueFlowForwardAssign(Token* const tok,
|
||||||
values.remove_if(std::mem_fn(&ValueFlow::Value::isLifetimeValue));
|
values.remove_if(std::mem_fn(&ValueFlow::Value::isLifetimeValue));
|
||||||
}
|
}
|
||||||
if (std::all_of(
|
if (std::all_of(
|
||||||
vars.begin(), vars.end(), [&](const Variable* var) { return !var->isPointer() && !var->isSmartPointer(); }))
|
vars.begin(), vars.end(), [&](const Variable* var) {
|
||||||
values.remove_if(std::mem_fn(&ValueFlow::Value::isTokValue));
|
return !var->isPointer() && !var->isSmartPointer();
|
||||||
|
}))
|
||||||
|
values.remove_if(std::mem_fn(&ValueFlow::Value::isTokValue));
|
||||||
if (tok->astParent()) {
|
if (tok->astParent()) {
|
||||||
for (ValueFlow::Value& value : values) {
|
for (ValueFlow::Value& value : values) {
|
||||||
const std::string info = "Assignment '" + tok->astParent()->expressionString() + "', assigned value is " + value.infoString();
|
const std::string info = "Assignment '" + tok->astParent()->expressionString() + "', assigned value is " + value.infoString();
|
||||||
|
@ -4194,9 +4196,9 @@ struct ConditionHandler {
|
||||||
if (isExpressionChanged(cond.vartok, start, end, settings, tokenlist->isCPP())) {
|
if (isExpressionChanged(cond.vartok, start, end, settings, tokenlist->isCPP())) {
|
||||||
// If its reassigned in loop then analyze from the end
|
// If its reassigned in loop then analyze from the end
|
||||||
if (!Token::Match(tok, "%assign%|++|--") &&
|
if (!Token::Match(tok, "%assign%|++|--") &&
|
||||||
findExpression(cond.vartok->exprId(), start, end, [&](const Token* tok2) {
|
findExpression(cond.vartok->exprId(), start, end, [&](const Token* tok2) {
|
||||||
return Token::Match(tok2->astParent(), "%assign%") && astIsLHS(tok2);
|
return Token::Match(tok2->astParent(), "%assign%") && astIsLHS(tok2);
|
||||||
})) {
|
})) {
|
||||||
// Start at the end of the loop body
|
// Start at the end of the loop body
|
||||||
Token* bodyTok = top->link()->next();
|
Token* bodyTok = top->link()->next();
|
||||||
reverse(bodyTok->link(), bodyTok, cond.vartok, values, tokenlist, settings);
|
reverse(bodyTok->link(), bodyTok, cond.vartok, values, tokenlist, settings);
|
||||||
|
@ -4458,8 +4460,7 @@ struct SimpleConditionHandler : ConditionHandler {
|
||||||
const Token* exprTok,
|
const Token* exprTok,
|
||||||
const std::list<ValueFlow::Value>& values,
|
const std::list<ValueFlow::Value>& values,
|
||||||
TokenList* tokenlist,
|
TokenList* tokenlist,
|
||||||
const Settings* settings) const OVERRIDE
|
const Settings* settings) const OVERRIDE {
|
||||||
{
|
|
||||||
return valueFlowReverse(start, endToken, exprTok, values, tokenlist, settings);
|
return valueFlowReverse(start, endToken, exprTok, values, tokenlist, settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6179,8 +6180,7 @@ struct ContainerConditionHandler : ConditionHandler {
|
||||||
const Token* exprTok,
|
const Token* exprTok,
|
||||||
const std::list<ValueFlow::Value>& values,
|
const std::list<ValueFlow::Value>& values,
|
||||||
TokenList* tokenlist,
|
TokenList* tokenlist,
|
||||||
const Settings* settings) const OVERRIDE
|
const Settings* settings) const OVERRIDE {
|
||||||
{
|
|
||||||
if (values.empty())
|
if (values.empty())
|
||||||
return;
|
return;
|
||||||
if (!exprTok->variable())
|
if (!exprTok->variable())
|
||||||
|
|
|
@ -2137,8 +2137,7 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer69()
|
void nullpointer69() {
|
||||||
{
|
|
||||||
check("void f(const Scope *scope) {\n"
|
check("void f(const Scope *scope) {\n"
|
||||||
" if (scope->definedType) {}\n"
|
" if (scope->definedType) {}\n"
|
||||||
" while (scope) {\n"
|
" while (scope) {\n"
|
||||||
|
@ -2212,7 +2211,7 @@ private:
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:10]: (warning) Either the condition 'first' is redundant or there is possible null pointer dereference: first.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:8] -> [test.cpp:10]: (warning) Either the condition 'first' is redundant or there is possible null pointer dereference: first.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer_addressOf() { // address of
|
void nullpointer_addressOf() { // address of
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" struct X *x = 0;\n"
|
" struct X *x = 0;\n"
|
||||||
|
|
Loading…
Reference in New Issue