Update the isVariableChanged to correctly check the const bit (#4912)

This commit is contained in:
Paul Fultz II 2023-03-26 08:12:49 -05:00 committed by GitHub
parent 38f9c81dd2
commit 7231d1cece
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 38 additions and 29 deletions

View File

@ -262,15 +262,16 @@ int CppCheckExecutor::check_internal(CppCheck& cppcheck)
Settings& settings = cppcheck.settings();
const bool std = tryLoadLibrary(settings.library, settings.exename, "std.cfg");
for (const std::string &lib : settings.libraries) {
if (!tryLoadLibrary(settings.library, settings.exename, lib.c_str())) {
const std::string msg("Failed to load the library " + lib);
auto failed_lib = std::find_if(settings.libraries.begin(), settings.libraries.end(), [&](const std::string& lib) {
return !tryLoadLibrary(settings.library, settings.exename, lib.c_str());
});
if (failed_lib != settings.libraries.end()) {
const std::string msg("Failed to load the library " + *failed_lib);
const std::list<ErrorMessage::FileLocation> callstack;
ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal);
reportErr(errmsg);
return EXIT_FAILURE;
}
}
if (!std) {
const std::list<ErrorMessage::FileLocation> callstack;

View File

@ -2477,19 +2477,19 @@ bool isVariableChanged(const Token *tok, int indirect, const Settings *settings,
}
}
const ValueType* vt = tok->variable() ? tok->variable()->valueType() : tok->valueType();
// If its already const then it cant be modified
if (vt) {
if (vt->isConst(indirect))
return false;
}
// Check addressof
if (tok2->astParent() && tok2->astParent()->isUnaryOp("&") &&
isVariableChanged(tok2->astParent(), indirect + 1, settings, depth - 1)) {
return true;
}
const ValueType* vt = tok->variable() ? tok->variable()->valueType() : tok->valueType();
// If its already const then it cant be modified
if (vt) {
if (vt->constness & (1 << indirect))
return false;
}
if (cpp && Token::Match(tok2->astParent(), ">>|&") && astIsRHS(tok2) && isLikelyStreamRead(cpp, tok2->astParent()))
return true;

View File

@ -107,13 +107,13 @@ static bool isVclTypeInit(const Type *type)
{
if (!type)
return false;
for (const Type::BaseInfo &baseInfo: type->derivedFrom) {
return std::any_of(type->derivedFrom.begin(), type->derivedFrom.end(), [&](const Type::BaseInfo& baseInfo) {
if (!baseInfo.type)
return true;
if (isVclTypeInit(baseInfo.type))
return true;
}
return false;
});
}
//---------------------------------------------------------------------------

View File

@ -1832,7 +1832,7 @@ static bool isConstTop(const Token *tok)
if (!bracTok->astParent())
return true;
}
if (tok->str() == "," && tok->astParent() && tok->astParent()->isAssignmentOp())
if (tok->str() == "," && tok->astParent()->isAssignmentOp())
return true;
return false;
}

View File

@ -7416,6 +7416,13 @@ std::string ValueType::dump() const
return ret.str();
}
bool ValueType::isConst(nonneg int indirect) const
{
if (indirect > pointer)
return false;
return constness & (1 << (pointer - indirect));
}
MathLib::bigint ValueType::typeSize(const cppcheck::Platform &platform, bool p) const
{
if (p && pointer)

View File

@ -1349,6 +1349,8 @@ public:
return typeScope && typeScope->type == Scope::eEnum;
}
bool isConst(nonneg int indirect = 0) const;
MathLib::bigint typeSize(const cppcheck::Platform &platform, bool p=false) const;
/// Check if type is the same ignoring const and references

View File

@ -2210,6 +2210,7 @@ class SelectValueFromVarIdMapRange {
using value_type = const ValueFlow::Value;
using pointer = value_type *;
using reference = value_type &;
using difference_type = std::ptrdiff_t;
explicit Iterator(const M::const_iterator & it)
: mIt(it) {}
@ -2268,21 +2269,19 @@ static bool isAliasOf(const Variable * var, const Token *tok, nonneg int varid,
if (var && !var->isPointer())
return false;
// Search through non value aliases
for (const ValueFlow::Value &val : values) {
return std::any_of(values.begin(), values.end(), [&](const ValueFlow::Value& val) {
if (!val.isNonValue())
continue;
if (val.isInconclusive())
continue;
if (val.isLifetimeValue() && !val.isLocalLifetimeValue())
continue;
if (val.isLifetimeValue() && val.lifetimeKind != ValueFlow::Value::LifetimeKind::Address)
continue;
if (!Token::Match(val.tokvalue, ".|&|*|%var%"))
continue;
if (astHasVar(val.tokvalue, tok->varId()))
return true;
}
return false;
if (val.isInconclusive())
return false;
if (val.isLifetimeValue() && !val.isLocalLifetimeValue())
return false;
if (val.isLifetimeValue() && val.lifetimeKind != ValueFlow::Value::LifetimeKind::Address)
return false;
if (!Token::Match(val.tokvalue, ".|&|*|%var%"))
return false;
return astHasVar(val.tokvalue, tok->varId());
});
}
static bool bifurcate(const Token* tok, const std::set<nonneg int>& varids, const Settings* settings, int depth = 20);