Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2482,13 +2482,6 @@ static bool isArray(const Token* tok)
return false;
}

static inline
// limit it to CLang as compiling with GCC might fail with
// error: inlining failed in call to always_inline 'bool isMutableExpression(const Token*)': function not considered for inlining
// error: inlining failed in call to ‘always_inline’ ‘bool isMutableExpression(const Token*)’: recursive inlining
#if defined(__clang__)
__attribute__((always_inline))
#endif
bool isMutableExpression(const Token* tok)
{
if (!tok)
Expand Down Expand Up @@ -2632,7 +2625,9 @@ static bool hasOverloadedMemberAccess(const Token* tok)

bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
{
if (!isMutableExpression(tok))
if (!tok)
return false;
if (!tok->isMutableExpr())
return false;

if (indirect == 0 && isConstVarExpression(tok))
Expand Down Expand Up @@ -2924,7 +2919,9 @@ static bool isExpressionChangedAt(const F& getExprTok,
{
if (depth < 0)
return true;
if (!isMutableExpression(tok))
if (!tok)
return false;
if (!tok->isMutableExpr())
return false;
if (tok->exprId() != exprid || (!tok->varId() && !tok->isName())) {
if (globalvar && Token::Match(tok, "%name% (") &&
Expand Down
2 changes: 2 additions & 0 deletions lib/astutils.h
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,8 @@ Token* getTokenArgumentFunction(Token* tok, int& argn);

std::vector<const Variable*> getArgumentVars(const Token* tok, int argnr);

bool isMutableExpression(const Token* tok);

/** Is variable changed by function call?
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
* the return value is false and the output parameter inconclusive is set to true
Expand Down
7 changes: 7 additions & 0 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2753,3 +2753,10 @@ const SmallVector<ReferenceToken>& Token::refs(bool temporary) const
mImpl->mRefs.reset(new SmallVector<ReferenceToken>(followAllReferences(this, false)));
return *mImpl->mRefs;
}

bool Token::isMutableExpr() const
{
if (mImpl->mMutableExpr == -1)
mImpl->mMutableExpr = isMutableExpression(this);
return !!mImpl->mMutableExpr;
}
4 changes: 4 additions & 0 deletions lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ class CPPCHECKLIB Token {
std::unique_ptr<SmallVector<ReferenceToken>> mRefs;
std::unique_ptr<SmallVector<ReferenceToken>> mRefsTemp;

std::int8_t mMutableExpr{-1};

void setCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint value);
bool getCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint &value) const;

Expand Down Expand Up @@ -1364,6 +1366,8 @@ class CPPCHECKLIB Token {
// provides and caches result of a followAllReferences() call
const SmallVector<ReferenceToken>& refs(bool temporary = true) const;

bool isMutableExpr() const;

/**
* Sets the original name.
*/
Expand Down
Loading