ValueFlow: don't perform UB when a function returns shifts of/by negative values. Fixes #7814.
This commit is contained in:
parent
8be50fd822
commit
213589ee68
|
@ -2097,10 +2097,19 @@ static void execute(const Token *expr,
|
||||||
*result = result1 / result2;
|
*result = result1 / result2;
|
||||||
else if (expr->str() == "%")
|
else if (expr->str() == "%")
|
||||||
*result = result1 % result2;
|
*result = result1 % result2;
|
||||||
else if (expr->str() == "<<")
|
else if (expr->str() == "<<") {
|
||||||
*result = result1 << result2;
|
if (result2 < 0 || result1 < 0) { // dont perform UB
|
||||||
else if (expr->str() == ">>")
|
*error= true;
|
||||||
*result = result1 >> result2;
|
} 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() == "&&") {
|
else if (expr->str() == "&&") {
|
||||||
|
|
|
@ -4626,6 +4626,16 @@ private:
|
||||||
// #6383 - unsigned type
|
// #6383 - unsigned type
|
||||||
check("const int x = (unsigned int)(-1) >> 2;");
|
check("const int x = (unsigned int)(-1) >> 2;");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void incompleteArrayFill() {
|
||||||
|
|
Loading…
Reference in New Issue