V2609. MISRA. There should be no occurrence of undefined or critical unspecified behaviour.
This diagnostic rule is based on the software development guidelines developed by MISRA (Motor Industry Software Reliability Association).
This rule is only relevant to C. If undefined behaviour occurs in a program, a developer has no guarantees how the program will run. This behaviour is inadmissible.
If critical unspecified behaviour occurs in a program, it means that depending on the compiler and its configuration, generated executable code may vary. This behaviour is inadmissible as well.
Undefined or unspecified behaviour can be unpredictable. Not all cases of undefined behaviour are recognizable. Therefore, an algorithm that guarantees the absence of undefined or unspecified behaviour in a particular program doesn't exist.
However, many situations may lead to undefined or critical unspecified behaviour. The analyzer can recognize them algorithmically. Let's look at some of these cases.
You can often determine possible dereferencing of a null pointer. Here is a code fragment:
void foo()
{
int len = GetLen();
char *str = (char *) malloc(mlen + 1);
str[len] = '\0';
}
There is no protection from null pointer dereferencing in this code. If the 'malloc' function cannot allocate memory, it will write 'nullptr' to the 'str' variable. Then 'nullptr' will be dereferenced in the expression 'str[len]', which is undefined behaviour. The analyzer will issue a warning:
V2609 Undefined behaviour should not occur. There might be dereferencing of a potential null pointer 'str'. Check lines: 4, 5.
At first, it may seem that such errors immediately lead to the program crash. At the beginning of the address space, the first pages of memory are protected by the operating system. And if you try to address to them, the operating system will generate a signal/exception. Which means the error is not critical. And that's not true.
- If the 'len' variable has a large value, the 'str[len]' expression can refer to relatively remote memory cells available for recording. Writing null there will lead to unpredictable consequences. That is, to undefined behaviour.
- A program crash is a critical error for some apps as well.
- In some microcontroller architectures, low addresses of the address space are not protected from recording. And the operating system will not detect the writing by the null pointer. They often don't have an operating system at all.
More detailed information you will find in the article: "Why it is important to check what the malloc function returned".
One more situation that analyzer can recognize algorithmically - a variable modification between two sequence points and repeated access to it.
Here is a code fragment:
void foo()
{
int *ptr;
....
*ptr++ = *(ptr + 1);
}
From developer's perspective, first, the 'ptr' pointer will be increased by 1. Then the expression 'ptr + 1' would be evaluated, and the new value 'ptr' would be used.
However, here, we access the 'ptr' variable twice between the two sequence points. One of the calls modifies the variable value. We deal with null pointer dereferencing here.
The analyzer will issue a warning:
V2609 Undefined behaviour should not occur. The 'bufl' variable is modified while being used twice between sequence points.
It is also possible to detect incorrect use of shift operators. Code example:
void foo()
{
int delta = -2;
....
int expr = DoSomeCalculations();
expr <<= delta;
}
Here, we see the shift of the 'expr' variable to the left by -2 bits. Shifting of negative values is an incorrect operation. It leads to undefined behaviour.
This diagnostic is classified as:
|