| 57 | |
| 58 | |
| 59 | void CheckTypeImpl::checkTooBigBitwiseShift() |
| 60 | { |
| 61 | // unknown sizeof(int) => can't run this checker |
| 62 | if (mSettings.platform.type == Platform::Type::Unspecified) |
| 63 | return; |
| 64 | |
| 65 | logChecker("CheckType::checkTooBigBitwiseShift"); // platform |
| 66 | |
| 67 | for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { |
| 68 | // C++ and macro: OUT(x<<y) |
| 69 | if (tok->isCpp() && Token::Match(tok, "[;{}] %name% (") && Token::simpleMatch(tok->linkAt(2), ") ;") && tok->next()->isUpperCaseName() && !tok->next()->function()) |
| 70 | tok = tok->linkAt(2); |
| 71 | |
| 72 | tok = skipUnreachableBranch(tok); |
| 73 | |
| 74 | if (!tok->astOperand1() || !tok->astOperand2()) |
| 75 | continue; |
| 76 | |
| 77 | if (!Token::Match(tok, "<<|>>|<<=|>>=")) |
| 78 | continue; |
| 79 | |
| 80 | // get number of bits of lhs |
| 81 | const ValueType * const lhstype = tok->astOperand1()->valueType(); |
| 82 | if (!lhstype || !lhstype->isIntegral() || lhstype->pointer >= 1) |
| 83 | continue; |
| 84 | // C11 Standard, section 6.5.7 Bitwise shift operators, states: |
| 85 | // The integer promotions are performed on each of the operands. |
| 86 | // The type of the result is that of the promoted left operand. |
| 87 | std::uint8_t lhsbits; |
| 88 | if ((lhstype->type == ValueType::Type::CHAR) || |
| 89 | (lhstype->type == ValueType::Type::SHORT) || |
| 90 | (lhstype->type == ValueType::Type::WCHAR_T) || |
| 91 | (lhstype->type == ValueType::Type::BOOL) || |
| 92 | (lhstype->type == ValueType::Type::INT)) |
| 93 | lhsbits = mSettings.platform.int_bit; |
| 94 | else if (lhstype->type == ValueType::Type::LONG) |
| 95 | lhsbits = mSettings.platform.long_bit; |
| 96 | else if (lhstype->type == ValueType::Type::LONGLONG) |
| 97 | lhsbits = mSettings.platform.long_long_bit; |
| 98 | else |
| 99 | continue; |
| 100 | |
| 101 | // Get biggest rhs value. preferably a value which doesn't have 'condition'. |
| 102 | const ValueFlow::Value * value = tok->astOperand2()->getValueGE(lhsbits, mSettings); |
| 103 | if (value && mSettings.isEnabled(value, false)) |
| 104 | tooBigBitwiseShiftError(tok, lhsbits, *value); |
| 105 | else if (lhstype->sign == ValueType::Sign::SIGNED) { |
| 106 | value = tok->astOperand2()->getValueGE(lhsbits-1, mSettings); |
| 107 | if (value && mSettings.isEnabled(value, false)) |
| 108 | tooBigSignedBitwiseShiftError(tok, lhsbits, *value); |
| 109 | } |
| 110 | } |
| 111 | } |
| 112 | |
| 113 | void CheckTypeImpl::tooBigBitwiseShiftError(const Token *tok, int lhsbits, const ValueFlow::Value &rhsbits) |
| 114 | { |
no test coverage detected