[C] Detecting halt/reset

Hello @mek363,

Currently, the analyzer works on each translation unit separately. So when it analyses TcpClientProcessConnection in TcpClientProcessConnection.c, it can see that the assert calls LogError after several macro expansions, but it does not know that this function, which is defined in reset.c, ultimately calls the function ResetBoard which is marked as __attribute__((noreturn)).

If LogError was always non-returning, a solution would be to declare LogError in a header, and decorate it with the noreturn attribute. However, this is not the case, so my suggestion would be to put in the header the first non-conditionally-noreturn function, as well as all functions leading to calling it (inline, of course). In your case, it could look like this (it will need more code to make this compile of course):

__attribute__((noreturn)) 
void Reset(resetMode_t mode); // Only the declaration

inline
void CriticalHalt(appError_t err, uint32_t cfsr, uint32_t state)
{
  int x = err + cfsr + state;
  
  // Perform a reset of the processor using the common implementation.
  if (x > 0)
    Reset(RESET_MODE_APPLICATION);
}

inline
appError_t LogError(appError_t err)
{
  if (APP_SEVERITY_IS_FAIL_HARD(APP_GET_SEVERITY(err))) {
    // If this is a critical error, go in to our halt logic. This does not
    // return
    CriticalHalt(err, 1, 2);
  }

  return err;
}

With this change, all code that includes this header will have the information needed to deduce when LogError returns and when it does not.

2 Likes