Правило MISRA2004-12_8-3 имеет нарушение статического анализа для операнда RHS (32u - n) даже с проверкой пределов

В настоящее время я пытаюсь использовать программное обеспечение parasoft для исправления нарушений статического анализа моего кода с использованием стандартов кодирования MISRA C. Мой код изначально имел эту функцию:

static inline uint32_t rotate_right(uint32_t val, uint32_t n)
{
    return (val >> n) | (val << (32 - n));
}

Это вызывает нарушение статического анализа по правилу MISRA2004-12_8-3. Правило говорит

Правый операнд оператора сдвига должен лежать между нулем и единицей меньше ширины в битах базового типа левого операнда.

В документации правила указано, что это конкретное правило сообщает о нарушении, если

  • правый операнд является константой с отрицательным значением или со значением, которое превышает длину (в битах) левого операнда
  • правый операнд не является константой и не проверяется по определенному шаблону

Поскольку я не использую константу для правого операнда, правила MISRA-C требуют, чтобы я окружал это выражение проверками пределов. MISRA-C также заявляет, что

Использование целочисленного типа без знака гарантирует, что операнд неотрицательный, поэтому необходимо проверять только верхний предел (динамически во время выполнения или при просмотре). В противном случае необходимо будет проверить оба предела.

Поскольку я использую беззнаковый тип uint32_t, мне нужно только проверить верхние пределы правого операнда. Однако для val << (32u - n) я не могу иметь значение n как 0u. Поэтому я попытался устранить это нарушение, добавив следующие проверки:

static inline uint32_t rotate_right(uint32_t val, uint32_t n)
{
    if (n == 0u)
    {
        return val;
    }
    else if ((n > 0u) && (n <= 31u))
    {
        return (val >> n) | (val << (32u - n)); 
    }
    else
    {
        return 0u;
    }
}

Это устраняет нарушение статического анализа для (val >> n), но о том же нарушении по-прежнему сообщается для (val << (32u - n)).

Следовательно, мои вопросы:

  1. Оператор if явно ограничивает значение n меньше 32u. Следовательно, (32u - n) также будет иметь значение, меньшее или равное 32u. Почему программное обеспечение parasoft все еще сообщает об ошибке для правого операнда, равного (32u - n), несмотря на проверку предела?

  2. Как правильно устранить это нарушение?


person Alaiko    schedule 17.09.2020    source источник


Ответы (1)


Как говорится в документе MISRA-C, разумно проверять это только динамически во время выполнения или во время проверки кода. Что, конечно, не остановит неработающих статических анализаторов от попыток сделать это во время статического анализа...

Почему программное обеспечение parasoft все еще сообщает об ошибке для правого операнда (32u - n), несмотря на проверку предела?

Вероятно, потому что он прослушивается и сообщает о ложном срабатывании.

Если, конечно, он не заметил, что какой-то код вызывающей стороны предоставляет n, который больше, чем 32. Некоторые статические анализаторы способны выдавать несколько более разумные предупреждения, когда они проверяют проект целиком, а не отдельные единицы перевода по одному.

Как правильно устранить это нарушение?

Ваш исходный код в порядке, и, кроме 32 -> 32u, он совместим с MISRA. Не загромождайте его защитным программированием только для того, чтобы заставить замолчать потенциально неисправный инструмент. Добавляйте такие проверки только в том случае, если у вас есть основания полагать, что n на самом деле будет равно нулю или больше 32.

Для соответствия MISRA-C должно быть достаточно указать, что случай переменной n будет рассмотрен при проверке кода.

(Чтобы быть придирчивым, MISRA-C: 2004 не разрешает inline, поскольку он не разрешает C99, для этого вам нужен MISRA-C: 2012.)

person Lundin    schedule 17.09.2020
comment
Итак, лучший способ справиться с этим — сохранить исходный код и просто подавить его примечаниями о том, что это будет рассмотрено при проверке кода? Я не думаю, что n будет 0 или больше 32 в моем случае. - person Alaiko; 17.09.2020
comment
@Alaiko Или просто подавите его замечанием, что инструмент сломан. Учитывая среднее качество средств проверки MISRA-C, вам понадобится подпрограмма для обработки ложных срабатываний, вызванных ошибками инструмента. - person Lundin; 17.09.2020
comment
MISRA C:2004 Permits предоставляет механизм, который позволяет использовать встроенные - person Andrew; 26.10.2020