diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 5b70b9ddd..76d8c8a9e 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -82,6 +82,9 @@ void CheckType::checkTooBigBitwiseShift() else continue; + if (lhstype->sign == ValueType::Sign::SIGNED) + --lhsbits; + // Get biggest rhs value. preferably a value which doesn't have 'condition'. const ValueFlow::Value *value = tok->astOperand2()->getValueGE(lhsbits, _settings); if (value && _settings->isEnabled(value, false)) diff --git a/test/testtype.cpp b/test/testtype.cpp index 3f1c3d791..7011f4f9a 100644 --- a/test/testtype.cpp +++ b/test/testtype.cpp @@ -65,11 +65,14 @@ private: Settings settings; settings.platform(Settings::Unix32); - check("int foo(int x) {\n" + check("int foo(unsigned int x) {\n" " return x << 32;\n" "}",&settings); ASSERT_EQUALS("[test.cpp:2]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n", errout.str()); + check("x = (short)x << 31;",&settings); + ASSERT_EQUALS("[test.cpp:1]: (error) Shifting 31-bit value by 31 bits is undefined behaviour\n", errout.str()); + check("int foo(int x) {\n" " return x << 2;\n" "}",&settings); @@ -87,16 +90,16 @@ private: ASSERT_EQUALS("", errout.str()); // Ticket #6793 - check("template int foo(int x) { return x << I; }\n" - "const int f = foo<31>(0);\n" - "const int g = foo<100>(0);\n" - "template int hoo(int x) { return x << 32; }\n" - "const int h = hoo<100>(0);", &settings); + check("template int foo(unsigned int x) { return x << I; }\n" + "const unsigned int f = foo<31>(0);\n" + "const unsigned int g = foo<100>(0);\n" + "template int hoo(unsigned int x) { return x << 32; }\n" + "const unsigned int h = hoo<100>(0);", &settings); ASSERT_EQUALS("[test.cpp:4]: (error) Shifting 32-bit value by 32 bits is undefined behaviour\n" "[test.cpp:1]: (error) Shifting 32-bit value by 100 bits is undefined behaviour\n", errout.str()); // #7266: C++, shift in macro - check("void f(int x) {\n" + check("void f(unsigned int x) {\n" " UINFO(x << 1234);\n" "}"); ASSERT_EQUALS("", errout.str()); @@ -136,11 +139,6 @@ private: " return 123456U * x;\n" "}",&settings); ASSERT_EQUALS("", errout.str()); - - check("int foo() {\n" - " x = 1 << 31;\n" // this is technically integer overflow but it's common code - "}", &settings, "test.c"); - ASSERT_EQUALS("", errout.str()); } void signConversion() {