From 7231d1ceceb4434142cbe1a2ac5129237adf06fb Mon Sep 17 00:00:00 2001 From: Paul Fultz II Date: Sun, 26 Mar 2023 08:12:49 -0500 Subject: [PATCH] Update the isVariableChanged to correctly check the const bit (#4912) --- cli/cppcheckexecutor.cpp | 17 +++++++++-------- lib/astutils.cpp | 14 +++++++------- lib/checkclass.cpp | 6 +++--- lib/checkother.cpp | 2 +- lib/symboldatabase.cpp | 7 +++++++ lib/symboldatabase.h | 2 ++ lib/valueflow.cpp | 19 +++++++++---------- 7 files changed, 38 insertions(+), 29 deletions(-) diff --git a/cli/cppcheckexecutor.cpp b/cli/cppcheckexecutor.cpp index 85a8cde9e..ee7d59921 100644 --- a/cli/cppcheckexecutor.cpp +++ b/cli/cppcheckexecutor.cpp @@ -262,14 +262,15 @@ 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); - const std::list callstack; - ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal); - reportErr(errmsg); - return EXIT_FAILURE; - } + 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 callstack; + ErrorMessage errmsg(callstack, emptyString, Severity::information, msg, "failedToLoadCfg", Certainty::normal); + reportErr(errmsg); + return EXIT_FAILURE; } if (!std) { diff --git a/lib/astutils.cpp b/lib/astutils.cpp index f822faee9..21e9aa603 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -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; diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index bc437300a..9c93ffe9b 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -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; + return false; + }); } //--------------------------------------------------------------------------- diff --git a/lib/checkother.cpp b/lib/checkother.cpp index bdbf41447..a90adbed5 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -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; } diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 0b5e9a308..94590cd9e 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -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) diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 669ea7799..707520971 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -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 diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index b08c379fa..55abcaef6 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -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; + return false; if (val.isInconclusive()) - continue; + return false; if (val.isLifetimeValue() && !val.isLocalLifetimeValue()) - continue; + return false; if (val.isLifetimeValue() && val.lifetimeKind != ValueFlow::Value::LifetimeKind::Address) - continue; + return false; if (!Token::Match(val.tokvalue, ".|&|*|%var%")) - continue; - if (astHasVar(val.tokvalue, tok->varId())) - return true; - } - return false; + return false; + return astHasVar(val.tokvalue, tok->varId()); + }); } static bool bifurcate(const Token* tok, const std::set& varids, const Settings* settings, int depth = 20);