diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index d87be4b77..9a15200d0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -2097,10 +2097,19 @@ static void execute(const Token *expr, *result = result1 / result2; else if (expr->str() == "%") *result = result1 % result2; - else if (expr->str() == "<<") - *result = result1 << result2; - else if (expr->str() == ">>") - *result = result1 >> result2; + else if (expr->str() == "<<") { + if (result2 < 0 || result1 < 0) { // dont perform UB + *error= true; + } else { + *result = result1 << result2; + } + } else if (expr->str() == ">>") { + if (result2 < 0) { // don't perform UB + *error=true; + } else { + *result = result1 >> result2; + } + } } else if (expr->str() == "&&") { diff --git a/test/testother.cpp b/test/testother.cpp index ce67cef5b..c0551020c 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -4626,6 +4626,16 @@ private: // #6383 - unsigned type check("const int x = (unsigned int)(-1) >> 2;"); ASSERT_EQUALS("", errout.str()); + + // #7814 - UB happening in valueflowcode when it tried to compute shifts. + check("int shift1() { return 1 >> -1 ;}\n" + "int shift2() { return 1 << -1 ;}\n" + "int shift3() { return -1 >> 1 ;}\n" + "int shift4() { return -1 << 1 ;}\n"); + ASSERT_EQUALS("[test.cpp:1]: (error) Shifting by a negative value is undefined behaviour\n" + "[test.cpp:2]: (error) Shifting by a negative value is undefined behaviour\n" + "[test.cpp:3]: (error) Shifting a negative value is undefined behaviour\n" + "[test.cpp:4]: (error) Shifting a negative value is undefined behaviour\n", errout.str()); } void incompleteArrayFill() {