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

Method checkVariableScope

lib/checkother.cpp:1186–1301  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Check scope of variables.. ---------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

1184// Check scope of variables..
1185//---------------------------------------------------------------------------
1186void CheckOtherImpl::checkVariableScope()
1187{
1188 if (mSettings.clang)
1189 return;
1190
1191 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("variableScope"))
1192 return;
1193
1194 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
1195
1196 // In C it is common practice to declare local variables at the
1197 // start of functions.
1198 if (mSettings.daca && mTokenizer->isC())
1199 return;
1200
1201 logChecker("CheckOther::checkVariableScope"); // style,notclang
1202
1203 for (const Variable* var : symbolDatabase->variableList()) {
1204 if (!var || !var->isLocal() || var->isConst())
1205 continue;
1206
1207 if (var->nameToken()->isExpandedMacro())
1208 continue;
1209 if (isStructuredBindingVariable(var) && // warn for single decomposition
1210 !(Token::simpleMatch(var->nameToken()->astParent(), "[") && var->nameToken()->astParent()->astOperand2() == var->nameToken()))
1211 continue;
1212
1213 const bool isPtrOrRef = var->isPointer() || var->isReference();
1214 const bool isSimpleType = var->typeStartToken()->isStandardType() || var->typeStartToken()->isEnumType() || var->typeStartToken()->isC() || symbolDatabase->isRecordTypeWithoutSideEffects(var->type());
1215 if (!isPtrOrRef && !isSimpleType && !astIsContainer(var->nameToken()))
1216 continue;
1217
1218 if (mTokenizer->hasIfdef(var->nameToken(), var->scope()->bodyEnd))
1219 continue;
1220
1221 // reference of range for loop variable..
1222 if (Token::Match(var->nameToken()->previous(), "& %var% = %var% .")) {
1223 const Token *otherVarToken = var->nameToken()->tokAt(2);
1224 const Variable *otherVar = otherVarToken->variable();
1225 if (otherVar && Token::Match(otherVar->nameToken(), "%var% :") &&
1226 otherVar->nameToken()->next()->astParent() &&
1227 Token::simpleMatch(otherVar->nameToken()->next()->astParent()->previous(), "for ("))
1228 continue;
1229 }
1230
1231 bool forHead = false; // Don't check variables declared in header of a for loop
1232 for (const Token* tok = var->typeStartToken(); tok; tok = tok->previous()) {
1233 if (tok->str() == "(") {
1234 forHead = true;
1235 break;
1236 }
1237 if (Token::Match(tok, "[;{}]"))
1238 break;
1239 }
1240 if (forHead)
1241 continue;
1242
1243 const Token* tok = var->nameToken()->next();

Callers 1

runChecksMethod · 0.80

Calls 15

astIsContainerFunction · 0.85
isSimpleExprFunction · 0.85
isWithinScopeFunction · 0.85
isPremiumEnabledMethod · 0.80
isCMethod · 0.80
isConstMethod · 0.80
astParentMethod · 0.80
astOperand2Method · 0.80
isEnumTypeMethod · 0.80
typeMethod · 0.80
hasIfdefMethod · 0.80

Tested by

no test coverage detected