Анализатор обнаружил неправильный способ определения переполнения, которое может возникать при сложении переменных типов 'unsigned short' или переменных типов 'unsigned char'.
Пример некорректно написанного кода:
bool IsValidAddition(unsigned short x, unsigned short y)
{
if (x + y < x)
return false;
return true;
}
При сложении двух переменных типов 'unsigned short', обе переменные приводятся к типу 'int'. Результат сложения также будет иметь тип 'int'. Поэтому, независимо от того, какие значения будут в переменных 'x' и 'y', в результате их сложения переполнения никогда не возникнет. Далее выполняется операция сравнения. При этом правый операнд (переменная 'x') вновь расширяется до типа 'int'. В итоге, приведённый выше код эквивалентен этому:
bool IsValidAddition(unsigned short x, unsigned short y)
{
if ((int)(x) + (int)(y) < (int)(x))
return false;
return true;
}
Получается, что выражение "x + y < x" всегда будет ложно. Вероятнее всего, компилятор оптимизирует функцию, подставив в места ее вызова значение 'true'. Итог: функция ничего на самом деле не проверяет и не защищает от переполнения.
Примечание: Если вы используете модель данных, где размер типа 'short' и типа 'int' совпадают, то такая проверка будет работать корректно и анализатор не будет выдавать предупреждение.
Чтобы получить корректно работающий код, нужно явно выполнить приведение результата сложения к типу 'unsigned short':
if ((unsigned short)(x + y) < x)
{
...
}
Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки целочисленного переполнения и некорректного совместного использования знаковых и беззнаковых чисел. |
Данная диагностика классифицируется как:
|