From 8a708e556c9ac65739187e330f0d435915b1c847 Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sat, 4 Sep 2021 12:05:41 -0500 Subject: [PATCH] Fix 10456: FP identicalConditionAfterEarlyExit with variable captured by reference (#3439) --- lib/checkcondition.cpp | 2 ++ lib/valueflow.cpp | 4 ++++ test/testcondition.cpp | 11 +++++++++++ test/testvalueflow.cpp | 10 ++++++++++ 4 files changed, 27 insertions(+) diff --git a/lib/checkcondition.cpp b/lib/checkcondition.cpp index c7f7e82b1..29d127210 100644 --- a/lib/checkcondition.cpp +++ b/lib/checkcondition.cpp @@ -654,6 +654,8 @@ void CheckCondition::multiCondition2() const Token * const endToken = tok->scope()->bodyEnd; for (; tok && tok != endToken; tok = tok->next()) { + if (isExpressionChangedAt(cond1, tok, 0, false, mSettings, mTokenizer->isCPP())) + break; if (Token::Match(tok, "if|return")) { const Token * condStartToken = tok->str() == "if" ? tok->next() : tok; const Token * condEndToken = tok->str() == "if" ? condStartToken->link() : Token::findsimplematch(condStartToken, ";"); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index e4869c7ed..427afed34 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2131,6 +2131,10 @@ struct ValueFlowAnalyzer : Analyzer { } virtual Action isAliasModified(const Token* tok) const { + // Lambda function call + if (Token::Match(tok, "%var% (")) + // TODO: Check if modified in the lambda function + return Action::Invalid; int indirect = 0; if (tok->valueType()) indirect = tok->valueType()->pointer; diff --git a/test/testcondition.cpp b/test/testcondition.cpp index 587b4bfbb..32af00bc9 100644 --- a/test/testcondition.cpp +++ b/test/testcondition.cpp @@ -2676,6 +2676,17 @@ private: " return ret;\n" "}"); ASSERT_EQUALS("", errout.str()); + + // #10456 + check("int f() {\n" + " int i = 0;\n" + " auto f = [&](bool b) { if (b) ++i; };\n" + " if (i) return i;\n" + " f(true);\n" + " if (i) return i;\n" + " return 0;\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void innerConditionModified() { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 4c75f55d5..749cd8ff4 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3242,6 +3242,16 @@ private: " f();\n" "}"; TODO_ASSERT_EQUALS(true, false, testValueOfX(code, 3U, 3)); + + code = "void f() {\n" + " int x=3;\n" + " auto f = [&](){ x++; }\n" + " x = 1;\n" + " f();\n" + " int a = x;\n" // x is actually 2 + "}"; + ASSERT_EQUALS(false, testValueOfX(code, 6U, 1)); + ASSERT_EQUALS(false, testValueOfX(code, 6U, 3)); } void valueFlowForwardTryCatch() {