| 7126 | } |
| 7127 | |
| 7128 | static void valueFlowUnknownFunctionReturn(TokenList& tokenlist, const Settings& settings) |
| 7129 | { |
| 7130 | if (!tokenlist.front()) |
| 7131 | return; |
| 7132 | for (Token* tok = tokenlist.front()->next(); tok; tok = tok->next()) { |
| 7133 | if (!tok->astParent() || tok->str() != "(" || !tok->previous()->isName()) |
| 7134 | continue; |
| 7135 | |
| 7136 | if (const auto* f = settings.library.getAllocFuncInfo(tok->astOperand1())) { |
| 7137 | if (f->noFail) { |
| 7138 | // Allocation function that cannot fail |
| 7139 | } else if (settings.library.returnValueType(tok->astOperand1()).find('*') != std::string::npos) { |
| 7140 | // Allocation function that returns a pointer |
| 7141 | ValueFlow::Value value(0); |
| 7142 | value.setPossible(); |
| 7143 | value.errorPath.emplace_back(tok, "Assuming allocation function fails"); |
| 7144 | if (Library::ismemory(f->groupId)) |
| 7145 | value.unknownFunctionReturn = ValueFlow::Value::UnknownFunctionReturn::outOfMemory; |
| 7146 | else |
| 7147 | value.unknownFunctionReturn = ValueFlow::Value::UnknownFunctionReturn::outOfResources; |
| 7148 | setTokenValue(tok, std::move(value), settings); |
| 7149 | continue; |
| 7150 | } |
| 7151 | } |
| 7152 | |
| 7153 | if (settings.checkUnknownFunctionReturn.find(tok->strAt(-1)) == settings.checkUnknownFunctionReturn.end()) |
| 7154 | continue; |
| 7155 | std::vector<MathLib::bigint> unknownValues = settings.library.unknownReturnValues(tok->astOperand1()); |
| 7156 | if (unknownValues.empty()) |
| 7157 | continue; |
| 7158 | |
| 7159 | // Get min/max values for return type |
| 7160 | const std::string& typestr = settings.library.returnValueType(tok->previous()); |
| 7161 | MathLib::bigint minvalue, maxvalue; |
| 7162 | if (!getMinMaxValues(typestr, settings, tok->isCpp(), minvalue, maxvalue)) |
| 7163 | continue; |
| 7164 | |
| 7165 | for (MathLib::bigint value : unknownValues) { |
| 7166 | if (value < minvalue) |
| 7167 | value = minvalue; |
| 7168 | else if (value > maxvalue) |
| 7169 | value = maxvalue; |
| 7170 | setTokenValue(tok, ValueFlow::Value(value), settings); |
| 7171 | } |
| 7172 | } |
| 7173 | } |
| 7174 | |
| 7175 | static void valueFlowDebug(TokenList& tokenlist, ErrorLogger& errorLogger, const Settings& settings) |
| 7176 | { |
no test coverage detected