ValueFlow: Fix false positive for container size

This commit is contained in:
Daniel Marjamäki 2018-09-08 10:43:08 +02:00
parent 738fb1b23a
commit d7de46f50e
2 changed files with 14 additions and 5 deletions

View File

@ -3495,7 +3495,7 @@ static void valueFlowContainerReverse(const Token *tok, unsigned int containerId
}
}
static void valueFlowContainerForward(const Token *tok, unsigned int containerId, const ValueFlow::Value &value, const Settings *settings)
static void valueFlowContainerForward(const Token *tok, unsigned int containerId, const ValueFlow::Value &value, const Settings *settings, bool cpp)
{
while (nullptr != (tok = tok->next())) {
if (Token::Match(tok, "[{}]"))
@ -3504,6 +3504,8 @@ static void valueFlowContainerForward(const Token *tok, unsigned int containerId
continue;
if (Token::Match(tok, "%name% ="))
break;
if (isLikelyStreamRead(cpp, tok->astParent()))
break;
if (isContainerSizeChangedByFunction(tok))
break;
if (!tok->valueType() || !tok->valueType()->container)
@ -3566,7 +3568,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
}
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
value.setKnown();
valueFlowContainerForward(var->nameToken()->next(), var->declarationId(), value, settings);
valueFlowContainerForward(var->nameToken()->next(), var->declarationId(), value, settings, tokenlist->isCPP());
}
// after assignment
@ -3578,7 +3580,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
ValueFlow::Value value(Token::getStrLength(containerTok->tokAt(2)));
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
value.setKnown();
valueFlowContainerForward(containerTok->next(), containerTok->varId(), value, settings);
valueFlowContainerForward(containerTok->next(), containerTok->varId(), value, settings, tokenlist->isCPP());
}
}
}
@ -3627,7 +3629,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
if (Token::simpleMatch(after, "} else {"))
after = isEscapeScope(after->tokAt(2), tokenlist) ? nullptr : after->linkAt(2);
if (after && !isContainerSizeChanged(tok->varId(), scope.bodyStart, after))
valueFlowContainerForward(after, tok->varId(), value, settings);
valueFlowContainerForward(after, tok->varId(), value, settings, tokenlist->isCPP());
}
// known value in conditional code
@ -3637,7 +3639,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
parent = parent->astParent();
if (!parent) {
value.setKnown();
valueFlowContainerForward(scope.bodyStart, tok->varId(), value, settings);
valueFlowContainerForward(scope.bodyStart, tok->varId(), value, settings, tokenlist->isCPP());
}
}
}

View File

@ -3371,6 +3371,13 @@ private:
"}";
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front"), 10));
code = "void f() {\n"
" std::string s;\n"
" cin >> s;\n"
" s[0];\n"
"}";
ASSERT(tokenValues(code, "s [").empty());
code = "void f() {\n"
" std::string s=\"abc\";\n" // size of s is 3
" s.size();\n"