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

Method va_list_usage

lib/checkvaarg.cpp:93–156  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

91//---------------------------------------------------------------------------
92
93void CheckVaargImpl::va_list_usage()
94{
95 if (mSettings.clang)
96 return;
97
98 logChecker("CheckVaarg::va_list_usage"); // notclang
99
100 const SymbolDatabase* const symbolDatabase = mTokenizer->getSymbolDatabase();
101 for (const Variable* var : symbolDatabase->variableList()) {
102 if (!var || var->isPointer() || var->isReference() || var->isArray() || !var->scope() || var->typeStartToken()->str() != "va_list")
103 continue;
104 if (!var->isLocal() && !var->isArgument()) // Check only local variables and arguments
105 continue;
106
107 bool open = var->isArgument(); // va_list passed as argument are opened
108 bool exitOnEndOfStatement = false;
109
110 const Token* tok = var->nameToken()->next();
111 for (; tok && tok != var->scope()->bodyEnd; tok = tok->next()) {
112 // Skip lambdas
113 const Token* tok2 = findLambdaEndToken(tok);
114 if (tok2)
115 tok = tok2;
116 if (Token::Match(tok, "va_start ( %varid%", var->declarationId())) {
117 if (open)
118 va_start_subsequentCallsError(tok, var->name());
119 open = true;
120 tok = tok->linkAt(1);
121 } else if (Token::Match(tok, "va_end ( %varid%", var->declarationId())) {
122 if (!open)
123 va_list_usedBeforeStartedError(tok, var->name());
124 open = false;
125 tok = tok->linkAt(1);
126 } else if (Token::simpleMatch(tok, "va_copy (")) {
127 bool nopen = open;
128 if (tok->linkAt(1)->previous()->varId() == var->declarationId()) { // Source
129 if (!open)
130 va_list_usedBeforeStartedError(tok, var->name());
131 }
132 if (tok->tokAt(2)->varId() == var->declarationId()) { // Destination
133 if (open)
134 va_start_subsequentCallsError(tok, var->name());
135 nopen = true;
136 }
137 open = nopen;
138 tok = tok->linkAt(1);
139 } else if (Token::Match(tok, "throw|return"))
140 exitOnEndOfStatement = true;
141 else if (tok->str() == "break") {
142 tok = findNextTokenFromBreak(tok);
143 if (!tok)
144 return;
145 } else if (tok->str() == "goto" || (tok->isCpp() && tok->str() == "try")) {
146 open = false;
147 break;
148 } else if (!open && tok->varId() == var->declarationId())
149 va_list_usedBeforeStartedError(tok, var->name());
150 else if (exitOnEndOfStatement && tok->str() == ";")

Callers 1

runChecksMethod · 0.80

Calls 11

findLambdaEndTokenFunction · 0.85
findNextTokenFromBreakFunction · 0.85
isArrayMethod · 0.80
scopeMethod · 0.80
nextMethod · 0.80
linkAtMethod · 0.80
simpleMatchFunction · 0.70
strMethod · 0.45
nameTokenMethod · 0.45
nameMethod · 0.45
tokAtMethod · 0.45

Tested by

no test coverage detected