From d7de46f50e66f3b9607462dc1d563fd31f767313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Sep 2018 10:43:08 +0200 Subject: [PATCH] ValueFlow: Fix false positive for container size --- lib/valueflow.cpp | 12 +++++++----- test/testvalueflow.cpp | 7 +++++++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 97c1a9b2b..571990cd4 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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()); } } } diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index cbc04a29b..991878015 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -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"