| 7028 | } |
| 7029 | |
| 7030 | static void valueFlowSafeFunctions(const TokenList& tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger& errorLogger, const Settings& settings) |
| 7031 | { |
| 7032 | for (const Scope *functionScope : symboldatabase.functionScopes) { |
| 7033 | if (!functionScope->bodyStart) |
| 7034 | continue; |
| 7035 | const Function *function = functionScope->function; |
| 7036 | if (!function) |
| 7037 | continue; |
| 7038 | |
| 7039 | const bool safe = function->isSafe(settings); |
| 7040 | const bool all = safe && settings.platform.type != Platform::Type::Unspecified; |
| 7041 | |
| 7042 | for (const Variable &arg : function->argumentList) { |
| 7043 | if (!arg.nameToken() || !arg.valueType()) |
| 7044 | continue; |
| 7045 | |
| 7046 | if (arg.valueType()->type == ValueType::Type::CONTAINER) { |
| 7047 | if (!safe) |
| 7048 | continue; |
| 7049 | std::list<ValueFlow::Value> argValues; |
| 7050 | argValues.emplace_back(0); |
| 7051 | argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; |
| 7052 | argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " is empty"); |
| 7053 | argValues.back().safe = true; |
| 7054 | argValues.emplace_back(1000000); |
| 7055 | argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE; |
| 7056 | argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " size is 1000000"); |
| 7057 | argValues.back().safe = true; |
| 7058 | for (const ValueFlow::Value &value : argValues) |
| 7059 | valueFlowForward(const_cast<Token*>(functionScope->bodyStart), arg.nameToken(), value, tokenlist, errorLogger, settings); |
| 7060 | continue; |
| 7061 | } |
| 7062 | |
| 7063 | MathLib::bigint low, high; |
| 7064 | bool isLow = arg.nameToken()->getCppcheckAttribute(Token::CppcheckAttributesType::LOW, low); |
| 7065 | bool isHigh = arg.nameToken()->getCppcheckAttribute(Token::CppcheckAttributesType::HIGH, high); |
| 7066 | |
| 7067 | if (!isLow && !isHigh && !all) |
| 7068 | continue; |
| 7069 | |
| 7070 | const bool safeLow = !isLow; |
| 7071 | const bool safeHigh = !isHigh; |
| 7072 | |
| 7073 | if ((!isLow || !isHigh) && all) { |
| 7074 | MathLib::bigint minValue, maxValue; |
| 7075 | if (ValueFlow::getMinMaxValues(arg.valueType(), settings.platform, minValue, maxValue)) { |
| 7076 | if (!isLow) |
| 7077 | low = minValue; |
| 7078 | if (!isHigh) |
| 7079 | high = maxValue; |
| 7080 | isLow = isHigh = true; |
| 7081 | } else if (arg.valueType()->type == ValueType::Type::FLOAT || arg.valueType()->type == ValueType::Type::DOUBLE || arg.valueType()->type == ValueType::Type::LONGDOUBLE) { |
| 7082 | std::list<ValueFlow::Value> argValues; |
| 7083 | argValues.emplace_back(0); |
| 7084 | argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT; |
| 7085 | argValues.back().floatValue = isLow ? static_cast<double>(low) : -1E25; |
| 7086 | argValues.back().errorPath.emplace_back(arg.nameToken(), "Safe checks: Assuming argument has value " + MathLib::toString(argValues.back().floatValue)); |
| 7087 | argValues.back().safe = true; |
no test coverage detected