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

Method isVariableUsage

lib/checkuninitvar.cpp:1154–1354  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1152}
1153
1154const Token* CheckUninitVarImpl::isVariableUsage(const Token *vartok, const Library& library, bool pointer, Alloc alloc, int indirect)
1155{
1156 const bool cpp = vartok->isCpp();
1157 const Token *valueExpr = vartok; // non-dereferenced , no address of value as variable
1158 while (Token::Match(valueExpr->astParent(), ".|::") && astIsRhs(valueExpr))
1159 valueExpr = valueExpr->astParent();
1160 // stuff we ignore..
1161 while (valueExpr->astParent()) {
1162 // *&x
1163 if (valueExpr->astParent()->isUnaryOp("&") && valueExpr->astParent()->astParent() && valueExpr->astParent()->astParent()->isUnaryOp("*"))
1164 valueExpr = valueExpr->astParent()->astParent();
1165 // (type &)x
1166 else if (valueExpr->astParent()->isCast() && valueExpr->astParent()->isUnaryOp("(") && Token::simpleMatch(valueExpr->astParent()->link()->previous(), "& )"))
1167 valueExpr = valueExpr->astParent();
1168 // designated initializers: {.x | { ... , .x
1169 else if (Token::simpleMatch(valueExpr->astParent(), ".") &&
1170 Token::Match(valueExpr->astParent()->previous(), ",|{"))
1171 valueExpr = valueExpr->astParent();
1172 else
1173 break;
1174 }
1175 if (!pointer) {
1176 if (Token::Match(vartok, "%name% [.(]") && vartok->variable() && !vartok->variable()->isPointer())
1177 return nullptr;
1178 while (Token::simpleMatch(valueExpr->astParent(), ".") && astIsLhs(valueExpr) && valueExpr->astParent()->valueType() && valueExpr->astParent()->valueType()->pointer == 0)
1179 valueExpr = valueExpr->astParent();
1180 }
1181 const Token *derefValue = nullptr; // dereferenced value expression
1182 if (alloc != NO_ALLOC) {
1183 const int arrayDim = (vartok->variable() && vartok->variable()->isArray()) ? vartok->variable()->dimensions().size() : 1;
1184 int deref = 0;
1185 derefValue = valueExpr;
1186 while (Token::Match(derefValue->astParent(), "+|-|*|[|.") ||
1187 (derefValue->astParent() && derefValue->astParent()->isCast()) ||
1188 (deref < arrayDim && Token::simpleMatch(derefValue->astParent(), "&") && derefValue->astParent()->isBinaryOp())) {
1189 const Token * const derefValueParent = derefValue->astParent();
1190 if (derefValueParent->str() == "*") {
1191 if (derefValueParent->isUnaryOp("*"))
1192 ++deref;
1193 else
1194 break;
1195 } else if (derefValueParent->str() == "[") {
1196 if (astIsLhs(derefValue))
1197 ++deref;
1198 else
1199 break;
1200 } else if (Token::Match(derefValueParent, "[+-]")) {
1201 if (deref >= arrayDim)
1202 break;
1203 } else if (derefValueParent->str() == ".")
1204 ++deref;
1205 derefValue = derefValueParent;
1206 if (deref < arrayDim)
1207 valueExpr = derefValue;
1208 }
1209 if (deref < arrayDim) {
1210 // todo compare deref with array dimensions
1211 derefValue = nullptr;

Callers

nothing calls this directly

Calls 15

astIsRhsFunction · 0.85
astIsLhsFunction · 0.85
isVoidCastFunction · 0.85
isLikelyStreamReadFunction · 0.85
isVariableUsageFunction · 0.85
astParentMethod · 0.80
isUnaryOpMethod · 0.80
isCastMethod · 0.80
variableMethod · 0.80
isArrayMethod · 0.80
isBinaryOpMethod · 0.80
astOperand1Method · 0.80

Tested by

no test coverage detected