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

Method clarifyCalculation

lib/checkother.cpp:153–200  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Clarify calculation precedence for ternary operators. ---------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

151// Clarify calculation precedence for ternary operators.
152//---------------------------------------------------------------------------
153void CheckOtherImpl::clarifyCalculation()
154{
155 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("clarifyCalculation"))
156 return;
157
158 logChecker("CheckOther::clarifyCalculation"); // style
159
160 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
161 for (const Scope * scope : symbolDatabase->functionScopes) {
162 for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
163 // ? operator where lhs is arithmetical expression
164 if (tok->str() != "?" || !tok->astOperand1() || !tok->astOperand1()->isCalculation())
165 continue;
166 if (!tok->astOperand1()->isArithmeticalOp() && tok->astOperand1()->tokType() != Token::eBitOp)
167 continue;
168
169 // non-pointer calculation in lhs and pointer in rhs => no clarification is needed
170 if (tok->astOperand1()->isBinaryOp() && Token::Match(tok->astOperand1(), "%or%|&|%|*|/") && tok->astOperand2()->valueType() && tok->astOperand2()->valueType()->pointer > 0)
171 continue;
172
173 // bit operation in lhs and char literals in rhs => probably no mistake
174 if (tok->astOperand1()->tokType() == Token::eBitOp && Token::Match(tok->astOperand2()->astOperand1(), "%char%") && Token::Match(tok->astOperand2()->astOperand2(), "%char%"))
175 continue;
176
177 // 2nd operand in lhs has known integer value => probably no mistake
178 if (tok->astOperand1()->isBinaryOp() && tok->astOperand1()->astOperand2()->hasKnownIntValue()) {
179 const Token *op = tok->astOperand1()->astOperand2();
180 if (op->isNumber())
181 continue;
182 if (op->valueType() && op->valueType()->isEnum())
183 continue;
184 }
185
186 // Is code clarified by parentheses already?
187 const Token *tok2 = tok->astOperand1();
188 for (; tok2; tok2 = tok2->next()) {
189 if (tok2->str() == "(")
190 tok2 = tok2->link();
191 else if (tok2->str() == ")")
192 break;
193 else if (tok2->str() == "?") {
194 clarifyCalculationError(tok, tok->astOperand1()->str());
195 break;
196 }
197 }
198 }
199 }
200}
201
202void CheckOtherImpl::clarifyCalculationError(const Token *tok, const std::string &op)
203{

Callers 1

runChecksMethod · 0.45

Calls 11

isPremiumEnabledMethod · 0.80
nextMethod · 0.80
astOperand1Method · 0.80
isCalculationMethod · 0.80
isArithmeticalOpMethod · 0.80
isBinaryOpMethod · 0.80
astOperand2Method · 0.80
isEnumMethod · 0.80
isEnabledMethod · 0.45
strMethod · 0.45
hasKnownIntValueMethod · 0.45

Tested by

no test coverage detected