Комментарии 5
С Int_VecDo3 разве не ошибка в анализаторе? Смотрите, GetNumVectorElements возвращает числа из множества {0, 1, 2, 3, 4}. Если n >= 1 , то проблемы с n + n - 2 нет. Значит, беда будет в случае n == 0.
Это бывает, если аргумент GetNumVectorElements, полученный в строке VectorSize sz = GetVecSize(op);, не лежит во множестве {V_Single, V_Pair, V_Triple, V_Quad} == {1, 2, 3, 4}. Хорошо, а что же такое GetVecSize?
static inline VectorSize GetVecSize(MIPSOpcode op) {
int a = (op >> 7) & 1;
int b = (op >> 14) & 2;
return (VectorSize)(a + b + 1); // Safe, there are no other possibilities
}MIPSOpcode - просто обёртка над uint32_t. Как видим, здесь вычисляются a и b. Первое - либо 0, либо 1. Второе - либо 0, либо 2. Поэтому их сумма принадлежит множеству {0, 1, 2, 3}. Докидывая в сумму единичку, получаем {1, 2, 3, 4}, т.е. sz всегда корректно, а значит, n тоже.
Спасибо за интересное замечание!
Мне понятна ваша логика. Однако, если следовать ей, то можно сделать вывод, что дефолтная ветвь в GetNumVectorElements является недостижимым кодом:
static inline int GetNumVectorElements(VectorSize sz)
{
switch (sz)
{
case V_Single: return 1;
case V_Pair: return 2;
case V_Triple: return 3;
case V_Quad: return 4;
default: return 0; //unreachable code
}
}
Недостижимый код тоже является ошибкой и в данном случае можно сказать, что является меньшим злом. Итак, имеем недостижимый код в виде default: return 0;
Можно убрать эту ветвь, но тогда получим предупреждение от компилятора, что control flow graph функции имеет путь без возвращаемого значения. Хорошо, заменим возвращаемое значение на std::optional и на этом казалось бы всё.
Но! Можно всё же заметить, что VectorSize имеет такой вариант значения как V_Invalid = -1, который как раз обрабатывается этой ветвью и может прийти из указанной вами функции GetVecSize.
Предположим даже, что обёртка MIPSOpcode , которая представляет из себя Memory::Opcode всегда будет иметь значения из того же диапазона, что и uint32_t, а переменные a и b , которые удачно объявлены как int, никогда не будут отрицательными. И результат каста (VectorSize)(a + b + 1) тоже никогда не будет V_Invalid (-1).
Есть ли гарантия, что в результате рефакторинга или других изменений в коде всё это не рассыплется как карточный домик?
Предположим даже, что обёртка
MIPSOpcode, которая представляет из себяMemory::Opcodeвсегда будет иметь значения из того же диапазона, что иuint32_t, а переменныеaиb, которые удачно объявлены какint, никогда не будут отрицательными.
Сейчас вообще не понял)
Ну, Memory::Opcode олицетворяет 4 байта, в которых закодирована команда процессору (RISC, всё такое, удобно), конечно, он будет принимать значения, как и то, что у него под капотом - uint32_t. А как объявлены переменные a и b, неважно, т.к. мы срезаем битовыми масками по степени двойки в каждом случае.
Что же касается рефакторинга... Ну, у нас есть тесты. Их мы гоняем на каждый PR, чтобы сравнить, не перестали ли мы походить на реальную PSP. Да-да-да, покрытия идеального не бывает, избыточность тестирования... Это всё ясно, но лучше варианта нет. Те же статические анализаторы могут ошибаться, как мы видим.
Что касается dummyThreadHackAddr, я его просто ещё не отрефакторил. Месяц назад я вытащил код, относящийся к системе AdhocMatching, в отдельные файлы, а потом почистил hadouken codestyle. На очереди AdhocCtl как раз, просто руки не дошли.
Вы контрибьютор? У пиписисипипи вроде не русскоязычный автор
Верно, можете посмотреть мой вклад: https://github.com/hrydgard/ppsspp/pulls/Nemoumbra
Информация
- Сайт
- pvs-studio.ru
- Дата регистрации
- Дата основания
- 2008
- Численность
- 51–100 человек
- Местоположение
- Россия
- Представитель
- Андрей Карпов
PPSSPP или всё же psp? Смотрим баги в коде из прошлого