Skip to content

Commit 31da8a2

Browse files
authored
refs #10765/#11262 - Token: introduced cache for isMutableExpression() calls (danmar#8145)
1 parent df927d5 commit 31da8a2

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

lib/astutils.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2482,13 +2482,6 @@ static bool isArray(const Token* tok)
24822482
return false;
24832483
}
24842484

2485-
static inline
2486-
// limit it to CLang as compiling with GCC might fail with
2487-
// error: inlining failed in call to always_inline 'bool isMutableExpression(const Token*)': function not considered for inlining
2488-
// error: inlining failed in call to ‘always_inline’ ‘bool isMutableExpression(const Token*)’: recursive inlining
2489-
#if defined(__clang__)
2490-
__attribute__((always_inline))
2491-
#endif
24922485
bool isMutableExpression(const Token* tok)
24932486
{
24942487
if (!tok)
@@ -2632,7 +2625,9 @@ static bool hasOverloadedMemberAccess(const Token* tok)
26322625

26332626
bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
26342627
{
2635-
if (!isMutableExpression(tok))
2628+
if (!tok)
2629+
return false;
2630+
if (!tok->isMutableExpr())
26362631
return false;
26372632

26382633
if (indirect == 0 && isConstVarExpression(tok))
@@ -2924,7 +2919,9 @@ static bool isExpressionChangedAt(const F& getExprTok,
29242919
{
29252920
if (depth < 0)
29262921
return true;
2927-
if (!isMutableExpression(tok))
2922+
if (!tok)
2923+
return false;
2924+
if (!tok->isMutableExpr())
29282925
return false;
29292926
if (tok->exprId() != exprid || (!tok->varId() && !tok->isName())) {
29302927
if (globalvar && Token::Match(tok, "%name% (") &&

lib/astutils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,8 @@ Token* getTokenArgumentFunction(Token* tok, int& argn);
319319

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

322+
bool isMutableExpression(const Token* tok);
323+
322324
/** Is variable changed by function call?
323325
* In case the answer of the question is inconclusive, e.g. because the function declaration is not known
324326
* the return value is false and the output parameter inconclusive is set to true

lib/token.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2753,3 +2753,10 @@ const SmallVector<ReferenceToken>& Token::refs(bool temporary) const
27532753
mImpl->mRefs.reset(new SmallVector<ReferenceToken>(followAllReferences(this, false)));
27542754
return *mImpl->mRefs;
27552755
}
2756+
2757+
bool Token::isMutableExpr() const
2758+
{
2759+
if (mImpl->mMutableExpr == -1)
2760+
mImpl->mMutableExpr = isMutableExpression(this);
2761+
return !!mImpl->mMutableExpr;
2762+
}

lib/token.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,8 @@ class CPPCHECKLIB Token {
173173
std::unique_ptr<SmallVector<ReferenceToken>> mRefs;
174174
std::unique_ptr<SmallVector<ReferenceToken>> mRefsTemp;
175175

176+
std::int8_t mMutableExpr{-1};
177+
176178
void setCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint value);
177179
bool getCppcheckAttribute(CppcheckAttributesType type, MathLib::bigint &value) const;
178180

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

1369+
// provides and caches the result of a isMutableExpression() call
1370+
bool isMutableExpr() const;
1371+
13671372
/**
13681373
* Sets the original name.
13691374
*/

0 commit comments

Comments
 (0)