ValueFlow: Fix false positive for container size
This commit is contained in:
parent
738fb1b23a
commit
d7de46f50e
|
@ -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())) {
|
while (nullptr != (tok = tok->next())) {
|
||||||
if (Token::Match(tok, "[{}]"))
|
if (Token::Match(tok, "[{}]"))
|
||||||
|
@ -3504,6 +3504,8 @@ static void valueFlowContainerForward(const Token *tok, unsigned int containerId
|
||||||
continue;
|
continue;
|
||||||
if (Token::Match(tok, "%name% ="))
|
if (Token::Match(tok, "%name% ="))
|
||||||
break;
|
break;
|
||||||
|
if (isLikelyStreamRead(cpp, tok->astParent()))
|
||||||
|
break;
|
||||||
if (isContainerSizeChangedByFunction(tok))
|
if (isContainerSizeChangedByFunction(tok))
|
||||||
break;
|
break;
|
||||||
if (!tok->valueType() || !tok->valueType()->container)
|
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.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
valueFlowContainerForward(var->nameToken()->next(), var->declarationId(), value, settings);
|
valueFlowContainerForward(var->nameToken()->next(), var->declarationId(), value, settings, tokenlist->isCPP());
|
||||||
}
|
}
|
||||||
|
|
||||||
// after assignment
|
// after assignment
|
||||||
|
@ -3578,7 +3580,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
|
||||||
ValueFlow::Value value(Token::getStrLength(containerTok->tokAt(2)));
|
ValueFlow::Value value(Token::getStrLength(containerTok->tokAt(2)));
|
||||||
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
value.valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
||||||
value.setKnown();
|
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 {"))
|
if (Token::simpleMatch(after, "} else {"))
|
||||||
after = isEscapeScope(after->tokAt(2), tokenlist) ? nullptr : after->linkAt(2);
|
after = isEscapeScope(after->tokAt(2), tokenlist) ? nullptr : after->linkAt(2);
|
||||||
if (after && !isContainerSizeChanged(tok->varId(), scope.bodyStart, after))
|
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
|
// known value in conditional code
|
||||||
|
@ -3637,7 +3639,7 @@ static void valueFlowContainerSize(TokenList *tokenlist, SymbolDatabase* symbold
|
||||||
parent = parent->astParent();
|
parent = parent->astParent();
|
||||||
if (!parent) {
|
if (!parent) {
|
||||||
value.setKnown();
|
value.setKnown();
|
||||||
valueFlowContainerForward(scope.bodyStart, tok->varId(), value, settings);
|
valueFlowContainerForward(scope.bodyStart, tok->varId(), value, settings, tokenlist->isCPP());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3371,6 +3371,13 @@ private:
|
||||||
"}";
|
"}";
|
||||||
ASSERT_EQUALS("", isKnownContainerSizeValue(tokenValues(code, "ints . front"), 10));
|
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"
|
code = "void f() {\n"
|
||||||
" std::string s=\"abc\";\n" // size of s is 3
|
" std::string s=\"abc\";\n" // size of s is 3
|
||||||
" s.size();\n"
|
" s.size();\n"
|
||||||
|
|
Loading…
Reference in New Issue