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.