From cac7146cac402e4b60c1f73fc70f623e5885bd20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Tue, 19 Sep 2017 14:43:48 +0200 Subject: [PATCH] checkIntegerOverflow: check all calculations, not only in function bodies --- lib/checktype.cpp | 39 +++++++++++++++++---------------------- test/testtype.cpp | 3 +++ 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 1191f5c3f..7ccfe0247 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -145,32 +145,27 @@ void CheckType::checkIntegerOverflow() // max int value according to platform settings. const MathLib::bigint maxint = (1LL << (_settings->int_bit - 1)) - 1; - const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); - const std::size_t functions = symbolDatabase->functionScopes.size(); - for (std::size_t i = 0; i < functions; ++i) { - const Scope * scope = symbolDatabase->functionScopes[i]; - for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { - if (!tok->isArithmeticalOp()) - continue; + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { + if (!tok->isArithmeticalOp()) + continue; - // is result signed integer? - const ValueType *vt = tok->valueType(); - if (!vt || vt->type != ValueType::Type::INT || vt->sign != ValueType::Sign::SIGNED) - continue; + // is result signed integer? + const ValueType *vt = tok->valueType(); + if (!vt || vt->type != ValueType::Type::INT || vt->sign != ValueType::Sign::SIGNED) + continue; - // is there a overflow result value - const ValueFlow::Value *value = tok->getValueGE(maxint + 1, _settings); - if (!value) - value = tok->getValueLE(-maxint - 2, _settings); - if (!value || !_settings->isEnabled(value,false)) - continue; + // is there a overflow result value + const ValueFlow::Value *value = tok->getValueGE(maxint + 1, _settings); + if (!value) + value = tok->getValueLE(-maxint - 2, _settings); + if (!value || !_settings->isEnabled(value,false)) + continue; - // For left shift, it's common practice to shift into the sign bit - if (tok->str() == "<<" && value->intvalue > 0 && value->intvalue < (1LL << _settings->int_bit)) - continue; + // For left shift, it's common practice to shift into the sign bit + if (tok->str() == "<<" && value->intvalue > 0 && value->intvalue < (1LL << _settings->int_bit)) + continue; - integerOverflowError(tok, *value); - } + integerOverflowError(tok, *value); } } diff --git a/test/testtype.cpp b/test/testtype.cpp index cebbb7941..76f8ce85a 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -110,6 +110,9 @@ private: settings.platform(Settings::Unix32); settings.addEnabled("warning"); + check("x = (int)0x10000 * (int)0x10000;", &settings); + ASSERT_EQUALS("[test.cpp:1]: (error) Signed integer overflow for expression '(int)65536*(int)65536'.\n", errout.str()); + check("void foo() {\n" " int intmax = 0x7fffffff;\n" " return intmax + 1;\n"