Update the isVariableChanged to correctly check the const bit (#4912)
This commit is contained in:
parent
38f9c81dd2
commit
7231d1cece
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
});
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue