MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / isVariableChanged

Function isVariableChanged

lib/astutils.cpp:2638–2859  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2636}
2637
2638bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
2639{
2640 if (!tok)
2641 return false;
2642 if (!tok->isMutableExpr())
2643 return false;
2644
2645 if (isConstVarExpression(tok))
2646 return false;
2647
2648 const Token *tok2 = tok;
2649 int derefs = 0;
2650 while ((tok2->astParent() && tok2->astParent()->isUnaryOp("*")) ||
2651 (Token::simpleMatch(tok2->astParent(), ".") && !Token::Match(tok2->astParent()->astParent(), "[(,]")) ||
2652 (tok2->astParent() && tok2->astParent()->isUnaryOp("&") && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->") ||
2653 (Token::simpleMatch(tok2->astParent(), "[") && tok2 == tok2->astParent()->astOperand1()) ||
2654 (Token::simpleMatch(tok2->astParent(), "(") && tok2->astParent()->isCast())) {
2655 if (tok2->astParent() && (tok2->astParent()->isUnaryOp("*") || (astIsLHS(tok2) && tok2->astParent()->originalName() == "->" && !hasOverloadedMemberAccess(tok2))))
2656 derefs++;
2657 if (derefs > indirect)
2658 break;
2659 if (tok2->astParent() && tok2->astParent()->isUnaryOp("&") && Token::simpleMatch(tok2->astParent()->astParent(), ".") && tok2->astParent()->astParent()->originalName()=="->")
2660 tok2 = tok2->astParent();
2661 tok2 = tok2->astParent();
2662 }
2663
2664 if (tok2->astParent() && tok2->astParent()->isUnaryOp("&")) {
2665 const Token* parent = tok2->astParent();
2666 while (parent->astParent() && parent->astParent()->isCast())
2667 parent = parent->astParent();
2668 if (parent->astParent() && parent->astParent()->isUnaryOp("*"))
2669 tok2 = parent->astParent();
2670 }
2671
2672 while ((Token::simpleMatch(tok2, ":") && Token::simpleMatch(tok2->astParent(), "?")) ||
2673 (Token::simpleMatch(tok2->astParent(), ":") && Token::simpleMatch(tok2->astParent()->astParent(), "?")))
2674 tok2 = tok2->astParent();
2675
2676 if (indirect == 0 && tok2->astParent() && tok2->astParent()->tokType() == Token::eIncDecOp)
2677 return true;
2678
2679 auto skipRedundantPtrOp = [](const Token* tok, const Token* parent) {
2680 const Token* gparent = parent ? parent->astParent() : nullptr;
2681 while (parent && gparent && ((parent->isUnaryOp("*") && gparent->isUnaryOp("&")) || (parent->isUnaryOp("&") && gparent->isUnaryOp("*")))) {
2682 tok = gparent;
2683 parent = gparent->astParent();
2684 if (parent)
2685 gparent = parent->astParent();
2686 }
2687 return tok;
2688 };
2689 tok2 = skipRedundantPtrOp(tok2, tok2->astParent());
2690
2691 if (tok2->astParent() && tok2->astParent()->isAssignmentOp()) {
2692 if (astIsLHS(tok2))
2693 return true;
2694 // Check if assigning to a non-const lvalue
2695 const Variable * var = getLHSVariable(tok2->astParent());

Callers 15

afterConditionMethod · 0.85
valueFlowForLoopSimplifyFunction · 0.85
valueFlowContainerSizeFunction · 0.85
assignIfParseScopeMethod · 0.85
multiCondition2Method · 0.85
valueFlowUninitMethod · 0.85
isModifiedFunction · 0.85
isAliasModifiedFunction · 0.85
ExpressionAnalyzerMethod · 0.85
checkPassByReferenceMethod · 0.85

Calls 15

isConstVarExpressionFunction · 0.85
astIsLHSFunction · 0.85
getLHSVariableFunction · 0.85
astIsRHSFunction · 0.85
isLikelyStreamReadFunction · 0.85
isLikelyStreamFunction · 0.85
astIsPointerFunction · 0.85
astIsContainerFunction · 0.85
containsFunction · 0.85
astIsSmartPointerFunction · 0.85

Tested by 1

isVariableChangedTestMethod · 0.68