>
>
>
V2555. MISRA. Incorrect shifting expres…


V2555. MISRA. Incorrect shifting expression.

Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.

При побитовом сдвиге значение правого операнда должно находиться в диапазоне [0 .. N - 1], где N - количество бит, которое необходимо для представления левого операнда. Несоблюдение этого правила ведет к неопределенному поведению.

На следующий код будут выданы соответствующие предупреждения:

(int32_t) 1 << 128u;
(unsigned int64_t) 2 >> 128u;
int64_X >>= 64u;
any_var << -2u;

Рассмотрим пример из реального приложения, в котором происходит неопределенное поведение вследствие неверного побитового сдвига:

UINT32 m_color1_mask;
UINT32 m_color2_mask;

#define ARRAY_LENGTH(x) (sizeof(x) / sizeof(x[0]))

PALETTE_INIT( montecar )
{
 static const UINT8 colortable_source[] =
 {
  0x00, 0x00, 0x00, 0x01,
  0x00, 0x02, 0x00, 0x03,
  0x03, 0x03, 0x03, 0x02,
  0x03, 0x01, 0x03, 0x00,
  0x00, 0x00, 0x02, 0x00,
  0x02, 0x01, 0x02, 0x02,
  0x00, 0x10, 0x20, 0x30,
  0x00, 0x04, 0x08, 0x0c,
  0x00, 0x44, 0x48, 0x4c,
  0x00, 0x84, 0x88, 0x8c,
  0x00, 0xc4, 0xc8, 0xcc
 };
 
 ....
 for (i = 0; i < ARRAY_LENGTH(colortable_source); i++)
 {
  UINT8 color = colortable_source[i];

  if (color == 1)
   state->m_color1_mask |= 1 << i;                  // <=
  else if (color == 2)
   state->m_color2_mask |= 1 << i;                  // <=

  prom_to_palette(machine, i,
    color_prom[0x100 + colortable_source[i]]);
 }
  ....
}

В коде в цикле на i-ой итерации сдвигают единицу на i позиций влево. В результате цикла переменная 'i' будет принимать значения в диапазоне [0 .. 43], что больше допустимого диапазона, начиная с 32-ой итерации цикла (в случае, если int - 32-х битовый тип данных).

Данная диагностика классифицируется как:

  • MISRA-C-12.2
  • MISRA-CPP-5.8.1