diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index aa0b2c91c29..fc464cc925b 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5160,9 +5160,10 @@ static void valueFlowInferCondition(TokenList& tokenlist, const Settings& settin setTokenValue(tok, std::move(value), settings); } } - } else if (Token::Match(tok->astParent(), "?|&&|!|%oror%") || + } else if (Token::Match(tok->astParent(), "&&|!|%oror%") || Token::Match(tok->astParent()->previous(), "if|while (") || - (astIsPointer(tok) && isUsedAsBool(tok, settings))) { + (astIsPointer(tok) && isUsedAsBool(tok, settings)) || + (astIsLHS(tok) && Token::simpleMatch(tok->astParent(), "?"))) { std::vector result = infer(makeIntegralInferModel(), "!=", tok->values(), 0); if (result.size() != 1) continue; diff --git a/lib/vf_settokenvalue.cpp b/lib/vf_settokenvalue.cpp index 9f56b57db0a..bd47aa2bdc5 100644 --- a/lib/vf_settokenvalue.cpp +++ b/lib/vf_settokenvalue.cpp @@ -426,22 +426,6 @@ namespace ValueFlow setTokenValue(parent, std::move(value), settings); } } else if (!value.isImpossible()) { - // is condition only depending on 1 variable? - nonneg int varId = 0; - bool ret = false; - visitAstNodes(parent->astOperand1(), - [&](const Token *t) { - if (t->varId()) { - if (varId > 0 || value.varId != 0) - ret = true; - varId = t->varId(); - } else if (t->str() == "(" && Token::Match(t->previous(), "%name%")) - ret = true; // function call - return ret ? ChildrenToVisit::done : ChildrenToVisit::op1_and_op2; - }); - if (ret) - return; - value.conditional = true; value.changeKnownToPossible(); diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index dfb61665b8a..675645b6adf 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -3631,7 +3631,7 @@ class TestSymbolDatabase : public TestFixture { ASSERT(fredScope != nullptr); // The struct Fred has two functions, a constructor and a destructor - ASSERT_EQUALS(2U, fredScope->functionList.size()); + ASSERT_EQUALS(2U, fredScope->functionList.size()); // cppcheck-suppress nullPointer // see ticket #9747 // Get linenumbers where the bodies for the constructor and destructor are.. unsigned int constructor = 0; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 618e16624d8..73f31875b2d 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -4286,6 +4286,26 @@ class TestValueFlow : public TestFixture { "}\n"; auto values = tokenValues(code, "s :", ValueFlow::Value::ValueType::FLOAT); ASSERT_EQUALS(0, values.size()); + + code = "int a[5];\n" // 15034 + "int g(int i) {\n" + " return a[i < 0 ? -i : i];\n" + "}\n" + "int f() {\n" + " return g(-5);\n" + "}\n"; + values = tokenValues(code, "?"); + ASSERT_EQUALS(2, values.size()); + auto it = values.begin(); + ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueType::INT, it->valueType); + ASSERT_EQUALS(0, it->intvalue); + ASSERT_EQUALS_ENUM(ValueFlow::Value::Bound::Lower, it->bound); + ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueKind::Possible, it->valueKind); + ++it; + ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueType::INT, it->valueType); + ASSERT_EQUALS(5, it->intvalue); + ASSERT_EQUALS_ENUM(ValueFlow::Value::Bound::Point, it->bound); + ASSERT_EQUALS_ENUM(ValueFlow::Value::ValueKind::Possible, it->valueKind); } void valueFlowForwardLambda() {