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

Method checkIncorrectLogicOperator

lib/checkcondition.cpp:1159–1368  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1157}
1158
1159void CheckConditionImpl::checkIncorrectLogicOperator()
1160{
1161 const bool printStyle = mSettings.severity.isEnabled(Severity::style);
1162 const bool printWarning = mSettings.severity.isEnabled(Severity::warning);
1163 if (!printWarning && !printStyle && !mSettings.isPremiumEnabled("incorrectLogicOperator"))
1164 return;
1165 const bool printInconclusive = mSettings.certainty.isEnabled(Certainty::inconclusive);
1166
1167 logChecker("CheckCondition::checkIncorrectLogicOperator"); // style,warning
1168
1169 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
1170 for (const Scope * scope : symbolDatabase->functionScopes) {
1171
1172 for (const Token* tok = scope->bodyStart->next(); tok != scope->bodyEnd; tok = tok->next()) {
1173 if (!Token::Match(tok, "%oror%|&&") || !tok->astOperand1() || !tok->astOperand2())
1174 continue;
1175
1176
1177 // 'A && (!A || B)' is equivalent to 'A && B'
1178 // 'A || (!A && B)' is equivalent to 'A || B'
1179 // 'A && (A || B)' is equivalent to 'A'
1180 // 'A || (A && B)' is equivalent to 'A'
1181 if (printStyle &&
1182 ((tok->str() == "||" && tok->astOperand2()->str() == "&&") ||
1183 (tok->str() == "&&" && tok->astOperand2()->str() == "||"))) {
1184 const Token* tok2 = tok->astOperand2()->astOperand1();
1185 if (isOppositeCond(true, tok->astOperand1(), tok2, mSettings, true, false)) {
1186 std::string expr1(tok->astOperand1()->expressionString());
1187 std::string expr2(tok->astOperand2()->astOperand1()->expressionString());
1188 std::string expr3(tok->astOperand2()->astOperand2()->expressionString());
1189 // make copy for later because the original string might get overwritten
1190 const std::string expr1VerboseMsg = expr1;
1191 const std::string expr2VerboseMsg = expr2;
1192 const std::string expr3VerboseMsg = expr3;
1193
1194 if (expr1.length() + expr2.length() + expr3.length() > 50U) {
1195 if (expr1[0] == '!' && expr2[0] != '!') {
1196 expr1 = "!A";
1197 expr2 = "A";
1198 } else {
1199 expr1 = "A";
1200 expr2 = "!A";
1201 }
1202
1203 expr3 = "B";
1204 }
1205
1206 const std::string cond1 = expr1 + " " + tok->str() + " (" + expr2 + " " + tok->astOperand2()->str() + " " + expr3 + ")";
1207 const std::string cond2 = expr1 + " " + tok->str() + " " + expr3;
1208
1209 const std::string cond1VerboseMsg = expr1VerboseMsg + " " + tok->str() + " " + expr2VerboseMsg + " " + tok->astOperand2()->str() + " " + expr3VerboseMsg;
1210 const std::string cond2VerboseMsg = expr1VerboseMsg + " " + tok->str() + " " + expr3VerboseMsg;
1211 // for the --verbose message, transform the actual condition and print it
1212 const std::string msg = tok2->expressionString() + ". '" + cond1 + "' is equivalent to '" + cond2 + "'\n"
1213 "The condition '" + cond1VerboseMsg + "' is equivalent to '" + cond2VerboseMsg + "'.";
1214 redundantConditionError(tok, msg, false);
1215 continue;
1216 }

Callers 1

runChecksMethod · 0.80

Calls 15

isOppositeCondFunction · 0.85
isSameExpressionFunction · 0.85
parseComparisonFunction · 0.85
isFloatFunction · 0.85
isIfConstexprFunction · 0.85
conditionStringFunction · 0.85
checkFloatRelationFunction · 0.85
checkIntRelationFunction · 0.85
sufficientConditionFunction · 0.85
isPremiumEnabledMethod · 0.80
nextMethod · 0.80
astOperand1Method · 0.80

Tested by

no test coverage detected