Почему SonarQube вызывает критическое замечание MISRA- C < > по "стартовому" коду для ARM Cortex-M3? - PullRequest
1 голос
/ 17 марта 2020

Generi c description

Я обнаружил следующее замечание SonarQube (MISRA- C: 2012) при реализации кода запуска в C для ARM Cortex-M3:

Имена функций следует использовать либо как вызов со списком параметров, либо с оператором «&»

со следующим описанием:

Использование «лысого» имени функции, скорее всего, ошибка. Вместо того, чтобы проверять возвращаемое значение функции со списком пустых параметров, она неявно получает адрес этой функции в памяти. Если это действительно то, что предназначено, то это следует сделать явным с помощью оператора & (address-of). Если это не так, то после имени функции следует добавить список параметров (даже пустой).

Я использую следующий компилятор:

armclang V6.12, с языком C99

Версия SonarQube:

Версия 6.7 (сборка 33306)

Замечание SonarQube вызывается в ссылке Reset_Handler внутри массива векторной таблицы. (см. код ниже)

Базовый c код, который был отсканирован:

/*----------------------------------------------------------------------------
  Exception / Interrupt Handler Function Prototype
 *----------------------------------------------------------------------------*/
typedef void (*pFunc)(void);

/*----------------------------------------------------------------------------
  External References
 *----------------------------------------------------------------------------*/
extern uint32_t __INITIAL_SP;

extern __NO_RETURN void __PROGRAM_START(void);

/*----------------------------------------------------------------------------
  Internal References
 *----------------------------------------------------------------------------*/
__NO_RETURN void Default_Handler(void);
__NO_RETURN void Reset_Handler(void);

/*----------------------------------------------------------------------------
  Exception / Interrupt Handler
 *----------------------------------------------------------------------------*/
/* Exceptions */
void NMI_Handler            (void) __attribute__ ((weak, alias("Default_Handler")));
void HardFault_Handler      (void) __attribute__ ((weak, alias("Default_Handler")));
void MemManage_Handler      (void) __attribute__ ((weak, alias("Default_Handler")));
void BusFault_Handler       (void) __attribute__ ((weak, alias("Default_Handler")));
void UsageFault_Handler     (void) __attribute__ ((weak, alias("Default_Handler")));
void SVC_Handler            (void) __attribute__ ((weak, alias("Default_Handler")));
void DebugMon_Handler       (void) __attribute__ ((weak, alias("Default_Handler")));
void PendSV_Handler         (void) __attribute__ ((weak, alias("Default_Handler")));
void SysTick_Handler        (void) __attribute__ ((weak, alias("Default_Handler")));
/*----------------------------------------------------------------------------
  Exception / Interrupt Vector table
 *----------------------------------------------------------------------------*/

extern const pFunc __VECTOR_TABLE[16];
       const pFunc __VECTOR_TABLE[16] __VECTOR_TABLE_ATTRIBUTE = {
  (pFunc)(&__INITIAL_SP),                   /*     Initial Stack Pointer */
  Reset_Handler,                            /*     Reset Handler <<<<<------ WHERE THE SONARQUBE REMARK IS */
  NMI_Handler,                              /* -14 NMI Handler */
  HardFault_Handler,                        /* -13 Hard Fault Handler */
  MemManage_Handler,                        /* -12 MPU Fault Handler */
  BusFault_Handler,                         /* -11 Bus Fault Handler */
  UsageFault_Handler,                       /* -10 Usage Fault Handler */
  0,                                        /*     Reserved */
  0,                                        /*     Reserved */
  0,                                        /*     Reserved */
  0,                                        /*     Reserved */
  SVC_Handler,                              /*  -5 SVCall Handler */
  DebugMon_Handler,                         /*  -4 Debug Monitor Handler */
  0,                                        /*     Reserved */
  PendSV_Handler,                           /*  -2 PendSV Handler */
  SysTick_Handler,                          /*  -1 SysTick Handler */
};

void Reset_Handler(void)
{
    SystemInit(); // CMSIS System Initialization
    __PROGRAM_START(); // Enter PreMain (C library entry point)
}

void Default_Handler(void)
{
    while (1) {
        __asm volatile(""); /* this line is considered to have side-effects */
    }
}

Базовая c проблема

Я не совсем понимаю, почему он жалуется в данный момент, и я не вижу, что мне не хватает:
- функция указатель определяется в начале pFun c
- тип возвращаемого значения определяется как void , а также нет параметров для функций
- тип массив Vector Table имеет вид "pFun c"
- оба Default_Handler , а также Reset_Handler соответствуют правильному прототипу, определенному указателем функции

Любая помощь будет оценена. :)

Спасибо.

Позднее редактирование

@ Лундин Я нашел следующий пример несовместимого кода:

int func(void) {
  // ...
}

void f2(int a, int b) {
  // ...
  if (func) {  // Noncompliant - tests that the memory address of func() is non-null
    //...
  }
  // ...
}  

Соответствующий код:

void f2(int a, int b) {
  // ...
  if (func()) {  // tests that the return value of func() > 0
    //...
  }
  // ...
}

Так что, похоже, вы правы. Инструмент думает, что это другая проблема.

1 Ответ

0 голосов
/ 17 марта 2020

Предупреждение SonarQube жалуется на то, что вы используете имя функции, не вызывая ее, подозревая, что вы намеревались фактически вызвать ее.

Поскольку имя функции автоматически преобразуется в указатель на функцию , func и &func относятся к одной и той же вещи, поэтому вы можете использовать их взаимозаменяемо.

Поскольку вы не пытаетесь вызывать функции, а вместо этого помещаете их адреса в массив, используйте адрес -of, чтобы сделать явным, что вы хотите взять адрес функции вместо ее вызова вместе с любыми другими указателями на функции.

extern const pFunc __VECTOR_TABLE[16];
       const pFunc __VECTOR_TABLE[16] __VECTOR_TABLE_ATTRIBUTE = {
  (pFunc)(&__INITIAL_SP),                    /*     Initial Stack Pointer */
  &Reset_Handler,                            /*     Reset Handler */
  &NMI_Handler,                              /* -14 NMI Handler */
  &HardFault_Handler,                        /* -13 Hard Fault Handler */
  &MemManage_Handler,                        /* -12 MPU Fault Handler */
  &BusFault_Handler,                         /* -11 Bus Fault Handler */
  &UsageFault_Handler,                       /* -10 Usage Fault Handler */
  NULL,                                      /*     Reserved */
  NULL,                                       /*     Reserved */
  NULL,                                      /*     Reserved */
  NULL,                                      /*     Reserved */
  &SVC_Handler,                              /*  -5 SVCall Handler */
  &DebugMon_Handler,                         /*  -4 Debug Monitor Handler */
  NULL,                                      /*     Reserved */
  &PendSV_Handler,                           /*  -2 PendSV Handler */
  &SysTick_Handler,                          /*  -1 SysTick Handler */
};
...