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())) { 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());
} }
} }
} }

View File

@ -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"