| 1152 | } |
| 1153 | |
| 1154 | const 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; |
nothing calls this directly
no test coverage detected