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

Method redundantBitwiseOperationInSwitchError

lib/checkother.cpp:795–910  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

793}
794
795void CheckOtherImpl::redundantBitwiseOperationInSwitchError()
796{
797 if (!mSettings.severity.isEnabled(Severity::warning))
798 return;
799
800 logChecker("CheckOther::redundantBitwiseOperationInSwitch"); // warning
801
802 const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase();
803
804 // Find the beginning of a switch. E.g.:
805 // switch (var) { ...
806 for (const Scope &switchScope : symbolDatabase->scopeList) {
807 if (switchScope.type != ScopeType::eSwitch || !switchScope.bodyStart)
808 continue;
809
810 // Check the contents of the switch statement
811 std::map<int, const Token*> varsWithBitsSet;
812 std::map<int, std::string> bitOperations;
813
814 for (const Token *tok2 = switchScope.bodyStart->next(); tok2 != switchScope.bodyEnd; tok2 = tok2->next()) {
815 if (tok2->str() == "{") {
816 // Inside a conditional or loop. Don't mark variable accesses as being redundant. E.g.:
817 // case 3: b = 1;
818 // case 4: if (a) { b = 2; } // Doesn't make the b=1 redundant because it's conditional
819 if (Token::Match(tok2->previous(), ")|else {") && tok2->link()) {
820 const Token* endOfConditional = tok2->link();
821 for (const Token* tok3 = tok2; tok3 != endOfConditional; tok3 = tok3->next()) {
822 if (tok3->varId() != 0) {
823 varsWithBitsSet.erase(tok3->varId());
824 bitOperations.erase(tok3->varId());
825 } else if (isFunctionOrBreakPattern(tok3)) {
826 varsWithBitsSet.clear();
827 bitOperations.clear();
828 }
829 }
830 tok2 = endOfConditional;
831 }
832 }
833
834 // Variable assignment. Report an error if it's assigned to twice before a break. E.g.:
835 // case 3: b = 1; // <== redundant
836 // case 4: b = 2;
837
838 if (Token::Match(tok2->previous(), ";|{|}|: %var% = %any% ;")) {
839 varsWithBitsSet.erase(tok2->varId());
840 bitOperations.erase(tok2->varId());
841 }
842
843 // Bitwise operation. Report an error if it's performed twice before a break. E.g.:
844 // case 3: b |= 1; // <== redundant
845 // case 4: b |= 1;
846 else if (Token::Match(tok2->previous(), ";|{|}|: %var% %assign% %num% ;") &&
847 (tok2->strAt(1) == "|=" || tok2->strAt(1) == "&=") &&
848 Token::Match(tok2->next()->astOperand2(), "%num%")) {
849 std::string bitOp = tok2->strAt(1)[0] + tok2->strAt(2);
850 const auto i2 = utils::as_const(varsWithBitsSet).find(tok2->varId());
851
852 // This variable has not had a bit operation performed on it yet, so just make a note of it

Callers 2

runChecksMethod · 0.80
getErrorMessagesMethod · 0.80

Calls 11

isFunctionOrBreakPatternFunction · 0.85
nextMethod · 0.80
astOperand2Method · 0.80
reportErrorFunction · 0.70
isEnabledMethod · 0.45
strMethod · 0.45
eraseMethod · 0.45
clearMethod · 0.45
findMethod · 0.45
endMethod · 0.45
tokAtMethod · 0.45

Tested by

no test coverage detected