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

Method checkTokenInsideExpression

lib/checkleakautovar.cpp:890–956  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

888
889
890const Token * CheckLeakAutoVarImpl::checkTokenInsideExpression(const Token * const tok, VarInfo &varInfo, bool inFuncCall)
891{
892 // Deallocation and then dereferencing pointer..
893 if (tok->varId() > 0) {
894 // TODO : Write a separate checker for this that uses valueFlowForward.
895 const auto var = utils::as_const(varInfo.alloctype).find(tok->varId());
896 if (var != varInfo.alloctype.end()) {
897 bool unknown = false;
898 if (var->second.status == VarInfo::DEALLOC && tok->valueType() && tok->valueType()->pointer &&
899 CheckNullPointerImpl::isPointerDeRef(tok, unknown, mSettings, /*checkNullArg*/ false) && !unknown) {
900 deallocUseError(tok, tok->str());
901 } else if (Token::simpleMatch(tok->tokAt(-2), "= &")) {
902 varInfo.erase(tok->varId());
903 } else {
904 // check if tok is assigned into another variable
905 const Token *rhs = tok;
906 bool isAssignment = false;
907 while (rhs->astParent()) {
908 if (rhs->astParent()->str() == "=") {
909 isAssignment = true;
910 break;
911 }
912 rhs = rhs->astParent();
913 }
914 while (rhs->isCast()) {
915 rhs = rhs->astOperand2() ? rhs->astOperand2() : rhs->astOperand1();
916 }
917 if ((rhs->str() == "." || rhs->varId() == tok->varId()) && isAssignment) {
918 // simple assignment
919 varInfo.erase(tok->varId());
920 } else if (rhs->astParent() && rhs->str() == "(" && !mSettings.library.returnValue(rhs->astOperand1()).empty()) {
921 // #9298, assignment through return value of a function
922 const std::string &returnValue = mSettings.library.returnValue(rhs->astOperand1());
923 if (startsWith(returnValue, "arg")) {
924 int argn;
925 const Token *func = getTokenArgumentFunction(tok, argn);
926 if (func) {
927 const std::string arg = "arg" + std::to_string(argn + 1);
928 if (returnValue == arg) {
929 varInfo.erase(tok->varId());
930 }
931 }
932 }
933 }
934 }
935 } else if (Token::Match(tok->previous(), "& %name% = %var% ;")) {
936 varInfo.referenced.insert(tok->tokAt(2)->varId());
937 }
938 }
939
940 // check for function call
941 const Token * const openingPar = inFuncCall ? nullptr : isFunctionCall(tok);
942 if (openingPar) {
943 const Library::AllocFunc* allocFunc = mSettings.library.getDeallocFuncInfo(tok);
944 VarInfo::AllocInfo alloc(allocFunc ? allocFunc->groupId : 0, VarInfo::DEALLOC, tok);
945 if (alloc.type == 0)
946 alloc.status = VarInfo::NOALLOC;
947 functionCall(tok, openingPar, varInfo, alloc, nullptr);

Callers

nothing calls this directly

Calls 15

getTokenArgumentFunctionFunction · 0.85
isCPPCastFunction · 0.85
astParentMethod · 0.80
isCastMethod · 0.80
astOperand2Method · 0.80
astOperand1Method · 0.80
getDeallocFuncInfoMethod · 0.80
simpleMatchFunction · 0.70
startsWithFunction · 0.70
isFunctionCallFunction · 0.70
findMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected