| 5829 | } |
| 5830 | |
| 5831 | static void valueFlowFunctionReturn(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) |
| 5832 | { |
| 5833 | for (Token* tok = tokenlist.back(); tok; tok = tok->previous()) { |
| 5834 | if (tok->str() != "(" || !tok->astOperand1() || tok->isCast()) |
| 5835 | continue; |
| 5836 | |
| 5837 | const Function* function = nullptr; |
| 5838 | if (Token::Match(tok->previous(), "%name% (")) |
| 5839 | function = tok->previous()->function(); |
| 5840 | else |
| 5841 | function = tok->astOperand1()->function(); |
| 5842 | if (!function) |
| 5843 | continue; |
| 5844 | // TODO: Check if member variable is a pointer or reference |
| 5845 | if (function->isImplicitlyVirtual() && !function->hasFinalSpecifier()) |
| 5846 | continue; |
| 5847 | |
| 5848 | if (tok->hasKnownValue()) |
| 5849 | continue; |
| 5850 | |
| 5851 | std::vector<const Token*> returns = Function::findReturns(function); |
| 5852 | if (returns.empty()) |
| 5853 | continue; |
| 5854 | |
| 5855 | bool hasKnownValue = false; |
| 5856 | |
| 5857 | for (const ValueFlow::Value& v : getCommonValuesFromTokens(returns)) { |
| 5858 | setFunctionReturnValue(function, tok, v, settings, false); |
| 5859 | if (v.isKnown()) |
| 5860 | hasKnownValue = true; |
| 5861 | } |
| 5862 | |
| 5863 | if (hasKnownValue) |
| 5864 | continue; |
| 5865 | |
| 5866 | // Arguments.. |
| 5867 | std::vector<const Token*> arguments = getArguments(tok); |
| 5868 | |
| 5869 | ProgramMemory programMemory; |
| 5870 | for (std::size_t i = 0; i < arguments.size(); ++i) { |
| 5871 | const Variable* const arg = function->getArgumentVar(i); |
| 5872 | if (!arg) { |
| 5873 | if (settings.debugwarnings) |
| 5874 | bailout(tokenlist, errorLogger, tok, "function return; unhandled argument type"); |
| 5875 | programMemory.clear(); |
| 5876 | break; |
| 5877 | } |
| 5878 | const ValueFlow::Value* v = getKnownValueFromToken(arguments[i]); |
| 5879 | if (!v) |
| 5880 | continue; |
| 5881 | programMemory.setValue(arg->nameToken(), *v); |
| 5882 | } |
| 5883 | if (programMemory.empty() && !arguments.empty()) |
| 5884 | continue; |
| 5885 | std::vector<ValueFlow::Value> values = execute(function->functionScope, programMemory, settings); |
| 5886 | for (const ValueFlow::Value& v : values) { |
| 5887 | if (v.isUninitValue()) |
| 5888 | continue; |
no test coverage detected