Why does SonarQube raise a MISRA-C critical remark <<Function names should be used either as a call […]>> on the “startup” code for ARM Cortex-M3?

Must-share information (formatted with Markdown):

  • which versions are you using (SonarQube, Scanner, Plugin, and any relevant extension)
    • SonarQube version: Version 6.7 (build 33306)
    • Language: C
    • Quality Profile: (C) Sonar way (This quality profile is provided by a plugin)
    • Quality Gate: (Default) SonarQube way

Hi all,

Generic description

I encountered the following SonarQube remark (MISRA-C:2012), while implementing the startup code in C, for an ARM Cortex-M3:

Function names should be used either as a call with a parameter list or with the “&” operator

with the following description:

Using a “bald” function name is likely a bug. Rather than testing the return value of a function with a void parameter list, it implicitly retrieves the address of that function in memory. If that’s truly what’s intended, then it should be made explicit with the use of the & (address-of) operator. If it’s not, then a parameter list (even an empty one) should be added after the function name.

I am using the following compiler:

armclang V6.12, with Language C99


The SonarQube remark is raised on the Reference of Reset_Handler inside the Vector Table array. (see the code below)

The basic code that was scanned:

/*----------------------------------------------------------------------------
  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 */
    }
}

The basic problem

I don’t really understand why it complains at that particular point, and I don’t really see what am I missing:
- the function pointer is defined at the beginning pFunc
- the return type is defined as void, and also there are no parameters for the functions
- the type of the Vector Table array is “pFunc”
- both the Default_Handler, as well as the Reset_Handler match the correct prototype as defined by the function pointer

Any help would be appreciated. :slight_smile:

Thank you.

Closed the topic. Apparently, this is a false-flag raised by SonarQube, because it expects the functions to be called.
However, the intent in this particular case, is to just store the Handler functions addresses in the Interrupt Vector table, but NOT call the functions explicitly.

Hello @AlexandruAn,

Welcome to the community!

This seems like a false-positive.
I couldn’t reproduce the issue on my side. It might be related to parsing error or a bug on our side.
To help me debug the issue

  • Can you share the scanner log in debug mode?
  • After that can you add the reproducer option to the scanner configuration:
    sonar.cfamily.reproducer= "Full path to the .cpp file that has the false-positive"
    This should create a file named sonar-cfamily.reproducer in the project folder. This file will help me in debugging the issue.

Hi @Abbas,

Thank you for your reply.

Unfortunately, I am not very experienced in the Sonarqube, so I would need some help:

  • What would be the scanner log in debug mode? Where can I find it?
  • Should I add the following option sonar.cfamily.reproducer= “Full path to the .cpp file that has the false-positive” in the sonar-project.properties file?

Thank you for your help and patience. :slight_smile:

@AlexandruAn

  • When you run sonar-scanner you can pass -X or --debug to display debug output. you can redirect them to a file and upload it here so I can have a look if everything is configured correctly.

yes. but you should replace “Full path to the .cpp file that has the false-positive” by your actual file full path.