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

Method comparison

lib/checkcondition.cpp:359–422  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

357}
358
359void CheckConditionImpl::comparison()
360{
361 if (!mSettings.severity.isEnabled(Severity::style) && !mSettings.isPremiumEnabled("comparisonError"))
362 return;
363
364 logChecker("CheckCondition::comparison"); // style
365
366 for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
367 if (!tok->isComparisonOp())
368 continue;
369
370 const Token *expr1 = tok->astOperand1();
371 const Token *expr2 = tok->astOperand2();
372 if (!expr1 || !expr2)
373 continue;
374 if (expr1->hasKnownIntValue())
375 std::swap(expr1,expr2);
376 if (!expr2->hasKnownIntValue())
377 continue;
378 if (!compareTokenFlags(expr1, expr2, /*macro*/ true))
379 continue;
380 const MathLib::bigint num2 = expr2->getKnownIntValue();
381 if (num2 < 0)
382 continue;
383 if (!Token::Match(expr1,"[&|]"))
384 continue;
385 std::list<MathLib::bigint> numbers;
386 getnumchildren(expr1, numbers);
387 for (const MathLib::bigint num1 : numbers) {
388 if (num1 < 0)
389 continue;
390 if (Token::Match(tok, "==|!=")) {
391 if ((expr1->str() == "&" && (num1 & num2) != num2) ||
392 (expr1->str() == "|" && (num1 | num2) != num2)) {
393 const std::string& op(tok->str());
394 comparisonError(expr1, expr1->str(), num1, op, num2, op != "==");
395 }
396 } else if (expr1->str() == "&") {
397 const bool or_equal = Token::Match(tok, ">=|<=");
398 const std::string& op(tok->str());
399 if ((Token::Match(tok, ">=|<")) && (num1 < num2)) {
400 comparisonError(expr1, expr1->str(), num1, op, num2, !or_equal);
401 } else if ((Token::Match(tok, "<=|>")) && (num1 <= num2)) {
402 comparisonError(expr1, expr1->str(), num1, op, num2, or_equal);
403 }
404 } else if (expr1->str() == "|") {
405 if ((expr1->astOperand1()->valueType()) &&
406 (expr1->astOperand1()->valueType()->sign == ValueType::Sign::UNSIGNED)) {
407 const bool or_equal = Token::Match(tok, ">=|<=");
408 const std::string& op(tok->str());
409 if ((Token::Match(tok, ">=|<")) && (num1 >= num2)) {
410 //"(a | 0x07) >= 7U" is always true for unsigned a
411 //"(a | 0x07) < 7U" is always false for unsigned a
412 comparisonError(expr1, expr1->str(), num1, op, num2, or_equal);
413 } else if ((Token::Match(tok, "<=|>")) && (num1 > num2)) {
414 //"(a | 0x08) <= 7U" is always false for unsigned a
415 //"(a | 0x07) > 6U" is always true for unsigned a
416 comparisonError(expr1, expr1->str(), num1, op, num2, !or_equal);

Callers 1

runChecksMethod · 0.45

Calls 11

compareTokenFlagsFunction · 0.85
getnumchildrenFunction · 0.85
isPremiumEnabledMethod · 0.80
nextMethod · 0.80
astOperand1Method · 0.80
astOperand2Method · 0.80
getKnownIntValueMethod · 0.80
swapFunction · 0.70
isEnabledMethod · 0.45
hasKnownIntValueMethod · 0.45
strMethod · 0.45

Tested by

no test coverage detected