diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 8f7f9d9e1..733f5f047 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -1689,20 +1689,6 @@ bool isConstFunctionCall(const Token* ftok, const Library& library) } else if (f->argumentList.empty()) { return f->isConstexpr(); } - } else if (const Library::Function* lf = library.getFunction(ftok)) { - if (lf->ispure) - return true; - for (auto&& p : lf->argumentChecks) { - const Library::ArgumentChecks& ac = p.second; - if (ac.direction != Library::ArgumentChecks::Direction::DIR_IN) - return false; - } - if (Token::simpleMatch(ftok->previous(), ".")) { - if (!lf->isconst) - return false; - } else if (lf->argumentChecks.empty()) { - return false; - } } else if (Token::Match(ftok->previous(), ". %name% (") && ftok->previous()->originalName() != "->" && astIsSmartPointer(ftok->previous()->astOperand1())) { return Token::Match(ftok, "get|get_deleter ( )"); @@ -1715,6 +1701,14 @@ bool isConstFunctionCall(const Token* ftok, const Library& library) if (container->getAction(ftok->str()) == Library::Container::Action::FIND) return true; return false; + } else if (const Library::Function* lf = library.getFunction(ftok)) { + if (lf->ispure) + return true; + if (lf->containerYield != Library::Container::Yield::NO_YIELD) + return true; + if (lf->containerAction == Library::Container::Action::FIND) + return true; + return false; } else { bool memberFunction = Token::Match(ftok->previous(), ". %name% ("); bool constMember = !memberFunction; diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index c3bb4d399..e729a7b6b 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -7215,6 +7215,12 @@ private: "}\n"; ASSERT_EQUALS(false, testValueOfX(code, 6U, -1)); ASSERT_EQUALS(true, testValueOfXImpossible(code, 6U, -1)); + + code = "char* f() {\n" + " char *x = malloc(10);\n" + " return x;\n" + "}\n"; + ASSERT_EQUALS(false, testValueOfX(code, 3U, "malloc(10)", 0)); } void valueFlowSymbolicIdentity()