Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MISRA 2012 Rule 2.2 The result of this logical operation is always 'false'

Tags:

c

misra

qa-c

I need to check if a parameters fits in a well known list. To do so I wrote this function

#define INV       (0x1UL << 15U)
#define NON_INV   0X00000000U
#define RISING    0X00000000U
#define FALLING   (0x1UL << 1U)  
#define BOTH_EDGE ((0x1UL << 1U)|(0x1UL << 3U))  

bool IsTimClockPolarity(uint32_t pol)
{
    bool result = false;
    if ((pol == RISING) || (pol == FALLING) || (pol == INV) || (pol == NON_INV) || (pol == BOTH_EDGE))
    {
        result = true;
    }
    return result;
}

For the sake of clarity, these macros are target implemented for stm32h7 device, I didn't choose them. In QAC analyzer I have the following MISRA violation:

The result of this logical operation is always 'false'

Do you know how to solve this?

like image 282
Vincenzo Cristiano Avatar asked Sep 16 '25 04:09

Vincenzo Cristiano


1 Answers

The warning occurs because the subexpression pol == NON_INV is always false when it is evaluated.

Per C 2018 6.5.14, in an expression E1 || E2, the expression E2 is evaluated only if E1 is false (compares unequal to zero). Therefore, in (pol == RISING) || … || (pol == NON_INV) || …, (pol == NON_INV) is evaluated only if the prior tests are false. In particular, if (pol == NON_INV) is evaluated, we know that (pol == RISING) is false.

But RISING and INV are both defined to be zero, so (pol == NON_INV) and (pol == RISING) are each equivalent to (pol == 0). So, if we are evaluating (pol == NON_INV), we already know (pol == 0) is false, so (pol == NON_INV) must be false, and so the MISRA checker reports the result of (pol == NON_INV) is always false.

Additionally, I suspect the warning is apropos because the code is not doing what is intended. It looks like INV and FALLING are each supposed to be a bit flag indicating some event or condition, in which case the complement of that condition is not that the entire word pol is zero but rather that the specific bit is off. If so, pol == RISING and pol == NON_INV are the wrong tests for that. The entire expression must be corrected to properly test the desired compound condition, but we do not know what that is without further explanation of what INV and BOTH_EDGE mean and what the compound condition is supposed to be.

Regarding the phrasing of the warning, “The result of this logical operation…,” note that || operation in the formal C grammar is expressed as “logical-OR-expression || logical-AND-expression”. Thus, (pol == NON_INV) appears as an instance of a logical-AND-expression, and thus it is reasonable called a “logical expression.” While the technicalities of the C grammar may unfortunately present concepts and terminology that are not immediately evident to novices, if one is writing code to be highly safe, secure, portable, and reliable, as the use of MISRA indicates, then it is imperative not just to learn C code from practice but to study the C standard and learn it in detail.

like image 73
Eric Postpischil Avatar answered Sep 17 '25 19:09

Eric Postpischil