| 252 | //--------------------------------------------------------------------------- |
| 253 | |
| 254 | void CheckTypeImpl::checkSignConversion() |
| 255 | { |
| 256 | if (!mSettings.severity.isEnabled(Severity::warning)) |
| 257 | return; |
| 258 | |
| 259 | logChecker("CheckType::checkSignConversion"); // warning |
| 260 | |
| 261 | for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) { |
| 262 | if (!tok->isArithmeticalOp() || Token::Match(tok,"+|-")) |
| 263 | continue; |
| 264 | |
| 265 | // Is result unsigned? |
| 266 | if (!(tok->valueType() && tok->valueType()->sign == ValueType::Sign::UNSIGNED)) |
| 267 | continue; |
| 268 | |
| 269 | // Check if an operand can be negative.. |
| 270 | const Token * astOperands[] = { tok->astOperand1(), tok->astOperand2() }; |
| 271 | for (const Token * tok1 : astOperands) { |
| 272 | if (!tok1) |
| 273 | continue; |
| 274 | const ValueFlow::Value* negativeValue = |
| 275 | ValueFlow::findValue(tok1->values(), mSettings, [&](const ValueFlow::Value& v) { |
| 276 | return !v.isImpossible() && v.isIntValue() && (v.intvalue <= -1 || v.wideintvalue <= -1); |
| 277 | }); |
| 278 | if (!negativeValue) |
| 279 | continue; |
| 280 | if (tok1->valueType() && tok1->valueType()->sign != ValueType::Sign::UNSIGNED) |
| 281 | signConversionError(tok1, negativeValue, tok1->isNumber()); |
| 282 | } |
| 283 | } |
| 284 | } |
| 285 | |
| 286 | void CheckTypeImpl::signConversionError(const Token *tok, const ValueFlow::Value *negativeValue, const bool constvalue) |
| 287 | { |
no test coverage detected