Safe checks: Clarify a warning message
This commit is contained in:
parent
2d5f3ae3b4
commit
45d1ca6f7c
|
@ -181,6 +181,14 @@ bool CmdLineParser::parseFromArgs(int argc, const char* const argv[])
|
||||||
else if (std::strcmp(argv[i], "--inconclusive") == 0)
|
else if (std::strcmp(argv[i], "--inconclusive") == 0)
|
||||||
mSettings->inconclusive = true;
|
mSettings->inconclusive = true;
|
||||||
|
|
||||||
|
// Experimental: Safe checking
|
||||||
|
else if (std::strcmp(argv[i], "--safe-classes") == 0)
|
||||||
|
mSettings->safeChecks.classes = true;
|
||||||
|
|
||||||
|
// Experimental: Safe checking
|
||||||
|
else if (std::strcmp(argv[i], "--safe-functions") == 0)
|
||||||
|
mSettings->safeChecks.externalFunctions = mSettings->safeChecks.internalFunctions = true;
|
||||||
|
|
||||||
// Enforce language (--language=, -x)
|
// Enforce language (--language=, -x)
|
||||||
else if (std::strncmp(argv[i], "--language=", 11) == 0 || std::strcmp(argv[i], "-x") == 0) {
|
else if (std::strncmp(argv[i], "--language=", 11) == 0 || std::strcmp(argv[i], "-x") == 0) {
|
||||||
std::string str;
|
std::string str;
|
||||||
|
|
|
@ -66,3 +66,12 @@ std::list<Check *> &Check::instances()
|
||||||
return _instances;
|
return _instances;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Check::getMessageId(const ValueFlow::Value &value, const char id[])
|
||||||
|
{
|
||||||
|
if (value.condition != nullptr)
|
||||||
|
return id + std::string("Cond");
|
||||||
|
if (value.safe)
|
||||||
|
return std::string("safe") + (char)std::toupper(id[0]) + (id + 1);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
|
@ -118,6 +118,8 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static std::string getMessageId(const ValueFlow::Value &value, const char id[]);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Tokenizer * const mTokenizer;
|
const Tokenizer * const mTokenizer;
|
||||||
const Settings * const mSettings;
|
const Settings * const mSettings;
|
||||||
|
|
|
@ -200,9 +200,12 @@ void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &v
|
||||||
else
|
else
|
||||||
msg = "Signed integer overflow for expression '" + expr + "'.";
|
msg = "Signed integer overflow for expression '" + expr + "'.";
|
||||||
|
|
||||||
|
if (value.safe)
|
||||||
|
msg = "Safe checks: " + msg;
|
||||||
|
|
||||||
reportError(getErrorPath(tok, &value, "Integer overflow"),
|
reportError(getErrorPath(tok, &value, "Integer overflow"),
|
||||||
value.errorSeverity() ? Severity::error : Severity::warning,
|
value.errorSeverity() ? Severity::error : Severity::warning,
|
||||||
(value.condition == nullptr) ? "integerOverflow" : "integerOverflowCond",
|
getMessageId(value, "integerOverflow").c_str(),
|
||||||
msg,
|
msg,
|
||||||
CWE190,
|
CWE190,
|
||||||
value.isInconclusive());
|
value.isInconclusive());
|
||||||
|
|
|
@ -374,6 +374,7 @@ static void combineValueProperties(const ValueFlow::Value &value1, const ValueFl
|
||||||
result->varId = (value1.varId != 0U) ? value1.varId : value2.varId;
|
result->varId = (value1.varId != 0U) ? value1.varId : value2.varId;
|
||||||
result->varvalue = (result->varId == value1.varId) ? value1.varvalue : value2.varvalue;
|
result->varvalue = (result->varId == value1.varId) ? value1.varvalue : value2.varvalue;
|
||||||
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
|
result->errorPath = (value1.errorPath.empty() ? value2 : value1).errorPath;
|
||||||
|
result->safe = value1.safe || value2.safe;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -5462,9 +5463,11 @@ static void valueFlowSafeFunctions(TokenList *tokenlist, SymbolDatabase *symbold
|
||||||
argValues.emplace_back(0);
|
argValues.emplace_back(0);
|
||||||
argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
||||||
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " is empty");
|
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " is empty");
|
||||||
|
argValues.back().safe = true;
|
||||||
argValues.emplace_back(1000000);
|
argValues.emplace_back(1000000);
|
||||||
argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
argValues.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;
|
||||||
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " size is 1000000");
|
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming " + arg.name() + " size is 1000000");
|
||||||
|
argValues.back().safe = true;
|
||||||
for (const ValueFlow::Value &value : argValues)
|
for (const ValueFlow::Value &value : argValues)
|
||||||
valueFlowContainerForward(const_cast<Token*>(functionScope->bodyStart), arg.declarationId(), value, settings, tokenlist->isCPP());
|
valueFlowContainerForward(const_cast<Token*>(functionScope->bodyStart), arg.declarationId(), value, settings, tokenlist->isCPP());
|
||||||
continue;
|
continue;
|
||||||
|
@ -5477,6 +5480,9 @@ static void valueFlowSafeFunctions(TokenList *tokenlist, SymbolDatabase *symbold
|
||||||
if (!isLow && !isHigh && !all)
|
if (!isLow && !isHigh && !all)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
const bool safeLow = !isLow;
|
||||||
|
const bool safeHigh = !isHigh;
|
||||||
|
|
||||||
if ((!isLow || !isHigh) && all) {
|
if ((!isLow || !isHigh) && all) {
|
||||||
MathLib::bigint minValue, maxValue;
|
MathLib::bigint minValue, maxValue;
|
||||||
if (getMinMaxValues(arg.valueType(), *settings, &minValue, &maxValue)) {
|
if (getMinMaxValues(arg.valueType(), *settings, &minValue, &maxValue)) {
|
||||||
|
@ -5490,11 +5496,13 @@ static void valueFlowSafeFunctions(TokenList *tokenlist, SymbolDatabase *symbold
|
||||||
argValues.emplace_back(0);
|
argValues.emplace_back(0);
|
||||||
argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT;
|
argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||||
argValues.back().floatValue = isLow ? low : -1E25f;
|
argValues.back().floatValue = isLow ? low : -1E25f;
|
||||||
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming argument has value " + MathLib::toString(argValues.back().floatValue));
|
argValues.back().errorPath.emplace_back(arg.nameToken(), "Safe checks: Assuming argument has value " + MathLib::toString(argValues.back().floatValue));
|
||||||
|
argValues.back().safe = true;
|
||||||
argValues.emplace_back(0);
|
argValues.emplace_back(0);
|
||||||
argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT;
|
argValues.back().valueType = ValueFlow::Value::ValueType::FLOAT;
|
||||||
argValues.back().floatValue = isHigh ? high : 1E25f;
|
argValues.back().floatValue = isHigh ? high : 1E25f;
|
||||||
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming argument has value " + MathLib::toString(argValues.back().floatValue));
|
argValues.back().errorPath.emplace_back(arg.nameToken(), "Safe checks: Assuming argument has value " + MathLib::toString(argValues.back().floatValue));
|
||||||
|
argValues.back().safe = true;
|
||||||
valueFlowForward(const_cast<Token *>(functionScope->bodyStart->next()),
|
valueFlowForward(const_cast<Token *>(functionScope->bodyStart->next()),
|
||||||
functionScope->bodyEnd,
|
functionScope->bodyEnd,
|
||||||
&arg,
|
&arg,
|
||||||
|
@ -5512,11 +5520,13 @@ static void valueFlowSafeFunctions(TokenList *tokenlist, SymbolDatabase *symbold
|
||||||
std::list<ValueFlow::Value> argValues;
|
std::list<ValueFlow::Value> argValues;
|
||||||
if (isLow) {
|
if (isLow) {
|
||||||
argValues.emplace_back(low);
|
argValues.emplace_back(low);
|
||||||
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming argument has value " + MathLib::toString(low));
|
argValues.back().errorPath.emplace_back(arg.nameToken(), std::string(safeLow ? "Safe checks: " : "") + "Assuming argument has value " + MathLib::toString(low));
|
||||||
|
argValues.back().safe = safeLow;
|
||||||
}
|
}
|
||||||
if (isHigh) {
|
if (isHigh) {
|
||||||
argValues.emplace_back(high);
|
argValues.emplace_back(high);
|
||||||
argValues.back().errorPath.emplace_back(arg.nameToken(), "Assuming argument has value " + MathLib::toString(high));
|
argValues.back().errorPath.emplace_back(arg.nameToken(), std::string(safeHigh ? "Safe checks: " : "") + "Assuming argument has value " + MathLib::toString(high));
|
||||||
|
argValues.back().safe = safeHigh;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!argValues.empty())
|
if (!argValues.empty())
|
||||||
|
@ -5574,6 +5584,7 @@ ValueFlow::Value::Value(const Token *c, long long val)
|
||||||
varvalue(val),
|
varvalue(val),
|
||||||
condition(c),
|
condition(c),
|
||||||
varId(0U),
|
varId(0U),
|
||||||
|
safe(false),
|
||||||
conditional(false),
|
conditional(false),
|
||||||
defaultArg(false),
|
defaultArg(false),
|
||||||
lifetimeKind(LifetimeKind::Object),
|
lifetimeKind(LifetimeKind::Object),
|
||||||
|
|
|
@ -50,6 +50,7 @@ namespace ValueFlow {
|
||||||
varvalue(val),
|
varvalue(val),
|
||||||
condition(nullptr),
|
condition(nullptr),
|
||||||
varId(0U),
|
varId(0U),
|
||||||
|
safe(false),
|
||||||
conditional(false),
|
conditional(false),
|
||||||
defaultArg(false),
|
defaultArg(false),
|
||||||
lifetimeKind(LifetimeKind::Object),
|
lifetimeKind(LifetimeKind::Object),
|
||||||
|
@ -161,6 +162,9 @@ namespace ValueFlow {
|
||||||
/** For calculated values - varId that calculated value depends on */
|
/** For calculated values - varId that calculated value depends on */
|
||||||
nonneg int varId;
|
nonneg int varId;
|
||||||
|
|
||||||
|
/** value relies on safe checking */
|
||||||
|
bool safe;
|
||||||
|
|
||||||
/** Conditional value */
|
/** Conditional value */
|
||||||
bool conditional;
|
bool conditional;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue