From de5bef27fedd36011728bd16d19bf6a7b2d6c03e Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 8 Sep 2021 21:31:17 -0500 Subject: [PATCH 1/3] Fix 10467: FP mismatchingContainers with array of vectors --- lib/valueflow.cpp | 16 ++++++++++++---- test/teststl.cpp | 10 ++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 1f5047a6f36..6a46e6550dd 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -505,6 +505,8 @@ static ValueFlow::Value truncateImplicitConversion(Token* parent, const ValueFlo /** set ValueFlow value and perform calculations if possible */ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* settings) { + if (Token::Match(tok, "it") && value.isLifetimeValue() && value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator) + assert(true); // Skip setting values that are too big since its ambiguous if (!value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) && ValueFlow::getSizeOf(*tok->valueType(), settings) >= sizeof(MathLib::bigint)) @@ -3577,11 +3579,17 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog if (i->container != returnContainer) continue; const Token * const argTok = args[argnr - 1]; + bool forward = false; + for(ValueFlow::Value val:argTok->values()) { + if (!val.isLifetimeValue()) + continue; + val.errorPath.emplace_back(argTok, "Passed to '" + tok->str() + "'."); + setTokenValue(tok->next(), val, settings); + forward = true; + } // Check if lifetime is available to avoid adding the lifetime twice - ValueFlow::Value val = getLifetimeObjValue(argTok); - if (val.tokvalue) { - LifetimeStore{argTok, "Passed to '" + tok->str() + "'.", ValueFlow::Value::LifetimeKind::Iterator}.byVal( - tok->next(), tokenlist, errorLogger, settings); + if (forward) { + valueFlowForwardLifetime(tok, tokenlist, errorLogger, settings); break; } } diff --git a/test/teststl.cpp b/test/teststl.cpp index e523690db9a..4acb808a951 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1704,6 +1704,16 @@ class TestStl : public TestFixture { " if (c.end() == d.end()) {}\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #10467 + check("void f(std::array, N>& A) {\n" + " for (auto& a : A) {\n" + " auto it = std::find_if(a.begin(), a.end(), \n" + " [](auto i) { return i == 0; });\n" + " if (it != a.end()) {}\n" + " }\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } // Dereferencing invalid pointer From 560f43f707c2e0e41c4e332ee071913747763b21 Mon Sep 17 00:00:00 2001 From: Paul Date: Wed, 8 Sep 2021 21:32:25 -0500 Subject: [PATCH 2/3] Format --- lib/valueflow.cpp | 5 +++-- test/teststl.cpp | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 6a46e6550dd..d31d1eb1594 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -505,7 +505,8 @@ static ValueFlow::Value truncateImplicitConversion(Token* parent, const ValueFlo /** set ValueFlow value and perform calculations if possible */ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* settings) { - if (Token::Match(tok, "it") && value.isLifetimeValue() && value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator) + if (Token::Match(tok, "it") && value.isLifetimeValue() && + value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator) assert(true); // Skip setting values that are too big since its ambiguous if (!value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) && @@ -3580,7 +3581,7 @@ static void valueFlowLifetimeFunction(Token *tok, TokenList *tokenlist, ErrorLog continue; const Token * const argTok = args[argnr - 1]; bool forward = false; - for(ValueFlow::Value val:argTok->values()) { + for (ValueFlow::Value val : argTok->values()) { if (!val.isLifetimeValue()) continue; val.errorPath.emplace_back(argTok, "Passed to '" + tok->str() + "'."); diff --git a/test/teststl.cpp b/test/teststl.cpp index 4acb808a951..261a10c7828 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -1707,12 +1707,12 @@ class TestStl : public TestFixture { // #10467 check("void f(std::array, N>& A) {\n" - " for (auto& a : A) {\n" - " auto it = std::find_if(a.begin(), a.end(), \n" - " [](auto i) { return i == 0; });\n" - " if (it != a.end()) {}\n" - " }\n" - "}\n"); + " for (auto& a : A) {\n" + " auto it = std::find_if(a.begin(), a.end(), \n" + " [](auto i) { return i == 0; });\n" + " if (it != a.end()) {}\n" + " }\n" + "}\n"); ASSERT_EQUALS("", errout.str()); } From f6e43600c7243221e058017fec645db5d082a58b Mon Sep 17 00:00:00 2001 From: Paul Date: Thu, 9 Sep 2021 10:42:02 -0500 Subject: [PATCH 3/3] Remove debug code --- lib/valueflow.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index d31d1eb1594..d7ffa28b989 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -505,9 +505,6 @@ static ValueFlow::Value truncateImplicitConversion(Token* parent, const ValueFlo /** set ValueFlow value and perform calculations if possible */ static void setTokenValue(Token* tok, ValueFlow::Value value, const Settings* settings) { - if (Token::Match(tok, "it") && value.isLifetimeValue() && - value.lifetimeKind == ValueFlow::Value::LifetimeKind::Iterator) - assert(true); // Skip setting values that are too big since its ambiguous if (!value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) && ValueFlow::getSizeOf(*tok->valueType(), settings) >= sizeof(MathLib::bigint))